【网络结构】GoogLeNet-Incepetion 系列

GoogLeNet-Incepetion V1

概述

作者想要实现在不增加过多的计算资源的同时,增加网络的深度和宽度,而要实现它,核心就是将全连接甚至一般的卷积都转化为稀疏连接。前者可以使用全局平均池化处理(不仅可以减少参数,还有利于迁移学习),但是对于后者而言,很困难。因为大部分的硬件都是对密集矩阵进行加速的,稀疏矩阵很难加速,所以作者提出了Incepetion 结构,构建密集的块结构来近似最优的稀疏结构(原理是相关研究表明将稀疏矩阵聚类为较为密集的子矩阵可以提高计算性能,这里反用了一下)。

一些思考

转载自:这里
Inception Net设计的思考是什么?(好的深度网络有哪些设计原则)
逐层构造网络:如果数据集的概率分布能够被一个神经网络所表达,那么构造这个网络的最佳方法是逐层构筑网络,即将上一层高度相关的节点连接在一起。几乎所有效果好的深度网络都具有这一点,不管AlexNet VGG堆叠多个卷积,googLeNet堆叠多个inception模块,还是ResNet堆叠多个resblock。

稀疏的结构:人脑的神经元连接就是稀疏的,因此大型神经网络的合理连接方式也应该是稀疏的。稀疏的结构对于大型神经网络至关重要,可以减轻计算量并减少过拟合。 卷积操作(局部连接,权值共享)本身就是一种稀疏的结构,相比于全连接网络结构是很稀疏的。

符合Hebbian原理: Cells that fire together, wire together. 一起发射的神经元会连在一起。 相关性高的节点应该被连接而在一起。

inception中 1×1的卷积恰好可以融合三者。我们一层可能会有多个卷积核,在同一个位置但在不同通道的卷积核输出结果相关性极高。一个1×1的卷积核可以很自然的把这些相关性很高,在同一个空间位置,但不同通道的特征结合起来。而其它尺寸的卷积核(3×3,5×5)可以保证特征的多样性,因此也可以适量使用。于是,这就完成了inception module下图的设计初衷:4个分支。

细节

左边是朴素版本,右边使用了1x1卷积降低计算量。
在这里插入图片描述
我理解的Incepetion模块作用:1、让网络自己学习,决定是使用卷积还是池化,使用哪个池化,还是使用其中的一部分操作,或者全部操作。有点像残差连接的思想,模型可以选择什么都不做恒等映射,也可以选择在原来的基础上做一点什么。模型的选择就是参数的更新情况,不做这个操作就是学习到的参数都是0,不让这个部分起到什么作用。2、多尺度的特征提取、特征融合

一些补充:

  1. 网络越到后面,语义级别高了,而且每个特征所涉及的感受野也更大了,因此随着层数的增加,3x3和5x5卷积的比例也要增加。
  2. 1x1卷积一方面降低计算量,另一方面多使用一次非线性函数,增加模型的表征能力,还可以实现跨通道信息交融

简答实现

import paddle
import paddle.nn as nn


class BasicConv2d(nn.Layer):
    def __init__(self,in_channels,out_channels,kernel_size,stride,padding):
        super(BasicConv2d, self).__init__()
        self.conv=nn.Conv2D(in_channels,out_channels,kernel_size,stride,padding)
        self.relu=nn.ReLU()

    def forward(self,x):
        x=self.conv(x)
        x=self.relu(x)
        return x

class Inception1(nn.Layer):
    # 参数分别表示
    # 输入通道数
    # 第一个块的输出通道数
    # 第二个块使用的降维通道数和输出通道数
    # 第三个块使用的降维通道数和输出通道数
    # 第四个块的输出通道数
    def __init__(self,in_channels,out_channels1,out_channels3reduce,out_channels3,out_channels5reduce,out_channels5,out_channels_pool):
        super(Inception1, self).__init__()
        # 注意:下面的卷积和池化操作都是不改变图像尺寸的,不然不能进行concat操作
        self.conv1=BasicConv2d(in_channels,out_channels1,1,1,0)
        self.conv3=nn.Sequential(
            BasicConv2d(in_channels, out_channels3reduce, 1, 1, 0),
            BasicConv2d(out_channels3reduce, out_channels3, 3, 1, 1),
        )
        self.conv5 = nn.Sequential(
            BasicConv2d(in_channels, out_channels5reduce, 1, 1, 0),
            BasicConv2d(out_channels5reduce, out_channels5, 5, 1, 2),
        )
        self.pool = nn.Sequential(
            nn.MaxPool2D(3,1,1),
            BasicConv2d(in_channels, out_channels_pool, 1, 1, 0),
        )


    def forward(self,x):
        conv1=self.conv1(x)
        conv3=self.conv3(x)
        conv5=self.conv5(x)
        pool=self.pool(x)
        out=paddle.concat([conv1,conv3,conv5,pool],axis=1)
        return out

def main():
    x=paddle.randn((1,5,24,24))
    inception1=Inception1(5,10,1,10,1,10,10)
    print(inception1(x).shape)

if __name__ == '__main__':
    main()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值