文章目录
一、卷积池化层原理
该层的顺序是:卷积——>ReLU——>池化——>归一化。
卷积池化层原理:
根据神经元公式:h(x)=f(wx+b)
上式子就是神经元所表示的函数,x表示输入(图片矩阵),w表示权重(卷积核参数),b表示偏置,f表示**函数(ReLU),h(x)表示输出,输出后的数据经过池化,然后归一化。形成完成的卷积池化层。
训练卷积神经网络的过程就是不断调整权重w(卷积核参数)与偏置b的过程,以使其输出h(x)达到预期值。
总结:
首先对输入的图片与卷积核w进行运算,并且每个卷积核参加卷积运算时添加偏置b,然后用**函数处理卷积运算结果,**后的图片尺寸不变,然后再进行池化运算,池化运算可以降低图片尺寸,然后对池化后的结果进行归一化处理。
二、全连接层原理
根据神经元公式:h(x)=f(wx+b)
全连接层x表示上一层的输出值,w表示本层的神经元权重,权重数量等于本全连接层神经元数目,然后再加偏置b,偏置数量等于本层神经元数目。
三、模型参数详解
原始论文中的图如下:网络模型由5个卷积池化层,3个全连接层组成,最后一层全连接层的输出是1000维softmax的输入,softmax会产生1000类标签的分布。
注:AlexNet论文错误点
:原始论文中的图有点小错误,输入图片的大小应该是227 x 227,而不是224 x 224,否则后面参数将不能被整除。
为了更加清晰的说明参数,引入如下更全的网络结构。
1.卷积池化层1
(1)卷积运算
第一层输入数据为原始的227x227x3的图像,这个图像被11x11x3的卷积核进行卷积运算,卷积核对原始图像的每次卷积都生成一个新的像素。卷积核沿原始图像的x轴方向和y轴方向两个方向移动,移动的步长是4个像素。因此,卷积核在移动的过程中会生成(227-11)/4+1=55个像素,行和列的55x55个像素形成对原始图像卷积之后的像素层。共有96个卷积核,会生成55x55x96个卷积后的像素层。
(2)分组
96个卷积核分成2组,每组48个卷积核。对应生成2组55x55x48的卷积后的像素层数据。
(3)**函数层
这些像素层经过relu1单元的处理,生成**像素层,尺寸仍为2组55x55x48的像素层数据。
(4)池化层
经过**函数的像素层经过pool运算的处理,池化运算的尺度为3x3,运算的步长为2,则池化后图像的尺寸为(55-3)/2+1=27。 即池化后像素的规模为27x27x96。
(5)归一化处理
归一化运算的尺度为5x5,即选择5x5的像素区域进行批归一化处理。第一卷积层运算结束后形成的像素层的规模为27x27x96。分别对应96个卷积核所运算形成。这96层像素层分为2组,每组48个像素层,每组在一个独立的GPU上进行运算。
(6)参数数量
卷积层的参数 = 卷积核大小 x 卷积核的数量 + 偏置数量(即卷积核的数量)。
本层参数数量为: (11 x 11 x 3 x 96) + 96 = 34848, 注:参数分为2部分 w 和 b ,“+”前面一部分是 w 的数量, “+”后面那部分是 b 的数量,后面的层也按这个思路来计算。
2.卷积池化层2
(1)卷积运算
第二层输入数据为第一层输出的27x27x96的像素层,为便于后续处理,每幅像素层的左右两边和上下两边都要填充2个像素;27x27x96的像素数据分成272748的两组像素数据,两组数据分别再两个不同的GPU中进行运算。每组像素数据被5548的卷积核进行卷积运算,共有256个5x5x48卷积核。卷积核沿原始图像的x轴方向和y轴方向两个方向移动,移动的步长是1个像素。因此,卷积核在移动的过程中会生成(27-5+2x2)/1+1=27个像素。即会生成27x27x256个卷积后的像素层。
(2)分组
这256个卷积核分成两组。会生成两组27x27x128个卷积后的像素层。
(3)**函数层
这些像素层经过relu2单元的处理,生成**像素层,尺寸仍为两组27x27x128的像素层。
(4)池化层
这些像素层经过pool运算(池化运算)的处理,池化运算的尺度为3*3,运算的步长为2,则池化后图像的尺寸为(57-3)/2+1=13。 即池化后像素的规模为2组13x13x128的像素层;
(5)归一化处理
然后经过归一化处理,归一化运算的尺度为5x5,即选择5x5的像素区域进行批归一化处理。第二卷积层运算结束后形成的像素层的规模为2组13x13x128的像素层。分别对应2组128个卷积核所运算形成。
(4)参数数量
卷积层, 使用256个5x5x48卷积核,节点数量:27x27x128x2 = 186624,参数数量:(5x5x48x128+128)x2 = 307456,最后"*2"是因为网络层均匀分布在两个GPU上,分2组,先计算单个GPU上的参数,再乘以GPU数量2。
3.卷积层3
(1)卷积运算
第三层输入数据为第二层输出的2组13x13x128的像素层;为便于后续处理,每幅像素层的左右两边和上下两边都要填充1个像素;2组像素层数据都被送至2个不同的GPU中进行运算。每个GPU中都有192个卷积核,每个卷积核的尺寸是3x3x256。因此,每个GPU中的卷积核都能对2组13x13x128的像素层的所有数据进行卷积运算。
(2)分组
这384个卷积核分成两组。会生成两组13x13x192个卷积后的像素层。
(3)**层
这些像素层经过relu3单元的处理,生成**像素层,尺寸仍为2组13x13x192像素层,共13x13x384个像素层。
(4)参数数量
卷积层,使用384个3x3x256卷积核,节点数量:13x13x192x2 = 64896,参数数量:3x3x256x384+384 = 885120。
4.卷积层4
(1)卷积运算
第四层输入数据为第三层输出的2组13x13x192的像素层;为便于后续处理,每幅像素层的左右两边和上下两边都要填充1个像素;2组像素层数据都被送至2个不同的GPU中进行运算。每个GPU中都有192个卷积核,每个卷积核的尺寸是3x3x192。因此,每个GPU中的卷积核能对1组13x13x192的像素层的数据进行卷积运算。卷积核对每组数据的每次卷积都生成一个新的像素。卷积核沿像素层数据的x轴方向和y轴方向两个方向移动,移动的步长是1个像素。因此,运算后的卷积核的尺寸为(13-3+12)/1+1=13,2个GPU中共1313*384个卷积后的像素层。即与上一层相同。
(2)分组
这384个卷积核分成两组。会生成两组13x13x192个卷积后的像素层。
(3)**层
这些像素层经过relu4单元的处理,生成**像素层,尺寸仍为2组13x13x192像素层,共13x13x384个像素层。
(4)参数数量
卷积层,使用384个3x3x192卷积核,分2组,节点数量:13x13x192x2 = 64896,参数数量:(3x3x192x192+192)x2 = 663936。
5.卷积池化层5
(1)卷积运算
第五层输入数据为第四层输出的2组13x13x192的像素层;为便于后续处理,每幅像素层的左右两边和上下两边都要填充1个像素;2组像素层数据都被送至2个不同的GPU中进行运算。每个GPU中都有128个卷积核,每个卷积核的尺寸是3x3x192。因此,每个GPU中的卷积核能对1组13x13x192的像素层的数据进行卷积运算。卷积核对每组数据的每次卷积都生成一个新的像素。卷积核沿像素层数据的x轴方向和y轴方向两个方向移动,移动的步长是1个像素。因此,运算后的卷积核的尺寸为(13-3+1x2)/1+1=13,每个GPU中共13x13x128个卷积核。
(2)分组
分组为2组13x13x128像素层,共13x13x256个像素层。
(3)**函数
这些像素层经过relu5单元的处理,生成**像素层,尺寸仍为2组13x13x128像素层,共13x13x256个像素层。
(4)池化层
2组13x13x128像素层分别在2个不同GPU中进行池化(pool)运算处理。池化运算的尺度为3x3,运算的步长为2,则池化后图像的尺寸为(13-3)/2+1=6。 即池化后像素的规模为两组6x6x128的像素层数据,共6x6x256规模的像素层数据。
(5)参数数量
卷积层,使用256个3x3x192卷积核,分2组,节点数量:13x13x128x2 = 43264,参数数量:(3x3x192x128+128)x2 = 442624。
6.全连接层1
(1)卷积运算
第六层输入数据的尺寸是6x6x256,采用6x6x256=9216尺寸的滤波器对第六层的输入数据进行卷积运算;每个6x6x256尺寸的滤波器对第六层的输入数据进行卷积运算生成一个运算结果,通过一个神经元输出这个运算结果;共有4096个6x6x256尺寸的滤波器对输入数据进行卷积运算,通过4096个神经元输出运算结果;
(2)**函数
这4096个运算结果通过relu6**函数生成4096个值。
(3)Dropout
**可以看到卷积神经网络的计算量其实主要集中在全连接层,这些层参数太多了,也最容易发生过拟合。**DropOut通过训练时随机使得一部分结点失效,不贡献连接权重而减少过拟合风险。同时强迫这些神经元去学习互补的一些特征。因此最后通过dropout6运算后输出4096个本层的输出结果值。
(4)参数数量
根据全连接层的参数数量 = 上一层节点数量(pooling之后的) x 下一层节点数量 + 偏置数量(即下一层的节点数量)。
参数数量为:(66128*2)*4096+4096 = 37752832,可以看到这个参数数量远远大于之前所有卷积层的参数数量之和。也就是说AlexNet的参数大部分位于后面的全连接层。
7.全连接层2
(1)卷积运算
第六层输出的4096个数据与第七层的4096个神经元进行全连接
(2)**函数
然后经由relu7进行处理后生成4096个数据
(3)Dropout
再经过dropout7处理后输出4096个数据。
(4)参数数量
全连接层,节点数量为4096。参数数量为:4096*4096 + 4096= 16781312。
8.全连接层3
(1)卷积运算
第七层输出的4096个数据与第八层的1000个神经元进行全连接,经过训练后输出被训练的数值。
(2)参数数量
全连接层,节点数量为1000。参数数量为: 4096*1000 + 1000 = 4097000。
四、PyTorch实现
import torch
from torch import nn
import numpy as np
from torch.autograd import Variable
class AlexNet(nn.Module):
def __init__(self):
super().__init__()
# 第一层是 5x5 的卷积,输入的channels 是 3,输出的channels是 64,步长 1,没有 padding
# Conv2d 的第一个参数为输入通道,第二个参数为输出通道,第三个参数为卷积核大小
# ReLU 的参数为inplace,True表示直接对输入进行修改,False表示创建新创建一个对象进行修改
self.conv1 = nn.Sequential(
nn.Conv2d(3,64,5),
nn.ReLU()
)
# 第二层为 3x3 的池化,步长为2,没有padding
self.max_pool1 = nn.MaxPool2d(3, 2)
# 第三层是 5x5 的卷积, 输入的channels 是64,输出的channels 是64,没有padding
self.conv2 = nn.Sequential(
nn.Conv2d(64, 64, 5, 1),
nn.ReLU(True)
)
#第四层是 3x3 的池化, 步长是 2,没有padding
self.max_pool2 = nn.MaxPool2d(3,2)
#第五层是全连接层,输入是 1204 ,输出是384
self.fc1 = nn.Sequential(
nn.Linear(1024,384),
nn.ReLU(True)
)
# 第六层是全连接层,输入是 384, 输出是192
self.fc2 = nn.Sequential(
nn.Linear(384, 192),
nn.ReLU(True)
)
# 第七层是全连接层,输入是192, 输出是 10
self.fc3 = nn.Linear(192, 10)
def forward(self, x):
x = self.conv1(x)
x = self.max_pool1(x)
x = self.conv2(x)
x = self.max_pool2(x)
#将图片矩阵拉平
x = x.view(x.shape[0], -1)
x = self.fc1(x)
x = self.fc2(x)
x = self.fc3(x)
return x
alexnet = AlexNet()
print(alexnet)
输出:
输入图像大小(1, 3, 32, 32),验证模型输出大小。
input_demo = Variable(torch.zeros(1, 3, 32, 32))
output_demo = alexnet(input_demo)
print(output_demo.shape)