使用pytorch搭建自己的网络之GoogLeNet

一、introduction

在上一篇博客中提到了2014年分类比赛的第二名VGG,今天来自己动手搭建当年比赛的冠军GoogLeNet网络。tips:注意该网络中google的L是大写的,据说是为了致敬当年的LeNet。
很巧的是,这两个卷积神经网络的特点都是加深了网络层数,而GoogLeNet在此基础上提出了Inception网络结构,这是一个稀疏网络结构,但是能够产生稠密的数据,既能增加神经网络表现,又能保证计算资源的使用效率。
从2014年2016年,Inception经历了Inception v1、Inception v2、Inception v3、Inception v4这四个版本,本文主要介绍最原始的GoogLeNet网络结构。

二、Inception 结构

在这里插入图片描述
在介绍GoogLeNet网络之前,我们必须讲到Inception 结构。上图是原始版本的Inception,而下图是Inception v1的结构。由于原始版本的Inception中所有卷积核都在上一层的输出上来进行,而3x3、5x5的卷积核所需的计算量太大,会造成计算资源的浪费。在 NIN 模型中与1*1卷积层等效的 MLPConv 既能跨通道组织信息,提高网络的表达能力,同时可以对输出有效进行降维,因为GoogLeNet模型也借鉴了这种思想,在3x3前、5x5前、max pooling后分别加上1x1的卷积核,在不损失模型特征表示能力的前提下,尽量减少 filters 的数量,达到降低模型复杂度的目的。这也就形成了Inception v1的网络结构。
在这里插入图片描述
Inception v1结构的具体实现代码如下:

class Inception(nn.Module):
    #c1-c2为每条线路里的层的输出通道数
    def __init__(self, in_c, c1, c2, c3, c4):
        super(Inception, self).__init__()
        #线路1,单个1*1的卷积层
        self.p1_1 = nn.Conv2d(in_c, c1, kernel_size=1)
        #线路2, 1*1卷积层后接3*3卷积层
        self.p2_1 = nn.Conv2d(in_c, c2[0], kernel_size=1)
        self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)
        #线路3, 1*1卷积层后接5*5卷积层
        self.p3_1 = nn.Conv2d(in_c, c3[0], kernel_size=1)
        self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)
        #线路4, 3*3最大池化层后接 1*1卷积层
        self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
        self.p4_2 = nn.Conv2d(in_c, c4, kernel_size=1)

    def forward(self, x):
        p1 = nn.functional.relu(self.p1_1(x))
        p2 = nn.functional.relu(self.p2_2(nn.functional.relu(self.p2_1(x))))
        p3 = nn.functional.relu(self.p3_2(nn.functional.relu(self.p3_1(x))))
        p4 = nn.functional.relu(self.p4_2(self.p4_1(x)))
        return torch.cat((p1, p2, p3, p4), dim=1) #在通道维上连结输出

其中p1-p4分别是inception的四个分支,参数in_c表示输入的通道数,c1-c4表示每个分支的输出通道数。每个卷积层后接上relu激活函数。

三、GoogLeNet网络结构

在这里插入图片描述
网上比较流行的网络结构如上图所示,在进行代码实现时我们通过torch.nn.Sequential容器来堆叠实现其网络结构。

import torch
from torch import nn

#输入通道数和类别数
in_channels = 3
classes=40

class Flatten(nn.Module):
    def __init__(self):
        super(Flatten, self).__init__()

    def forward(self, input):
        input = nn.functional.dropout(input, p=0.4)
        return input.view(input.size(0), -1)

#全局平均池化层
class GlobalAvgPool2d(nn.Module):
    def __init__(self):
        super(GlobalAvgPool2d, self).__init__()
    def forward(self, x):
        return nn.functional.avg_pool2d(x, kernel_size=x.size()[2:])

b1 = nn.Sequential(
    nn.Conv2d(in_channels, 64, kernel_size=7, stride=2, padding=3),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)
b2 = nn.Sequential(
    nn.Conv2d(64, 64, kernel_size=1),
    nn.Conv2d(64, 192, kernel_size=3, padding=1),
    nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)
b3 = nn.Sequential(
    Inception(192, 64, (96, 128), (16, 32), 32),
    Inception(256, 128, (128, 192), (32, 96), 64),
    nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)
b4 = nn.Sequential(
    Inception(480, 192, (96, 208), (16, 48), 64),
    Inception(512, 160, (112, 224), (24, 64), 64),
    Inception(512, 128, (128, 256), (24, 64), 64),
    Inception(512, 112, (144, 288), (32, 64), 64),
    Inception(528, 256, (160, 320), (32, 128), 128),
    nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
)
b5 = nn.Sequential(
    Inception(832, 256, (160, 320), (32, 128), 128),
    Inception(832, 384, (192, 384), (48, 128), 128),
    GlobalAvgPool2d()
)

net = nn.Sequential(
    b1, b2, b3, b4, b5,
    Flatten(),
    nn.Linear(1024, classes)
)

四、Inception V1-V4

此部分转载于https://blog.csdn.net/hejin_some/article/details/78636586

Inception V1——构建了1x1、3x3、5x5的 conv 和3x3的 pooling 的分支网络,同时使用1X1卷积 和全局平均池化,扩宽卷积层网络宽度,增加了网络对尺度的适应性;

