pytorch写一个LeNet网络

我们先介绍下pytorch中的cnn网络

学过深度卷积网络的应该都非常熟悉这张demo图(LeNet):

先不管怎么训练,我们必须先构建出一个CNN网络,很快我们写了一段关于这个LeNet的代码,并进行注释:

 1 # coding=utf-8
 2 import torch
 3 import torch.nn as nn
 4 import torch.nn.functional as F
 5 from torch.autograd import Variable
 6 
 7 
 8 class Net(nn.Module):
 9     # 定义Net的初始化函数,这个函数定义了该神经网络的基本结构
10     def __init__(self):
11         super(Net, self).__init__()  # 复制并使用Net的父类的初始化方法,即先运行nn.Module的初始化函数
12         self.conv1 = nn.Conv2d(1, 6, 5)  # 定义conv1函数的是图像卷积函数:输入为图像(1个频道,即灰度图),输出为 6张特征图, 卷积核为5x5正方形
13         self.conv2 = nn.Conv2d(6, 16, 5)  # 定义conv2函数的是图像卷积函数:输入为6张特征图,输出为16张特征图, 卷积核为5x5正方形
14         self.fc1 = nn.Linear(16 * 5 * 5, 120)  # 定义fc1(fullconnect)全连接函数1为线性函数:y = Wx + b,并将16*5*5个节点连接到120个节点上。
15         self.fc2 = nn.Linear(120, 84)  # 定义fc2(fullconnect)全连接函数2为线性函数:y = Wx + b,并将120个节点连接到84个节点上。
16         self.fc3 = nn.Linear(84, 10)  # 定义fc3(fullconnect)全连接函数3为线性函数:y = Wx + b,并将84个节点连接到10个节点上。
17 
18     # 定义该神经网络的向前传播函数,该函数必须定义,一旦定义成功,向后传播函数也会自动生成(autograd)
19     def forward(self, x):
20         x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))  # 输入x经过卷积conv1之后,经过激活函数ReLU,使用2x2的窗口进行最大池化Max pooling,然后更新到x。
21         x = F.max_pool2d(F.relu(self.conv2(x)), 2)  # 输入x经过卷积conv2之后,经过激活函数ReLU,使用2x2的窗口进行最大池化Max pooling,然后更新到x。
22         x = x.view(-1, self.num_flat_features(x))  # view函数将张量x变形成一维的向量形式,总特征数并不改变,为接下来的全连接作准备。
23         x = F.relu(self.fc1(x))  # 输入x经过全连接1,再经过ReLU激活函数,然后更新x
24         x = F.relu(self.fc2(x))  # 输入x经过全连接2,再经过ReLU激活函数,然后更新x
25         x = self.fc3(x)  # 输入x经过全连接3,然后更新x
26         return x
27 
28     # 使用num_flat_features函数计算张量x的总特征量(把每个数字都看出是一个特征,即特征总量),比如x是4*2*2的张量,那么它的特征总量就是16。
29     def num_flat_features(self, x):
30         size = x.size()[1:]  # 这里为什么要使用[1:],是因为pytorch只接受批输入,也就是说一次性输入好几张图片,那么输入数据张量的维度自然上升到了4维。【1:】让我们把注意力放在后3维上面
31         num_features = 1
32         for s in size:
33             num_features *= s
34         return num_features
35 
36 
37 net = Net()
38 
39 # 以下代码是为了看一下我们需要训练的参数的数量
40 print (net)
41 params = list(net.parameters())
42 
43 k = 0
44 for i in params:
45     l = 1
46     print ("该层的结构:" + str(list(i.size())))
47     for j in i.size():
48         l *= j
49     print ("参数和:" + str(l))
50     k = k + l
51 
52 print ("总参数和:" + str(k))

注意:torch.nn只接受mini-batch的输入,也就是说我们输入的时候是必须是好几张图片同时输入。

例如:nn. Conv2d 允许输入4维的Tensor:n个样本 x n个色彩频道 x 高度 x 宽度。

这段代码运行 (运行于pytorch0.4版本) 效果如下:

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)
)
该层的结构:[6, 1, 5, 5]
参数和:150
该层的结构:[6]
参数和:6
该层的结构:[16, 6, 5, 5]
参数和:2400
该层的结构:[16]
参数和:16
该层的结构:[120, 400]
参数和:48000
该层的结构:[120]
参数和:120
该层的结构:[84, 120]
参数和:10080
该层的结构:[84]
参数和:84
该层的结构:[10, 84]
参数和:840
该层的结构:[10]
参数和:10
总参数和:61706

参考链接:https://www.jianshu.com/p/cde4a33fa129

猜你喜欢

转载自www.cnblogs.com/www-caiyin-com/p/9951960.html