सहायता Kaggle पर TensorFlow साथ ग्रेट बैरियर रीफ की रक्षा चैलेंज में शामिल हों

TensorFlow विवश अनुकूलन अनुकूलन CelebA डेटासेट का उपयोग करना

TensorFlow.org पर देखें Google Colab में चलाएं गिटहब पर देखें नोटबुक डाउनलोड करें

यह नोटबुक TFCO लाइब्रेरी का उपयोग करके विवश समस्याओं के निर्माण और अनुकूलन का एक आसान तरीका प्रदर्शित करता है। यह विधि उन मॉडलों को बेहतर बनाने में उपयोगी हो सकती है जब हम पाते हैं कि वे हमारे डेटा के विभिन्न स्लाइस में समान रूप से अच्छा प्रदर्शन नहीं कर रहे हैं, जिसे हम फेयरनेस संकेतक का उपयोग करके पहचान सकते हैं। Google के AI सिद्धांतों में से दूसरा कहता है कि हमारी तकनीक को अनुचित पूर्वाग्रह बनाने या मजबूत करने से बचना चाहिए, और हमारा मानना ​​है कि यह तकनीक कुछ स्थितियों में मॉडल निष्पक्षता में सुधार करने में मदद कर सकती है। विशेष रूप से, यह नोटबुक होगा:

  • tf.keras और बड़े पैमाने पर CelebFaces Attributes ( CelebA ) डेटासेट का उपयोग करके छवियों में किसी व्यक्ति की मुस्कान का पता लगाने के लिए एक सरल, बिना tf.keras तंत्रिका नेटवर्क मॉडल को प्रशिक्षित करें
  • फेयरनेस संकेतक का उपयोग करते हुए, आयु समूहों में आमतौर पर उपयोग किए जाने वाले निष्पक्षता मीट्रिक के खिलाफ मॉडल प्रदर्शन का मूल्यांकन करें।
  • आयु समूहों में उचित प्रदर्शन प्राप्त करने के लिए एक सरल विवश अनुकूलन समस्या का समाधान करें।
  • अब विवश मॉडल को पुनः धारण करें और फिर से प्रदर्शन का मूल्यांकन करें, यह सुनिश्चित करें कि हमारे चुने हुए निष्पक्षता मीट्रिक में सुधार हुआ है।

अंतिम अद्यतन: 3/11 फरवरी 2020

इंस्टालेशन

यह नोटबुक Colaboratory में बनाई गई थी, जो Python 3 Google Compute Engine backend से जुड़ी थी। यदि आप इस नोटबुक को एक अलग वातावरण में होस्ट करना चाहते हैं, तो आपको किसी भी बड़े मुद्दे का अनुभव नहीं करना चाहिए, बशर्ते कि आप नीचे दिए गए कक्षों में सभी आवश्यक पैकेजों को शामिल करें।

ध्यान दें कि जब आप पहली बार पाइप इंस्टॉल चलाते हैं, तो आपसे पुराने पैकेज को प्रीइंस्टॉल्ड करने के कारण रनटाइम को फिर से शुरू करने के लिए कहा जा सकता है। एक बार जब आप ऐसा करते हैं, तो सही पैकेज का उपयोग किया जाएगा।

पिप स्थापित करता है

ध्यान दें कि जब आप नीचे दिए गए सेल को चलाते हैं, तो आपको जल्द ही Colens में TensorFlow के TensorFlow 2.X पर स्विच करने के डिफ़ॉल्ट संस्करण के बारे में चेतावनी मिल सकती है। आप सुरक्षित रूप से उस चेतावनी को अनदेखा कर सकते हैं क्योंकि इस नोटबुक को TensorFlow 1.X और 2.X के साथ संगत करने के लिए डिज़ाइन किया गया था।

आयात मॉड्यूल

इसके अतिरिक्त, हम कुछ आयात जोड़ते हैं जो फेयरनेस इंडिकेटर्स के लिए विशिष्ट हैं जिन्हें हम मॉडल के प्रदर्शन का मूल्यांकन और कल्पना करने के लिए उपयोग करेंगे।

