TensorFlow训练后Hessian矩阵未更新问题求助
解决TensorFlow中tf.hessians值不随变量更新变化的问题
我之前也踩过类似的坑,你的问题得先结合模型类型来分析——从你给出的代码片段(线性模型+平方损失)来看,大概率是两种情况之一:
情况1:数学特性导致的“假问题”
你的模型是线性结构:linear_model = W*x + b,损失用的是平方和loss = sum((Wx + b - y)^2)。对这个损失求关于W和b的二阶导数(也就是Hessian矩阵),你会发现:
- 对W的二阶导数是
2*sum(x²),只和输入样本x有关 - 对b的二阶导数是
2*N(N是样本数量) - W和b的交叉二阶导数是
2*sum(x)
这些值完全不依赖W和b的当前取值!所以不管你怎么训练更新变量,Hessian矩阵的数值肯定不会变,甚至和初始变量值无关——这是线性平方损失的数学特性,不是TensorFlow的bug。
情况2:非线性模型下的计算图构建问题
要是你用了非线性模型(比如加了ReLU、sigmoid激活)但Hessian还是不变,那就是计算图构建时机不对——比如你在变量初始化前就定义了Hessian计算节点,或者复用了旧的计算图节点。
给你个修正后的非线性模型示例,运行后就能看到Hessian随变量更新的变化:
import tensorflow as tf # 模型参数 W = tf.Variable([.3], dtype=tf.float32) b = tf.Variable([-.3], dtype=tf.float32) # 输入输出(加入非线性激活) x = tf.placeholder(tf.float32) linear_model = tf.sigmoid(W * x + b) # 用sigmoid引入非线性 y = tf.placeholder(tf.float32) # 损失函数 loss = tf.reduce_sum(tf.square(linear_model - y)) # 定义Hessian计算(要在变量和损失定义之后) hessian = tf.hessians(loss, [W, b]) # 优化器 optimizer = tf.train.GradientDescentOptimizer(0.01) train = optimizer.minimize(loss) # 非线性的训练数据 x_train = [1,2,3,4] y_train = [0.1, 0.05, 0.02, 0.01] # 训练循环 init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) for i in range(100): sess.run(train, {x:x_train, y:y_train}) if i % 20 == 0: current_W, current_b, current_loss, current_hessian = sess.run( [W, b, loss, hessian], {x:x_train, y:y_train} ) print(f"Step {i}: W={current_W[0]:.4f}, b={current_b[0]:.4f}, loss={current_loss:.4f}") print(f"Hessian (W, b): {current_hessian}\n")
关键点总结
- 先确认模型类型:线性模型+平方损失的Hessian是常数,属于数学规律,不用排查代码
- 非线性模型下,要保证Hessian的计算节点在变量、损失定义之后构建,且每次训练后传入正确样本重新计算Hessian
内容的提问来源于stack exchange,提问作者Sergii Dudkin
相关产品推荐
相关产品推荐

