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

PyTorch带requires_grad属性张量调用numpy()报错RuntimeError求助

错误根因
  • 你实际运行的代码中,目标函数function_parabola用了Numpy的np.log、np.prod处理带梯度的PyTorch张量:带requires_grad=True的张量需要保持计算图以完成反向传播,不能直接转为Numpy数组传入Numpy运算,因此触发报错。
  • 额外的兼容问题:绘制等高线的show_contours函数会传入Numpy数组调用目标函数,纯PyTorch张量运算的目标函数无法直接处理Numpy输入,后续也会报错。
修复方案
  1. 目标函数统一用PyTorch内置运算,同时对Numpy输入做自动类型转换,保证梯度计算和绘图两种场景都能正常运行。
  2. 所有需要转Numpy存储的张量结果,先调用.detach()切断梯度跟踪,避开计算图限制。
可运行的修改后代码
import torch
import numpy as np
import matplotlib.pyplot as plt

x = torch.tensor([[5., 10.],
                  [1., 2.]], requires_grad=True)
var_history = []
fn_history = []
alpha = 0.001
optimizer = torch.optim.SGD([x], lr=alpha)

def function_parabola(variable):
    # 兼容numpy输入,自动转成张量
    if isinstance(variable, np.ndarray):
        variable = torch.tensor(variable, dtype=torch.float32)
    return (variable + 7).log().log().prod()


def make_gradient_step(function, variable):
    function_result = function(variable)
    function_result.backward()
    optimizer.step()
    optimizer.zero_grad()


for i in range(500):
    var_history.append(x.detach().numpy().copy())
    # 先detach切断梯度再转numpy
    fn_history.append(function_parabola(x).detach().cpu().numpy().copy())
    make_gradient_step(function_parabola, x)
print(x)

def show_contours(objective,
                  x_lims=[-10.0, 10.0],
                  y_lims=[-10.0, 10.0],
                  x_ticks=100,
                  y_ticks=100):
    x_step = (x_lims[1] - x_lims[0]) / x_ticks
    y_step = (y_lims[1] - y_lims[0]) / y_ticks
    X, Y = np.mgrid[x_lims[0]:x_lims[1]:x_step, y_lims[0]:y_lims[1]:y_step]
    res = []
    for x_index in range(X.shape[0]):
        res.append([])
        for y_index in range(X.shape[1]):
            x_val = X[x_index, y_index]
            y_val = Y[x_index, y_index]
            res[-1].append(objective(np.array([[x_val, y_val]]).T))
    res = np.array(res)
    plt.figure(figsize=(7,7))
    plt.contour(X, Y, res, 100)
    plt.xlabel('$x_1$')
    plt.ylabel('$x_2$')

show_contours(function_parabola)
plt.scatter(np.array(var_history)[:,0], np.array(var_history)[:,1], s=10, c='r')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:09:01