Lenet5网络
定义初始化网络:
神经网络的典型处理如下:
1.定义可学习参数的网络结构(堆叠各层和层的设计);
2.数据集输入;
3.对输入进行处理(由定义的网络层进行处理),主要体现在网络的前向传播;
4.计算loss,由loss层计算;
5.反向传播求梯度;
6.根据梯度改变参数值,最简单的实现方式为(SGD)为:weight = weight - learning_rate * gradient
def __init__(self):
super(Lenet5, self).__init__()
self.conv_unit = nn.Sequential(
# x: [b, 3, 32, 32] => [b, 16, ]
nn.Conv2d(3, 16, kernel_size=5, stride=1, padding=0),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
#
nn.Conv2d(16, 32, kernel_size=5, stride=1, padding=0),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0),
#
)
# flatten
# fc unit
self.fc_unit = nn.Sequential(
nn.Linear(32*5*5, 32),
nn.ReLU(),
# nn.Linear(120, 84),
# nn.ReLU(),
nn.Linear(32, 10)
)
def forward(self, x):
"""
:param x: [b, 3, 32, 32]
:return:
"""
batchsz = x.size(0)
# [b, 3, 32, 32] => [b, 16, 5, 5]
x = self.conv_unit(x)
# [b, 16, 5, 5] => [b, 16*5*5]
x = x.view(batchsz, 32*5*5)
# [b, 16*5*5] => [b, 10]
logits = self.fc_unit(x)
return logits
由上例代码可以看到,不论是在定义网络结构还是定义网络层,均需要定义forward函数. Pytorch官网上的解释.
那么调用forward方法的具体流程是什么样的呢?具体流程是这样的:
以一个Module为例:
1. 调用module的call方法
2. module的call里面调用module的forward方法
3. forward里面如果碰到Module的子类,回到第1步,如果碰到的是Function的子类,继续往下
4. 调用Function的call方法
5. Function的call方法调用了Function的forward方法。
6. Function的forward返回值
7. module的forward返回值
8. 在module的call进行forward_hook操作,然后返回值。
定义网络层
self.conv_unit = nn.Sequential(
#x:[b,3,32,32] => [b,6,]
nn.Conv2d(3,6,kernel_size=5,stride=1,padding=0), #搭积木,第一层
nn.AvgPool2d(kernel_size=2,stride=2,padding=0), #搭积木,第二次
#
nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0), #搭积木,第三层
nn.AvgPool2d(kernel_size=2,stride=2,padding=0), #搭积木,第四层
)
第一,卷积层:输入通道,输出通道,卷积核大小,步长,填充.
nn.Conv2d(3,6,kernel_size=5,stride=1,padding=0)
第二,池化层:卷积核为2,步长为2,填充为0
nn.AvgPool2d(kernel_size=2,stride=2,padding=0)
第三,卷积层:输入通道,输出通道,卷积核,步长,填充.
nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0)
第四,池化层:卷积核,步长,填充
nn.AvgPool2d(kernel_size=2,stride=2,padding=0)
这里显示是4层.
nn.Sequential(
nn.Linear(2,120), #搭积木,第五层
nn.ReLU(),
nn.Linear(120,84), #搭积木,第六层
nn.ReLU(),
nn.Linear(84,10) #搭积木,第七层
)
第5,连接层.
nn.Linear(2,120)
第6,连接层.
nn.Linear(120,84)
第7,连接层.
nn.Linear(84,10)
将四维数据改造成二维数据
#将四维数据改造成二维数据
#输出为b=32
batchsz = x.size(0)
# [b, 3, 32, 32] => [b, 16, 5, 5],[32, 3, 32, 32] => [32, 16, 5, 5]
x = self.conv_unit(x)
# [b, 16, 5, 5] => [b, 16*5*5]
x = x.view(batchsz, 32*5*5)
# [b, 16*5*5] => [b, 10]
logits = self.fc_unit(x)