2017-02-13 70 views
-1

我的一個操作需要整數,但卷積輸出是float。
這意味着我需要使用tf.floor,tf.ceil,tf.cast等來處理它。
但這些operactions引起None梯度,因爲像tf.floor operactions不是微tf.floor的替代計劃

所以,我想類似下面

首先。的test.compute_gradient_error彎路

out1 = tf.subtract(vif, tf.subtract(vif, tf.floor(vif))) 

但輸出爲500或0,我不認爲這是一個合理的梯度。

第二。覆蓋地板的test.compute_gradient_error

@ops.RegisterGradient("CustomFloor")  
def _custom_floor_grad(op, grads):  
    return [grads] 



A, B = 50, 7 
shape = [A, B] 
f = np.ones(shape, dtype=np.float32) 
vif = tf.constant(f, dtype=tf.float32) 

# out1 = tf.subtract(vif, tf.subtract(vif, tf.floor(vif))) 
with tf.get_default_graph().gradient_override_map({"Floor": "CustomFloor"}): 
    out1 = tf.floor(vif) 

with tf.Session() as sess: 
    err1 = tf.test.compute_gradient_error(vif, shape, out1, shape) 
    print err1 

輸出爲500或1的梯度功能,不太工作。

問題:一種方式來獲得整數並保持反向傳播做工精細(價值2.0一樣,5.0就可以了)

回答

2

一般來說,它不是不可取的解決離散問題與梯度下降。你應該能夠在某種程度上表達TF中的整數求解器,但你自己或多或少都能表達。

FWIW,地板功能看起來像一把鋸子。它的導數是1的常數函數,每個整數都有小孔。在這些位置你有一個向下的Dirac功能,如果你願意的話可以使用耙子。狄拉克函數具有有限的能量但沒有有限的值。

解決這些問題的標準方法是通過(至少一次)微分(平滑)的東西「硬化」硬地板約束來緩解問題。

有多種方法可以做到這一點。也許最流行的是:

  1. 破解一個看起來像你想要的功能。例如,一種快速向下傾斜的分段線性函數,但不是垂直的。
  2. 通過S形
  3. 使用的濾波器逼近這是很好理解的,如果它是一個時間序列代替階躍函數
+0

你的意思'floor'像一個階躍函數,我可以嘗試找到一個線性函數的樣子'_/- ',所以函數幾乎可以作爲'floor'工作。 – xxi

+0

是的,確切地說。在訓練時,確保逐漸增加坡度。 – drpng

+0

我無法理解「漸增坡度」的意思。如果我有這種功能,爲什麼我需要逐漸增加坡度。或者這個功能是通過訓練產生的?謝謝 – xxi