PyTorch中sin(x)梯度计算及绘图的反向传播问题求助
解决方案
报错原因
PyTorch 默认仅支持标量输出的反向传播,你的y是长度为100的向量,直接调用y.backward()会因无法确定梯度计算规则报错。
解决步骤与完整代码
import numpy as np import torch import matplotlib.pyplot as plt # 生成输入张量 x_np = np.linspace(-np.pi, np.pi, 100) x = torch.tensor(x_np, requires_grad=True) y = torch.sin(x) # 传入与y同形状的全1张量,实现向量对向量的梯度计算 y.backward(torch.ones_like(y)) # 验证梯度正确性 assert torch.allclose(x.grad[10].float(), torch.Tensor([-0.8053]), rtol=1e-2) assert torch.allclose(x.grad[50].float(), torch.Tensor([0.9995]), rtol=1e-2) # 提取绘图数据(分离计算图,避免梯度追踪) y_vals = y.detach().numpy() dy_dx_vals = x.grad.detach().numpy() # 绘制图像 plt.figure(figsize=(10, 6)) plt.plot(x_np, y_vals, label='f(x) = sin(x)', color='#1f77b4') plt.plot(x_np, dy_dx_vals, label='df(x)/dx (自动求导)', color='#ff7f0e', linestyle='--') plt.xlabel('x') plt.ylabel('函数值') plt.title('sin(x) 及其导数曲线') plt.legend() plt.grid(alpha=0.3) plt.show()
关键说明
torch.ones_like(y):生成与y形状一致的全1张量,传给backward()后,相当于计算sum(y)对x的梯度。由于每个y_i = sin(x_i)仅依赖对应x_i,最终x.grad会存储每个点的导数(即cos(x_i),但全程未手动调用cos())。detach():将张量从计算图中分离,转换为numpy数组用于绘图,避免后续操作触发不必要的梯度计算。
内容的提问来源于stack exchange,提问作者Kin_99
相关产品推荐
相关产品推荐

