تخصيص MinDiffModel

مقدمة

في معظم الحالات، وذلك باستخدام MinDiffModel مباشرة كما هو موضح في "إدماج MinDiff مع MinDiffModel" دليل غير كاف. ومع ذلك ، من المحتمل أنك ستحتاج إلى سلوك مخصص. السببان الأساسيان لذلك هما:

  • و keras.Model كنت تستخدم لديها سلوك المخصصة التي تريد الحفاظ عليها.
  • تريد MinDiffModel أن تتصرف بشكل مختلف من الافتراضي.

في كلتا الحالتين، سوف تحتاج إلى فئة فرعية MinDiffModel لتحقيق النتائج المرجوة.

يثبت

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 ترث كما هو موضح هنا . إذا النموذج الخاص بك وتخصيص التطبيقات التي ترغب في الحفاظ عند تطبيق MinDiff، وسوف تحتاج إلى فئة فرعية MinDiffModel .

نموذج مخصص أصلي

لنرى كيف يمكن الحفاظ على التخصيصات، وخلق نموذج مخصص الذي يحدد سمة ل True عندما كعادتها train_step يسمى. هذا ليس تخصيصًا مفيدًا ولكنه سيعمل على توضيح السلوك.

class CustomModel(tf.keras.Model):

  # Customized train_step
  def train_step(self, *args, **kwargs):
    self.used_custom_train_step = True  # Marker that we can check for.
    return super(CustomModel, self).train_step(*args, **kwargs)

سيكون تدريب نموذج مثل هذا ينظر الى نفسه على أنه طبيعي Sequential نموذج.

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

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

_ = model.fit(train_ds.take(1), epochs=1, verbose=0)

# Model has used the custom train_step.
print('Model used the custom train_step:')
print(hasattr(model, 'used_custom_train_step'))  # True
Model used the custom train_step:
True

تصنيف فرعي MinDiffModel

لو كنت في محاولة لاستخدام MinDiffModel مباشرة، فإن نموذج عدم استخدام مخصص train_step .

model = tutorials_utils.get_uci_model(model_class=CustomModel)
model = min_diff.keras.MinDiffModel(model, min_diff.losses.MMDLoss())

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

_ = model.fit(train_with_min_diff_ds.take(1), epochs=1, verbose=0)

# Model has not used the custom train_step.
print('Model used the custom train_step:')
print(hasattr(model, 'used_custom_train_step'))  # False
Model used the custom train_step:
False

من أجل استخدام الصحيح train_step الطريقة، كنت في حاجة الى الدرجة المخصصة التي فرعية على حد سواء MinDiffModel و CustomModel .

class CustomMinDiffModel(min_diff.keras.MinDiffModel, CustomModel):
  pass  # No need for any further implementation.

سوف تدريب هذا النموذج استخدام train_step من CustomModel .

model = tutorials_utils.get_uci_model(model_class=CustomModel)

model = CustomMinDiffModel(model, min_diff.losses.MMDLoss())

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

_ = model.fit(train_with_min_diff_ds.take(1), epochs=1, verbose=0)

# Model has used the custom train_step.
print('Model used the custom train_step:')
print(hasattr(model, 'used_custom_train_step'))  # True
Model used the custom train_step:
True

تخصيص السلوكيات الافتراضي MinDiffModel

وفي حالات أخرى، قد ترغب في تغيير السلوكيات الافتراضية المحددة من MinDiffModel . في معظم الحالات استخدام الشائعة لهذا هو تغيير تفريغ السلوك الافتراضي لمعالجة البيانات بشكل صحيح إذا كنت لا تستخدم pack_min_diff_data .

عند تعبئة البيانات في تنسيق مخصص ، قد يظهر هذا على النحو التالي.

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)

  return ({
      'min_diff_data': min_diff_data,
      'original_inputs': original_inputs}, original_labels)

customized_train_with_min_diff_ds = train_with_min_diff_ds.map(_reformat_input)

و customized_train_with_min_diff_ds بيانات عوائد دفعات تتألف من الصفوف (x, y) حيث x هو ديكت تحتوي على min_diff_data و original_inputs و y هو original_labels .

