• 神经网络


    1. 走向深度:VGGNet

        随着AlexNet2012ImageNet大赛上大放异彩后, 卷积网络进入了飞速的发展阶段, 而2014年的ImageNet亚军结构VGGNetVisual Geometry Group Network) 则将卷积网络进行了改良, 探索了网络深度与性能的关系, 用更小的卷积核与更深的网络结构, 取得了较好的效果, 成为卷积结构发展史上较为重要的一个网络。

        VGGNet网络结构组成如图3.12所示, 一共有6个不同的版本, 最常用的是VGG16。 从图3.12中可以看出, VGGNet采用了五组卷积与三个全连接层, 最后使用Softmax做分类。 VGGNet有一个显著的特点: 每次经过池化层(maxpool) 后特征图的尺寸减小一倍, 而通道数则增加一倍(最后一个池化层除外) 。

        AlexNet中有使用到5×5的卷积核, 而在VGGNet中, 使用的卷积核基本都是3×3, 而且很多地方出现了多个3×3堆叠的现象, 这种结构的优点在于, 首先从感受野来看, 两个3×3的卷积核与一个5×5的卷积核是一样的; 其次, 同等感受野时, 3×3卷积核的参数量更少。 更为重要的是, 两个3×3卷积核的非线性能力要比5×5卷积核强, 因为其拥有两个激活函数, 可大大提高卷积网络的学习能力。

      下面使用PyTorch来搭建VGG16经典网络结构, 新建一个vgg.py文件, 并输入以下内容 :

     1 import torch
     2 from torch import nn
     3 
     4 class VGG(nn.Module):
     5 
     6     def __init__(self, num_classes=1000):
     7         super(VGG, self).__init__()
     8         layers = []
     9         in_dim = 3
    10         out_dim = 64
    11 
    12         # 循环构造卷积层, 一共有13个卷积层
    13         for i in range(13):
    14             layers += [nn.Conv2d(in_dim, out_dim, 3, 1, 1), nn.ReLU(inplace=True)]
    15             in_dim = out_dim
    16             # 在第2、 4、 7、 10、 13个卷积层后增加池化层
    17             if i==1 or i==3 or i==6 or i==9 or i==12:
    18                 layers += [nn.MaxPool2d(2, 2)]
    19                 # 第10个卷积后保持和前边的通道数一致, 都为512, 其余加倍
    20                 if i!=9:
    21                     out_dim*=2
    22          
    23         self.features = nn.Sequential(*layers)
    24          # VGGNet的3个全连接层, 中间有ReLU与Dropout层
    25         self.classifier = nn.Sequential(
    26                 nn.Linear(512*7*7, 4096),
    27                 nn.ReLU(True),
    28                 nn.Dropout(),
    29                 nn.Linear(4096, 4096),
    30                 nn.ReLU(True),
    31                 nn.Dropout(),
    32                 nn.Linear(4096, num_classes),
    33          )
    34 
    35     def forward(self, x):
    36         x = self.features(x)
    37     # 这里是将特征图的维度从[1, 512, 7, 7]变到[1, 512*7*7]
    38         x = x.view(x.size(0), -1)
    39         x =  self.classifier(x)
    40         return x
    View Code

     在终端中进入上述vgg.py文件的同级目录, 输入python3进入交互式环境, 利用下面代码调用该模块。

     1 import torch
     2 from vgg import VGG
     3 
     4 vgg = VGG(21).cuda()
     5 input = torch.randn(1, 3, 224, 224).cuda()
     6 print(input.shape)
     7 >> torch.Size([1, 3, 224, 224]
     8 
     9 scores = vgg(input)
    10 print(scores.shape)
    11 >> torch.Size([1, 21])
    12 
    13 features = vgg.features(input)
    14 print(features.shape)
    15 >> torch.Size([1, 512, 7, 7])
    16 print(vgg.features)
    17 >> Sequential(
    18   (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    19   (1): ReLU(inplace=True)
    20   (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    21   (3): ReLU(inplace=True)
    22   (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    23   (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    24   (6): ReLU(inplace=True)
    25   (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    26   (8): ReLU(inplace=True)
    27   (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    28   (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    29   (11): ReLU(inplace=True)
    30   (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    31   (13): ReLU(inplace=True)
    32   (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    33   (15): ReLU(inplace=True)
    34   (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    35   (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    36   (18): ReLU(inplace=True)
    37   (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    38   (20): ReLU(inplace=True)
    39   (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    40   (22): ReLU(inplace=True)
    41   (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    42   (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    43   (25): ReLU(inplace=True)
    44   (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    45   (27): ReLU(inplace=True)
    46   (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    47   (29): ReLU(inplace=True)
    48   (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    49 )
    View Code
  • 相关阅读:
    前端 CSS 与HTML 学习笔记详细讲解
    Python-Django之DRF
    Flask
    flask
    Python
    Python爬虫
    前端开发规范
    为什么 [] == ![] 输出是true?
    javascript准确判断各种数据类型
    JavaScript数组扁平化常用方法总结
  • 原文地址:https://www.cnblogs.com/zhaopengpeng/p/13674554.html
Copyright © 2020-2023  润新知