CelebA Veri Kümesini Kullanan TensorFlow Kısıtlı Optimizasyon Örneği

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın GitHub'da görüntüle Not defterini indir

Bu not defteri, TFCO kitaplığını kullanarak kısıtlı sorunları oluşturmanın ve optimize etmenin kolay bir yolunu gösterir. Biz onlar kullandığımız belirleyebilir mamızdaki farklı dilimler arasında eşit olarak iyi performans olduğunu öğreniyorsunuz, bu yöntem modelleri iyileştirmede yararlı olabilir Adil Göstergeleri . Google'ın yapay zeka ilkelerinden ikincisi, teknolojimizin haksız önyargı oluşturmaktan veya bu önyargıyı güçlendirmekten kaçınması gerektiğini belirtir ve bu tekniğin bazı durumlarda model adaletini geliştirmeye yardımcı olabileceğine inanıyoruz. Bu defter özellikle:

  • Kullanarak görüntülerde bir kişinin gülümseme algılamak için basit, kısıtsız sinir ağı modeli Train tf.keras ve büyük ölçekli CelebFaces Nitelikler ( CelebA ) veri kümesi.
  • Adalet Göstergelerini kullanarak, yaş grupları arasında yaygın olarak kullanılan bir adalet metriğine göre model performansını değerlendirin.
  • Yaş grupları arasında daha adil performans elde etmek için basit bir kısıtlı optimizasyon problemi kurun.
  • Şimdi kısıtlı modelini yeniden eğit ve seçtiğimiz adalet metrik geliştirdi sağlamak, yine performansını değerlendirmek.

Son güncelleme: 3/11 Şub 2020

Kurulum

Bu defter oluşturulan Colaboratory Python 3 Google Compute Engine arka uç bağlı. Bu not defterini farklı bir ortamda barındırmak istiyorsanız, aşağıdaki hücrelere gerekli tüm paketleri dahil ettiğiniz takdirde herhangi bir önemli sorunla karşılaşmamalısınız.

Pip kurulumlarını ilk kez çalıştırdığınızda, önceden yüklenmiş güncel olmayan paketler nedeniyle çalışma zamanını yeniden başlatmanız istenebileceğini unutmayın. Bunu yaptığınızda, doğru paketler kullanılacaktır.

Pip yüklemeleri

Aşağıdaki hücreyi ne zaman çalıştırdığınıza bağlı olarak, Colab'de TensorFlow'un varsayılan sürümünün yakında TensorFlow 2.X'e geçişi hakkında bir uyarı alabileceğinizi unutmayın. Bu dizüstü bilgisayar TensorFlow 1.X ve 2.X ile uyumlu olacak şekilde tasarlandığından bu uyarıyı güvenle yok sayabilirsiniz.

Modülleri İçe Aktar

Ayrıca, modelin performansını değerlendirmek ve görselleştirmek için kullanacağımız Adillik Göstergelerine özgü birkaç içe aktarma ekliyoruz.

TFCO, istekli ve grafik yürütme ile uyumlu olmasına rağmen, bu not defteri, TensorFlow 2.x'te olduğu gibi istekli yürütmenin varsayılan olarak etkinleştirildiğini varsayar. Hiçbir şeyin bozulmamasını sağlamak için aşağıdaki hücrede istekli yürütme etkinleştirilecektir.

İstekli Yürütmeyi ve Sürümleri Yazdırmayı Etkinleştir

Eager execution enabled by default.
TensorFlow 2.8.0-rc0
TFMA 0.36.0
TFDS 4.4.0
FI 0.36.0

CelebA Veri Kümesi

CelebA büyük ölçekli yüz ve 5 dönüm yerleri (göz, ağız ve burun pozisyonlarda) (örneğin saç tipi, moda aksesuarları, yüz hatları, vs.) 40 özellik ek açıklamalarla 200.000'den fazla ünlü görüntüler, her biri ile veri kümesi nitelikleri olduğunu. Daha fazla ayrıntı için bir göz atın kağıt . Sahiplerinin izniyle, Google Cloud Storage bu veri kümesini depolamış ve çoğunlukla aracılığıyla erişmek TensorFlow Veri kümeleri ( tfds ) .

