Integración de MinDiff con MinDiffModel

Introducción

Hay dos pasos para integrar MinDiff en su modelo:

  1. Preparar los datos (cubierto en la guía de preparación de entrada ).

  2. Modifique o cree un modelo que integre MinDiff durante el entrenamiento.

Esta guía cubre la forma más sencilla de completar el segundo paso: el uso de MinDiffModel .

Configuración

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

Primero, descargue los datos. Por concisión, la lógica de preparación de entrada ha sido factorizada hacia helper funciones como se describe en la guía de preparación de entrada . Puede leer la guía completa para obtener detalles sobre este proceso.

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

modelo original

En esta guía se utiliza una, sin sintonía básica keras.Model utilizando la API funcional para destacar el uso de MinDiff. En una aplicación del mundo real, elegiría cuidadosamente la arquitectura del modelo y usaría el ajuste para mejorar la calidad del modelo antes de intentar abordar cualquier problema de equidad.

Desde MinDiffModel está diseñado para trabajar con la mayoría de Keras Model clases, hemos factor fuera de la lógica de la construcción del modelo en una función auxiliar: get_uci_model .

Entrenamiento con un Pandas DataFrame

Esta guía entrena la velocidad en una sola época, pero podría mejorar fácilmente el rendimiento del modelo aumentando el número de épocas.

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)
77/77 [==============================] - 3s 23ms/step - loss: 0.8589

El entrenamiento con un tf.data.Dataset

La formación equivalente con un tf.data.Dataset se vería muy similar (aunque la inicialización y la aleatoriedad de entrada pueden producir resultados ligeramente diferentes).

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)
77/77 [==============================] - 3s 23ms/step - loss: 0.6416

Integrando MinDiff para entrenamiento

Una vez preparados los datos, aplica MinDiff a tu modelo con los siguientes pasos:

  1. Cree el modelo original como lo haría sin MinDiff.
original_model = tutorials_utils.get_uci_model()
  1. Envolverlo en un MinDiffModel .
min_diff_model = min_diff.keras.MinDiffModel(
    original_model=original_model,
    loss=min_diff.losses.MMDLoss(),
    loss_weight=1)
  1. Compílelo como lo haría sin MinDiff.
min_diff_model.compile(optimizer='adam', loss='binary_crossentropy')
  1. Entrenarlo con el conjunto de datos MinDiff ( train_with_min_diff_ds en este caso).
_ = min_diff_model.fit(train_with_min_diff_ds, epochs=1)
77/77 [==============================] - 6s 31ms/step - loss: 0.7883 - min_diff_loss: 0.0379

Evaluación y Predicción con MinDiffModel

Tanto evaluar y predecir con un MinDiffModel son similares a hacerlo con el modelo original.

Cuando se llama a evaluate se puede pasar ya sea en el conjunto de datos original o la que contiene los datos MinDiff. Si elige esta última, que también tendrá la min_diff_loss métrica, además de cualquier otra medida que se mide loss también incluirá la min_diff_loss .

Cuando se llama a evaluate se puede pasar ya sea en el conjunto de datos original o la que contiene los datos MinDiff. Si incluye MinDiff en la llamada para evaluar, dos cosas serán diferentes:

  • Una métrica adicional llamado min_diff_loss estará presente en la salida.
  • El valor de la loss métrica será la suma del original loss métrica (no se muestra en la salida) y el 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)
77/77 [==============================] - 2s 22ms/step - loss: 0.4638
77/77 [==============================] - 3s 32ms/step - loss: 0.5087 - min_diff_loss: 0.0451

Cuando se llama a predict que puede pasar técnicamente también en el conjunto de datos con los datos MinDiff pero será ignorado y no afectará a la salida.

_ = 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.

Limitaciones del uso de MinDiffModel directamente

Cuando se utiliza MinDiffModel como se describió anteriormente, la mayoría de métodos utilizarán las implementaciones por defecto de tf.keras.Model (excepciones enumeradas en la documentación de la 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)
MinDiffModel.fit == keras.Model.fit
True
MinDiffModel.train_step == keras.Model.train_step
True

Para keras.Sequential o keras.Model , esto está perfectamente bien ya que utilizan las mismas funciones.

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)
Sequential.fit == keras.Model.fit
True
tf.keras.Sequential.train_step == keras.Model.train_step
True

Sin embargo, si su modelo es una subclase de keras.Model , envolviéndolo con MinDiffModel perderá eficacia la personalización.

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)
CustomModel.train_step == keras.Model.train_step
False

Si este es su caso de uso, no se debe utilizar MinDiffModel directamente. En su lugar, tendrá que hacerla una subclase tal como se describe en el Manual de personalización .

Recursos adicionales