理解PyTorch的第一个例子
代码示例
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)
self.conv2 = nn.Conv2d(6, 16, 5)
# 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))
# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
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)
)
卷积层定义
# 1 input image channel, 6 output channels, 5x5 square convolution
# kernel
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
第一层卷积层nn.Conv2d(1, 6, 5)第一个参数值1,表示输入一个二维数组;
第二个参数值6,表示提取6个特征,得到6个feature map,或者说是activation map;
第三个参数值5,表示卷积核是一个5*5的矩阵。第二层卷积层的理解也类似。
全连接层(Fully Connected Layer) 定义
# 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)
这个例子是个线性模型,全连接层定义了三层线性转换。
nn.Linear(16 * 5* 5, 120),
第一个参数的取值是来自于卷积层输出了16个feature map, 每个feature map是66的二维数据,16 * 5 * 5就是把这16个二维数组拍扁了后一维向量的size;
第二个参数值120是说经过第一层全连接转换后得到120个神经元。
第二层,84个神经元;
第三层,10个神经元。
通过这个view()函数我们把二维数据变成了一维向量。
向前传播
def forward(self, x):
# Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv1(x)), (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 = 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
Convolution Layer和Fully Connected Layer的对接
x = x.view(-1, self.num_flat_features(x))
图像
1. Input
输入图像统一归一化为32*32。
2. C1卷积层
经过(5 * 5 * 1) * 6卷积核,stride=1, 生成featuremap为28 * 28 * 6。
3. S2池化层
经过(2 * 2)采样核,stride=2,生成featuremap为14 * 14 * 6。
4. C3卷积层
经过(5 * 5 * 6)*16卷积核,stride=1,生成featuremap为10 * 10 * 16。
5. S4池化层
经过(2 * 2)采样核,stride=2,生成featuremap为5 * 5 * 16。
6. C5卷积层
经过(5 * 5 * 16) * 120卷积核,stride=1, 生成featuremap为1 * 1 * 120。
7. F6全连接层
输入为1 * 1 * 120,输出为1 * 1 * 84,总参数量为120 * 84。
8. Output全连接层