深度学习网络

LeNet

由于使用的是MNIST数据集,每张图片是28 x 28大小的灰度图片,于是需要对LeNet模型进行适当修改

import torch.nn as nn
import torch.nn.functional as F

class LeNet(nn.Module):
    def __init__(self):  # 初始化网络结构
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(16 * 4 * 4, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):  # 正向传播过程
        x = F.relu(self.conv1(x))  # input(1, 28, 28) output(6, 24, 24)
        x = self.pool1(x)  # output(6, 12, 12)
        x = F.relu(self.conv2(x))  # input(6, 12, 12) output(16, 8, 8)
        x = self.pool2(x)  # output(16, 4, 4)
        x = x.view(-1, 16 * 4 * 4)  # output(16*4*4)
        x = F.relu(self.fc1(x))  # output(120)
        x = F.relu(self.fc2(x))  # output(84)
        x = self.fc3(x)  # output(10)
        return x

AlexNet

class AlexNet(nn.Module):
    # 子类继承中重新定义Module类的__init__()和forward()函数
    # init():进行初始化,申明模型中各层的定义
    def __init__(self):
        # super:引入父类的初始化方法给子类进行初始化
        super(AlexNet, self).__init__()
        # 卷积层,输入大小为224*224,输出大小为55*55,输入通道为3,输出为96,卷积核为11,步长为4
        self.c1 = nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4, padding=2)
        # 使用ReLU作为激活函数
        self.ReLU = nn.ReLU()
        # MaxPool2d:最大池化操作
        # 最大池化层,输入大小为55*55,输出大小为27*27,输入通道为96,输出为96,池化核为3,步长为2
        self.s1 = nn.MaxPool2d(kernel_size=3, stride=2)
        # 卷积层,输入大小为27*27,输出大小为27*27,输入通道为96,输出为256,卷积核为5,扩充边缘为2,步长为1
        self.c2 = nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, stride=1, padding=2)
        # 最大池化层,输入大小为27*27,输出大小为13*13,输入通道为256,输出为256,池化核为3,步长为2
        self.s2 = nn.MaxPool2d(kernel_size=3, stride=2)
        # 卷积层,输入大小为13*13,输出大小为13*13,输入通道为256,输出为384,卷积核为3,扩充边缘为1,步长为1
        self.c3 = nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, stride=1, padding=1)
        # 卷积层,输入大小为13*13,输出大小为13*13,输入通道为384,输出为384,卷积核为3,扩充边缘为1,步长为1
        self.c4 = nn.Conv2d(in_channels=384, out_channels=384, kernel_size=3, stride=1, padding=1)
        # 卷积层,输入大小为13*13,输出大小为13*13,输入通道为384,输出为256,卷积核为3,扩充边缘为1,步长为1
        self.c5 = nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, stride=1, padding=1)
        # 最大池化层,输入大小为13*13,输出大小为6*6,输入通道为256,输出为256,池化核为3,步长为2
        self.s5 = nn.MaxPool2d(kernel_size=3, stride=2)
        # Flatten():将张量(多维数组)平坦化处理,神经网络中第0维表示的是batch_size,所以Flatten()默认从第二维开始平坦化
        self.flatten = nn.Flatten()
        # 全连接层
        # Linear(in_features,out_features)
        # in_features指的是[batch_size, size]中的size,即样本的大小
        # out_features指的是[batch_size,output_size]中的output_size,样本输出的维度大小,也代表了该全连接层的神经元个数
        self.f6 = nn.Linear(6 * 6 * 256, 4096)
        self.f7 = nn.Linear(4096, 4096)
        # 全连接层&softmax
        self.f8 = nn.Linear(4096, 1000)
        self.f9 = nn.Linear(1000, 2)

    # forward():定义前向传播过程,描述了各层之间的连接关系
    def forward(self, x):
        x = self.ReLU(self.c1(x))
        x = self.s1(x)
        x = self.ReLU(self.c2(x))
        x = self.s2(x)
        x = self.ReLU(self.c3(x))
        x = self.ReLU(self.c4(x))
        x = self.ReLU(self.c5(x))
        x = self.s5(x)
        x = self.flatten(x)
        x = self.f6(x)
        # Dropout:随机地将输入中50%的神经元激活设为0,即去掉了一些神经节点,防止过拟合
        # “失活的”神经元不再进行前向传播并且不参与反向传播,这个技术减少了复杂的神经元之间的相互影响
        x = F.dropout(x, p=0.5)
        x = self.f7(x)
        x = F.dropout(x, p=0.5)
        x = self.f8(x)
        x = F.dropout(x, p=0.5)
        x = self.f9(x)
        return x