MinDiffModel olmadan MinDiff'i Entegre Etme

Tanıtım

MinDiff'i doğrudan modelinizin uygulamasına entegre etmek mümkündür. Kullanma kolaylığı yoktur Bunu yaparken MinDiffModel bu seçenek modeli bir alt sınıfı olduğu zaman özellikle yararlı olabilir en yüksek kontrol sunuyor tf.keras.Model .

Bu kılavuz ekleyerek özel bir modelin uygulanması doğrudan MinDiff entegre edebilirsiniz nasıl kullanılacağını gösterir train_step yöntemiyle.

Kurmak

pip install -q --upgrade tensorflow-model-remediation
import tensorflow as tf
tf.get_logger().setLevel('ERROR')  # Avoid TF warnings.
from tensorflow_model_remediation import min_diff
from tensorflow_model_remediation.tools.tutorials_utils import uci as tutorials_utils

İlk önce verileri indirin. Açıklandığı gibi özlülük için, giriş hazırlığı mantık YardımcıFonksiyonlar içine çarpanlarına girdi hazırlığı rehberi . Bu işlemle ilgili ayrıntılar için kılavuzun tamamını okuyabilirsiniz.

# Original Dataset for training, sampled at 0.3 for reduced runtimes.
train_df = tutorials_utils.get_uci_data(split='train', sample=0.3)
train_ds = tutorials_utils.df_to_dataset(train_df, batch_size=128)

# Dataset needed to train with MinDiff.
train_with_min_diff_ds = (
    tutorials_utils.get_uci_with_min_diff_dataset(split='train', sample=0.3))

Orijinal Özel Model Özelleştirmeleri

tf.keras.Model kolayca sınıflara yoluyla özelleştirilmiş olması tasarlanmıştır. Bu genellikle çağrısına neler olduğunu değiştirmeyi fit açıklandığı gibi burada .

Bu kılavuz özel bir uygulama kullanır train_step yakından varsayılan benzeyen tf.keras.Model.train_step . Normalde bunu yapmanın bir faydası olmaz, ancak burada MinDiff'in nasıl entegre edileceğini göstermeye yardımcı olacaktır.

class CustomModel(tf.keras.Model):

  def train_step(self, data):
    # Unpack the data.
    x, y, sample_weight = tf.keras.utils.unpack_x_y_sample_weight(data)

    with tf.GradientTape() as tape:
      y_pred = self(x, training=True)  # Forward pass.
      loss = self.compiled_loss(
          y, y_pred, sample_weight, regularization_losses=self.losses)
      # Compute the loss value.
      loss = self.compiled_loss(
          y, y_pred, sample_weight, regularization_losses=self.losses)

    # Compute gradients and update weights.
    self.optimizer.minimize(loss, self.trainable_variables, tape=tape)
    # Update and return metrics.
    self.compiled_metrics.update_state(y, y_pred, sample_weight)
    return {m.name: m.result() for m in self.metrics}

Tipik gibi modelini Train Model Fonksiyonel API kullanarak.

model = tutorials_utils.get_uci_model(model_class=CustomModel)  # Use CustomModel.

model.compile(optimizer='adam', loss='binary_crossentropy')

_ = model.fit(train_ds, epochs=1)
77/77 [==============================] - 3s 22ms/step - loss: 0.7273

MinDiff'i doğrudan modelinize entegre etme

İçin MinDiff ekleme train_step

MinDiff entegre etmek için, bazı satırları eklemeniz gerekecektir CustomModel olarak burada yeniden adlandırıldı CustomModelWithMinDiff .

Anlaşılır olması için, bu kılavuz denilen bir boolean bayrak kullanır apply_min_diff . O ayarlanırsa, MinDiff ilgili kodun tamamı sadece idare edilecek True . Olarak ayarlanırsa False sonra modeli tam olarak aynı davranır CustomModel .

min_diff_loss_fn = min_diff.losses.MMDLoss()  # Hard coded for convenience.
min_diff_weight = 2  # Arbitrary number for example, hard coded for convenience.
apply_min_diff = True  # Flag to help show where the additional lines are.

