使用Pytorch实现VGG的一般版本

在前面的博文中,我们已经实现了基于Pytorch的VGG11的搭建以及训练

在本文中,我们将:

1)进一步理解VGG11 13 16和19

2)实现这些不同的架构;

 

一、VGG网络中的不同架构

 

 ABDE较为常用;我们称之为VGG11 13 16和19

每个架构在某一特定的卷积层后都有最大池化操作;

同时每次卷积操作完成后我们都将对其进行ReLU激活;

 

其他需要注意的地方是,他们都有相同的全连接层;

 

二、使用PYTORCH实现VGG网络

 

导入包:

import torch
import torch.nn as nn

 

VGG的配置:

1 # VGG configurations according to Table 1 in the paper
2 # https://arxiv.org/pdf/1409.1556v6.pdf
3 # configurations A (VGG11), B (VGG13), D (VGG16), and E (VGG19)
4 vgg_cfgs = {
5     'A': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
6     'B': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
7     'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
8     'E': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
9 }
  • 利用vgg_cfgs字典,A B C D 这些名字都是他们的键;数字代表每个卷基层的输出通道;M代表了最大池化操作;

从上图中也可以看到每个卷积层都有3*3的卷积核;

这意味着我们可以用一种非常通用的方式来定义卷积层;

 

一些注意事项:

  • 这个论文在发表的时候,作者没有提及是否使用了BN方法在他们的网络层中;BN算法是为了解决在非常深的网络中梯度消失的问题;
  • 在后面的时候,使用了BN层,即使是官方的Pytorch版本也使用了BN层;
  • 因此我们也会使用BN层;
  • 另一个需要注意的地方是在前两个fc层之后使用了dropout。虽然在表2中没有提及,但是作者在训练的时候使用了dropout方法;

 

网络架构类

 1 # VGG neural network class
 2 class VGG(nn.Module):
 3     def __init__(self, in_channels=3, num_classes=1000, 
 4                  config=vgg_cfgs['A']):
 5         super(VGG, self).__init__()
 6         self.in_channels = in_channels
 7         self.num_classes = num_classes
 8         self.config = config
 9 
10         # select convolutional layer configuration for the VGG net
11         self.covolutional_layers = self.make_conv_layers(self.config)
12 
13         self.fully_connected = nn.Sequential(
14             nn.Linear(512*7*7, 4096),
15             nn.ReLU(),
16             nn.Dropout(0.5),
17             nn.Linear(4096, 4096),
18             nn.ReLU(),
19             nn.Dropout(0.5),
20             nn.Linear(4096, num_classes)
21         )
22 
23     # function to create the convolutional layers as per the selected config
24     def make_conv_layers(self, config):
25         layers = []
26         in_channels = self.in_channels
27         for op in config:
28             if op == 'M':
29                 layers += [nn.MaxPool2d(kernel_size=2, stride=1)]
30             else:
31                 layers += [
32                            nn.Conv2d(in_channels=in_channels, 
33                                       out_channels=op, kernel_size=3, 
34                                       padding=1),
35                            nn.BatchNorm2d(op),
36                            nn.ReLU()
37                 ]
38                 in_channels = op
39         return nn.Sequential(*layers)
40 
41     # the forward pass
42     def forward(self, x):
43         x = self.convolutional_layers(x)
44         # flatten to prepare for the fully connected layers
45         x = x.view(x.size(0), -1)
46         x = self.fully_connected(x)
47         return x

 

模型的调用:

1 if __name__ == '__main__':
2     device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
3     config_keys = list(vgg_cfgs.keys())
4     for i, config in enumerate(config_keys):
5         model = VGG(in_channels=3, num_classes=1000, config=vgg_cfgs[config]).to(device)
6         print(f"Config: {config}, {model}")
7         # total parameters in the model
8         total_params = sum(p.numel() for p in model.parameters())
9         print(f"[INFO]: {total_params:,} total parameters. \n")

 

posted @ 2021-05-21 15:39  hi_mxd  阅读(341)  评论(0编辑  收藏  举报