深度学习:NiN网络与实验拓展

什么是NiN网络?

        NiN(Network in Network)是2013年由Lin Min等人提出的一种新型卷积神经网络结构。与传统卷积神经网络相比,NiN在每个卷积层之后引入了1x1卷积层,以增强网络的表达能力和非线性特性。

NiN网络的主要特点
  1. 1x1卷积层:每个卷积层后增加1x1卷积层,用于对特征通道进行线性组合,增加网络的非线性表达能力。
  2. 全局平均池化:NiN网络用全局平均池化层代替全连接层,减少参数数量和防止过拟合。
  3. 更深的网络:通过叠加多个NiN块,形成更深层次的网络结构,提取更复杂的特征。
NiN块结构

        一个典型的NiN块包括一个卷积层和两个1x1卷积层:

def nin_block(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())
实验与分析
实验背景

根据《动手学深度学习7.3》练习2的问题,研究为什么NiN块中有两个1x1卷积层,并分析删除其中一个卷积层后的影响。

实验设计
  1. 原始NiN块:包括两个1x1卷积层。
  2. 修改后的NiN块:删除一个1x1卷积层,只保留一个。
def nin_block(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())

        同时加入简单的调参实验,修改学习率和批量大小,结果如下: 

配置学习率批量大小训练精度测试精度训练损失训练速度(examples/sec
两个1x1卷积层0.1640.8850.8890.3121228.7
一个1x1卷积层0.1640.2830.2921.9101530.3
两个1x1卷积层0.11280.8140.8200.5031460.4
两个1x1卷积层0.011280.5270.4791.2601472.5
 实验分析
  • 表达能力

    • 两个1x1卷积层:增加了网络的表达能力,使其能够提取和组合更多复杂的特征,得到较高的训练和测试精度。
    • 删除一个1x1卷积层:降低了网络的表达能力,模型无法有效提取复杂特征,训练和测试精度显著下降。
  • 训练损失

    • 两个1x1卷积层:较低的训练损失表明模型能够更好地拟合训练数据。
    • 删除一个1x1卷积层:较高的训练损失表明模型欠拟合,无法有效学习训练数据中的模式。
  • 学习率和批量大小对比

    • 学习率为0.1时,训练和测试精度较高,尤其是批量大小为64时性能最好。
    • 学习率为0.01时,训练和测试精度显著下降,表明学习率过低可能导致模型收敛速度慢,难以达到较好的效果。
  • 训练速度

    • 删除一个1x1卷积层后由于计算量减少,训练速度略有提升,但代价是性能显著下降。
理论研讨与总结
  1. 1x1卷积层的作用:1x1卷积层的主要作用是对输入特征进行通道间的线性组合,增加网络的非线性表达能力。这使得网络在特征提取过程中更加灵活,能够捕捉到更复杂的模式。
  2. 删除一个1x1卷积层的影响:删除一个1x1卷积层后,网络的表达能力下降,导致模型在训练和测试数据上的表现显著变差。这表明1x1卷积层在NiN块中的重要性。

        通过实验结果可以看出,1x1卷积层在NiN块中起到了关键作用。删除其中一个1x1卷积层会显著降低模型的表达能力,从而影响模型的性能。NiN网络通过增加1x1卷积层,增强了网络的非线性和表达能力,使其能够更好地提取和组合复杂的特征,从而提高模型的准确性和泛化能力。这一实验进一步验证了1x1卷积层在现代卷积神经网络设计中的重要性。

        调参实验结果表明,合理选择学习率和批量大小对模型性能的影响也非常重要。较高的学习率(如0.1)在本次实验中表现较好,而较低的学习率(如0.01)则导致模型难以有效训练。批量大小从128减少到64显著提高了训练和测试精度,表明在本次实验中较小的批量大小有助于模型性能的提升。通过合理调参,可以进一步提升模型的性能。

基线实验代码
import torch
from torch import nn
from d2l import torch as d2l
import os
import torchvision

data_dir = '自行设置地址'

os.makedirs(data_dir, exist_ok=True)
def load_data_fashion_mnist(batch_size, resize=None, root=data_dir):
    trans = [torchvision.transforms.ToTensor()]
    if resize:
        trans.insert(0, torchvision.transforms.Resize(resize))
    trans = torchvision.transforms.Compose(trans)
    mnist_train = torchvision.datasets.FashionMNIST(
        root=root, train=True, transform=trans, download=True)
    mnist_test = torchvision.datasets.FashionMNIST(
        root=root, train=False, transform=trans, download=True)
    return (torch.utils.data.DataLoader(mnist_train, batch_size, shuffle=True,
                                        num_workers=d2l.get_dataloader_workers()),
            torch.utils.data.DataLoader(mnist_test, batch_size, shuffle=False,
                                        num_workers=d2l.get_dataloader_workers()))

# NiN块
def nin_block(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())

# NiN模型
net = nn.Sequential(
    nin_block(1, 96, kernel_size=11, strides=4, padding=0),
    nn.MaxPool2d(3, stride=2),
    nin_block(96, 256, kernel_size=5, strides=1, padding=2),
    nn.MaxPool2d(3, stride=2),
    nin_block(256, 384, kernel_size=3, strides=1, padding=1),
    nn.MaxPool2d(3, stride=2),
    nn.Dropout(0.5),
    # 标签类别数是10
    nin_block(384, 10, kernel_size=3, strides=1, padding=1),
    nn.AdaptiveAvgPool2d((1, 1)),
    # 将四维的输出转成二维的输出,其形状为(批量大小,10)
    nn.Flatten())

X = torch.rand(size=(1, 1, 224, 224))
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape:\t', X.shape)
    
lr, num_epochs, batch_size = 0.1, 10, 128
train_iter, test_iter = load_data_fashion_mnist(batch_size, resize=224)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值