【问题标题】:Make a Custom loss function in Keras in detail详细在 Keras 中制作自定义损失函数
【发布时间】:2018-03-01 11:10:09
【问题描述】:

我尝试在 Keras 中制作自定义损失函数。

我想做这个损失函数

输出的维度是80。批量大小是5000。

所以我在下面构建了这个损失函数。但这不起作用。

def normalize_activation(y_true, y_pred):
    nb_divide = K.reshape(K.sqrt(K.sum(K.square(y_pred), axis=1)),(5000, 1))
    nb_divide=numpy.tile(nb_divide,80)
    predicted=numpy.divide(y_pred,nb_divide)
    return K.sum(K.square(y_true-predicted)) 

ValueError: 使用序列设置数组元素。

出现此错误。我认为y_true, y_pred的形状是(5000,80)。

我应该在哪里修复它??

【问题讨论】:

  • 相当于使用losses.mean_squared_error(y_true, K.l2_normalize(y_pred, axis=-1))
  • 或者您可以在模型末尾添加Lambda(lambda x: K.l2_normalize(x, axis=-1)) 层,并使用loss='mse'
  • @Yu-Yang 非常感谢!使用 lambda 时,最后一个链接的权重应该是 1。我做不到。所以我正在使用你的第一个解决方案。谢谢。但我想知道axis = -1的含义。我知道轴=0,轴=1。
  • axis=-1 只是“最后一个轴”,在这种情况下,它将等同于 axis=1,因此您可以使用其中任何一个。

标签: python neural-network keras


【解决方案1】:

损失函数应该避免各种不是来自keras backend的操作。这些值是张量,您必须像张量一样保持它们。

除非您确实希望它们以特定方式运行,否则您无需重塑事物。

如果你有形状 (5000,80) 和 (5000,1),你可以在不需要K.repeat_elements()(相当于 numpy.tile)的情况下对它们进行操作。

因此,假设 5000 是批量大小(样本数),而 80 是属于样本的唯一实际维度:

def normalize_loss(yTrue,yPred):
    nb_divide = K.sqrt(K.sum(K.square(yPred),axis=1,keepdims=True)) 
        #keepdims=True keeps the shape like (5000,1)
        #this is not summing the entire batch, but only a single sample, is that correct?

    predicted = yPred/nb_divide
    return K.sum(K.square(yTrue-predicted))

一些观察:

  • (我不是这里的损失函数专家)你只划分预测的部分,而不是真实的部分。这不会在两个值之间产生很大差异并导致误导性损失函数吗? (再次声明,我不是这里的专家)

  • 通常人们在损失函数的末尾使用K.mean(),但我看到你使用了K.sum()。这不是问题,也不会妨碍培训发挥作用。但是您可能希望为不同大小的数据可视化相同的损失函数,并能够独立地比较它们的大小。

【讨论】:

    猜你喜欢
    • 2018-02-08
    • 1970-01-01
    • 2020-12-19
    • 2017-12-18
    • 2020-03-27
    • 1970-01-01
    • 2018-10-28
    • 2017-12-29
    • 2020-04-11
    相关资源
    最近更新 更多