在这之前,在好好学一下1x1卷积层的知识:
其实就是改变维度和增加非线性性
https://blog.csdn.net/yaochunchu/article/details/95527760?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7EHighlightScore-3.queryctrv2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7EHighlightScore-3.queryctrv2&utm_relevant_index=2
NiN,用得不多,但是它提出了很多被其他网络用到的概念。
三个网络的全连接层的参数个数:
全连接层:参数非常多,基本上一个网络的绝大多数参数都分布在全连接层,参数多不仅占用很多内存和带宽,(不断访问内存占用了大量的时间),同时容易带来非常严重的过拟合问题。
NiN思想:我不要全连接层,我要用卷积层替代掉全连接层。
NiN块:一个卷积层,跟着两个1x1的卷积层(可以认为1x1的卷积层就是全连接层)
NiN架构:
1、没有全连接层。
2、交替使用NiN块和步幅为2的最大池化层,逐步减少高宽并增大通道数。
3、最后使用全局的平均池化层得到输出,其输出通道是类别数。
全局平均池化层的高宽 = = 输入的高宽 (我对每一个通道,拿出最大值)
总结:
NiN块使用卷积层和两个1x1的卷积层,后者对于每个像素增加了非线性性;
NiN使用全局平均池化层来代替VGG和AlexNet的全连接层。(全局平均:是因为会将原高宽变为1x1,如果选最大,会损失的信息实在是太多了)
因为使用的参数更少,不容易过拟合。
Q&A:
没学到什么东西感觉。
结果:可以看到基本没有过拟合的问题,另外还不如AlexNet准确率高,而且还没有AlexNet快,所以NiN一开始说的就是,NiN最大的贡献是对1x1卷积层的利用,而不是这个网络本身有多大能力,这个网络本身用的并不是很多。
总之一件事,要么更宽,要么更深,MLP看起来更宽的极端,NiN看起来更深的极端,而VGG比较中庸。
代码
import torch from torch import nn from d2l import torch as d2l 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(), # 用来当全连接层的1x1卷积 nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU()) net = nn.Sequential( # 可以看到,通道数是完全基于AlexNet写的 nin_block(1, 96, kernel_size=11, strides=4, padding=0),# 因为用的灰度图,所以输入通道数为1 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), # 到这里,大小是1x384x高x宽,1是批量大小 # 标签类别数是10 nin_block(384, 10, kernel_size=3, strides=1, padding=1),# 到这里,大小是1x10x高x宽 nn.AdaptiveAvgPool2d((1, 1)), # 全局平均池化层,高宽都会变成1,大小就成了1x10x1x1 # 将四维的输出转成二维的输出,其形状为(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 = d2l.load_data_fashion_mnist(batch_size, resize=224) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())