我正在尝试使用keras / tensorflow预测方位角。 y_true的范围是0-359,但我需要一个损失函数来处理已经缠绕并超出该范围的预测。不幸的是,当我尝试任何类型的模块化部门tf.mod()
或%
时,我都会收到错误...
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])
这处理以下边缘情况......我没有遇到预测< 0,所以我没有解决。
y = 1 y_pred = 361 err = 0
y = 359 y_pred = 1 err = 2
y = 359 y_pred = 361 err = 2
问题
提前致谢。
修改
无论出于何种原因......我的原始mse似乎适合训练集,但验证集似乎对时代来说非常嘈杂,在几个时代之后没有任何真正的改进。 rmse似乎是一个更有秩序的下降......直到损失在改进了几十个时代之后才进入inf。我可能比损失函数有更大的问题。
编辑2 - 添加我的实施@Patwie答案
啊......三角!!当然!!不幸的是,我正在使用tf v1.0,它似乎没有tf.atan2()。奇怪的是,我在tf存储库中找不到atan2实现,但我认为asos-ben在问题6095中的建议可以解决问题。见这里: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个时期,但似乎很有希望。
答案 0 :(得分:5)
将我的评论转换为答案。给定两个角度a(gt),b(预测)为弧度,你得到角度差
tf.atan2(tf.sin(a - b), tf.cos(a - b))
根据定义tf.atan2
在-45度,45度的间隔内自动给出差异。
因此,您可以使用
tf.reduce_mean(tf.abs(tf.atan2(tf.sin(a - b), tf.cos(a - b))))
我认为Keras了解这个TensorFlow代码。