Keras中ADAM优化器v_t输出方式及迭代数值获取问题
在Keras中获取Adam优化器v_t迭代数值的方法
你现在看到的输出是TensorFlow计算图里的张量节点标识,不是实际的数值——这是因为你只是打印了张量对象本身,而没有让计算图执行并输出它的具体值。接下来我会一步步教你怎么正确获取每次迭代的v_t数值,分两种常见环境说明:
情况1:TensorFlow 1.x + 原生Keras
在TF1的计算图模式下,你需要先定位Adam优化器为每个模型参数创建的v_t变量,再在会话中运行这些变量得到数值。具体操作如下:
- 构建并编译模型后,从优化器中筛选出所有v_t相关变量
- 在训练循环的每一步,执行训练操作后,运行v_t变量获取实际值
示例代码:
from keras.models import Sequential from keras.layers import Dense from keras.optimizers import Adam import tensorflow as tf import numpy as np # 构建测试模型 model = Sequential([ Dense(512, input_shape=(8,), activation='relu'), Dense(512, activation='relu') ]) model.compile(optimizer=Adam(), loss='mse') # 从Adam优化器中提取所有v_t变量 adam_opt = model.optimizer v_t_vars = [var for var in adam_opt.variables if 'v_t' in var.name] # 准备训练数据 x_train = np.random.rand(100, 8) y_train = np.random.rand(100, 512) # 初始化会话并开始训练 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for epoch in range(5): # 执行一步训练 loss_val, _ = sess.run( [model.total_loss, model.train_op], feed_dict={model.input: x_train, model.targets: y_train} ) print(f"Epoch {epoch+1} | Loss: {loss_val:.4f}") # 遍历每个v_t变量,获取并打印数值 for v_var in v_t_vars: v_val = sess.run(v_var) print(f"\nv_t for {v_var.name}") print(f"Shape: {v_val.shape}") # 打印前2行前2列的数值(避免输出过多) print("Sample values:\n", v_val[:2, :2])
情况2:TensorFlow 2.x + tf.keras
TF2默认是即时执行模式,不需要手动管理会话,直接通过变量的.numpy()方法就能获取数值。同样先定位v_t变量,再在训练循环中查看:
示例代码:
import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense # 构建模型 model = Sequential([ Dense(512, input_shape=(8,), activation='relu'), Dense(512, activation='relu') ]) optimizer = tf.keras.optimizers.Adam() loss_fn = tf.keras.losses.MeanSquaredError() # 准备训练数据 x_train = tf.random.normal((100, 8)) y_train = tf.random.normal((100, 512)) # 训练循环 for epoch in range(5): with tf.GradientTape() as tape: y_pred = model(x_train, training=True) loss = loss_fn(y_train, y_pred) # 计算梯度 grads = tape.gradient(loss, model.trainable_variables) # 更新前查看v_t数值 print(f"=== Epoch {epoch+1} (Before Update) ===") v_t_vars = [var for var in optimizer.variables() if 'v' in var.name] for v_var in v_t_vars: print(f"v_t for {v_var.name}") print(f"Shape: {v_var.shape}") print("Sample values:\n", v_var.numpy()[:2, :2]) # 应用梯度,更新参数和v_t optimizer.apply_gradients(zip(grads, model.trainable_variables)) # 更新后查看v_t数值 print(f"\n=== Epoch {epoch+1} (After Update) ===") for v_var in v_t_vars: print(f"v_t for {v_var.name}") print("Sample values:\n", v_var.numpy()[:2, :2]) print(f"Epoch {epoch+1} | Loss: {loss.numpy():.4f}\n")
关键说明
- 你之前看到的
Tensor("training/Adam/add_2:0", ...)只是计算图中节点的标识,不是实际数值——只有让计算图执行这个节点(TF1用sess.run(),TF2用.numpy()),才能得到矩阵形式的具体数值。 - Adam的v_t是每个可训练参数对应的一阶矩估计变量,所以每个层的权重/偏置都会对应一个v_t变量,你看到的多个不同形状的v_t输出,和你的模型结构完全匹配(比如示例中的(8,512)是第一层权重的v_t,(128,512)是第二层权重的v_t)。
内容的提问来源于stack exchange,提问作者Wendong Zheng
相关产品推荐
相关产品推荐