class CustomModelWithMinDiff(tf.keras.Model):

  def train_step(self, data):
    # Unpack the data.
    x, y, sample_weight = tf.keras.utils.unpack_x_y_sample_weight(data)

    # Unpack the MinDiff data.
    if apply_min_diff:
      min_diff_data = min_diff.keras.utils.unpack_min_diff_data(x)
      min_diff_x, membership, min_diff_sample_weight = (
          tf.keras.utils.unpack_x_y_sample_weight(min_diff_data))
      x = min_diff.keras.utils.unpack_original_inputs(x)

    with tf.GradientTape() as tape:
      y_pred = self(x, training=True)  # Forward pass.
      loss = self.compiled_loss(
          y, y_pred, sample_weight, regularization_losses=self.losses)
      # Compute the loss value.
      loss = self.compiled_loss(
          y, y_pred, sample_weight, regularization_losses=self.losses)

      # Calculate and add the min_diff_loss. This must be done within the scope
      # of tf.GradientTape().
      if apply_min_diff:
        min_diff_predictions = self(min_diff_x, training=True)
        min_diff_loss = min_diff_weight * min_diff_loss_fn(
            min_diff_predictions, membership, min_diff_sample_weight)
        loss += min_diff_loss

    # Compute gradients and update weights.
    self.optimizer.minimize(loss, self.trainable_variables, tape=tape)
    # Update and return metrics.
    self.compiled_metrics.update_state(y, y_pred, sample_weight)
    return {m.name: m.result() for m in self.metrics}

Bu modelle eğitim, kullanılan veri kümesi dışında öncekiyle tamamen aynı görünüyor.

model = tutorials_utils.get_uci_model(model_class=CustomModelWithMinDiff)

model.compile(optimizer='adam', loss='binary_crossentropy')

_ = model.fit(train_with_min_diff_ds, epochs=1)
77/77 [==============================] - 4s 30ms/step - loss: 0.7799

Girişinizi yeniden şekillendirme (isteğe bağlı)

Bu yaklaşımın tam kontrol sağladığı göz önüne alındığında, girdiyi biraz daha temiz bir forma dönüştürmek için bu fırsatı değerlendirebilirsiniz. Kullanırken MinDiffModel , min_diff_data her seriye ait ilk bileşen içine paketlenmiş gerekmektedir. Bu olduğu train_with_min_diff_ds veri kümesi.

for x, y in train_with_min_diff_ds.take(1):
  print('Type of x:', type(x))  # MinDiffPackedInputs
  print('Type of y:', type(y))  # Tensor (original labels)
Type of x: <class 'tensorflow_model_remediation.min_diff.keras.utils.input_utils.MinDiffPackedInputs'>
Type of y: <class 'tensorflow.python.framework.ops.EagerTensor'>

Bu gereksinim kaldırıldığında, orijinal ve MinDiff verileri temiz bir şekilde ayrılmış olarak verileri biraz daha sezgisel bir yapıda yeniden düzenleyebilirsiniz.

def _reformat_input(inputs, original_labels):
  min_diff_data = min_diff.keras.utils.unpack_min_diff_data(inputs)
  original_inputs = min_diff.keras.utils.unpack_original_inputs(inputs)
  original_data = (original_inputs, original_labels)

  return {
      'min_diff_data': min_diff_data,
      'original_data': original_data}

customized_train_with_min_diff_ds = train_with_min_diff_ds.map(_reformat_input)

Bu adım tamamen isteğe bağlıdır ancak verileri daha iyi organize etmek için faydalı olabilir. Bunu yaparsanız, nasıl uyguladıklarını tek fark CustomModelWithMinDiff Yerleşmene nasıl olacak data başında.

class CustomModelWithMinDiff(tf.keras.Model):

  def train_step(self, data):
    # Unpack the MinDiff data from the custom structure.
    if apply_min_diff:
      min_diff_data = data['min_diff_data']
      min_diff_x, membership, min_diff_sample_weight = (
          tf.keras.utils.unpack_x_y_sample_weight(min_diff_data))
      data = data['original_data']

    ... # possible preprocessing or validation on data before unpacking.

    x, y, sample_weight = tf.keras.utils.unpack_x_y_sample_weight(data)

    ...

Bu son adımla, MinDiff'i uygulamak için hem girdi biçimini hem de model içinde nasıl kullanıldığını tam olarak kontrol edebilirsiniz.

Ek kaynaklar

  • Adalet değerlendirmeye derin tartışmalara için bkz Adil Göstergeler rehberlik
  • İyileştirme ve MinDiff hakkında genel bilgi için, bkz düzeltme bakış .
  • MinDiff çevreleyen gereksinimleri hakkında ayrıntılı bilgi için bkz bu kılavuzu .
  • Keras içinde MinDiff kullanma konusunda uçtan uca öğretici görmek için bkz bu öğretici .