हालांकि TFCO उत्सुक और ग्राफ निष्पादन के साथ संगत है, यह नोटबुक मानता है कि उत्सुक निष्पादन डिफ़ॉल्ट रूप से सक्षम है जैसा कि TensorFlow 2.x में है। यह सुनिश्चित करने के लिए कि कुछ भी नहीं टूटता है, नीचे दिए गए सेल में उत्सुक निष्पादन सक्षम होगा।

ईगर निष्पादन और प्रिंट संस्करण सक्षम करें

Eager execution enabled by default.
TensorFlow 2.4.1
TFMA 0.29.0
TFDS 4.2.0
FI 0.29.0

सेलेबा डेटासैट

CelebA 200,000 से अधिक सेलेब्रिटी छवियों के साथ बड़े पैमाने पर चेहरे की विशेषता वाले डेटासेट हैं, जिनमें से प्रत्येक में 40 विशेषता एनोटेशन (जैसे कि बालों के प्रकार, फैशन के सामान, चेहरे की विशेषताएं, आदि) और 5 लैंडमार्क स्थान (आँखें, मुंह और नाक के स्थान) हैं। अधिक जानकारी के लिए कागज पर एक नज़र डालें। मालिकों की अनुमति के साथ, हमने इस डेटासेट को Google क्लाउड स्टोरेज पर संग्रहीत किया है और अधिकतर इसे TensorFlow Datasets ( tfds ) के माध्यम से एक्सेस करते हैं।

इस नोटबुक में:

  • हमारा मॉडल यह वर्गीकृत करने का प्रयास करेगा कि क्या छवि का विषय मुस्कुरा रहा है, जैसा कि "स्माइलिंग" विशेषता * द्वारा दर्शाया गया है।
  • प्रशिक्षण के समय निष्पादन और स्मृति को कम करने के लिए छवियों को 218x178 से 28x28 तक आकार दिया जाएगा।
  • हमारे मॉडल के प्रदर्शन का मूल्यांकन बाइनरी "यंग" विशेषता का उपयोग करके आयु समूहों में किया जाएगा। हम इस "आयु समूह" को इस नोटबुक में कहेंगे।

* जबकि इस डेटासेट के लिए लेबलिंग पद्धति के बारे में बहुत कम जानकारी उपलब्ध है, हम मानेंगे कि "मुस्कुराते हुए" विशेषता विषय के चेहरे पर एक प्रसन्न, दयालु या आकर्षक अभिव्यक्ति द्वारा निर्धारित की गई थी। इस केस स्टडी के उद्देश्य के लिए, हम इन लेबल को जमीनी सच्चाई के रूप में लेंगे।

gcs_base_dir = "gs://celeb_a_dataset/"
celeb_a_builder = tfds.builder("celeb_a", data_dir=gcs_base_dir, version='2.0.0')

celeb_a_builder.download_and_prepare()

num_test_shards_dict = {'0.3.0': 4, '2.0.0': 2} # Used because we download the test dataset separately
version = str(celeb_a_builder.info.version)
print('Celeb_A dataset version: %s' % version)
Celeb_A dataset version: 2.0.0

डेटासेट हेल्पर फ़ंक्शन का परीक्षण करें

चेतावनियां

