新闻中心

《动手学深度学习》Paddle 版源码-5.08章(NIN)

2025-08-01
浏览次数:
返回列表
网络中的网络(NiN)不同于LeNet、AlexNet和VGG,它串联多个含卷积层和1×1卷积层(替代全连接层)的NiN块构建深层网络。其用输出通道数等于标签类别数的NiN块加全局平均池化层替代全连接输出层,可减小参数、缓解过拟合,训练类似AlexNet但学习率更大,思想影响后续卷积神经网络设计。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

《动手学深度学习》paddle 版源码-5.08章(nin) -

网络中的网络(NiN)

前几节介绍的LeNet、AlexNet和VGG在设计上的共同之处是:先以由卷积层构成的模块充分抽取空间特征,再以由全连接层构成的模块来输出分类结果。其中,AlexNet和VGG对LeNet的改进主要在于如何对这两个模块加宽(增加通道数)和加深。本节我们介绍网络中的网络(NiN)[1]。它提出了另外一个思路,即串联多个由卷积层和“全连接”层构成的小网络来构建一个深层网络。

NiN块

我们知道,卷积层的输入和输出通常是四维数组(样本,通道,高,宽),而全连接层的输入和输出则通常是二维数组(样本,特征)。如果想在全连接层后再接上卷积层,则需要将全连接层的输出变换为四维。回忆在“多输入通道和多输出通道”一节里介绍的1×11×1卷积层。它可以看*连接层,其中空间维度(高和宽)上的每个元素相当于样本,通道相当于特征。因此,NiN使用1×11×1卷积层来替代全连接层,从而使空间信息能够自然传递到后面的层中去。图5.7对比了NiN同AlexNet和VGG等网络在结构上的主要区别。

《动手学深度学习》Paddle 版源码-5.08章(NIN) -        

NiN块是NiN中的基础块。它由一个卷积层加两个充当全连接层的1×11×1卷积层串联而成。其中第一个卷积层的超参数可以自行设置,而第二和第三个卷积层的超参数一般是固定的。

In [ ]
import paddleimport paddle.nn as nnimport numpy as npimport warnings
warnings.filterwarnings("ignore", category=Warning) # 过滤报警信息class Nin(nn.Layer):
    def __init__(self, num_channels, num_filters, kernel_size, strides, padding):
        super(Nin, self).__init__()
        model = [
            nn.Conv2D(num_channels, num_filters, kernel_size, stride=strides, padding=padding),
            nn.ReLU(),
            nn.Conv2D(num_filters, num_filters, 1),
            nn.ReLU(),
            nn.Conv2D(num_filters, num_filters, 1),
            nn.ReLU()
        ]
        self.model = nn.Sequential(*model)    def forward(self, X):
        return self.model(X)
   

NiN模型

NiN是在AlexNet问世不久后提出的。它们的卷积层设定有类似之处。NiN使用卷积窗口形状分别为11×1111×11、5×55×5和3×33×3的卷积层,相应的输出通道数也与AlexNet中的一致。每个NiN块后接一个步幅为2、窗口形状为3×33×3的最大池化层。

Motiff妙多 Motiff妙多

Motiff妙多是一款AI驱动的界面设计工具,定位为“AI时代设计工具”

Motiff妙多 334 查看详情 Motiff妙多

除使用NiN块以外,NiN还有一个设计与AlexNet显著不同:NiN去掉了AlexNet最后的3个全连接层,取而代之地,NiN使用了输出通道数等于标签类别数的NiN块,然后使用全局平均池化层对每个通道中所有元素求平均并直接用于分类。这里的全局平均池化层即窗口形状等于输入空间维形状的平均池化层。NiN的这个设计的好处是可以显著减小模型参数尺寸,从而缓解过拟合。然而,该设计有时会造成获得有效模型的训练时间的增加。

In [ ]
class Net(nn.Layer):
    def __init__(self, num_channels, class_dim):
        super(Net, self).__init__()
        model = [
            Nin(num_channels, 96, 11, strides=4, padding=0),
            nn.MaxPool2D(kernel_size=3, stride=2),
            Nin(96, 256, 5, strides=1, padding=2),
            nn.MaxPool2D(kernel_size=3, stride=2),
            Nin(256, 384, 3, strides=1, padding=1),
            nn.MaxPool2D(kernel_size=3, stride=2),
            nn.Dropout(),            # 标签类别数是10
            Nin(384, 10, 3, strides=1, padding=1),
            paddle.fluid.dygraph.Pool2D(pool_type='max', global_pooling=True)
        ]
        self.model = nn.Sequential(*model)    def forward(self, X):
        Y = self.model(X)
        Y = paddle.flatten(Y, start_axis=1)        return Y

