MinDiffModel के बिना MinDiff को एकीकृत करना

परिचय

MinDiff को सीधे आपके मॉडल के कार्यान्वयन में एकीकृत करना संभव है। ऐसा करने से उपयोग करने की सुविधा नहीं है, जबकि MinDiffModel , इस विकल्प को नियंत्रण जब अपने मॉडल का एक उपवर्ग है जो विशेष रूप से उपयोगी हो सकता है के उच्चतम स्तर प्रदान करता है tf.keras.Model

इस गाइड दर्शाता है कि कैसे आप के लिए जोड़कर एक कस्टम मॉडल के कार्यान्वयन में सीधे MinDiff एकीकृत कर सकते हैं train_step विधि।

सेट अप

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

सबसे पहले, डेटा डाउनलोड करें। संक्षिप्तता के लिए, इनपुट तैयारी तर्क में वर्णित के रूप सहायक कार्यों में बाहर कारक कर दिया गया है इनपुट तैयारी गाइड । आप इस प्रक्रिया के विवरण के लिए पूरी गाइड पढ़ सकते हैं।

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

मूल कस्टम मॉडल अनुकूलन

tf.keras.Model आसानी से उपवर्गीकरण के माध्यम से अनुकूलित किया जा करने के लिए बनाया गया है। यह आमतौर पर बदल रहा है क्या कॉल में क्या होता है करने के लिए शामिल है fit के रूप में वर्णित यहाँ

इस गाइड जहां एक कस्टम कार्यान्वयन का उपयोग करता train_step बारीकी डिफ़ॉल्ट जैसा दिखता है tf.keras.Model.train_step । आम तौर पर, ऐसा करने से कोई लाभ नहीं होगा, लेकिन यहां, यह प्रदर्शित करने में मदद करेगा कि मिनडिफ को कैसे एकीकृत किया जाए।

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}

मॉडल ट्रेन आप एक विशिष्ट के रूप में Model कार्यात्मक एपीआई का उपयोग कर।

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 को सीधे अपने मॉडल में एकीकृत करना

करने के लिए MinDiff जोड़ना train_step

MinDiff एकीकृत करने के लिए, आप के लिए कुछ पंक्तियाँ जोड़ने की आवश्यकता होगी CustomModel जो के रूप में यहाँ का नाम बदले जाने CustomModelWithMinDiff

स्पष्टता के लिए, इस गाइड एक बूलियन ध्वज कहा जाता है का उपयोग करता है apply_min_diff । MinDiff के लिए प्रासंगिक कोड के सभी केवल इसे करने के लिए सेट है, तो चलाया जाएगा True । करने के लिए सेट है, तो False तो मॉडल बिल्कुल के रूप में एक ही तरह से व्यवहार करेंगे 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}

उपयोग किए गए डेटासेट के अपवाद के साथ इस मॉडल के साथ प्रशिक्षण बिल्कुल पिछले जैसा ही दिखता है।

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

अपने इनपुट को फिर से आकार देना (वैकल्पिक)

यह देखते हुए कि यह दृष्टिकोण पूर्ण नियंत्रण प्रदान करता है, आप इस अवसर का उपयोग इनपुट को थोड़ा साफ-सुथरा रूप में बदलने के लिए कर सकते हैं। का उपयोग करते समय MinDiffModel , min_diff_data हर बैच के पहले घटक में पैक किया जाना चाहिए। इस के साथ मामला है train_with_min_diff_ds डाटासेट।

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'>

इस आवश्यकता को हटा लेने के साथ, आप डेटा को थोड़ा अधिक सहज संरचना में पुनर्व्यवस्थित कर सकते हैं जिसमें मूल और मिनडिफ डेटा साफ-साफ अलग हो जाते हैं।

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)

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

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)

    ...

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

अतिरिक्त संसाधन