ケラス/テンソルフローを使用して方位角を予測しようとしています。 y_trueの範囲は0-359ですが、私はその範囲外にあり、包まれた予測を処理する損失関数が必要です。私はモジュラー部門tf.mod()
または%
のいずれかの種類をしようとすると、残念ながら、私はエラーを取得...360度予測のケラス損失関数
LookupError: No gradient defined for operation 'FloorMod' (op type: FloorMod)
ので、私は次のようにこの問題を回避働いてきたと思います...
def mean_squared_error_360(y_true, y_pred):
delta = K.minimum(K.minimum(K.abs(y_pred - y_true),
K.abs(y_pred - (360+y_true))),
K.abs(y_true - (360+y_pred)))
return K.mean(K.square(delta), axis=-1)
def rmse_360(y_true, y_pred):
return K.sqrt(mean_squared_error_360(y_true, y_pred))
model.compile(loss=mean_squared_error_360,
optimizer=rmsprop(lr=0.0001),
metrics=[rmse_360])
これは次のようなケースを処理します...私は予測に出くわしていないので、私はアドレッシングしていません。
y = 1 y_pred = 361 err = 0
y = 359 y_pred = 1 err = 2
y = 359 y_pred = 361 err = 2
質問
- これは不格好な感じ。スマートな解決策がありますか?
- 直感的には、mean_squared_errorとroot_mean_squared_errorを損失として使用する場合の結果に違いはないと思います...勾配は異なりますが、同じ最適な重みが両方を解くでしょうか? 1つを選択する理由はありますか?私はmseがrmseよりやや簡単だと思いますが、それは簡単なはずです。私は両方を試してみましたが、rmseを使うと、mseよりも秩序だった降下のような感じがします...それらの二乗誤差の大きさについては何かありますか?
ありがとうございます。何らかの理由で
EDIT
...私のオリジナルMSEはトレーニングセットをフィットしているように見えますが、バリデーションセットは、いくつかのエポックの後に任意の実際の改善なしに、エポックにかなりうるさいエポックに見えました。 rmseはより秩序ある降下のように見えました...損失が数十エポックの間改善した後infになるまで。私は損失機能よりも大きな問題があるかもしれません。
EDIT 2 - 私の実装を追加するには、TRIG ...
ああ下に答える@Patwie !!もちろん!!残念ながら、私はtf.atan2()を持っていないtf v1.0を使用しています。不思議なことに、私はtfリポジトリでatan2の実装を見つけることができませんでしたが、問題6095のasos-benの提案がこのトリックを行うと思います。テスト実行の中https://github.com/tensorflow/tensorflow/issues/6095
def atan2(x, y, epsilon=1.0e-12):
x = tf.where(tf.equal(x, 0.0), x+epsilon, x)
y = tf.where(tf.equal(y, 0.0), y+epsilon, y)
angle = tf.where(tf.greater(x,0.0), tf.atan(y/x), tf.zeros_like(x))
angle = tf.where(tf.logical_and(tf.less(x,0.0), tf.greater_equal(y,0.0)), tf.atan(y/x) + np.pi, angle)
angle = tf.where(tf.logical_and(tf.less(x,0.0), tf.less(y,0.0)), tf.atan(y/x) - np.pi, angle)
angle = tf.where(tf.logical_and(tf.equal(x,0.0), tf.greater(y,0.0)), 0.5*np.pi * tf.ones_like(x), angle)
angle = tf.where(tf.logical_and(tf.equal(x,0.0), tf.less(y,0.0)), -0.5*np.pi * tf.ones_like(x), angle)
angle = tf.where(tf.logical_and(tf.equal(x,0.0), tf.equal(y,0.0)), tf.zeros_like(x), angle)
return angle
# y in radians
def rmse_360_2(y_true, y_pred):
return K.mean(K.abs(atan2(K.sin(y_true - y_pred), K.cos(y_true - y_pred))))
のみ約7エポック、それが有望と思われる:ここを参照してください。
ある角度が非常に低いか、または無効であるかどうかを確認します。もしそうなら、あなたはこの角度をゼロの中心に置くことができます.... –