PyTorch带requires_grad属性张量调用numpy()报错RuntimeError求助
错误根因
- 你实际运行的代码中,目标函数
function_parabola用了Numpy的np.log、np.prod处理带梯度的PyTorch张量:带requires_grad=True的张量需要保持计算图以完成反向传播,不能直接转为Numpy数组传入Numpy运算,因此触发报错。 - 额外的兼容问题:绘制等高线的
show_contours函数会传入Numpy数组调用目标函数,纯PyTorch张量运算的目标函数无法直接处理Numpy输入,后续也会报错。
修复方案
- 目标函数统一用PyTorch内置运算,同时对Numpy输入做自动类型转换,保证梯度计算和绘图两种场景都能正常运行。
- 所有需要转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
相关产品推荐
相关产品推荐

