将 MinDiff 与 MinDiffModel 集成

简介

将 MinDiff 集成到您的模型中需要两个步骤

  1. 准备数据(在 输入准备指南 中介绍)。

  2. 更改或创建将在训练期间集成 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 应用于您的模型

  1. 创建您在没有 MinDiff 的情况下会创建的原始模型。
original_model = tutorials_utils.get_uci_model()
  1. 将其包装在 MinDiffModel 中。
min_diff_model = min_diff.keras.MinDiffModel(
    original_model=original_model,
    loss=min_diff.losses.MMDLoss(),
    loss_weight=1)
  1. 像没有 MinDiff 的情况下一样进行编译。
min_diff_model.compile(optimizer='adam', loss='binary_crossentropy')
  1. 使用 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.Sequentialkeras.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。相反,您需要像在 定制指南 中描述的那样对其进行子类化。

其他资源

  • 有关公平性评估的深入讨论,请参阅 公平性指标指南
  • 有关修复和 MinDiff 的一般信息,请参阅 修复概述
  • 有关 MinDiff 周围要求的详细信息,请参阅 本指南
  • 要查看在 Keras 中使用 MinDiff 的端到端教程,请参阅 本教程