आगे बढ़ने से पहले, CelebA का उपयोग करने में ध्यान में रखने के लिए कई विचार हैं:

  • यद्यपि सिद्धांत रूप में यह नोटबुक चेहरे की छवियों के किसी भी डेटासेट का उपयोग कर सकता है, CelebA को चुना गया क्योंकि इसमें सार्वजनिक आंकड़ों की सार्वजनिक डोमेन छवियां हैं।
  • CelebA में सभी विशेषता एनोटेशन बाइनरी श्रेणियों के रूप में सक्रिय हैं। उदाहरण के लिए, "यंग" विशेषता (जैसा कि डेटासेट लेबलर्स द्वारा निर्धारित किया गया है) को छवि में मौजूद या अनुपस्थित के रूप में दर्शाया गया है।
  • सेलेबा के वर्गीकरण वास्तविक मानव विविधता की विशेषताओं को नहीं दर्शाते हैं।
  • इस नोटबुक के प्रयोजनों के लिए, "यंग" विशेषता वाले फीचर को "आयु समूह" के रूप में संदर्भित किया जाता है, जहां एक छवि में "यंग" विशेषता की उपस्थिति को "युवा" आयु वर्ग के सदस्य के रूप में लेबल किया जाता है। "यंग" विशेषता की अनुपस्थिति को "नॉट यंग" आयु समूह के सदस्य के रूप में लेबल किया गया है। इन मान्यताओं को बनाया गया है क्योंकि यह जानकारी मूल कागज में वर्णित नहीं है।
  • इस प्रकार, इस नोटबुक में प्रशिक्षित मॉडलों में प्रदर्शन उन तरीकों से जुड़ा हुआ है, जिन्हें CelebA के लेखकों द्वारा संचालित और एनोटेट किया गया है।
  • इस मॉडल का उपयोग वाणिज्यिक उद्देश्यों के लिए नहीं किया जाना चाहिए क्योंकि यह सेलेबस के गैर-वाणिज्यिक अनुसंधान समझौते का उल्लंघन करेगा।

इनपुट फ़ंक्शंस सेट करना

बाद की कोशिकाएँ इनपुट पाइपलाइन को सुव्यवस्थित करने के साथ-साथ प्रदर्शन की कल्पना करने में मदद करेंगी।

पहले हम कुछ डेटा-संबंधित चर को परिभाषित करते हैं और एक अपेक्षित प्रीप्रोसेसिंग फ़ंक्शन को परिभाषित करते हैं।

चर को परिभाषित करें

प्रीप्रोसेसिंग फ़ंक्शंस को परिभाषित करें

फिर, हम बाकी के कोलाब में आवश्यक डेटा फ़ंक्शन का निर्माण करते हैं।

# Train data returning either 2 or 3 elements (the third element being the group)
def celeb_a_train_data_wo_group(batch_size):
  celeb_a_train_data = celeb_a_builder.as_dataset(split='train').shuffle(1024).repeat().batch(batch_size).map(preprocess_input_dict)
  return celeb_a_train_data.map(get_image_and_label)
def celeb_a_train_data_w_group(batch_size):
  celeb_a_train_data = celeb_a_builder.as_dataset(split='train').shuffle(1024).repeat().batch(batch_size).map(preprocess_input_dict)
  return celeb_a_train_data.map(get_image_label_and_group)

# Test data for the overall evaluation
celeb_a_test_data = celeb_a_builder.as_dataset(split='test').batch(1).map(preprocess_input_dict).map(get_image_label_and_group)
# Copy test data locally to be able to read it into tfma
copy_test_files_to_local()

एक साधारण DNN मॉडल बनाएँ

क्योंकि यह नोटबुक TFCO पर केंद्रित है, इसलिए हम एक सरल, tf.keras.Sequential मॉडल को इकट्ठा करेंगे।

हम कुछ जटिलता जोड़कर मॉडल प्रदर्शन को बेहतर बनाने में सक्षम हो सकते हैं (जैसे, अधिक घनी-जुड़ी परतें, अलग-अलग सक्रियण कार्यों की खोज करना, छवि का आकार बढ़ाना), लेकिन यह प्रदर्शन के लक्ष्य से विचलित हो सकता है कि TFCO लाइब्रेरी को लागू करना कितना आसान है जब केरस के साथ काम करना। उस कारण से, मॉडल को सरल रखा जाएगा - लेकिन इस स्थान का पता लगाने के लिए प्रोत्साहित महसूस करें।