net = Net(3, 10)
X = paddle.to_tensor(np.random.uniform(-1., 1., [5, 3, 224, 224]).astype('float32'))
Y = net(X)print(Y.shape)
       
[5, 10]
       

我们构建一个数据样本来查看每一层的输出形状。

In [ ]
net = Net(1, 10)
param_info = paddle.summary(net, (1, 1, 224, 224))print(param_info)
       
---------------------------------------------------------------------------
 Layer (type)       Input Shape          Output Shape         Param #    
===========================================================================
   Conv2D-13     [[1, 1, 224, 224]]    [1, 96, 54, 54]        11,712     
    ReLU-13      [[1, 96, 54, 54]]     [1, 96, 54, 54]           0       
   Conv2D-14     [[1, 96, 54, 54]]     [1, 96, 54, 54]         9,312     
    ReLU-14      [[1, 96, 54, 54]]     [1, 96, 54, 54]           0       
   Conv2D-15     [[1, 96, 54, 54]]     [1, 96, 54, 54]         9,312     
    ReLU-15      [[1, 96, 54, 54]]     [1, 96, 54, 54]           0       
     Nin-5       [[1, 1, 224, 224]]    [1, 96, 54, 54]           0       
  MaxPool2D-4    [[1, 96, 54, 54]]     [1, 96, 26, 26]           0       
   Conv2D-16     [[1, 96, 26, 26]]     [1, 256, 26, 26]       614,656    
    ReLU-16      [[1, 256, 26, 26]]    [1, 256, 26, 26]          0       
   Conv2D-17     [[1, 256, 26, 26]]    [1, 256, 26, 26]       65,792     
    ReLU-17      [[1, 256, 26, 26]]    [1, 256, 26, 26]          0       
   Conv2D-18     [[1, 256, 26, 26]]    [1, 256, 26, 26]       65,792     
    ReLU-18      [[1, 256, 26, 26]]    [1, 256, 26, 26]          0       
     Nin-6       [[1, 96, 26, 26]]     [1, 256, 26, 26]          0       
  MaxPool2D-5    [[1, 256, 26, 26]]    [1, 256, 12, 12]          0       
   Conv2D-19     [[1, 256, 12, 12]]    [1, 384, 12, 12]       885,120    
    ReLU-19      [[1, 384, 12, 12]]    [1, 384, 12, 12]          0       
   Conv2D-20     [[1, 384, 12, 12]]    [1, 384, 12, 12]       147,840    
    ReLU-20      [[1, 384, 12, 12]]    [1, 384, 12, 12]          0       
   Conv2D-21     [[1, 384, 12, 12]]    [1, 384, 12, 12]       147,840    
    ReLU-21      [[1, 384, 12, 12]]    [1, 384, 12, 12]          0       
     Nin-7       [[1, 256, 12, 12]]    [1, 384, 12, 12]          0       
  MaxPool2D-6    [[1, 384, 12, 12]]     [1, 384, 5, 5]           0       
   Dropout-2      [[1, 384, 5, 5]]      [1, 384, 5, 5]           0       
   Conv2D-22      [[1, 384, 5, 5]]      [1, 10, 5, 5]         34,570     
    ReLU-22       [[1, 10, 5, 5]]       [1, 10, 5, 5]            0       
   Conv2D-23      [[1, 10, 5, 5]]       [1, 10, 5, 5]           110      
    ReLU-23       [[1, 10, 5, 5]]       [1, 10, 5, 5]            0       
   Conv2D-24      [[1, 10, 5, 5]]       [1, 10, 5, 5]           110      
    ReLU-24       [[1, 10, 5, 5]]       [1, 10, 5, 5]            0       
     Nin-8        [[1, 384, 5, 5]]      [1, 10, 5, 5]            0       
   Pool2D-2       [[1, 10, 5, 5]]       [1, 10, 1, 1]            0       
===========================================================================
Total params: 1,992,166
Trainable params: 1,992,166
Non-trainable params: 0
---------------------------------------------------------------------------
Input size (MB): 0.19
Forward/backward pass size (MB): 28.08
Params size (MB): 7.60
Estimated Total Size (MB): 35.87
---------------------------------------------------------------------------

