【PyTorch官方教程中文版学习笔记02】PyTorch 神经网络
学前准备: 1. python 中关于【类】的语法
2. 学会查阅官方文档Linear — PyTorch 1.10 documentation
基础知识: 1. nn.Module是PyTorch提供的神经网络类,并在类中实现了网络各层的定义及前向计算与反向传播机制。在实际使用时,如果想要实现某个神经网络,只需继承nn.Module,在初始化中定义模型结构与参数,在函数forward()中编写网络前向过程即可。更生动的比喻是,现有一个玩具车模型(nn.Module),我们自己改装了轮胎马达等(填装我们自己需要的函数),然后玩具车上跑道(forward函数)跑起来了。
2. 常见函数
a)卷积 convolution
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0)
有时,论文中给的神经网络框架图中可能没有给具体stride或padding的参数值,可以根据此公式推导。
b)池化 Pooling
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0)
在池中过滤出最大值,参数解释参考卷积。
作用:减少数据量,训练更快。可将图片马赛克化,或降低清晰度。
c) Linear
torch.nn.Linear(in_features, out_features)
Applies a linear transformation to the incoming data: y = xA^T + b
应用举例:
两个全连接层组成的感知机
d)激活函数
激活函数通常为非线性的平滑函数
神经网络中经常使用的一个激活函数就是sigmoid函数
最近则主要使用ReLU(Rectified Linear Unit)函数
e) 其他
torch.
randn
(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)
example:
实例1:
#下面具体以一个由两个全连接层组成的感知机为例,介绍如何使用nn.Module构造模块化的神经网络 import torch from torch import nn class Linear(nn.Module): def __init__(self, in_dim, out_dim): super(Linear, self).__init__() #super()帮助python将父类和子类联系起来,调用父类nn.Module的结构函数 self.w = nn.Parameter(torch.randn(in_dim, out_dim)) self.b = nn.Parameter(torch.randn(out_dim)) # torch.randn(*size, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor #size(int…) --定义输出张量形状的整数序列;out(Tensor, optional) --输出张量 #nn.Parameter函数:nn.Parameter()函数定义了全连接中的ω和b, # 这是一种特殊的Tensor的构造方法,默认需要求导,即requires_grad为True。 #Parameter:参数 def forward(self, x): x = x.matmul(self.w)#使用Tensor.matmul实现矩阵相乘,x*w y = x + self.b.expand_as(x)#将张量扩展为参数x的大小,保证矩阵形状一致。y=x*w+b return y #建立感知机类,继承nn.Module,并调用了Linear的子module class Perception(nn.Module):#perception 感知 def __init__(self, in_dim, hid_dim, out_dim): super(Perception, self).__init__()#super()同上 self.layer1 = Linear(in_dim, hid_dim) self.layer2 = Linear(hid_dim, out_dim) # Applies a linear transformation to the incoming data: y = xA^T + by=xA^T+b def forward(self, x): x = self.layer1(x) y = torch.sigmoid(x)#sigmoid作为激活函数 #sigmoid激活函数:h(x)=1/(1+e^(-x)),图像近似于阶跃函数,但是是连续的,平滑的非线性函数。 y = self.layer2(y) y = torch.sigmoid(y) return y
#调用该神经网络 import torch from perception import Perception perception = Perception(2,3,2) print(perception) # named_parameters()可以返回学习参数的迭代器,分别为参数名与参数值 for name, parameter in perception.named_parameters(): print(name, parameter) # 随机生成数据,注意这里的4代表了样本数为4,每个样本有两维 data = torch.randn(4,2)
#输出的结果
Perception(
(layer1): Linear()
(layer2): Linear()
)
#layer1的w,b参数信息
layer1.w Parameter containing:
tensor([[ 0.3498, -0.2598, -1.0321],
[ 0.6166, -1.6089, -0.0318]], requires_grad=True)
layer1.b Parameter containing:
tensor([-1.1886, -0.2010, 0.2120], requires_grad=True)
#layer2的w,b参数信息
layer2.w Parameter containing:
tensor([[-0.3462, -1.3090],
[ 2.2993, 0.5015],
[-0.1526, -1.4099]], requires_grad=True)
layer2.b Parameter containing:
tensor([ 0.3471, -0.3661], requires_grad=True)
知识补充:
实例2:
这是一个简单的前馈神经网络,它接收输入,让输入一个接着一个的通过一些层,最后给出输出。
import torch import torch.nn as nn import torch.nn.functional as F class Net(nn.Module): def __init__(self): super(Net, self).__init__() # 1 input image channel, 6 output channels, 5x5 square convolution # kernel self.conv1 = nn.Conv2d(1, 6, 5) #卷积1 self.conv2 = nn.Conv2d(6, 16, 5)#卷积2 # an affine operation: y = Wx + b self.fc1 = nn.Linear(16 * 5 * 5, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): # Max pooling over a (2, 2) window x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))#对x卷积1后,用relu激活,再进行最大池化,最大池化核为2*2 # If the size is a square you can only specify a single number x = F.max_pool2d(F.relu(self.conv2(x)), 2)#对上面的x继续卷积2后,用relu激活,再进行最大池化 x = x.view(-1, self.num_flat_features(x)) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x def num_flat_features(self, x): size = x.size()[1:] # all dimensions except the batch dimension num_features = 1 for s in size: num_features *= s return num_features
net = Net() print(net) #输出框架参数 Net( (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1)) (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1)) (fc1): Linear(in_features=400, out_features=120, bias=True) (fc2): Linear(in_features=120, out_features=84, bias=True) (fc3): Linear(in_features=84, out_features=10, bias=True) )
#尝试输入一个32*32的“图片” input = torch.randn(1, 1, 32, 32) print(input) out = net(input) print(out) #输出为一个1*10的tensor tensor([[ 0.0537, 0.0238, 0.0759, 0.0187, 0.0491, 0.0826, 0.0281, -0.0361, -0.1232, 0.0870]], grad_fn=)
在此,我们完成了:
1.定义一个神经网络
2.处理输入以及调用反向传播
参考文献:
《Pytorch官方教程中文版 》
《 深度学习之Pytorch物体检测实战》
《深度学习入门:基于python的理论与实现》