def create_model():
  # For this notebook, accuracy will be used to evaluate performance.
  METRICS = [
    tf.keras.metrics.BinaryAccuracy(name='accuracy')
  ]

  # The model consists of:
  # 1. An input layer that represents the 28x28x3 image flatten.
  # 2. A fully connected layer with 64 units activated by a ReLU function.
  # 3. A single-unit readout layer to output real-scores instead of probabilities.
  model = keras.Sequential([
      keras.layers.Flatten(input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3), name='image'),
      keras.layers.Dense(64, activation='relu'),
      keras.layers.Dense(1, activation=None)
  ])

  # TFCO by default uses hinge loss — and that will also be used in the model.
  model.compile(
      optimizer=tf.keras.optimizers.Adam(0.001),
      loss='hinge',
      metrics=METRICS)
  return model

हम प्रजनन योग्य परिणाम सुनिश्चित करने के लिए बीज निर्धारित करने के लिए एक फ़ंक्शन को भी परिभाषित करते हैं। ध्यान दें कि यह कोलाब एक शैक्षिक उपकरण के रूप में है और इसमें सूक्ष्मता से निर्मित उत्पादन पाइपलाइन की स्थिरता नहीं है। बीज की स्थापना के बिना चलने से विभिन्न परिणाम हो सकते हैं।

def set_seeds():
  np.random.seed(121212)
  tf.compat.v1.set_random_seed(212121)

निष्पक्षता संकेतक हेल्पर कार्य

हमारे मॉडल को प्रशिक्षित करने से पहले, हम कई सहायक कार्यों को परिभाषित करते हैं जो हमें निष्पक्षता संकेतक के माध्यम से मॉडल के प्रदर्शन का मूल्यांकन करने की अनुमति देगा।

सबसे पहले, हम अपने मॉडल को बचाने के लिए एक सहायक समारोह बनाते हैं, जब हम इसे प्रशिक्षित करते हैं।

def save_model(model, subdir):
  base_dir = tempfile.mkdtemp(prefix='saved_models')
  model_location = os.path.join(base_dir, subdir)
  model.save(model_location, save_format='tf')
  return model_location

अगला, हम TFMA के माध्यम से इसे सही ढंग से पारित करने के लिए डेटा को प्रीप्रोसेस करने के लिए उपयोग किए जाने वाले फ़ंक्शन को परिभाषित करते हैं।

डेटा प्रीप्रोसेसिंग फ़ंक्शंस के लिए

अंत में, हम एक फ़ंक्शन को परिभाषित करते हैं जो TFMA में परिणामों का मूल्यांकन करता है।

def get_eval_results(model_location, eval_subdir):
  base_dir = tempfile.mkdtemp(prefix='saved_eval_results')
  tfma_eval_result_path = os.path.join(base_dir, eval_subdir)

  eval_config_pbtxt = """
        model_specs {
          label_key: "%s"
        }
        metrics_specs {
          metrics {
            class_name: "FairnessIndicators"
            config: '{ "thresholds": [0.22, 0.5, 0.75] }'
          }
          metrics {
            class_name: "ExampleCount"
          }
        }
        slicing_specs {}
        slicing_specs { feature_keys: "%s" }
        options {
          compute_confidence_intervals { value: False }
          disabled_outputs{values: "analysis"}
        }
      """ % (LABEL_KEY, GROUP_KEY)

  eval_config = text_format.Parse(eval_config_pbtxt, tfma.EvalConfig())

  eval_shared_model = tfma.default_eval_shared_model(
        eval_saved_model_path=model_location, tags=[tf.saved_model.SERVING])

  schema_pbtxt = """
        tensor_representation_group {
          key: ""
          value {
            tensor_representation {
              key: "%s"
              value {
                dense_tensor {
                  column_name: "%s"
                  shape {
                    dim { size: 28 }
                    dim { size: 28 }
                    dim { size: 3 }
                  }
                }
              }
            }
          }
        }
        feature {
          name: "%s"
          type: FLOAT
        }
        feature {
          name: "%s"
          type: FLOAT
        }
        feature {
          name: "%s"
          type: BYTES
        }
        """ % (IMAGE_KEY, IMAGE_KEY, IMAGE_KEY, LABEL_KEY, GROUP_KEY)
  schema = text_format.Parse(schema_pbtxt, schema_pb2.Schema())
  coder = tf_example_record.TFExampleBeamRecord(
      physical_format='inmem', schema=schema,
      raw_record_column_name=tfma.ARROW_INPUT_COLUMN)
  tensor_adapter_config = tensor_adapter.TensorAdapterConfig(
    arrow_schema=coder.ArrowSchema(),
    tensor_representations=coder.TensorRepresentations())
  # Run the fairness evaluation.
  with beam.Pipeline() as pipeline:
    _ = (
          tfds_as_pcollection(pipeline, 'celeb_a', 'test')
          | 'ExamplesToRecordBatch' >> coder.BeamSource()
          | 'ExtractEvaluateAndWriteResults' >>
          tfma.ExtractEvaluateAndWriteResults(
              eval_config=eval_config,
              eval_shared_model=eval_shared_model,
              output_path=tfma_eval_result_path,
              tensor_adapter_config=tensor_adapter_config)
    )
  return tfma.load_eval_result(output_path=tfma_eval_result_path)