for x, _ in customized_train_with_min_diff_ds.take(1):
  print('Type of x:', type(x))  # dict
  print('Keys of x:', x.keys())  # 'min_diff_data', 'original_inputs'
Type of x: <class 'dict'>
Keys of x: dict_keys(['min_diff_data', 'original_inputs'])

هذا الشكل البيانات ليست ما MinDiffModel تتوقع افتراضيا وتمرير customized_train_with_min_diff_ds سيكون لها يؤدي إلى سلوك غير متوقع. لإصلاح ذلك ، ستحتاج إلى إنشاء فئة فرعية خاصة بك.

class CustomUnpackingMinDiffModel(min_diff.keras.MinDiffModel):

  def unpack_min_diff_data(self, inputs):
    return inputs['min_diff_data']

  def unpack_original_inputs(self, inputs):
    return inputs['original_inputs']

مع هذه الفئة الفرعية ، يمكنك التدريب كما هو الحال مع الأمثلة الأخرى.

model = tutorials_utils.get_uci_model()
model = CustomUnpackingMinDiffModel(model, min_diff.losses.MMDLoss())

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

_ = model.fit(customized_train_with_min_diff_ds, epochs=1)
77/77 [==============================] - 4s 30ms/step - loss: 0.6690 - min_diff_loss: 0.0395

قيود من تخصيص MinDiffModel

خلق العرف MinDiffModel يوفر قدرا كبيرا من المرونة للحالات استخدام أكثر تعقيدا. ومع ذلك ، لا تزال هناك بعض حالات الحافة التي لن تدعمها.

تجهيزها أو التحقق من صحة المدخلات قبل call

أكبر قيود على فئة فرعية من MinDiffModel هو أنه يتطلب x مكون من إدخال البيانات (أي العنصر الأول أو الوحيد في الدفعة التي تم إرجاعها بواسطة tf.data.Dataset ) لتمريرها من خلال تجهيزها دون التحقق من صحة أو إلى call .

هذا ببساطة لأن min_diff_data هي معبأة في x المكون من إدخال البيانات. فإن أي تجهيزها أو التحقق من صحة لا يتوقع بنية إضافية تحتوي على min_diff_data وسوف كسر احتمالا.

إذا كانت المعالجة المسبقة أو التحقق من الصحة قابلاً للتخصيص بسهولة (على سبيل المثال تم تحليلها في طريقتها الخاصة) ، فيمكن معالجة ذلك بسهولة عن طريق تجاوزها للتأكد من أنها تتعامل مع الهيكل الإضافي بشكل صحيح.

مثال مع التحقق من الصحة قد يبدو كالتالي:

class CustomMinDiffModel(min_diff.keras.MinDiffModel, CustomModel):

  # Override so that it correctly handles additional `min_diff_data`.
  def validate_inputs(self, inputs):
    original_inputs = self.unpack_original_inputs(inputs)
    ...  # Optionally also validate min_diff_data
    # Call original validate method with correct inputs
    return super(CustomMinDiffModel, self).validate(original_inputs)

إذا كان تجهيزها أو التحقق من صحة هو ليس من السهل تخصيص، ثم استخدام MinDiffModel لا يجوز العمل لسوف وتحتاج إلى دمج MinDiff دون ذلك كما هو موضح في هذا الدليل .

تضاربات اسم الطريقة

ومن الممكن أن يكون نموذجا لديه أساليب التي تتعارض مع تلك التي نفذت في أسماء MinDiffModel (انظر القائمة الكاملة للطرق العامة في وثائق API ).

هذه مشكلة فقط إذا تم استدعاؤها على مثيل من النموذج (وليس داخليًا في طريقة أخرى). بينما من المستبعد جدا، إذا كنت في هذه الحالة سيكون لديك إما تجاوز وإعادة تسمية بعض الأساليب أو، إذا تعذر ذلك، قد تحتاج إلى النظر في دمج MinDiff دون MinDiffModel كما هو موضح في هذا الدليل حول هذا الموضوع .

مصادر إضافية