什么是惩罚幅度和符号差异的良好损失函数

时间:2018-06-06 02:39:53

标签: machine-learning loss-function

我处于需要训练模型来预测标量值的情况,并且让预测值与真实值在同一方向上很重要,而平方误差最小。

对于那种损失函数有什么好的选择?

例如:

假设预测值为-1,真值为1.两者之间的损失应远大于3和1之间的损失,即使(3,1)的平方误差和( - 1,1)是平等的。

非常感谢!

2 个答案:

答案 0 :(得分:5)

这结果是一个非常有趣的问题 - 感谢您的提问!首先,请记住,您希望您的损失函数完全由差分运算定义,以便您可以通过它进行反向传播。这意味着任何旧的任意逻辑都不一定会这样做。重述你的问题:你想要找到两个变量的可微函数,当两个变量采用不同符号的值时会急剧增加,而当它们共享相同的符号时会更慢。此外,您希望对这些值相对于彼此的如何进行一些控制。因此,我们需要具有两个可配置常量的东西。我开始构建一个满足这些需求的函数,但后来记得你可以在任何高中几何教科书中找到的函数:elliptic paraboloid

A rotated elliptic paraboloid.

标准公式不符合符号协议对称性的要求,因此我不得不引入rotation。上图是结果。请注意,当符号不一致时,它会急剧增加,而当它们不同时,它会急剧增加,并且控制此行为的输入常量是可配置的。下面的代码是定义和绘制损失函数所需的全部内容。我以为我以前从未使用过几何形状作为损失函数 - 非常整洁。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm


def elliptic_paraboloid_loss(x, y, c_diff_sign, c_same_sign):

    # Compute a rotated elliptic parabaloid.
    t = np.pi / 4

    x_rot = (x * np.cos(t)) + (y * np.sin(t))

    y_rot = (x * -np.sin(t)) + (y * np.cos(t))

    z = ((x_rot**2) / c_diff_sign) + ((y_rot**2) / c_same_sign)

    return(z)


c_diff_sign = 4

c_same_sign = 2

a = np.arange(-5, 5, 0.1)

b = np.arange(-5, 5, 0.1)

loss_map = np.zeros((len(a), len(b)))

for i, a_i in enumerate(a):

    for j, b_j in enumerate(b):

        loss_map[i, j] = elliptic_paraboloid_loss(a_i, b_j, c_diff_sign, c_same_sign)



fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y = np.meshgrid(a, b)
surf = ax.plot_surface(X, Y, loss_map, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)

plt.show()

答案 1 :(得分:0)

据我了解,您当前的损失函数类似于:

loss = mean_square_error(y, y_pred)

你可以做的是,在你的损失中添加一个其他组件,作为一个惩罚负数的组件,对正数没有任何作用。你可以选择一个系数来表示你想要惩罚它的程度。为此,我们可以像使用负形状的 ReLU。像这样:

NegRElU

让我们为这个组件调用“Neg_ReLU”。那么,你的损失函数将是:

loss = mean_squared_error(y, y_pred) + Neg_ReLU(y_pred)

例如,如果您的结果为 -1,则总误差为:

mean_squared_error(1, -1) + 1

如果你的结果是 3,那么总误差为:

mean_squared_error(1, -1) + 0

(在上面的函数中看到 Neg_ReLU(3) = 0,和 Neg_ReLU(-1) = 1。

如果你想惩罚更多的负值,那么你可以添加一个系数:

coeff_negative_value = 2

loss = mean_squared_error(y, y_pred) + coeff_negative_value * Neg_ReLU

enter image description here

现在负值会受到更多惩罚。

ReLU 负函数我们可以这样构建:

tf.nn.relu(tf.math.negative(value))


总结一下,最终你的总损失将是:

coeff = 1

Neg_ReLU = tf.nn.relu(tf.math.negative(y))

total_loss = mean_squared_error(y, y_pred) + coeff * Neg_ReLU
相关问题