مقدمة
من الممكن دمج 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
تم تصميمه ليتم تخصيصها بسهولة عبر شاء subclasses ترث. هذا وعادة ما ينطوي تغيير ما يحدث في استدعاء fit
كما هو موضح هنا .
يستخدم هذا دليل تطبيق مخصص حيث train_step
يشبه الافتراضي tf.keras.Model.train_step
. في العادة ، لن تكون هناك فائدة من القيام بذلك ، ولكن هنا ، سيساعد ذلك في توضيح كيفية دمج MinDiff.
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
باستخدام API الوظيفي.
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'>
مع رفع هذا المطلب ، يمكنك إعادة تنظيم البيانات في بنية أكثر سهولة مع البيانات الأصلية وبيانات MinDiff منفصلة تمامًا.
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)
...
باستخدام هذه الخطوة الأخيرة ، يمكنك التحكم بشكل كامل في تنسيق الإدخال وكيفية استخدامه داخل النموذج لتطبيق MinDiff.
مصادر إضافية
- لفي مناقشة شاملة حول تقييم نزاهة رؤية التوجيه مؤشرات الإنصاف
- للحصول على معلومات عامة عن علاج وMinDiff، راجع نظرة عامة المعالجة .
- للحصول على تفاصيل حول متطلبات المحيطة MinDiff نرى هذا الدليل .
- للاطلاع على البرنامج التعليمي نهاية إلى نهاية على استخدام MinDiff في Keras، انظر هذا البرنامج التعليمي .