Bu not defterinde:

  • "Gülümseyen" özelliği * ile temsil Bizim modeli görüntünün konu gülümsüyor olmadığını sınıflandırmaya çalışacaktır.
  • Eğitim sırasında yürütme süresini ve belleği azaltmak için görüntüler 218x178'den 28x28'e yeniden boyutlandırılacaktır.
  • Modelimizin performansı, ikili "Genç" özniteliği kullanılarak yaş grupları arasında değerlendirilecektir. Bu defterde buna "yaş grubu" diyeceğiz.

* Bu veri kümesi için etiketleme metodolojisi konusunda yeterli veri bulunmamakla birlikte, biz "Gülen" özelliği öznenin yüzünde memnun, nazik, eğlendirdi veya ifade ile tespit edildi varsayar. Bu vaka çalışmasının amacı doğrultusunda, bu etiketleri temel gerçek olarak kabul edeceğiz.

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

Veri kümesi yardımcı işlevlerini test edin

uyarılar

İlerlemeden önce, CelebA'yı kullanırken akılda tutulması gereken birkaç nokta vardır:

  • Prensipte bu defter herhangi bir yüz görüntüsü veri kümesini kullanabilse de, CelebA tanınmış kişilerin kamuya açık görüntülerini içerdiği için seçildi.
  • CelebA'daki tüm öznitelik açıklamaları ikili kategoriler olarak işlevselleştirilmiştir. Örneğin, "Genç" özniteliği (veri kümesi etiketleyicileri tarafından belirlendiği gibi) görüntüde var veya yok olarak belirtilir.
  • CelebA'nın kategorizasyonları, gerçek insani nitelik çeşitliliğini yansıtmamaktadır.
  • Bu not defterinin amaçları doğrultusunda, "Genç" özniteliğini içeren özellik "yaş grubu" olarak adlandırılır; burada bir görüntüde "Genç" özniteliğinin varlığı "Genç" yaş grubunun bir üyesi olarak etiketlenir ve "Genç" özelliğinin olmaması, "Genç Değil" yaş grubunun bir üyesi olarak etiketlenir. Bunlar bu bilgilerin belirtilmeyen olarak yapılan varsayımlar şunlardır orijinal kağıt .
  • Bu nedenle, bu defterde eğitilen modellerdeki performans, özelliklerin CelebA'nın yazarları tarafından işlevselleştirilme ve açıklama eklenme biçimlerine bağlıdır.
  • Bu model ihlal edeceği gibi ticari amaçlarla kullanılmamalıdır CelebA en ticari olmayan araştırma anlaşması .

Giriş İşlevlerini Ayarlama

Sonraki hücreler, performansı görselleştirmenin yanı sıra giriş işlem hattını düzenlemeye yardımcı olacaktır.

İlk önce verilerle ilgili bazı değişkenleri tanımlıyoruz ve gerekli bir ön işleme işlevini tanımlıyoruz.

Değişkenleri Tanımla

Ön İşleme İşlevlerini Tanımlayın

Ardından, işbirliğinin geri kalanında ihtiyaç duyduğumuz veri işlevlerini oluştururuz.

# 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()

Basit bir DNN Modeli oluşturun

Bu defter TFCO odaklandığından, biz basit, kısıtsız monte edecek tf.keras.Sequential modeli.

Biraz karmaşıklık ekleyerek (örneğin, daha yoğun bağlantılı katmanlar, farklı etkinleştirme işlevlerini keşfetme, görüntü boyutunu artırma) model performansını büyük ölçüde iyileştirebiliriz, ancak bu, TFCO kitaplığını uygulamanın ne kadar kolay olduğunu gösterme hedefinden uzaklaşabilir. Keras ile çalışırken. Bu nedenle, model basit tutulacak - ancak bu alanı keşfetmeye teşvik edileceksiniz.

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

Ayrıca, tekrarlanabilir sonuçlar sağlamak için tohumları ayarlamak için bir fonksiyon tanımlıyoruz. Bu ortak çalışmanın bir eğitim aracı olarak tasarlandığını ve ince ayarlanmış bir üretim hattının kararlılığına sahip olmadığını unutmayın. Bir tohum koymadan koşmak, çeşitli sonuçlara yol açabilir.

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

Adalet Göstergeleri Yardımcı İşlevler

