【发布时间】:2021-12-08 20:32:51
【问题描述】:
我想计算 Tensorflow 中神经网络的损失函数相对于所有参数(或可训练变量)的 hessian。通过修改 Tensorflow 文档 (https://www.tensorflow.org/api_docs/python/tf/GradientTape) 中的示例代码,我设法计算了第一层的权重矩阵的 hessian w.r.t(如果我没记错的话):
with tf.GradientTape(persistent=True) as tape:
loss = tf.reduce_mean(model(x,training=True)**2)
g = tape.gradient(loss,model.trainable_variables[0])
h=tape.jacobian(g,model.trainable_variables[0])
如果我尝试使用 model.trainable_variables 来计算它,而不是 tape.jacobian 抱怨“列表对象没有属性形状”。相反,我尝试展平 model.trainable_variables 并根据展平向量计算它:
with tf.GradientTape(persistent=True) as tape:
loss = tf.reduce_mean(model(x,training=True)**2)
source = tf.concat([tf.reshape(x,[-1]) for x in model.trainable_variables],axis=0)
g = tape.gradient(loss,source)
h=tape.jacobian(g,source)
现在的问题是 g 出于某种原因是空的(NoneType)。我注意到 source 是 tf.Tensor-type 但 model.trainable_variables[0] 是 tf.ResourceVariable 类型,所以我尝试通过将 source 声明为来更改它
source = resource_variable_ops.ResourceVariable(tf.concat([tf.reshape(x,[-1]) for x in model.trainable_variables],axis=0))
但这并没有改变任何东西,所以我猜这不是问题所在。我还认为问题可能是源变量没有被观看,但似乎它设置为可训练,即使我执行tape.watch(source),g 仍然是空的。
有人知道我该如何解决这个问题吗?
【问题讨论】:
-
感谢您的回复。它看起来非常相似,但我认为并不完全相似(无论如何,当我尝试使用两个梯度带而不是雅可比时它不起作用)。我认为这可能与 model.trainable_variables 在进入循环之前没有构建的事实有关。我尝试用模型(x)在张量“x”上调用它。然后在循环之前创建了model.trainable_variables,但我仍然得到同样的错误。
标签: tensorflow hessian gradienttape