【问题标题】:Keras metric based on output of an intermediate layer基于中间层输出的 Keras 度量
【发布时间】:2019-04-08 16:27:27
【问题描述】:

问题: 我想在训练期间更好地监控我的模型。因为在某些情况下,损失会在训练过程中突然变成 nan,我想知道当这种情况发生时模型在做什么。 除此之外,我想看看某个层是否符合特定条件(行和列的总和应该为 1)。

方法: 定义一个自定义指标将无济于事,因为该指标仅适用于 y_predy_true。也许有一些复杂的解决方案,在模型中构建模型,并尝试以某种方式计算中间模型层输出的度量。但这感觉有点太复杂了。

解决方案: 否则我唯一能想到的就是切换到 Tensorflow 本身,这样我就可以更好地控制训练过程。还有其他想法吗?

【问题讨论】:

  • 你可以只做一个回调来完成你想要的计算并打印一些值。
  • 谢谢,就是这样。
  • 您仍然可以将自定义指标包装在以中间张量为参数的函数中。
  • 真的吗?因为这是我从文档“可以在编译步骤传递自定义指标。该函数需要将 (y_true, y_pred) 作为参数并返回单个张量值。”所以我认为我会受到这些输入值的限制

标签: python tensorflow keras


【解决方案1】:

有几种方法可以在不需要构造回调的情况下执行此操作,具体取决于您添加损失的方式。

如果您使用 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)])

【讨论】:

  • model.metrics_tensors.append 不适用于 tf.keras
【解决方案2】:

model.metrics_tensors.appendTensorFlow 2.x 中不起作用

所以如果你使用add_loss方法,你也可以使用Keras / TensorFlow 2.x中的model.add_metric方法。

例如,如果我们想在 VAE 中跟踪 z_meanz_log_var(中间层的输出)中的 KL loss,我们可以这样做:

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

【讨论】:

    猜你喜欢
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2017-12-18
    相关资源
    最近更新 更多