GoogLeNet网络
Inception 结构。inception的作用:增加网络深度和宽度的同时减少参数
1x1的卷积核如何起到降维的作用呢?目的是为了降维(减小深度),减少模型训练参数,减少计算量。
辅助分类器
AlexNet和VGG都只有一个输出层 ,而GoogLeNet有三个输出层(其中有两个辅助分类层,一个主分类器,两个辅助分类器的结构一样)
在训练模型时,将两个辅助分类器的损失乘以权重(论文中是0.3)加到网络的整体损失上,再进行反向传播。
(1)第一层是我们的平均下采样操作,池化核大小是5*5 ,步距是等于3
(2)采用128个卷积核大小为1*1的卷积层进行卷积处理,目的是为了降低维度,并且使用的是ReLU激活函数
(3)采用节点个数为1024的全连接层,同样使用ReLU激活函数
(4)全连接层与全连接层之间使用dropout函数,以70%的比例,随机失活神经元
(5)采用节点个数为1000的全连接层,这里的节点个数是对应我们的类别个数!!!
(6)通过softmax函数得到我们的概率分布
辅助分类器的两个分支有什么用呢?
作用一:可以把他看做inception网络中的一个小细节,它确保了即便是隐藏单元和中间层也参与了特征计算,他们也能预测图片的类别,他在inception网络中起到一种调整的效果,并且能防止网络发生过拟合。
作用二:给定深度相对较大的网络,有效传播梯度反向通过所有层的能力是一个问题。通过将辅助分类器添加到这些中间层,可以期望较低阶段分类器的判别力。在训练期间,它们的损失以折扣权重(辅助分类器损失的权重是0.3)加到网络的整个损失上。
GoogLeNet网络结构参数
表格中的参数所表示的具体含义
GoogLeNet网络整体结构
模型
import torch.nn as nn
import torch
import torch.nn.functional as F
class GoogLeNet(nn.Module):
def __init__(self, num_classes=1000, aux_logits=True, init_weights=False): #分类类别个数是1000 是否使用辅助分类器 是否对我们的权重进行初始化
super(GoogLeNet, self).__init__()
self.aux_logits = aux_logits#是否使用辅助分类器的布尔变量传入到我们的类变量中
self.conv1 = BasicConv2d(3, 64, kernel_size=7, stride=2, padding=3)
# 卷积层 输入维度为 3 卷积核个数64 卷积核大小7x7,stride是2,padding是3
# padding=3这样做是为了将特征矩阵缩减为原来的一半
# (224 - 7 + 2*3)/ 2 + 1 =112.5 pytorch默认向下取整,就是112
self.maxpool1 = nn.MaxPool2d(3, stride=2, ceil_mode=True)
# 池化核大小为3x3 ceil_mode=True是指向上取整
# 此次没有使用localResNorm层
self.conv2 = BasicConv2d(64, 64, kernel_size=1)
# 输入维度是上一层输出维度 卷积核个数为64
self.conv3 = BasicConv2d(64, 192, kernel_size=3, padding=1)
self.maxpool2 = nn.MaxPool2d(3, stride=2, ceil_mode=True)
# 此次没有使用localResNorm层
self.inception3a = Inception(192, 64, 96, 128, 16, 32, 32)
# 使用已经定义好的inception类
# 输入特征矩阵的深度,ch1x1代表#1x1 ch3x3red代表#3x3 reduce
# ch5x5red代表#5x5 reduce ch5x5代表#5x5 pool_pro代表pool proj
self.inception3b = Inception(256, 128, 128, 192, 32, 96, 64)
self.maxpool3 = nn.MaxPool2d(3, stride=2, ceil_mode=True)
self.inception4a = Inception(480, 192, 96, 208, 16, 48, 64)
self.inception4b = Inception(512, 160, 112, 224, 24, 64, 64)
self.inception4c = Inception(512, 128, 128, 256, 24, 64, 64)
self.inception4d = Inception(512, 112, 144, 288, 32, 64, 64)
self.inception4e = Inception(528, 256, 160, 320, 32, 128, 128)
self.maxpool4 = nn.MaxPool2d(3, stride=2, ceil_mode=True)
self.inception5a = Inception(832, 256, 160, 320, 32, 128, 128)
self.inception5b = Inception(832, 384, 192, 384, 48, 128, 128)
if self.aux_logits: #如果使用辅助分类器的话,这个是我们刚刚传入的布尔参数
self.aux1 = InceptionAux(512, num_classes)#输入特侦矩阵的深度(inception4a的输出)
self.aux2 = InceptionAux(528, num_classes)#输入特侦矩阵的深度(inception4d的输出)
self.avgpool = nn.AdaptiveAvgPool2d((1, 1))#自适应的平均池化下采样操作 参数所需要输出特征矩阵的高和宽 ,
<