ट्रेन और बिना पढ़े मॉडल का मूल्यांकन

अब परिभाषित मॉडल और जगह में इनपुट पाइपलाइन के साथ, अब हम अपने मॉडल को प्रशिक्षित करने के लिए तैयार हैं। निष्पादन समय और मेमोरी की मात्रा में कटौती करने के लिए, हम केवल कुछ दोहराए गए पुनरावृत्तियों के साथ डेटा को छोटे बैचों में विभाजित करके मॉडल को प्रशिक्षित करेंगे।

ध्यान दें कि TensorFlow <2.0.0 में इस नोटबुक को चलाने से np.where के लिए एक np.where चेतावनी मिल np.where । सुरक्षित रूप से इस चेतावनी को अनदेखा रूप TensorFlow का उपयोग करके 2.x में इस पते, tf.where के स्थान पर np.where

BATCH_SIZE = 32

# Set seeds to get reproducible results
set_seeds()

model_unconstrained = create_model()
model_unconstrained.fit(celeb_a_train_data_wo_group(BATCH_SIZE), epochs=5, steps_per_epoch=1000)
Epoch 1/5
1000/1000 [==============================] - 17s 11ms/step - loss: 0.6219 - accuracy: 0.7189
Epoch 2/5
1000/1000 [==============================] - 10s 10ms/step - loss: 0.4061 - accuracy: 0.8187
Epoch 3/5
1000/1000 [==============================] - 10s 10ms/step - loss: 0.3649 - accuracy: 0.8391
Epoch 4/5
1000/1000 [==============================] - 16s 16ms/step - loss: 0.3427 - accuracy: 0.8485
Epoch 5/5
1000/1000 [==============================] - 10s 10ms/step - loss: 0.3390 - accuracy: 0.8482
<tensorflow.python.keras.callbacks.History at 0x7f47c01a8550>

परीक्षण डेटा पर मॉडल का मूल्यांकन करने का परिणाम 85% से अधिक की अंतिम सटीकता स्कोर होना चाहिए। बिना ठीक ट्यूनिंग के एक साधारण मॉडल के लिए बुरा नहीं है।

print('Overall Results, Unconstrained')
celeb_a_test_data = celeb_a_builder.as_dataset(split='test').batch(1).map(preprocess_input_dict).map(get_image_label_and_group)
results = model_unconstrained.evaluate(celeb_a_test_data)
Overall Results, Unconstrained
19962/19962 [==============================] - 40s 2ms/step - loss: 0.2125 - accuracy: 0.8636

हालाँकि, आयु समूहों में किए गए प्रदर्शन से कुछ कमियों का पता चल सकता है।

इसे और जानने के लिए, हम निष्पक्षता संकेतक (TFMA के माध्यम से) के साथ मॉडल का मूल्यांकन करते हैं। विशेष रूप से, हम यह देखने में रुचि रखते हैं कि क्या सकारात्मक दर पर मूल्यांकन किए जाने पर "यंग" और "नॉट यंग" श्रेणियों के बीच महत्वपूर्ण अंतर है।

