2017-09-22 93 views
0

我正試圖使用​​keras/tensorflow來預測方位角。 y_true的範圍從0到359,但我需要一個處理預測的丟失函數,這個預測已經在這個範圍之外了。不幸的是,當我嘗試任何類型的模塊劃分tf.mod()%的,我得到一個錯誤......用於360度預測的keras損失函數

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 

問題

  • 這種感覺笨重;有更聰明的解決方案嗎?
  • 直覺上,我認爲使用mean_squared_error和root_mean_squared_error作爲損失的結果沒有區別......梯度將會不同,但相同的最優權重會解決這兩個問題,對嗎?有沒有理由選擇一個呢?我猜測mse比rmse稍微簡單一些,但這應該是微不足道的。我已經嘗試了兩種方法,並且使用rmse'覺得'比'mse'更像一種更有秩序的下降...是否有關於那些平方誤差的大小會讓它跳得更多?

在此先感謝。

編輯

不管是什麼原因?我原來的MSE似乎擬合訓練集,但驗證集似乎很嘈雜的時代到時代,沒有幾個時期之後的任何真正的改善。 rmse看起來像是一個更有秩序的下降......直到經過幾十個時代的改進之後,損失才進入inf。我可能會有比虧損功能更大的問題。

EDIT 2 - 加入我的實現@Patwie回答以下

啊... TRIG!當然!!不幸的是,我使用tf v1.0,它似乎沒有tf.atan2()。奇怪的是,我無法在tf repository中找到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時代,但它似乎有希望的。

+1

有沒有一個特定的角度,可能性很小,甚至無效?如果是這樣,你可以將這個角度置爲零。 –

回答

1

將我的評論轉換爲答案。給定兩個角的(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代碼。