【PyTorch基础】


参考教程 https://www.jianshu.com/p/aee6a3d72014

搭建一个简单的网络

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F

class mymodel(nn.Module):
    def __init__(self):
        super(mymodel, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5) # in_channels, out_channels, kernel_size
        self.pool = nn.MaxPool2d(2,2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc = nn.Linear(16*5*5, 120)
    def forward(self, x):
        out = self.pool(F.relu(self.conv1(x)))
        out = self.pool(F.relu(self.conv2(out)))
        print(out.shape)
        out = out.view(-1, 16*5*5)
        out = F.relu(self.fc(out))
        return out

model = mymodel() # 初始化模型
print(model.parameters()) # 打印模型参数(是一个生成器)
for param in model.state_dict():
    print(param, "\t", model.state_dict()[param].size())  # 打印模型参数
    
optimizer = optim.SGD(model.parameters(),lr=0.001, momentum=0.9)  # 初始化优化器
for var in optimizer.state_dict(): # 打印优化器参数
    print(var, "\t", optimizer.state_dict()[var])

使用优化器是用来训练网络的,optim优化器的定义在 https://github.com/pytorch/pytorch/tree/master/torch/optim 可以使用Adam,SGD等多种优化器。

构造优化器

https://blog.csdn.net/gdymind/article/details/82708920
要构造一个optimizer,需要使用一个用来包含所有参数(Tensor形式)的iterable,把相关参数(如learning rate、weight decay等)装进去。
注意,如果想要使用.cuda()方法来将model移到GPU中,一定要确保这一步在构造Optimizer之前。因为调用.cuda()之后,model里面的参数已经不是之前的参数了。

将需要训练的参数加入优化器

optimizer = optim.SGD(params=model.parameters(), lr = 0.01, momentum = 0.9) # 将模型的所有参数都加进去
optimizer = optim.SGD(params=model.classifier.parameters(), lr = 0.01, momentum = 0.9) # 指定模型的classifier层的参数,加入优化器
optimizer = optim.Adam(params=[var1, var2], lr = 0.0001) # 加入[var1, var2]

单独指定参数

也可以用一个dict的iterable指定参数。这里的每个dict都必须要params这个key,params包含它所属的参数列表。除此之外的key必须它的Optimizer(如SGD)里面有的参数。
这在针对特定部分进行操作时很有用。比如只希望给指定的几个层单独设置学习率:

optim.SGD([
			{'params': model.base.parameters()},
			{'params': model.classifier.parameters(), 'lr': 0.001}
			],	 
			lr = 0.01, momentum = 0.9)

在上面这段代码中model.base将会使用默认学习率0.01,而model.classifier的参数蒋欢使用0.001的学习率。

使用optimizer.step()进行单次优化

所有optimizer都实现了step()方法,调用optimizer.step()方法可以更新参数:

for input, target in dataset:
	optimizer.zero_grad() # 每个mini-batch使用之前,optimzier使用之前需要zero清零一下,因为如果不清零,那么使用的这个grad就得同上一个mini-batch有关
    output = model(input)
    loss = cal_loss(target, output)  # 计算损失函数
    loss.backward() 
    optimizer.step()  # optimizer更新参数空间需要基于反向梯度,因此要先进行loss.backward()这个回传操作

关于loss.backward()

参考 https://blog.csdn.net/douhaoexia/article/details/78821428 讲的十分详细
这里需要注意:

  • 只有标量才可以使用backward()
  • 对于需要backward()的变量,必须满足requires_grad = True,否则会报错。
  • 创建的tensor默认requires_grad = False,需要在创建时指定,例如my_tensor = torch.zeros(3, 4, requires_grad=True),也可以在创建后对其修改,例如existing_tensor.requires_grad_()existing_tensor.requires_grad()
  • 对于继承自 nn.Module 的某一网络 net 或网络层,定义好后,发现 默认情况下,net.paramters 的 requires_grad 就是 True 的

pytorch0.4开始合并Tensor和Variable,torch.Tensor 能够像之前的Variable一样追踪历史和反向传播。Variable仍能够正常工作,但是返回的是Tensor。所以在0.4的代码中,不需要使用Variable了。(参考

optimizer.step() 和scheduler.step()的区别

https://blog.csdn.net/qq_20622615/article/details/83150963
https://blog.csdn.net/xiaoxifei/article/details/87797935

optimizer.step()通常用在每个mini-batch之中,而scheduler.step()通常用在epoch大循环里面。
只有用了optimizer.step(),模型才会更新,而scheduler.step()是对lr进行调整。
在scheduler的step_size表示scheduler.step()每调用step_size次,对应的学习率就会按照策略调整一次。所以如果scheduler.step()是放在mini-batch里面,那么step_size指的是经过这么多次迭代,学习率改变一次。

模型保存和读取

参考这里 https://blog.csdn.net/aaon22357/article/details/82696938

加载不同的模型

加载他人训练的模型,可能需要忽略部分层。则将load_state_dict方法的strict参数设置为False。(strict参数的意思是,参数名字必须完全对应才能加载)例如:

torch.save(model1.state_dict(),PATH) # 把model1的参数保存到PATH中(只存了参数,没有存模型)
model2.load_state_dict(torch.load(PATH), strict=False) # 将model1模型的参数导入到model2中

加载不同设备的模型

将GPU保存的模型加载到CPU上

将torch.load()函数中的map_location参数设置为torch.device(‘cpu’),例如:

device = torch.device('cpu')
model.load_state_dict(torch.load(PATH, map_location=device))

将由GPU保存的模型加载到GPU上

确保对输入的tensors调用input = input.to(device)方法

device = torch.device("cuda")
model.load_state_dict(torch.load(PATH))
model.to(device) # 将模型 load进来后要转到cuda上去
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值