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

TensorFlow与PyTorch梯度计算对比及TensorFlow梯度返回None问题的排查与解决

为什么TensorFlow中梯度计算结果为None?如何正确计算?

问题根源

你的TensorFlow代码里,权重w和偏置b是用tf.random.normal()创建的普通tf.Tensor,这类张量默认不会被tf.GradientTape追踪梯度。而PyTorch里你给w和b设置了requires_grad=True,明确告诉框架要计算它们的梯度——这就是两者的核心差异。

TensorFlow的GradientTape默认只追踪tf.Variable类型的可训练变量的梯度,普通张量不在追踪范围内,所以调用tape.gradient()时会返回None。


正确的解决方法

有两种方式可以修复这个问题,推荐第一种(更符合TensorFlow的训练范式):

方法1:将w和b定义为tf.Variable

把原来的w和b的创建代码替换成tf.Variable,它会自动被GradientTape追踪:

import numpy as np
import tensorflow as tf

inputs = np.array([[73, 67, 43], [91, 88, 64], [87, 134, 58], [102, 43, 37], [69, 96, 70]], dtype='float32')
targets = np.array([[56, 70], [81, 101], [119, 133], [22, 37], [103, 119]], dtype='float32')
inputs = tf.convert_to_tensor(inputs)
targets = tf.convert_to_tensor(targets)

# 修改这里:用tf.Variable定义可训练参数
w = tf.Variable(tf.random.normal(shape=(2, 3)))
b = tf.Variable(tf.random.normal(shape=(2,)))
print(w, b)

def model(x):
    return tf.matmul(x, w, transpose_b = True) + b

def mse(t1, t2):
    diff = t1-t2
    return tf.reduce_sum(diff * diff) / tf.cast(tf.size(diff), 'float32')

with tf.GradientTape() as tape:
    pred = model(inputs)
    loss = mse(pred, targets)

# 现在可以正常得到梯度
grads = tape.gradient(loss, [w, b])
print(grads)

方法2:手动用tape.watch()追踪普通张量

如果你因为某些原因必须使用普通tf.Tensor,可以在GradientTape上下文里手动调用tape.watch()来指定要追踪的张量:

with tf.GradientTape() as tape:
    # 手动追踪w和b
    tape.watch([w, b])
    pred = model(inputs)
    loss = mse(pred, targets)

grads = tape.gradient(loss, [w, b])
print(grads)

不过这种方式更适合临时追踪单个张量,训练模型时还是推荐用tf.Variable,它还支持自动管理优化器更新、保存加载等功能。


补充说明

TensorFlow的GradientTape工作逻辑是:在上下文管理器内记录所有对可追踪张量的运算,离开上下文后通过tape.gradient()反向计算梯度。只有tf.Variable(默认trainable=True)或者被tape.watch()标记的张量才会被记录运算路径,否则无法计算梯度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:53:14