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卷积层使输入和输出层中间有了隐藏层,才相当于多层感知机。

相关推荐
学习星球2 分钟前
AI 原生游戏开发:Godot 4 + AI Agent 全栈指南(Ziva 3 / Godot MCP 深度实战)
人工智能·游戏引擎·godot
知几蜗牛12 分钟前
GPT-6 Astra来了:AI真的开始像“数字员工”一样工作了吗?
人工智能
夏文强14 分钟前
DeepSeek Harness 可观测性:用 OpenTelemetry 把会话遥测出去
人工智能·开源·大模型·agent·deepseek
艾莉丝努力练剑14 分钟前
【AI大模型接入SDK】Gemini模型接入知识体系
java·开发语言·网络·人工智能·网络协议·学习·http
AC赳赳老秦15 分钟前
电力能源公开数据采集实操:用 OpenClaw 合规抓取电网电价与发电量数据,生成区域能源供需分析报告
大数据·数据库·人工智能·python·php·deepseek·openclaw
一切皆是因缘际会16 分钟前
资源的适配
大数据·人工智能·算法
计算机编程-吉哥17 分钟前
小麦叶病害识别系统:基于MobileNet的智能农业病害检测实战【计算机毕业设计选题推荐、深度学习】
人工智能·深度学习·毕业设计·课程设计·计算机毕业设计选题·机器学习毕业设计·大数据毕业设计选题推荐
新知图书19 分钟前
第11章 智能体应用设计模式
人工智能·智能体
EDPJ20 分钟前
(2026|CVPR|安大,可学习正常/异常 token,空间感知交叉注意力)VisualAD:基于 ViT 的语言无关零样本异常检测
深度学习·计算机视觉·缺陷检测·异常检测
LlmCraft|大模型工程实践23 分钟前
09 大语言模型(LLM)演进与 Prompt 入门
人工智能·语言模型·prompt