web-dev-qa-db-ja.com

テンソルフロー平均二乗誤差損失関数

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)

これらの違いは何ですか?

20
Nitro

3番目の式は異なりますが、1番目と2番目は形式的には同じですが、数値の問題により動作が異なります。

3番目の式(l2_loss)は、2乗ユークリッドノルムの1/2、つまり、入力の要素ごとの2乗の合計、つまりx=prediction-Y。どこでもサンプルの数で割っていません。したがって、サンプルの数が非常に多い場合、計算がオーバーフローする可能性があります(Infを返す)。

他の2つは形式的に同じで、要素ごとの2乗xテンソルの平均を計算します。ただし、ドキュメントでは明示的に指定されていませんが、reduce_meanは、非常に多数のサンプルでのオーバーフローを回避するように適合されたアルゴリズムを使用します。言い換えると、最初にすべてを合計してthen Nで除算しようとはしませんが、オーバーフローを引き起こすことなく、任意の数のサンプルに適応できるローリング平均を使用します。

14
Javier Martín

1番目と2番目の損失関数は同じことを計算しますが、わずかに異なる方法で計算します。 3番目の関数は、まったく異なるものを計算します。これを確認するには、次のコードを実行します。

_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番目と2番目が(理論的には)同じことを計算することを確認できます。また、_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))
_
11
Salvador Dali