问题: 我想在训练期间更好地监控我的模型。因为在某些情况下,损失会在训练过程中突然变为nan,我想知道这种情况发生时模型在做什么。 除此之外,我想看看某个层是否符合特定条件(行和列的总和应为一个)。
方法:
定义自定义指标将无济于事,因为该指标仅适用于y_pred
和y_true
。也许存在一些复杂的解决方案,其中包括在模型内构建模型,并尝试以某种方式在中间模型层的输出上计算度量。但这感觉太复杂了。
解决方案: 否则,我唯一想到的就是切换到Tensorflow本身,这样我就可以更好地控制培训过程。还有其他想法吗?
答案 0 :(得分:1)
model.metrics_tensors.append
在TensorFlow 2.x
中不起作用
因此,如果您使用的是add_loss
方法,则也可以在model.add_metric
中使用Keras / TensorFlow 2.x
方法。
例如,如果要在VAE中跟踪KL loss
和z_mean
(中间层的输出)中的z_log_var
,我们可以这样做:
kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)
kl_loss = K.sum(kl_loss, axis=-1)
kl_loss *= -0.5
然后
model.add_loss(vae_loss)
model.add_metric(kl_loss,name='kl_loss')
model.add_metric(reconstruction_loss,name='reconstruction_loss')
model.compile(optimizer='adam')
然后
Epoch 1/50
469/469 [==============================] - 3s 6ms/step - loss: 51.4340 - kl_loss: 4.5296 - reconstruction_loss: 46.9097 - val_loss: 42.0644 - val_kl_loss: 6.0029 - val_reconstruction_loss: 36.0615
答案 1 :(得分:0)
有多种方法可以执行此操作而无需构造回调,具体取决于您如何增加损失。
如果您将损失与model.add_loss相加,则需要通过一种变通方法来显示该损失,方法是在编译步骤之后添加指标(如here所述)
这将导致如下情况(特别是对于VAE,人们对kl_loss感兴趣,这取决于中间层):
reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs))
kl_loss = beta*K.mean(- 0.5 * 1/latent_dim * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1))
model.add_loss(reconstruction_loss)
model.add_loss(kl_loss)
model.compile(optimizer='adam')
model.metrics_tensors.append(kl_loss)
model.metrics_names.append("kl_loss")
model.metrics_tensors.append(reconstruction_loss)
model.metrics_names.append("mse_loss")
对我来说,这样的输出:
Epoch 1/1
252/252 [==============================] - 23s 92ms/step - loss: 0.4336 - kl_loss: 0.0823 - mse_loss: 0.3513 - val_loss: 0.2624 - val_kl_loss: 0.0436 - val_mse_loss: 0.2188
如果您不使用model.add_loss而是直接在编译器中传递损失,则需要定义一个自定义指标(类似于custom loss metric)并将该指标传递给编译步骤。在上述情况下:
def customMetric(kl_loss):
def klLoss(y_true,y_pred):
return kl_loss
return klLoss
model.compile(..., metrics=[customMetric(kl_loss)])