Tensorflow 均方误差损失函数
Posted
技术标签:
【中文标题】Tensorflow 均方误差损失函数【英文标题】:Tensorflow mean squared error loss function 【发布时间】:2017-05-11 08:20:04 【问题描述】:我在 Tensorflow 中的回归模型的各种帖子中看到了一些不同的均方误差损失函数:
loss = tf.reduce_sum(tf.pow(prediction - Y,2))/(n_instances)
loss = tf.reduce_mean(tf.squared_difference(prediction, Y))
loss = tf.nn.l2_loss(prediction - Y)
这些有什么区别?
【问题讨论】:
1-st and 2-nd do the same thing in theory, 3-rd is scaled by a constant 另一种计算 MSE 的方法(相当于您的第一种和第二种方法):tf.losses.mean_squared_error 【参考方案1】:我想说第三个等式是不同的,而第一个和第二个在形式上是相同的,但由于数值问题而表现不同。
我认为第三个方程(使用l2_loss
)只是返回平方欧几里得范数的1/2,即输入的元素平方和,即x=prediction-Y
。您不会除以任何地方的样本数量。因此,如果您有大量样本,计算可能会溢出(返回 Inf)。
另外两个在形式上是相同的,计算元素平方 x
张量的平均值。然而,虽然文档没有明确指定它,但很可能reduce_mean
使用了一种算法,该算法适用于避免大量样本溢出。换句话说,它可能不会尝试先对所有内容求和然后然后除以 N,而是使用某种滚动均值来适应任意数量的样本而不必导致溢出。 p>
【讨论】:
“reduce_mean 很可能使用了一种算法来避免大量样本溢出”我认为这不是真的。 here is the relevant code,很明显,您声称正在发生的事情并没有发生。虽然,tf 代码有点像兔子洞,我不是这方面的专家。然而,在没有引用或证据的情况下,我发现其中一些说法是可疑的。【参考方案2】:第一个和第二个损失函数计算相同的东西,但方式略有不同。第三个函数计算完全不同的东西。您可以通过执行以下代码来看到这一点:
import tensorflow as tf
shape_obj = (5, 5)
shape_obj = (100, 6, 12)
Y1 = tf.random_normal(shape=shape_obj)
Y2 = tf.random_normal(shape=shape_obj)
loss1 = tf.reduce_sum(tf.pow(Y1 - Y2, 2)) / (reduce(lambda x, y: x*y, shape_obj))
loss2 = tf.reduce_mean(tf.squared_difference(Y1, Y2))
loss3 = tf.nn.l2_loss(Y1 - Y2)
with tf.Session() as sess:
print sess.run([loss1, loss2, loss3])
# when I run it I got: [2.0291963, 2.0291963, 7305.1069]
现在您可以通过注意到 tf.pow(a - b, 2)
与 tf.squared_difference(a - b, 2)
相同来验证 1-st 和 2-nd 计算相同的东西(理论上)。 reduce_mean
也与 reduce_sum / number_of_element
相同。问题是计算机无法准确计算所有内容。要了解数值不稳定性会对您的计算造成什么影响,请查看以下内容:
import tensorflow as tf
shape_obj = (5000, 5000, 10)
Y1 = tf.zeros(shape=shape_obj)
Y2 = tf.ones(shape=shape_obj)
loss1 = tf.reduce_sum(tf.pow(Y1 - Y2, 2)) / (reduce(lambda x, y: x*y, shape_obj))
loss2 = tf.reduce_mean(tf.squared_difference(Y1, Y2))
with tf.Session() as sess:
print sess.run([loss1, loss2])
很容易看出答案应该是 1,但你会得到这样的结果:[1.0, 0.26843545]
。
关于你的最后一个功能,文档说:
计算没有 sqrt 的张量 L2 范数的一半: output = sum(t ** 2) / 2
因此,如果您希望它(理论上)计算与第一个相同的东西,则需要适当地对其进行缩放:
loss3 = tf.nn.l2_loss(Y1 - Y2) * 2 / (reduce(lambda x, y: x*y, shape_obj))
【讨论】:
那么这是否意味着内置的 tensorflow 函数比你显式计算平方并取平均值更糟糕?这对我来说没有意义,内置的实现不应该在数值上更稳定吗?否则为什么还要麻烦做一个函数呢? 那么tf.nn.l2_loss
的用例是什么?以上是关于Tensorflow 均方误差损失函数的主要内容,如果未能解决你的问题,请参考以下文章
当损失是均方误差 (MSE) 时,啥函数定义 Keras 中的准确性?