एक गलत सकारात्मक त्रुटि तब होती है जब मॉडल गलत तरीके से सकारात्मक वर्ग की भविष्यवाणी करता है। इस संदर्भ में, एक गलत सकारात्मक परिणाम तब होता है जब जमीनी सच्चाई एक सेलिब्रिटी 'नॉट स्माइलिंग' की छवि होती है और मॉडल 'स्माइलिंग' की भविष्यवाणी करता है। विस्तार से, झूठी सकारात्मक दर, जो ऊपर विज़ुअलाइज़ेशन में उपयोग की जाती है, एक परीक्षण के लिए सटीकता का एक उपाय है। हालांकि इस संदर्भ में एक अपेक्षाकृत सांसारिक त्रुटि है, झूठी सकारात्मक त्रुटियां कभी-कभी अधिक समस्याग्रस्त व्यवहार का कारण बन सकती हैं। उदाहरण के लिए, स्पैम क्लासिफ़ायर में झूठी सकारात्मक त्रुटि उपयोगकर्ता को एक महत्वपूर्ण ईमेल मिस कर सकती है।

model_location = save_model(model_unconstrained, 'model_export_unconstrained')
eval_results_unconstrained = get_eval_results(model_location, 'eval_results_unconstrained')
INFO:tensorflow:Assets written to: /tmp/saved_modelseqklzviu/model_export_unconstrained/assets
INFO:tensorflow:Assets written to: /tmp/saved_modelseqklzviu/model_export_unconstrained/assets
WARNING:apache_beam.runners.interactive.interactive_environment:Dependencies required for Interactive Beam PCollection visualization are not available, please use: `pip install apache-beam[interactive]` to install necessary dependencies to enable all data visualization features.
WARNING:apache_beam.io.tfrecordio:Couldn't find python-snappy so the implementation of _TFRecordUtil._masked_crc32c is not as fast as it could be.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:113: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:113: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

जैसा कि ऊपर उल्लेख किया गया है, हम झूठी सकारात्मक दर पर ध्यान केंद्रित कर रहे हैं। फेयरनेस इंडिकेटर्स का मौजूदा संस्करण (0.1.2) डिफ़ॉल्ट रूप से झूठी नकारात्मक दर का चयन करता है। नीचे दी गई लाइन चलाने के बाद, हम जिस मीट्रिक में रुचि रखते हैं उसे देखने के लिए false_negative_rate का चयन करें और false_positive_rate का चयन करें।

