对于使用卷积神经网络加全连接层的结构而言,对于全连接的参数的巨大了,对于简单的任务容易造成过拟合,且会增加模型的额外开销,例如alexnet,vgg等,全连接层的开销会随着参数的增加而爆炸式增长。
nin旨在使用1x1的卷积层来获得如全连接层的作用,他主要将每个类别用一个通道来表示,即引入全局平均池化将每一个通道提出一个值来作为分类的类别,并且对于卷积层而言他的参数量表示为c-i x c_o x K**2,也就是与输入输出通道数和卷积核大小有关。由此可见,nin可以有效的减少参数个数,缓解过拟合问题。
----------------------------------------------------------------------------->
代码如下
import torch
import torch.nn as nn
class reshape_data(nn.Module):
def forward(self,X):
return X.view(-1,1,224,224)
def nin_block(in_channels, out_channels,kernel_size,strdes,padding):
return nn.Sequential(
nn.Conv2d(in_channels,out_channels,kernel_size=kernel_size,padding=padding,stride=strdes),
nn.ReLU(),
nn.Conv2d(out_channels,out_channels,kernel_size=1),
nn.ReLU(),
nn.Conv2d(out_channels,out_channels,kernel_size=1),
nn.ReLU(),
)
class ninnet(nn.Module):
def __init__(self):
super().__init__()
self.nin = nn.Sequential(
nin_block(1,96,kernel_size=11,strdes=4,padding=0),
nn.MaxPool2d(3,2),
nin_block(96,256,kernel_size=5,strdes=1,padding=2),
nn.MaxPool2d(3,2),
nin_block(256,384,kernel_size=3,strdes=1,padding=1),
nn.MaxPool2d(3,2),
nin_block(384,10,kernel_size=3,strdes=1,padding=1),
nn.AdaptiveAvgPool2d((1, 1)),
nn.Flatten()
)
self.reshape_data = reshape_data()
def forward(self,X):
X = self.reshape_data(X)
output = self.nin(X)
return output
模型结构如下:
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])
Sequential output shape: torch.Size([1, 10, 5, 5])
AdaptiveAvgPool2d output shape: torch.Size([1, 10, 1, 1])
Flatten output shape: torch.Size([1, 10])
其余部分请参见前面笔记,感谢您的查阅。