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

图像字幕生成模型RL训练时无梯度ValueError问题修复指导

问题修复:图像字幕生成模型梯度全为None的ValueError

核心问题分析

出现No gradients provided for any variable的根本原因有三个:

  • 未开启梯度追踪上下文:计算损失时没有用tf.GradientTape包裹模型前向传播过程,TensorFlow无法记录梯度计算路径。
  • y_pred与模型变量无关联:当前代码里的y_pred是手动构造的numpy数组,完全脱离模型计算图,损失对模型参数自然没有梯度。
  • 混用numpy与TensorFlow操作:自定义损失中使用np.exp而非tf.exp,断开了计算图的梯度传导链。

具体修复步骤

1. 开启GradientTape上下文

在模型前向传播、损失计算的整个流程外包裹tf.GradientTape(),确保TensorFlow追踪所有可训练变量的梯度。

2. 用模型输出生成y_pred张量

删除手动构造y_pred的代码,改为让模型重新处理输入并输出预测张量,保证损失与模型参数存在计算关联。

3. 替换numpy操作为TensorFlow操作

将自定义损失中的np.exp替换为tf.exp,维持计算图的连续性。

修复后的关键代码片段

import tensorflow as tf
from tensorflow.keras.optimizers import Adam
import numpy as np

def custom_loss(y_true, y_pred, feedback):
    # 替换np.exp为tf.exp,维持计算图连续性
    cross_entropy_loss = tf.keras.losses.categorical_crossentropy(y_true, y_pred)
    negative_feedback_loss = tf.reduce_mean(-1 * tf.exp(feedback))
    total_loss = cross_entropy_loss + negative_feedback_loss
    return total_loss

# ... 其他代码保持不变 ...

for img in os.listdir(dataset_images):
    RL_learning_loop += 1
    if RL_learning_loop < 10:
        # ... 图像加载、特征提取、生成caption的代码保持不变 ...
        
        feedback = float(input("Rate the quality of the caption (0-1): "))

        # ------------ 修复开始 ------------
        # 开启梯度追踪上下文
        with tf.GradientTape() as tape:
            # 获取真实标签并转为张量
            true_caption = get_true_caption(image_path, cln_descriptions)
            true_sequence = tokenizer.texts_to_sequences([true_caption])[0]
            true_sequence = pad_sequences([true_sequence], maxlen=max_length)
            y_true = np.zeros((1, max_length, len(tokenizer.word_index) + 1))
            for i, word_index in enumerate(true_sequence[0]):
                y_true[0, i, word_index] = 1
            y_true = tf.convert_to_tensor(y_true, dtype=tf.float32)
            
            # 让模型重新预测,得到与计算图关联的y_pred张量
            # 注:此处输入可根据任务逻辑,选择生成caption时的sequence或真实sequence
            y_pred = model([photo, sequence])
            
            # 计算损失
            loss = custom_loss(y_true, y_pred, feedback)
            loss = tf.reduce_mean(loss)
        # ------------ 修复结束 ------------

        print("Loss: ", loss)

        trainable_vars = [var for var in model.trainable_variables if 'embedding' not in var.name and 'conv2d' not in var.name]
        
        # 现在可正确计算梯度
        grads = tape.gradient(loss, trainable_vars)
        print("Gradient", grads)
        print("**************************")
        optimizer.apply_gradients(zip(grads, trainable_vars))

        # ... Q-table更新、模型保存的代码保持不变 ...

额外注意事项

  • 确保photo和sequence在tape上下文内是张量类型,若为numpy数组,需用tf.convert_to_tensor转换。
  • 生成caption阶段的模型前向传播可无需追踪梯度,但参数更新阶段必须重新运行模型并在tape内记录。

内容的提问来源于stack exchange,提问作者pyComali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:57:03