tfma.addons.fairness.view.widget_view.render_fairness_indicator(eval_results_unconstrained)
FairnessIndicatorViewer(slicingMetrics=[{'sliceValue': 'Overall', 'slice': 'Overall', 'metrics': {'example_cou…

जैसा कि परिणाम ऊपर दिखाते हैं, हम "युवा" और "नॉट यंग" श्रेणियों के बीच एक असमान अंतर देखते हैं।

यह वह जगह है जहां TFCO झूठी सकारात्मक दर को अधिक स्वीकार्य मानदंड के भीतर होने के लिए बाध्य करके मदद कर सकता है।

विवश मॉडल सेट अप

टीएफसीओ के पुस्तकालय में प्रलेखित के रूप में, कई सहायक हैं जो समस्या को कम करने के लिए आसान बनाएंगे:

  1. tfco.rate_context() - यह वह है जिसका उपयोग प्रत्येक आयु वर्ग की श्रेणी के लिए एक बाधा के निर्माण में किया जाएगा।
  2. tfco.RateMinimizationProblem() - यहां न्यूनतम की जाने वाली दर अभिव्यक्ति झूठी सकारात्मक दर आयु वर्ग के अधीन होगी। दूसरे शब्दों में, प्रदर्शन का मूल्यांकन अब आयु समूह की झूठी सकारात्मक दरों और समग्र डेटासेट के अंतर के आधार पर किया जाएगा। इस प्रदर्शन के लिए, 5% से कम या उसके बराबर की झूठी सकारात्मक दर को बाधा के रूप में सेट किया जाएगा।
  3. tfco.ProxyLagrangianOptimizerV2() - यह सहायक है जो वास्तव में दर बाधा समस्या का समाधान करेगा।

नीचे दी गई सेल निष्पक्षता की कमी के साथ मॉडल प्रशिक्षण स्थापित करने के लिए इन सहायकों को बुलाएगी।

# The batch size is needed to create the input, labels and group tensors.
# These tensors are initialized with all 0's. They will eventually be assigned
# the batch content to them. A large batch size is chosen so that there are
# enough number of "Young" and "Not Young" examples in each batch.
set_seeds()
model_constrained = create_model()
BATCH_SIZE = 32

# Create input tensor.
input_tensor = tf.Variable(
    np.zeros((BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3), dtype="float32"),
    name="input")

# Create labels and group tensors (assuming both labels and groups are binary).
labels_tensor = tf.Variable(
    np.zeros(BATCH_SIZE, dtype="float32"), name="labels")
groups_tensor = tf.Variable(
    np.zeros(BATCH_SIZE, dtype="float32"), name="groups")

# Create a function that returns the applied 'model' to the input tensor
# and generates constrained predictions.
def predictions():
  return model_constrained(input_tensor)

# Create overall context and subsetted context.
# The subsetted context contains subset of examples where group attribute < 1
# (i.e. the subset of "Not Young" celebrity images).
# "groups_tensor < 1" is used instead of "groups_tensor == 0" as the former
# would be a comparison on the tensor value, while the latter would be a
# comparison on the Tensor object.
context = tfco.rate_context(predictions, labels=lambda:labels_tensor)
context_subset = context.subset(lambda:groups_tensor < 1)

# Setup list of constraints.
# In this notebook, the constraint will just be: FPR to less or equal to 5%.
constraints = [tfco.false_positive_rate(context_subset) <= 0.05]

# Setup rate minimization problem: minimize overall error rate s.t. constraints.
problem = tfco.RateMinimizationProblem(tfco.error_rate(context), constraints)

# Create constrained optimizer and obtain train_op.
# Separate optimizers are specified for the objective and constraints
optimizer = tfco.ProxyLagrangianOptimizerV2(
      optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
      constraint_optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
      num_constraints=problem.num_constraints)

# A list of all trainable variables is also needed to use TFCO.
var_list = (model_constrained.trainable_weights + list(problem.trainable_variables) +
            optimizer.trainable_variables())

मॉडल को अब सेट किया गया है और आयु समूह में झूठी सकारात्मक दर बाधा के साथ प्रशिक्षित होने के लिए तैयार है।

अब, क्योंकि विवश मॉडल की अंतिम पुनरावृत्ति परिभाषित बाधा के संदर्भ में सबसे अच्छा प्रदर्शन करने वाला मॉडल नहीं हो सकता है, TFCO लाइब्रेरी tfco.find_best_candidate_index() सुसज्जित है जो प्रत्येक के बाद पाए जाने वाले सर्वश्रेष्ठ पुनरावृति को चुनने में मदद कर सकता है। युग। tfco.find_best_candidate_index() को जोड़ा गया अनुमान के रूप में देखें, जो सटीकता और निष्पक्षता की कमी के आधार पर प्रत्येक परिणाम को रैंक करता है (इस मामले में, आयु समूह में झूठी सकारात्मक दर) प्रशिक्षण डेटा के संबंध में अलग से। इस तरह, यह समग्र सटीकता और निष्पक्षता की कमी के बीच एक बेहतर व्यापार बंद की तलाश कर सकता है।

निम्नलिखित कोशिकाएं प्रति बाधा का सबसे अच्छा प्रदर्शन करने वाला मॉडल ढूंढते हुए बाधाओं के साथ प्रशिक्षण शुरू करेंगी।

# Obtain train set batches.

NUM_ITERATIONS = 100  # Number of training iterations.
SKIP_ITERATIONS = 10  # Print training stats once in this many iterations.

# Create temp directory for saving snapshots of models.
temp_directory = tempfile.mktemp()
os.mkdir(temp_directory)

# List of objective and constraints across iterations.
objective_list = []
violations_list = []

# Training iterations.
iteration_count = 0
for (image, label, group) in celeb_a_train_data_w_group(BATCH_SIZE):
  # Assign current batch to input, labels and groups tensors.
  input_tensor.assign(image)
  labels_tensor.assign(label)
  groups_tensor.assign(group)

  # Run gradient update.
  optimizer.minimize(problem, var_list=var_list)

  # Record objective and violations.
  objective = problem.objective()
  violations = problem.constraints()

  sys.stdout.write(
      "\r Iteration %d: Hinge Loss = %.3f, Max. Constraint Violation = %.3f"
      % (iteration_count + 1, objective, max(violations)))

  # Snapshot model once in SKIP_ITERATIONS iterations.
  if iteration_count % SKIP_ITERATIONS == 0:
    objective_list.append(objective)
    violations_list.append(violations)

    # Save snapshot of model weights.
    model_constrained.save_weights(
        temp_directory + "/celeb_a_constrained_" +
        str(iteration_count / SKIP_ITERATIONS) + ".h5")

  iteration_count += 1
  if iteration_count >= NUM_ITERATIONS:
    break

# Choose best model from recorded iterates and load that model.
best_index = tfco.find_best_candidate_index(
    np.array(objective_list), np.array(violations_list))

model_constrained.load_weights(
    temp_directory + "/celeb_a_constrained_" + str(best_index) + ".0.h5")

# Remove temp directory.
os.system("rm -r " + temp_directory)
Iteration 100: Hinge Loss = 0.614, Max. Constraint Violation = 0.268
0

बाधा लागू करने के बाद, हम एक बार फिर निष्पक्ष संकेतक का उपयोग करके परिणामों का मूल्यांकन करते हैं।

model_location = save_model(model_constrained, 'model_export_constrained')
eval_result_constrained = get_eval_results(model_location, 'eval_results_constrained')
INFO:tensorflow:Assets written to: /tmp/saved_modelsrnjadh_e/model_export_constrained/assets
INFO:tensorflow:Assets written to: /tmp/saved_modelsrnjadh_e/model_export_constrained/assets

पिछली बार की तरह हमने निष्पक्षता संकेतक का उपयोग किया, झूठे_नेगेटिव_डेट को अचयनित किया और जिस मीट्रिक में हम रुचि रखते हैं उसे देखने के लिए false_positive_rate का चयन करें।

ध्यान दें कि हमारे मॉडल के दो संस्करणों की तुलना करने के लिए, थ्रेसहोल्ड का उपयोग करना महत्वपूर्ण है जो समग्र झूठी सकारात्मक दर को लगभग बराबर करने के लिए निर्धारित करता है। यह सुनिश्चित करता है कि हम वास्तविक बदलाव को देख रहे हैं कि केवल थ्रेशोल्ड सीमा को स्थानांतरित करने के बराबर मॉडल में एक बदलाव के विपरीत। हमारे मामले में, 0.5 पर अप्रकाशित मॉडल की तुलना और 0.22 पर विवश मॉडल मॉडल के लिए उचित तुलना प्रदान करता है।

eval_results_dict = {
    'constrained': eval_result_constrained,
    'unconstrained': eval_results_unconstrained,
}
tfma.addons.fairness.view.widget_view.render_fairness_indicator(multi_eval_results=eval_results_dict)
FairnessIndicatorViewer(evalName='constrained', evalNameCompare='unconstrained', slicingMetrics=[{'sliceValue'…

टीएफसीओ को एक दर बाधा के रूप में अधिक जटिल आवश्यकता को व्यक्त करने की क्षमता के साथ, हमने इस मॉडल को समग्र प्रदर्शन के लिए थोड़े प्रभाव के साथ अधिक वांछनीय परिणाम प्राप्त करने में मदद की। बेशक, अभी भी सुधार की गुंजाइश है, लेकिन कम से कम TFCO एक मॉडल खोजने में सक्षम था जो बाधा को संतोषजनक करने के करीब पहुंचता है और समूहों के बीच असमानता को यथासंभव कम करता है।