Integrazione di MinDiff con MinDiffModel

introduzione

Ci sono due passaggi per integrare MinDiff nel tuo modello:

  1. Preparare i dati (coperto nella guida di preparazione di ingresso ).

  2. Modificare o creare un modello che integrerà MinDiff durante l'allenamento.

Questa guida riguarderà il modo più semplice per completare la seconda fase: usando MinDiffModel .

Impostare

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

Innanzitutto, scarica i dati. Per brevità, la logica preparazione ingresso è stato fattorizzato nella helper funzioni come descritto nella guida di preparazione ingresso . Puoi leggere la guida completa per i dettagli su questo processo.

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

Modello originale

Questa guida utilizza una base, non sintonizzato keras.Model utilizzando l' API funzionale per evidenziare utilizzando MinDiff. In un'applicazione del mondo reale, dovresti scegliere con cura l'architettura del modello e utilizzare l'ottimizzazione per migliorare la qualità del modello prima di tentare di risolvere eventuali problemi di equità.

Dal momento che MinDiffModel è progettato per funzionare con la maggior parte Keras Model classi, abbiamo fattorizzato la logica della costruzione del modello in una funzione di supporto: get_uci_model .

Allenarsi con un DataFrame Pandas

Questa guida si allena su una singola epoca per la velocità, ma potrebbe facilmente migliorare le prestazioni del modello aumentando il numero di epoche.

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

Formazione con un tf.data.Dataset

La formazione equivalente con una tf.data.Dataset sarebbe molto simile (anche se inizializzazione e casualità ingresso possono produrre risultati leggermente diversi).

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

Integrazione di MinDiff per la formazione

Una volta che i dati sono stati preparati, applica MinDiff al tuo modello con i seguenti passaggi:

  1. Crea il modello originale come faresti senza MinDiff.
original_model = tutorials_utils.get_uci_model()
  1. Avvolgerlo in un MinDiffModel .
min_diff_model = min_diff.keras.MinDiffModel(
    original_model=original_model,
    loss=min_diff.losses.MMDLoss(),
    loss_weight=1)
  1. Compilalo come faresti senza MinDiff.
min_diff_model.compile(optimizer='adam', loss='binary_crossentropy')
  1. Allenarsi con il set di dati MinDiff ( train_with_min_diff_ds in questo 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

Valutazione e previsione con MinDiffModel

Sia la valutazione e la previsione di un MinDiffModel sono simili a farlo con il modello originale.

Quando si chiama evaluate è possibile passare in entrambi i set di dati originale o quella che contiene i dati MinDiff. Se si sceglie quest'ultima, si riceverà anche il min_diff_loss metrica in aggiunta a qualsiasi altro metriche da misurare loss includerà anche la min_diff_loss .

Quando si chiama evaluate è possibile passare in entrambi i set di dati originale o quella che contiene i dati MinDiff. Se includi MinDiff nella chiamata per valutare, due cose saranno diverse:

  • Una metrica supplementare chiamato min_diff_loss sarà presente in uscita.
  • Il valore della loss metrica sarà la somma dell'originale loss metrica (non mostrato in uscita) e la 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

Quando si chiama predict è possibile tecnicamente passare anche nel set di dati con i dati MinDiff ma sarà ignorato e non influenza l'uscita.

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

Limitazioni di utilizzo MinDiffModel direttamente

Quando si utilizza MinDiffModel come descritto sopra, la maggior parte dei metodi utilizzeranno le implementazioni predefinite di tf.keras.Model (eccezioni elencate nella documentazione 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

Per keras.Sequential o keras.Model , questo è perfettamente bene dato che usano le stesse funzioni.

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

Tuttavia, se il modello è una sottoclasse di keras.Model , avvolgendolo con MinDiffModel perderà in modo efficace la personalizzazione.

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

Se questo è il vostro caso d'uso, non si dovrebbe usare MinDiffModel direttamente. Invece, è necessario creare una sottoclasse come descritto nel Manuale di personalizzazione .

Risorse addizionali