Modelimizi eğitmeden önce, Adillik Göstergeleri aracılığıyla modelin performansını değerlendirmemizi sağlayacak bir dizi yardımcı fonksiyon tanımlıyoruz.

İlk olarak, modelimizi eğittikten sonra kaydedecek bir yardımcı fonksiyon oluşturuyoruz.

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

Ardından, verileri TFMA'ya doğru bir şekilde iletmek için verileri önceden işlemek için kullanılan işlevleri tanımlarız.

için Veri Ön İşleme işlevleri

Son olarak, sonuçları TFMA'da değerlendiren bir fonksiyon tanımlıyoruz.

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)

Kısıtlanmamış Modeli Eğitin ve Değerlendirin

Şimdi tanımlanan model ve yerinde girdi hattı ile artık modelimizi eğitmeye hazırız. Yürütme süresini ve belleği azaltmak için, verileri yalnızca birkaç yinelenen yinelemeyle küçük gruplara bölerek modeli eğiteceğiz.

TensorFlow bu defteri <2.0.0 çalıştırmak için kullanımdan kaldırılması uyarı sonuçlanabileceğini Not np.where . TensorFlow kullanarak 2.x bu adresleri olarak güvenle bu uyarıyı göz ardı tf.where yerine 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 [==============================] - 12s 6ms/step - loss: 0.5038 - accuracy: 0.7733
Epoch 2/5
1000/1000 [==============================] - 7s 7ms/step - loss: 0.3800 - accuracy: 0.8301
Epoch 3/5
1000/1000 [==============================] - 6s 6ms/step - loss: 0.3598 - accuracy: 0.8427
Epoch 4/5
1000/1000 [==============================] - 25s 25ms/step - loss: 0.3435 - accuracy: 0.8474
Epoch 5/5
1000/1000 [==============================] - 5s 5ms/step - loss: 0.3402 - accuracy: 0.8479
<keras.callbacks.History at 0x7f0f5c476350>

Modeli test verileri üzerinde değerlendirmek, %85'in biraz üzerinde bir nihai doğruluk puanı ile sonuçlanmalıdır. İnce ayarı olmayan basit bir model için fena değil.

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 [==============================] - 50s 2ms/step - loss: 0.2125 - accuracy: 0.8636

Ancak yaş gruplarına göre değerlendirilen performans bazı eksiklikleri ortaya çıkarabilir.

Bunu daha fazla araştırmak için, modeli Adillik Göstergeleri ile (TFMA aracılığıyla) değerlendiriyoruz. Özellikle, "Genç" ve "Genç Değil" kategorileri arasında yanlış pozitif oranı değerlendirildiğinde performansta önemli bir boşluk olup olmadığını görmek istiyoruz.

Model, pozitif sınıfı yanlış tahmin ettiğinde yanlış bir pozitif hata oluşur. Bu bağlamda, temel gerçek bir ünlünün 'Gülmeyen' bir görüntüsü olduğunda ve model 'Gülümseyen' tahmininde bulunduğunda yanlış bir pozitif sonuç oluşur. Ek olarak, yukarıdaki görselleştirmede kullanılan yanlış pozitif oranı, bir test için bir doğruluk ölçüsüdür. Bu, bu bağlamda yapılması nispeten sıradan bir hata olsa da, yanlış pozitif hatalar bazen daha sorunlu davranışlara neden olabilir. Örneğin, bir spam sınıflandırıcısındaki yanlış pozitif bir hata, kullanıcının önemli bir e-postayı kaçırmasına neden olabilir.

