tensorflow - 如何在 Keras 中分别优化多个损失函数?
问题描述
我目前正在尝试在 Keras 中构建具有三种不同损失函数的深度学习模型。第一个损失函数是典型的均方误差损失。其他两个损失函数是我自己构建的,它发现了从输入图像和输出图像进行的计算之间的差异(这段代码是我正在做的简化版本)。
def p_autoencoder_loss(yTrue,yPred):
def loss(yTrue, y_Pred):
return K.mean(K.square(yTrue - yPred), axis=-1)
def a(image):
return K.mean(K.sin(image))
def b(image):
return K.sqrt(K.cos(image))
a_pred = a(yPred)
a_true = a(yTrue)
b_pred = b(yPred)
b_true = b(yTrue)
empirical_loss = (loss(yTrue, yPred))
a_loss = K.mean(K.square(a_true - a_pred))
b_loss = K.mean(K.square(b_true - b_pred))
final_loss = K.mean(empirical_loss + a_loss + b_loss)
return final_loss
然而,当我用这个损失函数训练时,它根本就不能很好地收敛。我想尝试的是分别最小化三个损失函数,而不是将它们添加到一个损失函数中。
我基本上想在这里做第二个选项Tensorflow: Multiple loss functions vs Multiple training ops but in Keras form。我还希望损失函数彼此独立。有没有一种简单的方法可以做到这一点?
解决方案
您的 keras 模型中可以有 3 个输出,每个输出都有您指定的损失,然后 keras 支持对这些损失进行加权。然后它还会在输出中为您生成最终的组合损失,但它将进行优化以减少所有三个损失。不过要小心这一点,因为根据您的数据/问题/损失,您可能会发现它会稍微停顿,或者如果您有损失相互争斗,它会很慢。然而,这需要使用功能 API。我不确定这是否真的实现了单独的优化器实例,但是我认为这与我知道的纯 Keras 一样接近,而无需开始编写更复杂的 TF 训练机制。
例如:
loss_out1 = layers.Dense(1, activation='sigmoid', name='loss1')(x)
loss_out2 = layers.Dense(1, activation='sigmoid', name='loss2')(x)
loss_out3 = layers.Dense(1, activation='sigmoid', name='loss3')(x)
model = keras.Model(inputs=[input],
outputs=[loss1, loss2, loss3])
model.compile(optimizer=keras.optimizers.RMSprop(1e-3),
loss=['binary_crossentropy', 'categorical_crossentropy', 'custom_loss1'],
loss_weights=[1., 1., 1.])
这应该从上面的 (x) 编译一个具有 3 个输出的模型。编译时,您将输出设置为列表,并将损失和损失权重设置为列表。请注意,当您 fit() 时,您也需要将目标输出作为列表提供三次,例如[y, y, y]
,因为您的模型现在具有三个输出。
我不是 Keras 专家,但它非常高级,我不知道使用纯 Keras 的另一种方式。希望有人可以用更好的解决方案来纠正我!
推荐阅读
- primefaces - 从 xa 更新版本迁移 PrimeFaces
- r - 重新缩放 ggplot 中的 alpha 以从 0 开始
- javascript - 在 Google Data Studio 中,有没有一种方法可以过滤我的数据,而无需在每次过滤请求后获取它?
- python - 精灵奇怪地运动
- python - 请解释下面的循环
- python - 尝试选择两列时出现 np.where 错误
- r - R 中的问题:从 tibble 中提取日期 - 直接解决时有效,但不是通过引用。有任何想法吗?
- python-3.x - 这个python3代码的正确缩进是什么
- flutter - 如何将相机捕获的图像转换为带有颤振的base64
- javascript - 如何在 React ES6 中解构我的对象中的数组?