【问题标题】:Keras custom loss function issue when using K.sum()使用 K.sum() 时的 Keras 自定义损失函数问题
【发布时间】:2019-10-16 07:06:21
【问题描述】:

我在 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_truey_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 

【问题讨论】:

  • 为什么不在K.sum() 中设置keepdim=True
  • @zihaozhihao 哦!这就是问题所在。我已经阅读了文档,但我没有明白这一点的重要性。非常感谢。您能否添加解释/答案以接受?
  • 您好,说明已添加,希望对您有所帮助!
  • 谢谢@zihaozhihao。顺便说一句,你对我函数中的两个打印语句有什么看法?
  • 我无法在我的机器上重现您的结果。用两种不同的形状做除法是无效的。你确定这是代码的输出吗?

标签: python tensorflow keras deep-learning


【解决方案1】:

所以基本上,K.sum(y_pred, axis=-1) 将计算最后一个暗角的总和。 K.sum() 中还有另一个参数 keepdim,默认为 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))

【讨论】:

    猜你喜欢
    • 2018-03-18
    • 2018-05-25
    • 2020-12-19
    • 2017-12-18
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    相关资源
    最近更新 更多