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

PyTorch需梯度Tensor调用numpy()报错的解决方法问询

问题排查与修复方案

报错根因

  • 核心问题是计算逻辑混用了NumPy算子和带梯度的PyTorch张量:
    1. 你定义的function_parabola中全部使用np.log、np.prod等NumPy原生算子,输入的参数variable是开启了requires_grad=True的PyTorch张量,NumPy无法直接处理带梯度的张量,会自动切断计算图甚至直接抛出类型错误,这是两次报错的共同根源。
    2. 原代码中NumPy处理后返回的是NumPy数组,你后续试图对该数组调用.data、.cpu()等只有PyTorch张量才有的方法,也会触发报错。

修复方案

第一步:修改损失函数兼容两种输入类型

因为后续show_contours函数会传入NumPy数组计算等高线,所以需要让损失函数自动判断输入类型,选择对应的算子:

def function_parabola(variable):
    # 输入为NumPy数组时使用NumPy算子
    if isinstance(variable, np.ndarray):
        return np.prod(np.log(np.log(variable + 7)))
    # 输入为PyTorch张量时使用PyTorch算子,保留计算图
    elif isinstance(variable, torch.Tensor):
        return torch.prod(torch.log(torch.log(variable + 7)))

第二步:调整历史值记录逻辑

使用规范的detach方法剥离梯度后再转NumPy数组,替换过时的.data用法:

# 原var_history记录代码调整为
var_history.append(x.detach().numpy().copy())
# 原fn_history记录代码调整为
fn_history.append(function_parabola(x).detach().cpu().numpy().copy())

完整可运行代码

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):
    if isinstance(variable, np.ndarray):
        return np.prod(np.log(np.log(variable + 7)))
    elif isinstance(variable, torch.Tensor):
        return torch.prod(torch.log(torch.log(variable + 7)))


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())
    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:48:03