经典神经网络(4)Nin-Net及其在Fashion-MNIST数据集上的应用

经典神经网络(4)Nin-Net及其在Fashion-MNIST数据集上的应用

1 Nin-Net的简述

1.1 Nin-Net的概述

LeNet、AlexNet和VGG都有⼀个共同的设计模式:通过⼀系列的卷积层与汇聚层来提取空间结构特征;然后通过全连接层对特征的表征进⾏处理。AlexNet和VGG对LeNet的改进主要在于如何扩⼤和加深这两个模块。

然⽽,如果使⽤了全连接层,可能会完全放弃表征的空间结构。⽹络中的⽹络(NiN)提供了⼀个⾮常简单的解决⽅案:在每个像素的通道上分别使⽤多层感知机。

NiN的想法是在每个像素位置(针对每个⾼度和宽度)应⽤⼀个全连接层。如果我们将权重连接到每个空间位置,我们可以将其视为1 *×* 1卷积层,或作为在每个像素位置上独⽴作⽤的全连接层。从另⼀个⻆度看,即将空间维度中的每个像素视为单个样本,将通道维度视为不同特征(feature)

1.2 Nin-Net的实现

在这里插入图片描述

import torch.nn as nn
import torch



class NinNet(nn.Module):


    def __init__(self):
        super().__init__()
        '''
        最初的NiN⽹络是在AlexNet后不久提出的,显然从中得到了⼀些启⽰。NiN使⽤窗⼝形状为11×11、5×5和3×
        3的卷积层,输出通道数量与AlexNet中的相同。每个NiN块后有⼀个最⼤汇聚层,汇聚窗⼝形状为3 × 3,步幅为2。
        
        NiN和AlexNet之间的⼀个显著区别是NiN完全取消了全连接层。相反,NiN使⽤⼀个NiN块,其输出通道数等
        于标签类别的数量。最后放⼀个全局平均汇聚层(global average pooling layer),⽣成⼀个对数⼏率(logits)。
        NiN设计的⼀个优点是,它显著减少了模型所需参数的数量。然⽽,在实践中,这种设计有时会增加训练模
        型的时间。
        '''
        self.model = nn.Sequential(
            self.nin_block(in_channels=1,out_channels=96,kernel_size=11,strides=4,padding=0),
            nn.MaxPool2d(kernel_size=3,stride=2),
            self.nin_block(in_channels=96, out_channels=256, kernel_size=5, strides=1, padding=2),
            nn.MaxPool2d(kernel_size=3, stride=2),
            self.nin_block(in_channels=256, out_channels=384, kernel_size=3, strides=1, padding=1),
            nn.MaxPool2d(kernel_size=3, stride=2),

            nn.Dropout(0.5),
            # 标签类别数是10
            self.nin_block(384, 10, kernel_size=3, strides=1, padding=1),
            nn.AdaptiveAvgPool2d((1, 1)),
            # 将四维的输出转成二维的输出,其形状为(批量⼤⼩,10)
            nn.Flatten()

        )

    def forward(self, X):
        X = self.model(X)
        return X



    def nin_block(self,in_channels, out_channels, kernel_size, strides, padding):
        return nn.Sequential(
            nn.Conv2d(in_channels, out_channels,kernel_size, strides, padding),nn.ReLU(),
            nn.Conv2d(out_channels,out_channels,kernel_size=1),nn.ReLU(),
            nn.Conv2d(out_channels,out_channels,kernel_size=1),nn.ReLU()
        )


if __name__ == '__main__':
    net = NinNet()
    # 测试神经网络是否可运行
    # inputs = torch.rand(size=(1, 1, 224, 224), dtype=torch.float32)
    # outputs = net(inputs)
    # print(outputs.shape)
    X = torch.rand(size=(1, 1, 224, 224), dtype=torch.float32)
    for layer in net.model:
        X = layer(X)
        print(layer.__class__.__name__, 'output shape:', X.shape)
Sequential output shape: torch.Size([1, 96, 54, 54])
MaxPool2d output shape: torch.Size([1, 96, 26, 26])
    
Sequential output shape: torch.Size([1, 256, 26, 26])
MaxPool2d output shape: torch.Size([1, 256, 12, 12])
    
Sequential output shape: torch.Size([1, 384, 12, 12])
MaxPool2d output shape: torch.Size([1, 384, 5, 5])
    
Dropout output shape: torch.Size([1, 384, 5, 5])
Sequential output shape: torch.Size([1, 10, 5, 5])
# 全局平均汇聚层(global average pooling layer)
AdaptiveAvgPool2d output shape: torch.Size([1, 10, 1, 1])
Flatten output shape: torch.Size([1, 10])

2 Nin-Net在Fashion-MNIST数据集上的应用示例

3.1 创建Nin-Net网络模型

如1.2代码所示。

3.2 读取Fashion-MNIST数据集

其他所有的函数,与经典神经网络(1)LeNet及其在Fashion-MNIST数据集上的应用完全一致。

batch_size = 128

train_iter,test_iter = get_mnist_data(batch_size,resize=224)

3.3 在GPU上进行模型训练

from _04_NinNet import NinNet

# 初始化模型
net = NinNet()

lr, num_epochs = 0.1, 10
train_ch(net, train_iter, test_iter, num_epochs, lr, try_gpu())

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44665283/article/details/130798444