在扁平参数张量上使用 tf.gradients 或 tf.hessians

Use tf.gradients or tf.hessians on flattened parameter tensor

假设我想针对某些参数 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={}) 到 return 一个 2x2 矩阵(等于 W)。事实证明,因为 params 是一个 2x2 张量,所以输出是一个形状为 [2, 2, 2, 2] 的张量。虽然我可以很容易地重塑张量以获得我想要的矩阵,但当 params 成为不同大小的张量列表时(例如,当模型是一个深度神经网络时),这个操作似乎非常麻烦.

似乎有两种解决方法:

self.params 是任意形状的张量列表时,是否没有从 tf.hessians 获取 Hessian 矩阵(如本例中的 2x2 矩阵)的直接方法?如果不是,您如何自动重塑 tf.hessians 的输出张量?

事实证明(根据 TensorFlow r1.13)如果 len(xs) > 1,则 tf.hessians(ys, xs) returns 张量仅对应于完整的 Hessian 矩阵。本文中的完整故事和解决方案 https://arxiv.org/pdf/1905.05559, and code at https://github.com/gknilsen/pyhessian