Pytorch 逃坑计划之——backward

跳坑一

RuntimeError: Trying to backward through the graph a second time, but the saved intermediate results have already been freed. Specify retain_graph=True when calling .backward() or autograd.grad() the first time.

查阅资料发现是在调用backward时发生的问题,也就是很重要的反向传播计算出错了!用个形象的例子

for i in range(1000):
    # 清零
    opt.zero_grad()
    # 计算损失
    cri=nn.MSELoss()
    loss=cri(out1,target.T)
    # 反向传播
    loss.backward()
    # 参数更新
    opt.step()
    if i% 100==0:
        print("loss=",loss.data)

pytorch构建的计算图是动态图,所以每次迭代完之后计算图就被内存释放。很显然,代码中迭代了1000次,为了让它不被立即释放,需要加入标识retain_graph=True

改写

loss.backward(retain_graph=True)

跳坑二

所以代码已经完成了吗?NO!NO!NO!,又出错了!
错了很长一大段
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [128, 4]], which is output 0 of TBackward, is at version 2; expected version 1 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).
这段说的就是梯度能求不了了,出现了nan?仔细瞅瞅这个代码是不是缺了点啥?是的,缺了脑子。。。。。

整个的迭代过程,输入特征没有参与,所以能迭代个毛啊!可不就是在第一次迭代之后出现nan嘛!

正确代码奉上!

for i in range(1000):
    # 重新执行一次网络
    out1 = net(x)
    # 清零
    opt.zero_grad()
    # 计算损失
    cri=nn.MSELoss()
    loss=cri(out1,target.T)
    # 反向传播
    loss.backward(retain_graph=True)
    # 参数更新
    opt.step()
    if i% 100==0:
        print("loss=",loss.data)

彩蛋!
不用自带的优化器,自己搞!

# 构建优化: 损失——梯度清零——反向传播
#
# for i in range(1000):
#     cri=nn.MSELoss()
#     loss=cri(out,target.T)
# # 清零
#     net.zero_grad()
# # 反向传播
#     loss.backward(retain_graph=True)
# # 更新权重
#     l_rate=0.3
#     for f in list(net.parameters()):
#         f.data.sub_(f.grad.data*l_rate)
#     if i%100==0:
#         print("loss=",loss.data,i)

参考链接
pytorch基础

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch中,要冻结某层参数,即保持其权重在训练过程中不发生更新。这种操作通常在迁移学习或固定特定的层的场景下使用,以便保留已经学到的知识。 要冻结某层参数,可以通过以下步骤实现: 1. 首先,加载模型并查看模型的结构。通过打印模型就可以看到每一层的名称以及对应的索引。 2. 在训练之前,确定需要冻结的层。可以通过模型的参数名称或索引来定位到具体的层。 3. 使用`requires_grad_()`函数来冻结参数,将需要冻结的层的`requires_grad`属性设置为False。这样,在反向传播过程中,这些参数的梯度就不会进行更新了。 4. 在训练过程中,只对其他未冻结的层进行梯度更新。 下面是一个简单的示例代码,演示如何冻结某层参数: ```python import torch import torch.nn as nn # 加载模型并创建优化器 model = torchvision.models.resnet18(pretrained=True) optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 查看模型结构 print(model) # 冻结某层参数 # 可以通过模型的named_parameters()函数获取每一层的名称和参数 # 这里以冻结ResNet的第4个卷积层参数为例 for name, param in model.named_parameters(): if 'layer4' in name: # 可根据具体需求来决定冻结哪些层 param.requires_grad_(False) # 训练过程 for inputs, labels in dataloader: outputs = model(inputs) loss = loss_func(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() ``` 通过以上步骤,我们可以实现冻结某层参数的操作。这样,在训练过程中,被冻结的层的参数将不会更新,从而保持其固定的权重。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值