Pytorch 目标检测学习 Day 3

详解GoogLeNetv1

GoogLeNet-1 以下简称为Inception v1

好处:

Inception v1网络是一个精心设计的22层卷积网络,并提出了具有良好局部特征结构的Inception模块,即对特征并行地执行多个大小不同的卷积运算与池化,最后再拼接到一起。由于1×1、3×3和5×5的卷积运算对应不同的特征图区域,因此这样做的好处是可以得到更好的图像表征信息。

使用三个不同大小的卷积核进行卷积运算,同时还有一个最大值池化,通过将这4部分级联起来(通道拼接),送入下一层

 在上述模块的基础上,为进一步降低网络参数量,Inception又增加了多个1×1的卷积模块。这种1×1的模块可以先将特征图降维,再送给3×3和5×5大小的卷积核,由于通道数的降低,参数量也有了较大的减少。

思考:为什么先最大值池化后1*1卷积呢? 

Inception v1网络一共有9个上述堆叠的模块,共有22层,在最后的Inception模块处使用了全局平均池化。

在第3个与第6个Inception模块输出后执行Softmax并计算损失,在训练时和最后的损失一并回传。

代码详解:

import torch
from torch import nn
import torch.nn.functional as F
#定义包含conv与ReLU的基础卷积类
class BasicConv2d(nn.Module):
    def __init__(self,in_channels,out_channels,kernel_size,padding=0):
        super(BasicConv2d,self).__init__()
        self.conv = nn.Conv2d(in_channels,out_channels,kernel_size,padding=padding)
    def forward(self,x):
            x = self.conv(x)
            return F.relu(x,inplace=True)
#Inceptionv1的类,初始化需要提供各个模块通道数大小
class Inceptionv1(nn.Module):
    def __init__(self,in_dim,hid_1_1,hid_2_1,hid_2_3,hid_3_1,out_3_5,out_4_1):
        super(Inceptionv1,self).__init__()
        #下面是四个子模块各自的网格定义
        self.branch1x1 = BasicConv2d(in_dim,hid_1_1,1)
        self.branch3x3 = nn.Sequential(
            BasicConv2d(in_dim,hid_2_1,1),
            BasicConv2d(hid_2_1,hid_2_3,3,padding=1)
        )
        self.branch5x5 = nn.Sequential(
            BasicConv2d(in_dim,hid_3_1,1),
            BasicConv2d(hid_3_1,out_3_5,5,padding=2)
        )
        self.branch_pool = nn.Sequential(
            nn.MaxPool2d(3,stride=1,padding=1),
            BasicConv2d(in_dim,out_4_1,1)
        )
    def forward(self,x):
        b1 = self.branch1x1(x)
        b2 = self.branch3x3(x)
        b3 = self.branch5x5(x)
        b4 = self.branch_pool(x)
        #将这四个子模块沿着通道方向进行拼接
        output = torch.cat((b1,b2,b3,b4),dim=1)
        return output
# a= torch.randn(2,3,3,4)
# b = torch.cat((a,a),dim=3)
# print(b.size())

验证:

import torch
from inception_v1 import Inceptionv1

net = Inceptionv1(3,64,32,64,64,96,32)

print(net)

inputs = torch.randn(1,3,256,256)

output = net(inputs)
print(output.size())

结果:

Inceptionv1(
  (branch1x1): BasicConv2d(
    (conv): Conv2d(3, 64, kernel_size=(1, 1), stride=(1, 1))
  )
  (branch3x3): Sequential(
    (0): BasicConv2d(
      (conv): Conv2d(3, 32, kernel_size=(1, 1), stride=(1, 1))
    )
    (1): BasicConv2d(
      (conv): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    )
  )
  (branch5x5): Sequential(
    (0): BasicConv2d(
      (conv): Conv2d(3, 64, kernel_size=(1, 1), stride=(1, 1))
    )
    (1): BasicConv2d(
      (conv): Conv2d(64, 96, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    )
  )
  (branch_pool): Sequential(
    (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=False)
    (1): BasicConv2d(
      (conv): Conv2d(3, 32, kernel_size=(1, 1), stride=(1, 1))
    )
  )
)
torch.Size([1, 256, 256, 256])

GoogLeNetv2

在Inception v1网络的基础上,随后又出现了多个Inception版本。Inception v2进一步通过卷积分解与正则化实现更高效的计算,增加了BN层,同时利用两个级联的3×3卷积取代了Inception v1版本中的5×5卷积,

更进一步,Inception v2将n×n的卷积运算分解为1×n与n×1两个卷积,如图3.16所示,这种分解的方式可以使计算成本降低33%。

 

Inception v3在Inception v2的基础上,使用了RMSProp优化器,在辅助的分类器部分增加了7×7的卷积,并且使用了标签平滑技术。

Inception v4则是将Inception的思想与残差网络进行了结合,显著提升了训练速度与模型准确率,这里对于模块细节不再展开讲述。至于残差网络这一里程碑式的结构,正是由下一节的网络ResNet引出的。

有机会将会继续补充

时间:2020年1月3日

 

 

おすすめ

転載: blog.csdn.net/abc123mma/article/details/112135963