7.3 详解NiN模型--首次使用多层感知机(1x1卷积核)替换掉全连接层的模型

一.前提知识

多层感知机:由一个输入层,一个或多个隐藏层和一个输出层组成。(至少有一个隐藏层,即至少3层)

全连接层:是MLP的一种特殊情况,每个节点都与前一层的所有节点连接,全连接层可以解决线性可分问题,无法学习到非线性特征。(只有输入和输出层)

二.NiN模型特点

NiN与过去模型的区别 :AlexNet和VGG对LeNet的改进在于如何扩大加深这两个模块。他们都使用了全连接层,使用全连接层就可能完全放弃表征的空间结构。

NiN放弃了使用全连接层,而是使用两个1x1卷积层(将空间维度中的每个像素视为单个样本,将通道维度视为不同特征。),相当于在每个像素的通道上分别使用多层感知机

优点:NiN去除了全连接层,可以减少过拟合,同时显著减少NiN的参数数量

三.模型架构

四.代码

python 复制代码
import torch
from torch import nn
from d2l import torch as d2l
import time
python 复制代码
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(),
        # 两个带有ReLU激活函数的 1x1卷积层
        nn.Conv2d(out_channels,out_channels,kernel_size=1),nn.ReLU(),
        nn.Conv2d(out_channels,out_channels,kernel_size=1),nn.ReLU()
    )
python 复制代码
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)),
    # 将(样本,通道,w,h) = (批量,10,1,1),四维的输出转成2维的输出,其形状为(批量大小,10)
    nn.Flatten()
)
python 复制代码
X = torch.rand(size=(1,1,224,224))
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape:\t',X.shape)
python 复制代码
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])
AdaptiveAvgPool2d output shape:	 torch.Size([1, 10, 1, 1])
Flatten output shape:	 torch.Size([1, 10])

六.不同参数训练结果

学习率是0.1的情况

python 复制代码
# 训练模型
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())

学习率是0.05的情况(提升了6个点)

python 复制代码
'''开始计时'''
start_time = time.time()
# 训练模型
lr,num_epochs,batch_size = 0.05,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())
'''计时结束'''
end_time = time.time()
run_time = end_time - start_time
# 将输出的秒数保留两位小数
print(f'{round(run_time,2)}s')

学习率为0.01,批次等于30的情况(反而下降了)

思考

为什么NiN块中有两个1x1卷积层?

从NiN替换掉全连接层,使用多层感知机角度来说:

因为1个1x1卷基层相当于全连接层,两个1x1卷积层使输入和输出层中间有了隐藏层,才相当于多层感知机。

相关推荐
xiaoyaohou11几秒前
014、Neck结构改进(二):自适应空间特征金字塔(ASPP)的引入
深度学习·计算机视觉·cnn
Lucas_coding1 分钟前
【语音相关ASR】FunASR 离线语音识别与FunASR热词优化
人工智能·语音识别·xcode
七颗糖很甜2 分钟前
基于 OpenCV 的 FY2 云顶图云块追踪算法实现
人工智能·opencv·算法
__Wedream__3 分钟前
NTIRE 2026 Challenge on Efficient Super-Resolution——冠军方案解读
人工智能·深度学习·算法·计算机视觉·超分辨率重建
FL16238631297 分钟前
基于深度学习mediape实现人员跌倒人体姿势跌倒检测算法源码+说明文件
人工智能·深度学习·算法
James5067 分钟前
NewAPI使用
人工智能·docker·newapi
FAFU_kyp7 分钟前
AP2 执行流程详解
人工智能
AI英德西牛仔9 分钟前
手机怎么把AI对话导出
人工智能·ai·智能手机·豆包·deepseek·ds随心转
Old Uncle Tom12 分钟前
Claude Code 记忆系统架构分析
人工智能·ai·系统架构·agent
空中湖14 分钟前
大模型修炼秘籍 第一卷灵气采集 第一章:天地为炉——海量数据之采集
人工智能