神经网络可以使用torch.nn包。nn.Module包含层和方法,forward(input)返回output。
神经网络的典型训练过程如下:
------定义具有一些可学习参数(或权重)的神经网络。
------迭代输入数据集
------通过网络处理输入
------计算损失(输出离正确有多远)
------将梯度传播回网络参数
------更新网络的权重,通常使用简单的更新规则:weight = weight - learning_rate * gradient
1.定义网络
定义类的时候只要写层结构和一个方法将会返回“output”。
class Net(nn.Module): # 定义类
def __init__(self): # 写一个层结构
def forward(self, x): # 定义方法
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 首先找到Net的父类(就是类nn.Module),然后把类nn.Module的对象转换为类Net的对象
# 1个输入图像通道,6个输出通道,3x3平方卷积
# 内核
self.conv1 = nn.Conv2d(1, 6, 3) # 图像卷积函数;输入通道为1,输出通道为6,卷积核为(3,3)
self.conv2 = nn.Conv2d(6, 16, 3) # 图像卷积函数;输入通道为6,输出通道16,卷积核为(3,3)
# nn.Conv2d(self, in_channels, out_channels, kernel_s ize, stride=1, padding=0, dilation=1, groups=1, bias=True)
# in_channel:输入数据的通道数;out_channel:输出数据的通道数;kennel_size: 卷积核大小
# 卷积核大小,可以是int或tuple;kennel_size=2,意味着卷积大小(2,2), kennel_size=(2,3),意味着卷积大小(2,3)即非正方形卷积
# stride:步长,默认为1;padding:填充
# 仿射运算:y=wx+b
self.fc1 = nn.Linear(16 * 6 * 6, 120) # 全连接函数;图像尺寸6*6,通道为16,将16*5*5个节点连接到120个节点上
self.fc2 = nn.Linear(120, 84) # 全连接函数;将120个节点连接到84个节点上
self.fc3 = nn.Linear(84, 10) # 全连接函数;将84个节点连接到10个节点上,最后输出为10
# 定义该神经网络的向前传播函数,该函数必须定义,一旦定义成功,向后传播函数也会自动生成(autograd)
def forward(self, x):
# (2,2)窗口上的最大池
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# 输入x经过卷积conv1之后,经过激活函数ReLU,使用2x2的窗口进行最大池化Max pooling,然后更新到x
# 如果大小是正方形,则只能指定一个数字
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
# 输入x经过卷积conv2之后,经过激活函数ReLU,使用2x2的窗口进行最大池化Max pooling,然后更新到x
x = x.view(-1, self.num_flat_features(x))
# num_flat_features函数是把经过两次池化后的16x5x5的矩阵组降维成二维,便于view函数处理,而其中用乘法也是为了不丢失每一层相关的特性
# 这里-1就是把后面的矩阵展成一维数组,以便后面线性变换层操作
# view函数将张量x变形成一维的向量形式,总特征数并不改变,为接下来的全连接作准备
# x = x.view(batchsize, -1)中batchsize指转换后有几行,而-1指在不告诉函数有多少列的情况下,根据原tensor数据和batchsize自动分配列数。
# view函数中-1表示不确定的数
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
# input−>conv2d−>relu−>maxpool2d−>conv2d−>relu−>maxpool2d−>flat−>view−>linear−>relu−>linear−>relu−>linear
# 使用num_flat_features函数把张量x降为2维,比如x是2*3*4*5的张量,那么它的计算结果为3*4*5=60
def num_flat_features(self, x):
size = x.size()[1:] # 除批次维度外的所有维度;因为pytorch只接受批输入,[1:]让我们把注意力放在后3维上面
# 例如x.size=([1, 2, 3, 4]),x.size()[1:]=([2, 3, 4]);即size=([2, 3, 4])
num_features = 1
for s in size: # 例如size=([2, 3, 4]),s分别为2,3,4
num_features *= s
return num_features
net = Net()
print(net)
输出:
Net(
(conv1): Conv2d(1, 6, kernel_size=(3, 3), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(3, 3), stride=(1, 1))
(fc1): Linear(in_features=576, 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)
)