소개
MinDiff를 모델 구현에 직접 통합할 수 있습니다. 사용의 편리 성이없는 그렇게하는 동안 MinDiffModel
,이 옵션은 모델의 서브 클래스 때 특히 유용 할 수있는 컨트롤의 최고 수준의 제공 tf.keras.Model
.
이 가이드는 당신이에 추가하여 사용자 정의 모델의 구현에 직접 MinDiff을 통합 할 수있는 방법을 보여줍니다 train_step
방법.
설정
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
쉽게 서브 클래스를 통해 사용자 정의 할 수 있도록 설계되었습니다. 이것은 보통의 호출로 발생하는 변경 포함 fit
설명 된대로 여기 .
이 가이드는 사용자 정의 구현 사용 train_step
밀접하게 기본 유사 tf.keras.Model.train_step
. 일반적으로 이렇게 하면 이점이 없지만 여기서는 MinDiff를 통합하는 방법을 보여 주는 데 도움이 됩니다.
class CustomModel(tf.keras.Model):
def train_step(self, data):
# Unpack the data.
x, y, sample_weight = tf.keras.utils.unpack_x_y_sample_weight(data)
with tf.GradientTape() as tape:
y_pred = self(x, training=True) # Forward pass.
loss = self.compiled_loss(
y, y_pred, sample_weight, regularization_losses=self.losses)
# Compute the loss value.
loss = self.compiled_loss(
y, y_pred, sample_weight, regularization_losses=self.losses)
# Compute gradients and update weights.
self.optimizer.minimize(loss, self.trainable_variables, tape=tape)
# Update and return metrics.
self.compiled_metrics.update_state(y, y_pred, sample_weight)
return {m.name: m.result() for m in self.metrics}
당신이 일반적인 것처럼 모델을 훈련 Model
기능성 API를 사용하여.
model = tutorials_utils.get_uci_model(model_class=CustomModel) # Use CustomModel.
model.compile(optimizer='adam', loss='binary_crossentropy')
_ = model.fit(train_ds, epochs=1)
77/77 [==============================] - 3s 22ms/step - loss: 0.7273
MinDiff를 모델에 직접 통합
받는 MinDiff 추가 train_step
MinDiff을 통합하려면, 당신은 몇 가지 라인을 추가해야합니다 CustomModel
여기에 이름이 변경됩니다 CustomModelWithMinDiff
.
명확하게하기 위해,이 가이드라는 부울 플래그 사용 apply_min_diff
. 이 설정되어있는 경우 MinDiff에 관련된 모든 코드는 실행됩니다 True
. 로 설정하면 False
다음 모델은 정확히 같은 행동을 할 CustomModel
.
min_diff_loss_fn = min_diff.losses.MMDLoss() # Hard coded for convenience.
min_diff_weight = 2 # Arbitrary number for example, hard coded for convenience.
apply_min_diff = True # Flag to help show where the additional lines are.
class CustomModelWithMinDiff(tf.keras.Model):
def train_step(self, data):
# Unpack the data.
x, y, sample_weight = tf.keras.utils.unpack_x_y_sample_weight(data)
# Unpack the MinDiff data.
if apply_min_diff:
min_diff_data = min_diff.keras.utils.unpack_min_diff_data(x)
min_diff_x, membership, min_diff_sample_weight = (
tf.keras.utils.unpack_x_y_sample_weight(min_diff_data))
x = min_diff.keras.utils.unpack_original_inputs(x)
with tf.GradientTape() as tape:
y_pred = self(x, training=True) # Forward pass.
loss = self.compiled_loss(
y, y_pred, sample_weight, regularization_losses=self.losses)
# Compute the loss value.
loss = self.compiled_loss(
y, y_pred, sample_weight, regularization_losses=self.losses)
# Calculate and add the min_diff_loss. This must be done within the scope
# of tf.GradientTape().
if apply_min_diff:
min_diff_predictions = self(min_diff_x, training=True)
min_diff_loss = min_diff_weight * min_diff_loss_fn(
min_diff_predictions, membership, min_diff_sample_weight)
loss += min_diff_loss
# Compute gradients and update weights.
self.optimizer.minimize(loss, self.trainable_variables, tape=tape)
# Update and return metrics.
self.compiled_metrics.update_state(y, y_pred, sample_weight)
return {m.name: m.result() for m in self.metrics}
이 모델을 사용한 훈련은 사용된 데이터 세트를 제외하고 이전과 완전히 동일합니다.
model = tutorials_utils.get_uci_model(model_class=CustomModelWithMinDiff)
model.compile(optimizer='adam', loss='binary_crossentropy')
_ = model.fit(train_with_min_diff_ds, epochs=1)
77/77 [==============================] - 4s 30ms/step - loss: 0.7799
입력 재구성(선택 사항)
이 접근 방식이 완전한 제어를 제공한다는 점을 감안할 때 이 기회에 입력을 약간 더 깔끔한 형식으로 재구성할 수 있습니다. 사용하는 경우 MinDiffModel
의 min_diff_data
모든 배치의 첫 번째 구성 요소로 포장 될 필요가있다. 이것은의 경우 train_with_min_diff_ds
데이터 세트.
for x, y in train_with_min_diff_ds.take(1):
print('Type of x:', type(x)) # MinDiffPackedInputs
print('Type of y:', type(y)) # Tensor (original labels)
Type of x: <class 'tensorflow_model_remediation.min_diff.keras.utils.input_utils.MinDiffPackedInputs'> Type of y: <class 'tensorflow.python.framework.ops.EagerTensor'>
이 요구 사항이 해제되면 원본 데이터와 MinDiff 데이터가 깔끔하게 분리되어 약간 더 직관적인 구조로 데이터를 재구성할 수 있습니다.
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)
original_data = (original_inputs, original_labels)
return {
'min_diff_data': min_diff_data,
'original_data': original_data}
customized_train_with_min_diff_ds = train_with_min_diff_ds.map(_reformat_input)
이 단계는 완전히 선택 사항이지만 데이터를 더 잘 구성하는 데 유용할 수 있습니다. 이렇게하면, 당신은 구현 방법의 유일한 차이점 CustomModelWithMinDiff
당신이 압축 방법이 될 것입니다 data
시작 부분에.
class CustomModelWithMinDiff(tf.keras.Model):
def train_step(self, data):
# Unpack the MinDiff data from the custom structure.
if apply_min_diff:
min_diff_data = data['min_diff_data']
min_diff_x, membership, min_diff_sample_weight = (
tf.keras.utils.unpack_x_y_sample_weight(min_diff_data))
data = data['original_data']
... # possible preprocessing or validation on data before unpacking.
x, y, sample_weight = tf.keras.utils.unpack_x_y_sample_weight(data)
...
이 마지막 단계를 통해 입력 형식과 MinDiff를 적용하기 위해 모델 내에서 사용되는 방식을 모두 완전히 제어할 수 있습니다.