深度学习笔记(五)——神经网络工具箱nn
神经网络工具箱
- 神经网络工具箱nn
- nn.Module
- nn.functional
- 优化器
- 动态修改学习率参数
- 优化器比较
- 参考文献
神经网络工具箱nn
在nn工具箱中有两个重要模块:nn.Model、nn.functional。
nn.Module
nn.Module是nn的一个核心数据结构,它可以是神经网络的某个层(Layer),也可以是包含多层的神经网络。在实际使用中,最常见的做法是继承nn.Module,生成自己的网络/层。例如上一篇博文中,所定义的Net类就是采用这种方法(class Net(torch.nn.Module))。nn中已实现了绝大多数层,包括全连接层、损失层、激活层、卷积层、循环层等。这些层都是nn.Module的子类,能够自动检测到自己的Parameter,并将其作为学习参数,且针对GPU运行进行了cuDNN优化。
nn.functional
nn中的层,一类是继承了nn.Module,其命名一般为nn.Xxx(第一个是大写),如:nn.Linear、nn.Conv2d、nn.CrossEntropyLoss等。另一类是nn.functional中的函数,其名称一般为nn.functional.xxx,如:nn.functional.linear、nn.functional.conv2d、nn.functionalcross_entropy等。从功能上来说两者相当,基于nn.Module能实现的层,使用nn.functional也可以实现,反之亦然。不过在具体使用时,两者还是有区别,主要区别如下:
(1)nn.Xxx继承于nn.Module,nn.Xxx需要先实例化并传入参数,然后以函数调用的方式调用实例化的对象并传入输入数据。它能够很好地与nn.Sequential结合使用,而nn.functional.xxx无法与nn.Sequential结合使用。
(2)nn.Xxx不需要自己定义和管理weight、bias参数;而nn.functional.xxx需要自己定义weight、bias参数,每次调用的时候都需要手动传入weight、bias等参数,不利于代码复用。
(3)Dropout操作在训练和测试阶段是有区别的,使用nn.Xxx方式定义Dropout,在调用model.eval()之后,自动实现状态的转换,而使用nn.functional.xxx却无此功能。
pytorch官方推荐:具有学习参数的(例如:conv2d, linear, batch_norm)采用nn.Xxx方式。没有学习参数的(例如,maxpool,loss_func,activation func)等根据个人选择来使用nn.functional.xxx或者nn.Xxx方式。例如上一篇博文中使用激活层,我们采用F.relu来实现,即nn.functional.xxx方式。
优化器
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) # 这里lr是指学习率
以下步骤在训练模型的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.param_groups:长度1的list,optimizer.param_groups[0]:长度为6的字典,包括权重参数、lr、momentum等参数。
len(optimizer.param_groups[0]) # 结果为6
这里是上一篇博文中动态修改学习率参数的代码:
# 动态修改参数学习率if epoch % 5 == 0:optimizer.param_groups[0]['lr'] *= 0.1
优化器比较
这里通过一个实例说明pytorch中的自适应优化器。
(1)导入需要的模块。
import torch
import torch.utils.data as Data
import torch.nn.functional as F
import matplotlib.pyplot as plt# 超参数
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)使用多种优化器
这里我把书中的代码做了改进,选择调用GPU进行操作。
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net_SGD = Net()
net_Momentum = Net()
net_RMSProp = Net()
net_Adam = Net()nets = list(map(lambda x: x.to(device), [net_SGD, net_Momentum, net_RMSProp, net_Adam]))
# nets = [net_SGD, net_Momentum, net_RMSProp, net_Adam]
opt_SGD = torch.optim.SGD(nets[0].parameters(), lr=LR)
opt_Momentum = torch.optim.SGD(nets[1].parameters(), lr=LR, momentum=0.9)
opt_RMSProp = torch.optim.RMSprop(nets[2].parameters(), lr=LR, alpha=0.9)
opt_Adam = torch.optim.Adam(nets[3].parameters(), lr=LR, betas=(0.9, 0.99))
optimizers = [opt_SGD, opt_Momentum, opt_RMSProp, opt_Adam]
(5)训练模型
这里的代码同样将输入数据用GPU处理。
loss_func = torch.nn.MSELoss()
loss_his =[[], [], [], []] # 记录损失
for epoch in range(EPOCH):for step, (batch_x, batch_y) in enumerate(loader):batch_x, batch_y = map(lambda x: x.to(device), (batch_x, batch_y))for net, opt, l_his in zip(nets, optimizers, loss_his):output = net(batch_x) # get output for every netloss = loss_func(output, batch_y) # compute loss for every netopt.zero_grad() # clear gradients for next trainloss.backward() # backpropagation, compute gradientsopt.step() # apply gradientsl_his.append(loss.data.cpu().numpy()) # loss recoder
labels = ['SGD', 'Momentum', 'RMSProp', 'Adam']
(6)可视化结果
for i, l_his 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()
参考文献
吴茂贵,郁明敏,杨本法,李涛,张粤磊. Python深度学习(基于Pytorch). 北京:机械工业出版社,2019.
深度学习笔记(五)——神经网络工具箱nn相关推荐
- July深度学习笔记之神经网络与反向传播算法
July深度学习笔记之神经网络与反向传播算法 一.神经网络 神经网络的大致结构如下: 大致可以分为输入层.隐藏层与输出层. 而我们可以单独拿出来一个结点,可以发现,其实它就是类似一个逻辑回归(LR), ...
- 深度学习——结构递归神经网络(Recursive NN)
深度学习--结构递归神经网络(Recursive NN) 1.递归神经网络介绍 目前,递归神经网络一共包含两种,一种是时间递归神经网络(Recurrent NN),另外一种是结构性递归神经网络(Rec ...
- 吴恩达深度学习笔记——卷积神经网络(Convolutional Neural Networks)
深度学习笔记导航 前言 传送门 卷积神经网络(Convolutional Neural Networks) 卷积神经网络基础(Foundations of Convolutional Neural N ...
- 1.4)深度学习笔记------深层神经网络
目录 1)Deep L-layer neural network 2)Forward Propagation in a Deep Network(重点) 3)Getting your matrix d ...
- 吴恩达深度学习笔记——卷积神经网络(CNN)
目录 一.计算机视觉(Computer vision) 二.边缘检测示例(Edge detection example) 三.更多的边缘检测内容(More edge detection) 四.Padd ...
- 深度学习笔记——循环神经网络RNN/LSTM
原文来自知乎专栏NLP进阶之路,作者韦伟. 以下文章是摘录了原文部分内容的学习笔记,侵删. 循环神经网络(Rerrent Neural Network) RNN是神经网络的一种,RNN对具有序列特性的 ...
- 吴恩达深度学习笔记(21)-神经网络的权重初始化为什么要随机初始化?
随机初始化(Random+Initialization) 当你训练神经网络时,权重随机初始化是很重要的. 对于逻辑回归,把权重初始化为0当然也是可以的. 但是对于一个神经网络,如果你把权重或者参数都初 ...
- 深度学习笔记(九):神经网络剪枝(Neural Network Pruning)详细介绍
文章目录 1:What is pruning 2:Pruning in MLP(多层感知机) 2.2 How to make mask 3.Pruning in CNN(卷积神经网络) 1:What ...
- 深度学习笔记:神经网络权重确定初始值方法
神经网络权重不可为相同的值,比如都为0,因为如果这样网络正向传播输出和反向传播结果对于各权重都完全一样,导致设置多个权重和设一个权重毫无区别.我们需要使用随机数作为网络权重 实验程序 在以下实验中,我 ...
- Ng深度学习笔记-卷积神经网络-目标检测
目标定位 符号表示: 图片左上角的坐标为(0,0)(0,0)(0,0),右下角标记为(1,1)(1,1)(1,1). 红色方框的中心点(bxb_{x}bx,byb_{y}by),边界框的高度为bh ...
最新文章
- 平头哥发布一站式芯片设计平台“无剑”,芯片设计成本降低50%
- 超过Google,微信AI在NLP领域又获一项世界第一
- LeetCode Reorder List
- java 矩形重叠问题_两个矩形重叠的问题
- java locale.us_JAVA实现国际化
- 【Pytorch神经网络理论篇】 24 神经网络中散度的应用:F散度+f-GAN的实现+互信息神经估计+GAN模型训练技巧
- java常问的报错_java常见报错及解决
- WPF 面试题及答案(三)
- markdown与latex:书写单边大括号左边或右边即在没有括号的一端加点
- 微信公众号开发 ----微信获取access_token(2)
- linux的df命令根目录,详细分析Linux df命令的使用方法
- JVM中也有并发GC,CMS机制
- java 8 API 开发文档中文
- SpringMVC+Mybatis框架集成开发基础——项目开发流程——01
- c语言 for循环说课,《程序的循环结构-For循环语句》教学设计
- this的指向问题总结
- 物联网IoT应用技术有哪些?
- 计算机软考英语复习,计算机软考综合之计算机英语经典短文
- Discuz如何开发移动端访客功能
- 图像分割技术与MATLAB仿真剖析