Pytorch完成模型常用API
1 nn.Module
nn.Module
是Torch.nn
提供的一个类,是Pytorch中我们自定义网络的一个基类。
需要注意的是:
_init_
需要调用super
方法,继承父类的属性和方法。farward
方法必须实现,用来定义我们的网络向前机选的过程。
例如,前面的y=wx+b
的实现如下:
import torch
import torch.nn as nn
from torch import optim
import time
class MyModel(nn.Module):#继承了nn.Module类
def __init__(self):
super(MyModel,self).__init__()
self.lr = nn.Linear(1,1)#全连接层,传入的参数为:输入的特征数量,输出的特征数量(in_features,out_features)
def forward(self, x): #x [500,1] ---> y_predict :[500,1]
return self.lr(x)
实例化并调用:
#1. 实例化模型
model = MyModel()
#2. 传入数据,计算结果
predict=model(x)
2 优化器类
优化器类都是由torch.optim
提供的,例如:
- 1.
torch.optim.SGD(参数,学习率)
- 2.
torch.optim.Adam(参数,学习率)
注意: - 1.参数可以通过使用
model.parameters()
来获取,获取模型组所有requires_grad=True
的参数 - 2.优化器的使用方法:
- 实例化
- 更新参数的梯度,将其置为0
- 反向传播计算梯度
- 更新参数值
示例如下:
optimizer=optim.SGD(model.parameters(),lr=1e-3)#1.实例化
optimizer.zero_grad()#2.设置梯度为0
loss.backward()#3.计算梯度
optimizer.step()#4.更新参数的值
3 损失函数
- 1.均方误差:
nn.MSELoss()
,常用于分类问题 - 2.交叉熵损失:
nn.CrossEntropyLoss()
,常用与逻辑回归
使用方法:
#1. 实例化模型
model = MyModel()
#2. 实例化优化器
optimizer = optim.Adam(model.parameters(),lr=0.1)#lr是学习率
#3. 实例化损失函数
loss_fn = nn.MSELoss()
for i in range(500):
#4. 梯度置为0
optimizer.zero_grad()
#5. 调用模型得到预测值
y_predict = model(x)
#6. 通过损失函数,计算得到损失
loss = loss_fn(y_predict,y_true)
#7. 反向传播,计算梯度
loss.backward()
#8. 更新参数
optimizer.step()
4 线性回归完整代码
import torch
import torch.nn as nn
from torch import optim
import time
class MyModel(nn.Module):
def __init__(self):
super(MyModel,self).__init__()
self.lr = nn.Linear(1,1)
def forward(self, x): #x [500,1] ---> y_predict :[500,1]
return self.lr(x)
#0 准备数据
x = torch.rand([500,1])
y_true = 3*x + 0.8
#1. 实例化模型
model = MyModel()
#2. 实例化优化器
optimizer = optim.Adam(model.parameters(),lr=0.1)
#3. 实例化损失函数
loss_fn = nn.MSELoss()
t0 = time.time()
for i in range(500):
#4. 梯度置为0
optimizer.zero_grad()
#5. 调用模型得到预测值
y_predict = model(x)
#6. 通过损失函数,计算得到损失
loss = loss_fn(y_predict,y_true)
#7. 反向传播,计算梯度
loss.backward()
#8. 更新参数
optimizer.step()
#打印部分数据
if i%10 ==0:
print(i,loss.item())
for param in model.parameters():
print(param.item())
print("total cost time:",time.time()-t0) #1.482062578201294
5 实例:复杂的多层神经网络实现
import torch
import torch.nn.functional as F
import torch.nn as nn
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
self.conv1=nn.Conv2d(3,6,5)#卷积层1
self.pool=nn.MaxPool2d(2,2)#池化
self.conv2=nn.Conv2d(6,16,5)
self.fc1 = nn.Linear(16 * 5 * 5, 120) # 全连接层
self.fc2 = nn.Linear(120, 84) # 全连接层
self.fc3 = nn.Linear(84, 10) # 最后一个全连接层用作10分类
def forward(self, x): # 使用__init__中的定义,构建卷积神经网络结构
x = self.pool(F.relu(self.conv1(x))) # 第一个卷积层首先要经过relu做激活,然后使用前面定义好的nn.MaxPool2d(2, 2)方法做池化
x = self.pool(F.relu(self.conv2(x))) # 第二个卷积层也要经过relu做激活,然后使用前面定义好的nn.MaxPool2d(2, 2)方法做池化
x = x.view(-1, 16 * 5 * 5) # 对特征层tensor维度进行变换
x = F.relu(self.fc1(x)) # 卷积神经网络的特征层经过第一次全连接层操作,然后再通过relu层激活
x = F.relu(self.fc2(x)) # 卷积神经网络的特征层经过第二次全连接层操作,然后再通过relu层激活
x = self.fc3(x) # 卷积神经网络的特征层经过最后一次全连接层操作,得到最终要分类的结果(10类标签)
return x
model = MyNet()#实例化
predict=model(x)#进行预测
5.1 卷积层
卷积层保留了输入图像的空间特征,即输入一张32 * 32 * 3的图片而言,卷积层输入就是32 * 32 * 3的矩阵。
卷积核(Keral):常简称为卷积,有时也叫滤波器filter,卷积的大小可以在实际需要时自定义其长和宽(常将其设为:1 * 1,3* 3,5 * 5),其通道数常与输入图片通道数设置一样。
Pytorch中的卷积函数:
import torch
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
# in_channels (int) :输入图片的channel
# out_channels (int) :输出图片(特征层)的channel
# kernel_size (int or tuple) :kernel卷积核的大小
# stride (int or tuple, optional) :卷积的步长,默认为1
# padding (int or tuple, optional) :四周pad的大小,默认为0
# dilation (int or tuple, optional) :kernel元素间的距离,默认为1(dilation翻译为扩张,有时候也称为“空洞”,有专门的文章研究dilation convolution)
# groups (int, optional) :将原始输入channel划分成的组数,默认为1(初级读者暂时可以不细究其用处)
# bias (bool, optional) :如果是Ture,则输出的bias可选,默认为 True
5.2 Relu层
也被称作激活层,利用激活函数进行数据的转化。
5.3 池化层
池化pooling是对图片进行压缩(降采样)的一种方法,池化的方法有很多,如max pooling、average pooling等等。
5.4 全连接层
全连接层一般位于整个卷积神经网络的最后,负责将卷积输出的二维特征图转化成一维的一个向量,由此实现了端到端的学习过程(即:输入一张图像或一段语音,输出一个向量或信息)。全连接层的每一个结点都与上一层的所有结点相连因而称之为全连接层。由于其全相连的特性,一般全连接层的参数也是最多的。
全连接层的主要作用就是将上层(卷积、池化等层)计算得到的特征空间映射样本标记空间。简单的说就是将特征表示整合成一个值,其优点在于减少特征位置对于分类结果的影响,提高了整个网络的鲁棒性。
6. model.eval()以及model.train()
在神经网络中,会有评估和训练的差别。model.eval() 作用等同于 self.train(False),即评估模式。而非训练模式。在评估模式下,batchNorm层,dropout层等用于优化训练而添加的网络层会被关闭,从而使得评估时不会发生偏移。
6.1 model.train()
启用 Batch Normalization 和 Dropout。
如果模型中有BN层(Batch Normalization)和Dropout,需要在训练时添加model.train()。
model.train()作用:对BN层,保证BN层能够用到每一批数据的均值和方差,并进行计算更新;对于Dropout,model.train()是随机取一部分网络连接来训练更新参数。
6.2 model.eval()
不启用 Batch Normalization 和 Dropout。
如果模型中有BN层(Batch Normalization)和Dropout,在测试时添加model.eval()。
model.eval()是保证BN层直接利用之前训练阶段得到的均值和方差,即测试过程中要保证BN层的均值和方差不变;对于Dropout,model.eval()是利用到了所有网络连接,即不进行随机舍弃神经元。
6.3 两者对比
简要理解如下代码:
loop:
model.train() # 切换至训练模式
train……
model.eval()
with torch.no_grad():#不会记录梯度的变化
Evaluation
end loop
可以看到,model.eval()
类似于代码运行在with torch.no_grad()
下。