简介
将 MinDiff 集成到您的模型中需要两个步骤
准备数据(在 输入准备指南 中介绍)。
更改或创建将在训练期间集成 MinDiff 的模型。
本指南将介绍完成第二步的最简单方法:使用 MinDiffModel
。
设置
pip install --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 DataFrame for training, sampled at 0.3 for reduced runtimes.
train_df = tutorials_utils.get_uci_data(split='train', sample=0.3)
# Dataset needed to train with MinDiff.
train_with_min_diff_ds = (
tutorials_utils.get_uci_with_min_diff_dataset(split='train', sample=0.3))
原始模型
本指南使用一个基本的、未经调整的 keras.Model
,使用 函数式 API 来突出显示使用 MinDiff。在实际应用中,您应该仔细选择模型架构并使用调整来提高模型质量,然后再尝试解决任何公平性问题。
由于 MinDiffModel
旨在与大多数 Keras Model
类一起使用,因此我们将构建模型的逻辑分解为一个辅助函数:get_uci_model
。
使用 Pandas DataFrame 进行训练
本指南在单个 epoch 上进行训练以提高速度,但可以通过增加 epoch 数轻松提高模型的性能。
model = tutorials_utils.get_uci_model()
model.compile(optimizer='adam', loss='binary_crossentropy')
df_without_target = train_df.drop(['target'], axis=1) # Drop 'target' for x.
_ = model.fit(
x=dict(df_without_target), # The model expects a dictionary of features.
y=train_df['target'],
batch_size=128,
epochs=1)
使用 tf.data.Dataset
进行训练
使用 tf.data.Dataset
进行的等效训练看起来非常相似(尽管初始化和输入随机性可能会产生略微不同的结果)。
model = tutorials_utils.get_uci_model()
model.compile(optimizer='adam', loss='binary_crossentropy')
_ = model.fit(
tutorials_utils.df_to_dataset(train_df, batch_size=128), # Converted to Dataset.
epochs=1)
集成 MinDiff 进行训练
数据准备完成后,请按照以下步骤将 MinDiff 应用于您的模型
- 创建您在没有 MinDiff 的情况下会创建的原始模型。
original_model = tutorials_utils.get_uci_model()
- 将其包装在
MinDiffModel
中。
min_diff_model = min_diff.keras.MinDiffModel(
original_model=original_model,
loss=min_diff.losses.MMDLoss(),
loss_weight=1)
- 像没有 MinDiff 的情况下一样进行编译。
min_diff_model.compile(optimizer='adam', loss='binary_crossentropy')
- 使用 MinDiff 数据集(在本例中为
train_with_min_diff_ds
)进行训练。
_ = min_diff_model.fit(train_with_min_diff_ds, epochs=1)
使用 MinDiffModel
进行评估和预测
使用 MinDiffModel
进行评估和预测与使用原始模型类似。
在调用 evaluate
时,您可以传入原始数据集或包含 MinDiff 数据的数据集。如果您选择后者,您还将在任何其他正在测量的指标之外获得 min_diff_loss
指标 loss
也将包含 min_diff_loss
。
在调用 evaluate
时,您可以传入原始数据集或包含 MinDiff 数据的数据集。如果您在调用 evaluate 时包含 MinDiff,则有两点不同
- 输出中将出现一个名为
min_diff_loss
的附加指标。 loss
指标的值将是原始loss
指标(未在输出中显示)和min_diff_loss
的总和。
_ = min_diff_model.evaluate(
tutorials_utils.df_to_dataset(train_df, batch_size=128))
# Calling with MinDiff data will include min_diff_loss in metrics.
_ = min_diff_model.evaluate(train_with_min_diff_ds)
在调用 predict
时,您也可以在技术上传入包含 MinDiff 数据的数据集,但它将被忽略,不会影响输出。
_ = min_diff_model.predict(
tutorials_utils.df_to_dataset(train_df, batch_size=128))
_ = min_diff_model.predict(train_with_min_diff_ds) # Identical to results above.
直接使用 MinDiffModel
的局限性
当按上述方式使用 MinDiffModel
时,大多数方法将使用 tf.keras.Model
的默认实现(API 文档 中列出了例外)。
print('MinDiffModel.fit == keras.Model.fit')
print(min_diff.keras.MinDiffModel.fit == tf.keras.Model.fit)
print('MinDiffModel.train_step == keras.Model.train_step')
print(min_diff.keras.MinDiffModel.train_step == tf.keras.Model.train_step)
对于 keras.Sequential
或 keras.Model
,这完全没问题,因为它们使用相同的函数。
print('Sequential.fit == keras.Model.fit')
print(tf.keras.Sequential.fit == tf.keras.Model.fit)
print('tf.keras.Sequential.train_step == keras.Model.train_step')
print(tf.keras.Sequential.train_step == tf.keras.Model.train_step)
但是,如果您的模型是 keras.Model
的子类,用 MinDiffModel
包装它将有效地丢失定制。
class CustomModel(tf.keras.Model):
def train_step(self, **kwargs):
pass # Custom implementation.
print('CustomModel.train_step == keras.Model.train_step')
print(CustomModel.train_step == tf.keras.Model.train_step)
如果这是您的用例,您不应该直接使用 MinDiffModel
。相反,您需要像在 定制指南 中描述的那样对其进行子类化。