我一直在尝试在 keras 中实现损失函数。但是我无法找到传递除 loss(y_true, y_predict) 之外的 2 个以上参数的方法,因此我想到使用 lambda 层作为最后一层,并在 lambda 层本身中进行计算,然后简单地在损失函数中返回 y_predict 的值,如下所示
def loss_function(x): loss = some calculations return loss def dummy_loss(y_true, y_pred): return y_pred def primary_network(): global prim_binary_tensor x = VGG16(weights='imagenet', include_top=True, input_shape=image_shape) last_layer = Dense(k_bit, activation='tanh', name='Dense11')(x.layers[-1].output) last_layer, x = basic_model() lambda_layer = Lambda(loss_function)([last_layer, prim_binary_tensor]) model = Model(inputs=[x.input, prim_binary_tensor], outputs=[lambda_layer]) model.compile(optimizer="adam", loss=dummy_loss,metrics=['accuracy']) return model
所以我的问题是:
\1) 我计算损失的方法正确吗? 是否保证对每个图像(input_data)调用 lambda 层函数?
2)有人可以建议我如何将多个参数传递给损失函数吗?
3)损失函数的最终结果可以是标量吗?还是必须是向量或矩阵?
让我们来逐一解答你的问题:
input_data
lambda
你的方法有效,但有些冗长。在 Lambda 层中执行损失计算可以绕过 Keras 的传统损失机制,但一般会增加复杂性,因为这会将损失计算过程移入模型图,而不是在 compile 的 loss 参数中指定损失函数。
Lambda
compile
loss
为了确保 loss_function 在每个输入上被调用,你可以使用 Lambda 层来进行逐步计算,这个过程确实会在每个样本输入时调用。Keras 会将 Lambda 层的输出作为 y_pred 传递给你的 dummy_loss 函数。
loss_function
y_pred
dummy_loss
Keras 的标准损失函数签名 loss(y_true, y_pred) 不直接支持额外的参数传递。不过,你可以通过以下方式实现:
loss(y_true, y_pred)
python def custom_loss(param1, param2): def loss(y_true, y_pred): # 使用 param1 和 param2 进行计算 return computed_loss return loss
然后在 compile 中调用带参数的损失函数:
python model.compile(optimizer="adam", loss=custom_loss(param1_value, param2_value))
partial
functools.partial
python from functools import partial model.compile(optimizer="adam", loss=partial(custom_loss, param1=param1_value, param2=param2_value))
model.fit({'input_data': x, 'extra_input': extra_params})
损失函数的最终输出必须是标量,因为 Keras 在每次反向传播中会将损失值汇总为一个数值,便于更新梯度。对于批量数据,Keras 会自动在批次维度上进行平均。因此,损失函数返回一个标量是最常见的情况。