【发布时间】:2022-07-12 10:05:33
【问题描述】:
我一直在尝试尽早停下来研究 LSTM VAE。 在训练期间,训练损失按应有的方式计算,但验证损失为 0。 我尝试编写一个自定义 val_step 函数(类似于 train_step 但没有跟踪器)来计算损失,但我认为我无法在 vae.fit() 调用中建立该函数和 validation_data 参数之间的连接。 自定义模型类如下图:
class VAE(Model):
def __init__(self, encoder, decoder, **kwargs):
super(VAE, self).__init__(**kwargs)
self.encoder = encoder
self.decoder = decoder
self.total_loss_tracker = tf.metrics.Mean(name="total_loss")
self.reconstruction_loss_tracker = tf.metrics.Mean(name="reconstruction_loss")
self.kl_loss_tracker = tf.metrics.Mean(name="kl_loss")
def call(self, x):
_, _, z = self.encoder(x)
return self.decoder(z)
@property
def metrics(self):
return [
self.total_loss_tracker,
self.reconstruction_loss_tracker,
self.kl_loss_tracker,
]
def train_step(self, data):
with tf.GradientTape() as tape:
z_mean, z_log_var, z = self.encoder(data)
reconstruction = self.decoder(z)
reconstruction_loss = tf.reduce_mean(tf.reduce_sum(losses.mse(data, reconstruction), axis=1))
kl_loss = -0.5 * (1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var))
kl_loss = tf.reduce_mean(tf.reduce_sum(kl_loss, axis=1))
total_loss = reconstruction_loss + kl_loss
grads = tape.gradient(total_loss, self.trainable_weights)
self.optimizer.apply_gradients(zip(grads, self.trainable_weights))
self.total_loss_tracker.update_state(total_loss)
self.reconstruction_loss_tracker.update_state(reconstruction_loss)
self.kl_loss_tracker.update_state(kl_loss)
return {
"loss": self.total_loss_tracker.result(),
"reconstruction_loss": self.reconstruction_loss_tracker.result(),
"kl_loss": self.kl_loss_tracker.result(),
}
def val_step(self, validation_data):
_, _, z = self.encoder(validation_data)
val_reconstruction = self.decoder(z)
val_reconstruction_loss = tf.reduce_mean(tf.reduce_sum(losses.mse(validation_data, val_reconstruction), axis=1))
val_kl_loss = -0.5 * (1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var))
val_kl_loss = tf.reduce_mean(tf.reduce_sum(val_kl_loss, axis=1))
val_total_loss = val_reconstruction_loss + val_kl_loss
return {"total_loss": self.val_total_loss}
es = callbacks.EarlyStopping(monitor='val_total_loss',
mode='min',
verbose=1,
patience=5,
restore_best_weights=True,
)
vae = VAE(encoder, decoder)
vae.compile(optimizer=tf.optimizers.Adam())
vae.fit(tf_train,
epochs=100,
callbacks=[es],
validation_data=tf_val,
shuffle=True
)
这是控制台在每个 epoch 后打印的内容(验证指标显示为 0):
38/38 [==============================] - 37s 731ms/step - loss: 3676.8105 - reconstruction_loss: 2402.6206 - kl_loss: 149.5690 - val_total_loss: 0.0000e+00 - val_reconstruction_loss: 0.0000e+00 - val_kl_loss: 0.0000e+00
如果有人能告诉我我做错了什么,那就太好了。 提前谢谢!
更新 1: 从 val_step 定义的返回值中删除了“val_”。 有趣的是,返回调用之前的行中的 val_total_loss 是灰色的,因为它没有被使用。所以看起来这两条线之间存在脱节。
【问题讨论】:
标签: tensorflow validation