model_location = save_model(model_unconstrained, 'model_export_unconstrained')
eval_results_unconstrained = get_eval_results(model_location, 'eval_results_unconstrained')
2022-01-07 18:46:05.881112: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
INFO:tensorflow:Assets written to: /tmp/saved_modelswhxcqdry/model_export_unconstrained/assets
INFO:tensorflow:Assets written to: /tmp/saved_modelswhxcqdry/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:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.
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.7/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:107: 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.7/site-packages/tensorflow_model_analysis/writers/metrics_plots_and_validations_writer.py:107: 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)`

Yukarıda belirtildiği gibi, yanlış pozitif oranına odaklanıyoruz. Adalet Göstergelerinin (0.1.2) mevcut sürümü, varsayılan olarak yanlış negatif oranı seçer. Aşağıdaki satırı çalıştırdıktan sonra ilgilendiğimiz metriğe bakmak için yanlış_negatif_oran seçimini kaldırın ve yanlış_pozitif_oran'ı seçin.

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

Sonuçlar Yukarıda gösterdiği gibi, biz "Young" ve "Değil Genç" kategoriler arasında orantısız bir boşluğu görüyorum.

Bu, TFCO'nun yanlış pozitif oranı daha kabul edilebilir bir kriter içinde olacak şekilde sınırlayarak yardımcı olabileceği yerdir.

Kısıtlı Model Kurulumu

Belgelendiği gibi TFCO kütüphanesinde , daha kolay sorunu sınırlamak için yapacak birkaç yardımcıları vardır:

  1. tfco.rate_context() - Bu, her yaş grubu kategorisi için bir sınırlama inşa kullanılacak budur.
  2. tfco.RateMinimizationProblem() - oran ifadesidir, yaş yanlış pozitif oran tabi olacaktır burada minimize edilmelidir. Başka bir deyişle, performans şimdi yaş grubunun yanlış pozitif oranları ile genel veri setininki arasındaki farka dayalı olarak değerlendirilecektir. Bu gösterim için, kısıtlama olarak %5'e eşit veya daha düşük bir yanlış pozitif oranı ayarlanacaktır.
  3. tfco.ProxyLagrangianOptimizerV2() - Bu aslında oran kısıtlaması sorunu çözecek yardımcısıdır.

Aşağıdaki hücre, bu yardımcıları adalet kısıtlaması ile model eğitimi kurmaya çağıracaktır.

# 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())

Model şimdi kuruldu ve yaş grubu genelinde yanlış pozitif oran kısıtlaması ile eğitilmeye hazır.

Kısıtlı modelin son yineleme mutlaka tanımlanmış kısıtlama açısından en iyi performans gösteren bir model olmayabilir çünkü Şimdi, TFCO kütüphanesi ile donatılmış olarak geliyor tfco.find_best_candidate_index() kutu yardım olanlardan iterate iyiyi ortaya seçmek her sonra bulundu çağ. Düşünün tfco.find_best_candidate_index() ayrı ayrı eğitim verileri açısından doğruluk ve adalet kısıtı (yaş grubunda genelinde bu durumda, yanlış pozitif oranı) dayalı sonuçların her rütbeleri eklenen bir sezgisel olarak. Bu şekilde, genel doğruluk ve adalet kısıtlaması arasında daha iyi bir denge arayabilir.

Aşağıdaki hücreler, yineleme başına en iyi performans gösteren modeli bulurken kısıtlamalarla eğitimi başlatacaktır.

# 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

Kısıtlamayı uyguladıktan sonra, Adillik Göstergelerini kullanarak sonuçları bir kez daha değerlendiririz.

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_modelsbztxt9fy/model_export_constrained/assets
INFO:tensorflow:Assets written to: /tmp/saved_modelsbztxt9fy/model_export_constrained/assets
WARNING:root:Make sure that locally built Python SDK docker image has Python 3.7 interpreter.

Adillik Göstergelerini daha önce kullandığımızda olduğu gibi, ilgilendiğimiz metriğe bakmak için yanlış_negatif_oran seçimini kaldırın ve yanlış_pozitif_oran'ı seçin.

Modelimizin iki versiyonunu adil bir şekilde karşılaştırmak için, genel yanlış pozitif oranı kabaca eşit olacak şekilde ayarlayan eşikler kullanmanın önemli olduğunu unutmayın. Bu, sadece eşik sınırını hareket ettirmeye eşdeğer modelde bir kaymaya karşıt olarak gerçek değişime bakmamızı sağlar. Bizim durumumuzda 0,5'teki kısıtsız model ile 0,22'deki kısıtlı modelin karşılaştırılması, modeller için adil bir karşılaştırma sağlar.

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'nun daha karmaşık bir gereksinimi bir hız kısıtlaması olarak ifade etme yeteneğiyle, bu modelin genel performans üzerinde çok az etkiyle daha arzu edilen bir sonuca ulaşmasına yardımcı olduk. Elbette hala iyileştirme için yer var, ancak en azından TFCO, kısıtlamayı karşılamaya yaklaşan ve gruplar arasındaki eşitsizliği mümkün olduğunca azaltan bir model bulabildi.