使用重复元素的网络(VGG)
前言
VGG是由牛津大学计算机视觉组(Visual Geometry Group)提出的一种深度卷积神经网络,是ImageNet竞赛中最出色的模型之一。VGG网络的特点是采用连续的小卷积核和深的网络结构,使得网络具备了更强的表达能力,同时也增加了网络的深度。
本文将从理论推导到实际代码实现,详细介绍使用重复元素的网络(VGG)。
理论推导
VGG网络结构
VGG网络具有以下特点:
- 采用小卷积核:使用3x3的小卷积核代替传统的5x5或7x7的大卷积核,可以减少参数数量,同时提高网络的非线性表达能力。
- 使用重复元素:采用连续的小卷积核和池化层进行堆叠,形成重复的模块。
- 深度网络结构:采用多层卷积层和池化层进行堆叠,形成深度网络结构。
下面是VGG网络的结构图:
VGG网络计算过程
下面是VGG网络的计算过程:
- 输入图像经过卷积层1-1,使用64个3x3的卷积核进行卷积操作,得到64个特征图,每个特征图大小为224x224。
- 将卷积层1-1的输出经过ReLU激活函数,得到64个特征图,每个特征图大小为224x224。
- 将ReLU激活函数的输出经过卷积层1-2,使用64个3x3的卷积核进行卷积操作,得到64个特征图,每个特征图大小为224x224。
- 将卷积层1-2的输出经过ReLU激活函数,得到64个特征图,每个特征图大小为224x224。
- 将ReLU激活函数的输出经过池化层1,使用2x2的池化核进行池化操作,得到64个特征图,每个特征图大小为112x112。
- 将池化层1的输出经过卷积层2-1,使用128个3x3的卷积核进行卷积操作,得到128个特征图,每个特征图大小为112x112。
- 将卷积层2-1的输出经过ReLU激活函数,得到128个特征图,每个特征图大小为112x112。
- 将ReLU激活函数的输出经过卷积层2-2,使用128个3x3的卷积核进行卷积操作,得到128个特征图,每个特征图大小为112x112。
- 将卷积层2-2的输出经过ReLU激活函数,得到128个特征图,每个特征图大小为112x112。
- 将ReLU激活函数的输出经过池化层2,使用2x2的池化核进行池化操作,得到128个特征图,每个特征图大小为56x56。
- 将池化层2的输出经过卷积层3-1,使用256个3x3的卷积核进行卷积操作,得到256个特征图,每个特征图大小为56x56。
- 将卷积层3-1的输出经过ReLU激活函数,得到256个特征图,每个特征图大小为56x56。
- 将ReLU激活函数的输出经过卷积层3-2,使用256个3x3的卷积核进行卷积操作,得到256个特征图,每个特征图大小为56x56。
- 将卷积层3-2的输出经过ReLU激活函数,得到256个特征图,每个特征图大小为56x56。
- 将ReLU激活函数的输出经过卷积层3-3,使用256个3x3的卷积核进行卷积操作,得到256个特征图,每个特征图大小为56x56。
- 将卷积层3-3的输出经过ReLU激活函数,得到256个特征图,每个特征图大小为56x56。
- 将ReLU激活函数的输出经过池化层3,使用2x2的池化核进行池化操作,得到256个特征图,每个特征图大小为28x28。
- 将池化层3的输出经过卷积层4-1,使用512个3x3的卷积核进行卷积操作,得到512个特征图,每个特征图大小为28x28。
- 将卷积层4-1的输出经过ReLU激活函数,得到512个特征图,每个特征图大小为28x28。
- 将ReLU激活函数的输出经过卷积层4-2,使用512个3x3的卷积核进行卷积操作,得到512个特征图,每个特征图大小为28x28。
- 将卷积层4-2的输出经过ReLU激活函数,得到512个特征图,每个特征图大小为28x28。
- 将ReLU激活函数的输出经过卷积层4-3,使用512个3x3的卷积核进行卷积操作,得到512个特征图,每个特征图大小为28x28。
- 将卷积层4-3的输出经过ReLU激活函数,得到512个特征图,每个特征图大小为28x28。
- 将ReLU激活函数的输出经过池化层4,使用2x2的池化核进行池化操作,得到512个特征图,每个特征图大小为14x14。
- 将池化层4的输出经过卷积层5-1,使用512个3x3的卷积核进行卷积操作,得到512个特征图,每个特征图大小为14x14。
- 将卷积层5-1的输出经过ReLU激活函数,得到512个特征图,每个特征图大小为14x14。
- 将ReLU激活函数的输出经过卷积层5-2,使用512个3x3的卷积核进行卷积操作,得到512个特征图,每个特征图大小为14x14。
- 将卷积层5-2的输出经过ReLU激活函数,得到512个特征图,每个特征图大小为14x14。
- 将ReLU激活函数的输出经过卷积层5-3,使用512个3x3的卷积核进行卷积操作,得到512个特征图,每个特征图大小为14x14。
- 将卷积层5-3的输出经过ReLU激活函数,得到512个特征图,每个特征图大小为14x14。
- 将ReLU激活函数的输出经过池化层5,使用2x2的池化核进行池化操作,得到512个特征图,每个特征图大小为7x7。
- 将池化层5的输出经过全连接层6,将特征图展开成一维向量,得到4096个神经元。
- 将全连接层6的输出经过ReLU激活函数。
- 将ReLU激活函数的输出经过全连接层7,得到4096个神经元。
- 将全连接层7的输出经过ReLU激活函数。
- 将ReLU激活函数的输出经过全连接层8,得到1000个神经元。
- 将全连接层8的输出经过Softmax激活函数,得到1000个类别的概率值。
代码实现
下面是使用PyTorch实现VGG网络的代码:
import torch
import torch.nn as nn
import torch.optim as optim
class VGG(nn.Module):
def __init__(self):
super(VGG, self).__init__()
self.conv1_1 = nn.Conv2d(3, 64, 3, padding=1)
self.conv1_2 = nn.Conv2d(64, 64, 3, padding=1)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2_1 = nn.Conv2d(64, 128, 3, padding=1)
self.conv2_2 = nn.Conv2d(128, 128, 3, padding=1)
self.pool2 = nn.MaxPool2d(2, 2)
self.conv3_1 = nn.Conv2d(128, 256, 3, padding=1)
self.conv3_2 = nn.Conv2d(256, 256, 3, padding=1)
self.conv3_3 = nn.Conv2d(256, 256, 3, padding=1)
self.pool3 = nn.MaxPool2d(2, 2)
self.conv4_1 = nn.Conv2d(256, 512, 3, padding=1)
self.conv4_2 = nn.Conv2d(512, 512, 3, padding=1)
self.conv4_3 = nn.Conv2d(512, 512, 3, padding=1)
self.pool4 = nn.MaxPool2d(2, 2)
self.conv5_1 = nn.Conv2d(512, 512, 3, padding=1)
self.conv5_2 = nn.Conv2d(512, 512, 3, padding=1)
self.conv5_3 = nn.Conv2d(512, 512, 3, padding=1)
self.pool5 = nn.MaxPool2d(2, 2)
self.fc6 = nn.Linear(512 * 7 * 7, 4096)
self.fc7 = nn.Linear(4096, 4096)
self.fc8 = nn.Linear(4096, 1000)
self.relu = nn.ReLU(inplace=True)
self.softmax = nn.Softmax(dim=1)
def forward(self, x):
x = self.conv1_1(x)
x = self.relu(x)
x = self.conv1_2(x)
x = self.relu(x)
x = self.pool1(x)
x = self.conv2_1(x)
x = self.relu(x)
x = self.conv2_2(x)
x = self.relu(x)
x = self.pool2(x)
x = self.conv3_1(x)
x = self.relu(x)
x = self.conv3_2(x)
x = self.relu(x)
x = self.conv3_3(x)
x = self.relu(x)
x = self.pool3(x)
x = self.conv4_1(x)
x = self.relu(x)
x = self.conv4_2(x)
x = self.relu(x)
x = self.conv4_3(x)
x = self.relu(x)
x = self.pool4(x)
x = self.conv5_1(x)
x = self.relu(x)
x = self.conv5_2(x)
x = self.relu(x)
x = self.conv5_3(x)
x = self.relu(x)
x = self.pool5(x)
x = x.view(-1, 512 * 7 * 7)
x = self.fc6(x)
x = self.relu(x)
x = self.fc7(x)
x = self.relu(x)
x = self.fc8(x)
x = self.softmax(x)
return x
model = VGG()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
总结
本文从理论推导到实际代码实现,详细介绍了使用重复元素的网络(VGG)。VGG网络采用了连续的小卷积