Tensorflow均方误差损失函数

时间:2016-12-27 03:04:36

标签: python machine-learning tensorflow

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

这些之间有什么区别?

2 个答案:

答案 0 :(得分:14)

我会说第三个等式是不同的,而第一个和第二个等式正式相同但由于数值问题而表现不同。

我认为第3个等式(使用- (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code here. } return self; } - (void)drawRect:(NSRect)dirtyRect { NSRect bounds= [self bounds]; [[NSColor whiteColor] set]; [NSBezierPath fillRect:bounds]; } )只返回平方欧几里德范数的1/2,即输入的元素平方和的总和,即{{1} }。您没有在任何地方除以样本数量。因此,如果您有大量样本,计算可能会溢出(返回Inf)。

另外两个正式相同,计算元素方形l2_loss张量的平均值。但是,虽然文档没有明确指定,但x=prediction-Y很可能使用适合于避免溢出大量样本的算法。换句话说,它可能不会先尝试对所有内容求和,而然后除以N,但使用某种滚动均值可以适应任意数量的样本而不必导致溢出。

答案 1 :(得分:10)

第一个和第二个损失函数计算相同的东西,但方式略有不同。第三个函数计算完全不同的东西。您可以通过执行以下代码来查看:

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:output = sum(t   ** 2)/ 2

因此,如果您希望它(在理论上)计算与第一个相同的东西,您需要适当地缩放它:

loss3 = tf.nn.l2_loss(Y1 - Y2) * 2 / (reduce(lambda x, y: x*y, shape_obj))