在keras中编写自定义损失函数时遇到了问题,特别是当我在损失函数中使用K.sum()
时。为了简化,让我们看下面的例子:
这很好:
from keras import backend as K
def custom_loss(y_true, y_pred):
return K.mean(K.abs(y_pred - y_true))
现在,如果我要归一化y_pred
,然后再评估上述损失:
def custom_loss(y_true, y_pred):
y_pred = y_pred / K.sum(y_pred, axis=-1)
return K.mean(K.abs(y_pred - y_true))
在model.fit_generator()
期间出现以下错误
InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: Incompatible shapes: [64,9] vs. [64]
[[{{node loss_13/dense_2_loss/truediv}}]]
[[metrics_9/mean_absolute_error/Mean_1/_5003]]
(1) Invalid argument: Incompatible shapes: [64,9] vs. [64]
[[{{node loss_13/dense_2_loss/truediv}}]]
0 successful operations.
0 derived errors ignored.
我已经看到很多有关不兼容形状错误的问题,但似乎没有人担心K.sum()
的使用。
我注意到批处理大小是64,而我拥有的类数是9(y_true
和y_pred
都应该是(64,9))。
我添加了一些打印语句,以查看在model.compile()
期间发生的情况,这是输出:
def custom_loss(y_true, y_pred):
print(f"Shape of y_pred before normalization: {y_pred.shape}")
y_pred = y_pred / K.sum(y_pred, axis=-1)
print(f"Shape of y_pred after normalization: {y_pred.shape}")
return K.mean(K.abs(y_pred - y_true))
编译
# compile the model
model.compile(loss=custom_loss, metrics=['mae'], optimizer='Adam')
# outputs
# Shape of y_pred before normalization: (?, 9)
# Shape of y_pred after normalization: (?, 9)
版本信息:
keras 2.2.4
keras-applications 1.0.8
keras-preprocessing 1.1.0
tensorflow-estimator 1.14.0
tensorflow-gpu 1.14.0
答案 0 :(得分:1)
因此,基本上,K.sum(y_pred, axis=-1)
将计算最后一个暗点的总和。 keepdim
中还有另一个参数K.sum()
,默认情况下为False。因此,在计算完最后一个暗角的和后,它将挤压该暗角。因为要标准化y_pred
,所以应保持最后一个暗淡状态(与广播相关)。
ef custom_loss_norm(y_true, y_pred):
y_pred = y_pred / K.sum(y_pred, axis=-1, keepdims=True)
return K.mean(K.abs(y_pred - y_true))