[pytorch]优化《python深度学习:基于pytorch》

参考资料:

一、优化器

PyTorch常用的优化方法都封装在torch. optim里面,其设计很灵活,可以扩展为自定义的优化方法。所有的优化方法都是继承了基类optim.Optimizer,并实现了自己的优化步骤。最常用的优化算法就是梯度下降法及其各种变种,后续章节我们将介绍各种算法的原理,这类优化算法通过使用参数的梯度值更新参数。

说明使用优化器的一-般步骤为:
(1) 建立优化器实例
导入optim模块,实例化SGD优化器,这里使用动量参数momentum (该值一般在(0,1) 之间),是SGD的改进版,效果一般比不使用动量规则的要好.

import torch.optim as optim
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

以下步骤在训练模型的for循环中
(2)向前传播
把输入数据传入神经网络Net实例化对象model中,自动执行forward函数,得到out输出值,然后用out与标记label计算损失值loss.

out=model(img)
loss=criterion(out,label)

(3)清空梯度
缺省情况梯度是累加的,在梯反向传播前,先需要把梯度清零.

optimizer.zero_grad()

(4)反向传播
基于损失值,把梯度进行反向传播.

loss.backward()

(5)更新参数
基于当前梯度(存储在参数的.grad属性中)更新参数

optimizer.step()

二、动态修改学习率参数

修改参数的方式可以通过修改参数optimizer. params_ groups或新建optimizer。 新建optimizer比较简单,optimizer十分轻量级, 所以开销很小。但是新的优化器会初始化动量等状态信息,这对于使用动量的优化器(momentum参数的sgd)可能会造成收敛中的震荡。所以,这里直接采用修改参数optimizer.params_ groups

optimizer.param_ groups: 长度1的list,
optimizer.param_ groups[0]: 长度为6的字典,包括权重参数、Ir、 momentum等参数。

len(optimizer.param_groups[0])#结果为6

动态修改学习率参数

for epoch in range(num_epoches):
	# 动态修改参数学习率
	if epoch%5 == 0:
		optimizer.param_groups[0][lr] *= 0.1
		print(optimizer.param_groups[O]['lr'])
	for img, label in train_loader:####

三、优化器比较

PyTorch中的优化器很多,各种优化器一-般都有 其适应的场景,不过,像自适应优化器在深度学习中比较受欢迎,除了性能较好,鲁棒性、泛化能力也更强。这里通过一个简单实例进行说明。
1)导入需要的模块。

import torch
import torch.utils.data as Data
import torch.nn.functional as F
import matplotlib. pyplot as plt
%matplotlib inline
#超参数
LR = 0.01
BATCH_SIZE = 32
EPOCH= 12

2)生成数据。

#生成训练数据
# torch.unsqueeze()的作用是将一维变二 维,torch只能处理二 维的数据
x = torch.unsqueeze(torch.linspace(-1, 1, 1000), dim=1) 
# 0.1 * torch.normal(x.size()增加噪点
y = x.pow(2) + 0.1 * torch.normal(torch.zeros(*x.size()))
torch_dataset = Data.TensorDataset(x,y)
#得 到一个代批量的生成器
loader = Data.DataLoader(dataset=torch_dataset,batch_size=BATCH_SIZE, shuffle=True)

3)构建神经网络。

class Net(torch.nn.Module):
    # 初始化
    def __init__(self):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(1, 20)
        self.predict = torch.nn.Linear(20, 1) # 前向传递
    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x

4)使用多种优化器。

net_SGD = Net()
net_Momentum = Net()
net_RMSProp = Net()
net_Adam = Net()

nets = [net_SGD, net_Momentum, net_RMSProp, net_Adam]

opt_SGD =torch.optim.SGD(net_SGD.parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(net_Momentum.parameters(),lr=LR, momentum=0.9)
opt_RMSProp =torch.optim.RMSprop(net_RMSProp.parameters(), lr=LR, alpha=0.9)
opt_Adam = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
optimizers = [opt_SGD, opt_Momentum, opt_RMSProp, opt_Adam]

5)训练模型。

loss_func = torch.nn.MSELoss() 
loss_his= [[],[],[], []] 
#记录损失
for epoch in range(EPOCH): 
    for step, (batch_x, batch_y) in enumerate(loader):
        for net, opt,l_his in zip(nets,optimizers, loss_his):
            output = net(batch_x) # get output for every net
            loss = loss_func(output, batch_y) # compute loss for every net
            opt.zero_grad() # clear gradients for next train
            loss.backward() # backpropagation, compute gradients
            opt.step() # apply gradients
            l_his.append(loss.data.numpy()) # loss recoder
labels= ['SGD', 'Momentum', 'RMSprop', 'Adam']
  1. 可视化结果。
for i,l_loss in enumerate(loss_his):
    plt.plot(l_his,label=labels[i])
plt.legend(loc="best")
plt.xlabel("Steps")
plt.ylabel("Loss")
plt.ylim((0,0.2))
plt.show()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值