【问题标题】:Calculating Hessian with tensorflow gradient tape使用 tensorflow 梯度带计算 Hessian
【发布时间】:2021-02-03 01:34:53
【问题描述】:

感谢您对此问题的关注。

我要计算tensorflow.keras.Model的hessian矩阵

对于高阶导数,我尝试了嵌套 GradientTape.# 示例图和输入

xs = tf.constant(tf.random.normal([100,24]))

ex_model = Sequential()
ex_model.add(Input(shape=(24)))
ex_model.add(Dense(10))
ex_model.add(Dense(1))

with tf.GradientTape(persistent=True) as tape:
    tape.watch(xs)
    ys = ex_model(xs)
g = tape.gradient(ys, xs)
h = tape.jacobian(g, xs)
print(g.shape)
print(h.shape)

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-20-dbf443f1ddab> in <module>
      5 h = tape.jacobian(g, xs)
      6 print(g.shape)
----> 7 print(h.shape)

AttributeError: 'NoneType' object has no attribute 'shape'

还有,另一个试验......

with tf.GradientTape() as tape1:
    with tf.GradientTape() as tape2:
        tape2.watch(xs)
        ys = ex_model(xs)
    g = tape2.gradient(ys, xs)
h = tape1.jacobian(g, xs)
    
print(g.shape)
print(h.shape)


(100, 24)

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-17-c5bbb17404bc> in <module>
      7 
      8 print(g.shape)
----> 9 print(h.shape)

AttributeError: 'NoneType' object has no attribute 'shape'

为什么我不能计算 g wrt x 的梯度?

【问题讨论】:

    标签: tensorflow autodiff


    【解决方案1】:

    您已经计算了 ys 梯度的二阶 wrt xs 为零,因为它应该是当您计算梯度 wrt 常数时,这就是为什么 tape1.jacobian(g, xs) 返回 None

    当二阶梯度 wrt常数时:

    import tensorflow as tf
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Input, Dense
    
    x = tf.Variable(1.0)
    w = tf.constant(3.0)
    with tf.GradientTape() as t2:
      with tf.GradientTape() as t1:
        y = w * x**3
      dy_dx = t1.gradient(y, x)
    d2y_dx2 = t2.gradient(dy_dx, x)
    
    print('dy_dx:', dy_dx) # 3 * 3 * x**2 => 9.0
    print('d2y_dx2:', d2y_dx2) # 9 * 2 * x => 18.0
    

    输出:

    dy_dx: tf.Tensor(9.0, shape=(), dtype=float32)
    d2y_dx2: tf.Tensor(18.0, shape=(), dtype=float32)
    

    当二阶梯度 wrt常数时:

    import tensorflow as tf
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Input, Dense
    
    x = tf.Variable(1.0)
    w = tf.constant(3.0)
    with tf.GradientTape() as t2:
      with tf.GradientTape() as t1:
        y = w * x
      dy_dx = t1.gradient(y, x)
    d2y_dx2 = t2.gradient(dy_dx, x)
    
    print('dy_dx:', dy_dx)
    print('d2y_dx2:', d2y_dx2)
    

    输出:

    dy_dx: tf.Tensor(3.0, shape=(), dtype=float32)
    d2y_dx2: None
    

    但是,您可以计算层参数二阶梯度 wrt xs,例如 Input gradient regularization

    【讨论】:

    • 感谢您的回复。在我将带有 x**2 的 lambda 层添加到模型中后,嵌套磁带返回张量。谢谢
    • @MyPrunus 很高兴为您提供帮助,如果我的回答解决了您的问题,请将其标记为答案,以便其他有类似问题的人知道在哪里可以找到答案,祝您有美好的一天:)
    猜你喜欢
    • 2022-01-04
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 2015-06-17
    • 2021-09-11
    • 2018-04-13
    相关资源
    最近更新 更多