2017-02-13 60 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