You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras中ADAM优化器v_t输出方式及迭代数值获取问题

在Keras中获取Adam优化器v_t迭代数值的方法

你现在看到的输出是TensorFlow计算图里的张量节点标识,不是实际的数值——这是因为你只是打印了张量对象本身,而没有让计算图执行并输出它的具体值。接下来我会一步步教你怎么正确获取每次迭代的v_t数值,分两种常见环境说明:

情况1:TensorFlow 1.x + 原生Keras

在TF1的计算图模式下,你需要先定位Adam优化器为每个模型参数创建的v_t变量,再在会话中运行这些变量得到数值。具体操作如下:

  1. 构建并编译模型后,从优化器中筛选出所有v_t相关变量
  2. 在训练循环的每一步,执行训练操作后,运行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:18:04