Deep learning Theano-如何覆盖op图部分的渐变

Deep learning Theano-如何覆盖op图部分的渐变,deep-learning,theano,Deep Learning,Theano,我手头有一个相当复杂的模型。该模型具有多个线性结构部分: y = theano.tensor.dot(W,x) + b 我想构建一个优化器,使用自定义规则计算所有线性结构的梯度,同时保持其他操作不变。对于我模型的所有线性部分,覆盖渐变操作的最简单方法是什么?最好不需要编写新的Op.因此,我花了一些时间为Theano编写了一个(截至2017年1月13日尚未合并)的Op.OpFromGraph实例,它使用户能够部分覆盖Theano.OpFromGraph实例的渐变。覆盖是通过符号图完成的,因此您仍

我手头有一个相当复杂的模型。该模型具有多个线性结构部分:

y = theano.tensor.dot(W,x) + b

我想构建一个优化器,使用自定义规则计算所有线性结构的梯度,同时保持其他操作不变。对于我模型的所有线性部分,覆盖渐变操作的最简单方法是什么?最好不需要编写新的Op.

因此,我花了一些时间为Theano编写了一个(截至2017年1月13日尚未合并)的Op.OpFromGraph实例,它使用户能够部分覆盖
Theano.OpFromGraph
实例的渐变。覆盖是通过符号图完成的,因此您仍然可以充分利用theano优化

典型用例:

  • 数值安全考虑
  • 重缩放/剪裁渐变
  • 特殊梯度例程,如黎曼自然梯度
要生成具有覆盖渐变的Op,请执行以下操作:

  • 制作所需的计算图
  • 为Op的渐变创建一个OpFromGraph实例(或python函数)
  • 将OfG实例设置为Op,并设置
    grad\u覆盖
    参数
  • 调用OfG实例来构建模型
  • 定义OpFromGraph类似于编译theano函数,但有一些区别:

    • 不支持
      更新
      givens
      (截至2017年1月)
    • 得到的是符号运算,而不是数值函数
    例如:

    '''
    This creates an atan2_safe Op with smoothed gradient at (0,0)
    '''
    import theano as th
    import theano.tensor as T
    
    # Turn this on if you want theano to build one large graph for your model instead of precompiling the small graph.
    USE_INLINE = False
    # In a real case you would set EPS to a much smaller value
    EPS = 0.01
    
    # define a graph for needed Op
    s_x, s_y = T.scalars('xy')
    s_darg = T.scalar(); # backpropagated gradient
    s_arg = T.arctan2(s_y, s_x)
    s_abs2 = T.sqr(s_x) + T.sqr(s_y) + EPS
    s_dx = -s_y / s_abs2
    s_dy = s_x / s_abs2
    
    # construct OfG with gradient overrides
    # NOTE: there are unused inputs in the gradient expression,
    #     however the input count must match, so we pass    
    #     on_unused_input='ignore'
    atan2_safe_grad = th.OpFromGraph([s_x, s_y, s_darg], [s_dx, s_dy], inline=USE_INLINE, on_unused_input='ignore')
    atan2_safe = th.OpFromGraph([s_x, s_y], [s_arg], inline=USE_INLINE, grad_overrides=atan2_safe_grad)
    
    # build graph using the new Op
    x, y = T.scalar(), T.scalar()
    arg = atan2_safe(x, y)
    dx, dy = T.grad(arg, [x, y])
    fn = th.function([x, y], [dx, dy])
    fn(1., 0.) # gives [-0.0, 0.99099]
    fn(0., 0.) # gives [0.0, 0.0], no more annoying nan!
    
    注意:
    theano.OpFromGraph
    仍然主要是实验性的,除了bug