使用tf.梯度或者黑森tf关于平坦参数十

2024-05-15 20:35:41 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我想计算一个标量值函数关于某些参数W(例如前馈神经网络的权值和偏差)的Hessian。 如果考虑以下代码,请实现一个经过训练以最小化MSE损失的二维线性模型:

import numpy as np
import tensorflow as tf

x = tf.placeholder(dtype=tf.float32, shape=[None, 2])  #inputs
t = tf.placeholder(dtype=tf.float32, shape=[None,])  #labels
W = tf.placeholder(np.eye(2), dtype=tf.float32)  #weights

preds = tf.matmul(x, W)  #linear model
loss = tf.reduce_mean(tf.square(preds-t), axis=0) #mse loss

params = tf.trainable_variables() 
hessian = tf.hessians(loss, params)

您希望session.run(tf.hessian,feed_dict={})返回一个2x2矩阵(等于W)。结果表明,由于params是2x2张量,因此输出的张量是形状为[2,2,2,2]的张量。虽然我可以很容易地重塑张量以获得我想要的矩阵,但是当params变成一个大小不等的张量列表时(例如,当模型是一个深层神经网络时),这个操作可能非常麻烦。在

似乎有两种方法可以解决这个问题:

  • params展平为1D张量,称为flat_params

    ^{pr2}$

    因此tf.hessians(loss, flat_params)自然返回一个2x2矩阵。然而,正如Why does Tensorflow Reshape tf.reshape() break the flow of gradients?中所述tf.梯度(但也适用于黑森tf),tensorflow无法在图中看到params和{}之间的符号链接,tf.hessians(loss, flat_params)将引发错误,因为渐变将被视为None

  • https://afqueiruga.github.io/tensorflow/2017/12/28/hessian-mnist.html中,代码的作者走另一条路,首先创建flat参数并将其部分重塑为self.params。sian矩阵(hesm)的形状得到了预期的结果。然而,在我看来,当您有一个复杂的模型时,这将是一个麻烦的使用,并且如果您通过内置函数(如tf.layers.dense,…)创建模型,则不可能应用。

tf.hessians是任意形状的张量列表时,没有直接的方法从tf.hessians得到Hessian矩阵(如本例中的2x2矩阵)吗?如果不是,如何自动地对tf.hessians的输出张量进行整形?在


Tags: 函数模型nonetftensorflow矩阵paramsplaceholder
1条回答
网友
1楼 · 发布于 2024-05-15 20:35:41

结果是(根据TensorFlow r1.13)如果len(xs)>1,那么黑森tf(ys,xs)返回只对应于完整Hessian矩阵的块对角子矩阵的张量。本文的全部内容和解决方案https://arxiv.org/pdf/1905.05559,代码位于https://github.com/gknilsen/pyhessian

相关问题 更多 >