Pytorch使用CUDA时优化失效、参数无更新问题问询
问题原因
核心问题是优化器初始化与参数设备迁移的顺序错误,PyTorch中张量的.cuda()方法不属于原位操作,会返回一个新的、存储在CUDA设备上的张量副本,原本CPU上的参数不会被修改。
现有代码的执行逻辑存在顺序问题:
- 第一步先初始化了CPU上的参数
W、b - 第二步直接把CPU上的
W、b绑定到了优化器 - 第三步调用
.cuda()得到了CUDA设备上的新W、b副本,此时优化器始终绑定的还是原来的CPU参数 - 训练迭代中梯度计算、回传都是作用在CUDA版本的
W、b上,但优化器执行step时只会更新自己绑定的CPU参数,导致实际参与计算的CUDA版本参数永远不会被更新,损失自然不会下降。
修复方案
调整操作顺序:先完成所有参数、数据的设备迁移,再初始化优化器,确保优化器绑定的是实际参与训练的设备上的参数。
修正后可正常运行的代码如下:
import torch import torch.nn as nn import torch.optim as optim use_gpu = torch.cuda.is_available() learning_rate = 0.05 loss_function = nn.MSELoss() train_inputs = torch.FloatTensor([1,2,3,4,5,6]).T.unsqueeze(0) y_truth = torch.FloatTensor([10, 15, 20, 25, 30, 35]).unsqueeze(0) # 先初始化参数 W = torch.nn.Parameter(torch.rand(1), requires_grad=True) b = torch.nn.Parameter(torch.rand(1), requires_grad=True) # 先完成所有数据、参数的设备迁移 if use_gpu: y_truth = y_truth.cuda() W = W.cuda() b = b.cuda() train_inputs = train_inputs.cuda() # 设备迁移完成后再初始化优化器,绑定对应设备的参数 optimizer = optim.Adam([b, W], lr=learning_rate) for epoch in range(1000): optimizer.zero_grad() y_preds = b + W * train_inputs loss = loss_function(y_truth, y_preds) loss.backward() optimizer.step() if epoch % 100 == 0: print(loss.data, W.data, b.data)
内容的提问来源于stack exchange,提问作者Damien
相关产品推荐
相关产品推荐