{'total_params': 1992166, 'trainable_params': 1992166}
       

训练模型

我们依然使用Fashion-MNIST数据集来训练模型。NiN的训练与AlexNet和VGG的类似,但这里使用的学习率更大。

In [ ]
import paddleimport paddle.vision.transforms as Tfrom paddle.vision.datasets import FashionMNIST# 数据集处理transform = T.Compose([
    T.Resize(64),
    T.Transpose(),
    T.Normalize([127.5], [127.5]),
])
train_dataset = FashionMNIST(mode='train', transform=transform)
val_dataset = FashionMNIST(mode='test', transform=transform)# 模型定义model = paddle.Model(Net(1, 10))# 设置训练模型所需的optimizer, loss, metricmodel.prepare(
    paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters()),
    paddle.nn.CrossEntropyLoss(),
    paddle.metric.Accuracy(topk=(1, 5)))# 启动训练、评估model.fit(train_dataset, val_dataset, epochs=2, batch_size=64, log_freq=100)
       
The loss value printed in the log is the current step, and the metric is the *erage value of previous step.
Epoch 1/2
step 100/938 - loss: 2.0404 - acc_top1: 0.1755 - acc_top5: 0.6389 - 353ms/step
step 200/938 - loss: 1.9281 - acc_top1: 0.1902 - acc_top5: 0.6545 - 355ms/step
step 300/938 - loss: 1.9774 - acc_top1: 0.2047 - acc_top5: 0.6621 - 355ms/step
step 400/938 - loss: 2.0007 - acc_top1: 0.2241 - acc_top5: 0.6729 - 356ms/step
step 500/938 - loss: 1.9303 - acc_top1: 0.2351 - acc_top5: 0.6763 - 357ms/step
       

小结

  • NiN重复使用由卷积层和代替全连接层的1×11×1卷积层构成的NiN块来构建深层网络。
  • NiN去除了容易造成过拟合的全连接输出层,而是将其替换成输出通道数等于标签类别数的NiN块和全局平均池化层。
  • NiN的以上设计思想影响了后面一系列卷积神经网络的设计。

以上就是《动手学深度学习》Paddle 版源码-5.08章(NIN)的详细内容,更多请关注其它相关文章!


# 区别  # 四维  # 科大  # 戛纳  # 开源  # 首款  # 系列产品  # 之处  # 多个  # 中文网  # type  # latte  # ai  # 更大  # 舞蹈网站推广方案策划书  # 鹤岗网站优化公司哪家好  # 佛山营销推广哪家有名  # 网站建设资讯  # 网站推广认可r火28星细心  # 宜昌seo整站优化方法  # 河南网站优化推广有用吗  # 丹东排名优化seo公司  # 保定建设厅网站  # 百度网站优化技巧 


相关栏目: 【 行业资讯67740 】 【 技术百科0 】 【 网络运营39195


相关推荐: awk命令如何对两列加分隔符  电动车power灯亮红灯是什么意思  如何打开命令框  什么是域名解析地址  春运订票什么时候抢票  燃气热水器上的power是什么意思  爱奇艺会员qq登录可以几个人用?  微信最多可以加多少好友  openwrt有什么用  360n6锁屏壁纸怎么设置  单片机计时程序怎么写  电脑如何查看固态硬盘  360f4怎么取消百变壁纸  远程桌面如何发送命令  如何进入cmd命令行  typescript适合什么用  苹果16有哪些款式的  bugly是什么  电焊机power和oc是什么意思  市盈率是负数是什么意思  美食音乐每日推荐怎么写  固态硬盘如何拆除  春运返程如何抢票成功  什么是泛域名解析  typescript是什么类型的语言  满射为什么没有逆映射  固态硬盘如何启动  路由器上的power按钮是什么意思  命令行如何打开打印机  命令控制台如何执行sql文件  如何设置从固态硬盘启动  2026年将会大爆发的15个新科技  苹果电脑如何输入命令  为什么夸克流畅播失败  得物怎样不扣手续费 如何通过得物不支付手续费  8k是多少钱  如何找出命令行  苹果16有哪些黑科技  华为如何面对苹果16  j*a数组对象怎么取  市盈率动亏损是什么意思  datediff快捷函数怎么用  什么软件能下载夸克视频  typescript 如何使用  typescript什么意思  ao3镜像网站永久地址入口  命令行如何运行j*a  折叠屏手机选择哪个好  如何用命令打开光驱  ping命令如何看问题 

搜索