《动手学深度学习》第二十天---网络中的网络(NiN)

NiN提出原因:
在传统cnn,可以用超完备过滤的方式来继续比较好的抽象。即:增加过滤器,但增加过滤器会增加下层的计算负担。即网络结构复杂,参数空间过大。
事实上,CNN 高层特征其实是低层特征通过某种运算的组合。于是作者就根据这个想法,提出在每个局部感受野中进行更加复杂的运算,提出了对卷积层的改进算法:MLP卷积层。

首先让我们了解一下NiN网络的特点:
① 1×1卷积的使用
使用mlpconv网络层替代传统的convolution层。mlp层实际上是卷积加传统的mlp(多层感知器),因为convolution是线性的,而mlp是非线性的,后者能够得到更高的抽象,泛化能力更强。在跨通道(cross channel,cross feature map)情况下,mlpconv等价于卷积层+1×1卷积层,所以此时mlpconv层也叫cccp层(cascaded cross channel parametric pooling)。

② CNN网络中不使用FC层(全连接层)
文中提出使用Global Average Pooling取代最后的全连接层,因为全连接层参数多且易过拟合。做法即移除全连接层,在最后一层(使用mlpconv)层,后面加一层Average Pooling层。很大程度上减少参数空间,便于加深网络和训练,有效防止过拟合。

以上两点,之所以重要,在于其在较大程度上减少了参数个数,能够得到一个较好的结果。而参数规模的减少,不仅有利用网络层数的加深(由于参数过多,网络规模过大,GPU显存等不够用而限制网络层数的增加,从而限制模型的泛化能力),而且在训练时间上也得到改进。

(一)NiN块

NiN使用1×1卷积层(参考1×1卷积层原理)来替代全连接层,从而使空间信息能够自然传递到后面的层中去。
在这里插入图片描述
定义NiN块,它由一个卷积层和两个充当全连接层的1×1卷积层组成。
这里的1×1卷积层的作用主要是实现了跨通道信息交互,利用1×1卷积核实现降维和升维的操作其实就是channel间的信息的线性变化。比如3×3,64channels的卷积核后面加一个1×1,28channels的卷积核,就变成了3×,28channels的卷积核,原来的64个channels就可以理解为跨通道线性组合变成了28channels,这就是通道间的信息交互。

(二)NiN模型

NiN去掉了AlexNet最后的3个全连接层,取而代之地,NiN使用了输出通道数等于标签类别数的NiN块,然后使用全局平均池化层对每个通道中所有元素求平均并直接用于分类。
全连接存在的问题:参数量过大,降低了训练的速度,且很容易过拟合

关于global average pooling
主要是用来解决全连接的问题,其主要是是将最后一层的特征图进行整张图的一个均值池化,形成一个特征点,将这些特征点组成最后的特征向量进行softmax中进行计算。
GAP的真正意义是:对整个网路在结构上做正则化防止过拟合。其直接剔除了全连接层中黑箱的特征,直接赋予了每个channel实际的内别意义。
实践证明其效果还是比较可观的,同时GAP可以实现任意图像大小的输入。但是值得我们注意的是,使用gap可能会造成收敛速度减慢。

在这里插入图片描述

(三)NiN简易实现

import d2lzh as d2l
from mxnet import gluon, init, nd
from mxnet.gluon import nn

def nin_block(num_channels, kernel_size, strides, padding):
    blk = nn.Sequential()
    blk.add(nn.Conv2D(num_channels, kernel_size,
                      strides, padding, activation='relu'),
            nn.Conv2D(num_channels, kernel_size=1, activation='relu'),
            nn.Conv2D(num_channels, kernel_size=1, activation='relu'))
    return blk

net = nn.Sequential()
net.add(nin_block(96, kernel_size=11, strides=4, padding=0),   #NiN块
        nn.MaxPool2D(pool_size=3, strides=2),
        nin_block(256, kernel_size=5, strides=1, padding=2),
        nn.MaxPool2D(pool_size=3, strides=2),
        nin_block(384, kernel_size=3, strides=1, padding=1),
        nn.MaxPool2D(pool_size=3, strides=2), nn.Dropout(0.5),
        nin_block(10, kernel_size=3, strides=1, padding=1),   # 标签类别数是10
        nn.GlobalAvgPool2D(),     # 全局平均池化层将窗口形状自动设置成输入的高和宽
        nn.Flatten())    # 将四维的输出转成二维的输出,其形状为(批量大小, 10)
X = nd.random.uniform(shape=(1, 1, 224, 224))
net.initialize()
for layer in net:
    X = layer(X)
    print(layer.name, 'output shape:\t', X.shape)

在这里插入图片描述

lr, num_epochs, batch_size, ctx = 0.1, 5, 128, d2l.try_gpu()
net.initialize(force_reinit=True, ctx=ctx, init=init.Xavier())
trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': lr})
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
d2l.train_ch5(net, train_iter, test_iter, batch_size, trainer, ctx,
              num_epochs)

总的来说,NiN通过创新的创建MLP卷积层,提高了网络的非线性表达的同时降低了参数量,用全局均值池化代替全连接层,极大的降低了参数量。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值