Inception V2——提出了 Batch Normalization,代替 Dropout 和 LRN,其正则化的效果让大型卷积网络的训练速度加快很多倍,同时收敛后的分类准确率也可以得到大幅提高,同时学习 VGG 使用两个3´3的卷积核代替5´5的卷积核,在降低参数量同时提高网络学习能力;

Inception V3——引入了 Factorization,将一个较大的二维卷积拆成两个较小的一维卷积,比如将3´3卷积拆成1´3卷积和3´1卷积,一方面节约了大量参数,加速运算并减轻了过拟合,同时增加了一层非线性扩展模型表达能力,除了在 Inception Module 中使用分支,还在分支中使用了分支(Network In Network In Network);

Inception V4——研究了 Inception Module 结合 Residual Connection,结合 ResNet 可以极大地加速训练,同时极大提升性能,在构建 Inception-ResNet 网络同时,还设计了一个更深更优化的 Inception v4 模型,能达到相媲美的性能。

这里还有一个关于GoogLeNet及其发展历程的详细讲解
https://my.oschina.net/u/876354/blog/1637819

五、writing in the end

不得不说GoogLeNet网络和Inception 结构设计得十分精妙,其中很多方法和思想也一直沿用至今。比如1X1的卷积层,BN层,使用多个小卷积核替代大的卷积核等等,在未来动手搭建自己的神经网络时也可以试试这些方法,或许能带来准确率的提升。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我可以给你一些关于使用PyTorch搭建HR-Net的建议:1. 先了解HR-Net的基本架构,然后熟悉PyTorch提供的相关API;2. 使用PyTorch搭建HR-Net的基本结构,并设置相应的参数;3. 调整参数,以获得最佳模型;4. 在测试集上进行验证,以确保模型具有良好的性能。 ### 回答2: HR-Net是一种用于人体关键点检测的神经网络模型,我们可以使用PyTorch搭建HR-Net。在搭建HR-Net之前,我们需要进行一些准备工作。 首先,我们需要安装PyTorch库。可以通过以下命令安装PyTorch: ``` pip install torch torchvision ``` 然后,我们需要下载HR-Net的代码和预训练的权重。可以在GitHub上找到HR-Net的代码库,并下载。下载完成后,解压缩代码包。 接下来,我们可以在PyTorch中定义HR-Net的网络结构。HR-Net基于两个主要的网络模块:骨干网络和多分支特征融合模块。 在骨干网络中,我们可以选择使用一些常见的神经网络模型,如ResNet、AlexNet等。我们可以在PyTorch中创建这些骨干网络,并将其作为HR-Net的输入。 在多分支特征融合模块中,我们通过将不同尺度的特征图进行融合,来提高人体关键点检测的准确性。我们可以在PyTorch中实现这个多分支特征融合模块,并将其添到HR-Net中。 最后,我们可以载HR-Net的预训练权重,并将其用于人体关键点检测任务。我们可以使用PyTorch的数据载器来载训练数据,并使用预定义的损失函数和优化器来训练模型。 使用PyTorch搭建HR-Net可以使我们更轻松地实现人体关键点检测任务,并利用PyTorch的丰富功能来优化和扩展HR-Net模型。 ### 回答3: 使用PyTorch搭建HR-Net可以通过以下步骤完成: 1. 安装PyTorch:首先要在计算机上安装PyTorch库,可以通过在终端或命令提示符中运行适用于您的系统的安装命令来完成。 2. 导入必要的库:在Python脚本中,导入PyTorch以及其他必要的库,如numpy、matplotlib等。 3. 构建HR-Net模型:HR-Net是一种深度卷积神经网络体系结构,它具有多个分支并行处理低分辨率和高分辨率特征。可以使用PyTorch的nn.Module类构建HR-Net模型,并定义需要的卷积、池化、Batch Normalization等操作层。 4. 定义前向传播函数:在HR-Net模型类中,定义一个前向传播函数,该函数定义了输入数据通过模型时的计算流程。在这个函数中,可以将输入数据传递到HR-Net的各个分支,然后将其联合起来形成最终的输出。 5. 定义损失函数和优化器:为了训练HR-Net模型,需要定义一个损失函数来度量模型的输出和真实标签之间的差距,并选择一个优化器来更新模型的参数。PyTorch提供了各种损失函数和优化器的选项,可以根据具体问题的需求选择合适的函数和优化器。 6. 训练模型:使用已定义的损失函数和优化器,在训练数据上进行模型的训练。通过将训练数据输入到HR-Net模型中,并计算其输出与真实标签之间的损失,根据这个损失来更新模型的参数。 7. 测试模型:在训练完成后,可以使用测试数据来评估模型的性能。将测试数据输入到HR-Net模型中,获取模型的预测输出,并与真实标签进行比较,可以计算一些评价指标,例如准确率、精确率、召回率等。 8. 调整模型和超参数:根据测试结果,可以对模型和超参数进行调整,以优化模型的性能。可以更改模型的结构、增或减少训练数据,调整学习率等。 9. 保存和载模型:在训练完成后,可以将模型保存到磁盘上,以便后续使用。同时,也可以从保存的模型文件中载已经训练好的模型,并在新的数据上进行预测。 以上是使用PyTorch搭建HR-Net的一般步骤,具体实现过程中可以根据需要进行进一步的细化和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值