带有非张量参数的Tensorflow custom_gradient

时间:2019-01-04 11:17:33

标签: python tensorflow python-decorators gradients

使用tensorflow的@ tf.custom_gradient装饰器时,我总是遇到麻烦,因为该函数的一个参数(可以争论是否是op)是不可变的,而我无法(或不想)定义它的梯度贡献。 由于似乎没有一种方法可以告诉tensorflow有关其输入属性的任何信息,因此我采用了以下解决方案,我认为这可能对其他人有用。这是定义泊松损失的示例。只有“ fwd”是张量,而其他所有参数都不是:

def Loss_Poisson(fwd,meas,Bg=0.05, checkPos=False):
    meanmeas=np.mean(meas)
    if checkPos:
        fwd=((tf.sign(fwd) + 1)/2)*fwd
    @tf.custom_gradient
    def BarePoisson(myfwd):
        def grad(dy):
            mygrad=dy*(1.0 - meas/(myfwd+Bg))/meas.size  # the size accounts for the mean operation (rather than sum)
            return mygrad
        totalError = tf.reduce_mean((myfwd+Bg-meas) - meas * tf.log((myfwd+Bg)/(meas+Bg)))  
        return totalError,grad    
    return BarePoisson(fwd)/meanmeas

诀窍是使用内部函数,该函数仅具有一个(张量)参数,并偷偷使用外部函数中的其他不可变参数。这样,@ tf.custom_gradient装饰器对那些装饰器是盲目的。在测试中,这很好。 也许更干净的解决方案会断言,那些(均值,Bg和checkPos)实际上都不是张量,因为这可能会导致错误的梯度。

有没有(更好的)替代这种黑客手段?

0 个答案:

没有答案