Python实现Vgg16经典网络架构代码

Posted quintin007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python实现Vgg16经典网络架构代码相关的知识,希望对你有一定的参考价值。

Python实现Vgg16经典网络架构代码

可以看到,从16层到19层,准确率上升了1.6%,但从19层到35层,准确率却只上升了0.6%。不难发现
——16层明显比13层要高,但19层却和16层差异不太大,35层与19层之间的差异就更小,随着深度的
加深,模型的学习能力大概率会增强,但深度与模型效果之间的关系不是线性的,可以增长的边际准确
率是在递减的,准确率的变化会逐渐趋于平缓。但同时,参数量却是高速增加的,VGG19的参数量就达
到了1.43亿个,对于任何个人计算机来说这个参数量都是一个巨大的考验。
受启发于VGG架构,在过去数年的研究中,人们通过实验发现了这样的结论:在不改变原始卷积层输入
输出机制的前提下,增加卷积层的数目来增加深度,会很快让模型效果和性能都达到上限。深度并不能
高效提升模型的效果,需要先降低模型的训练成本,才能够追求更深的神经网络。如果想要通过“加深”
卷积神经网络来实现网络效果的飞跃,那必须是从16层加到160层,而不是从16层加到19层。事实上,
在2014年后的ILSVRC上,赢得冠军的网络架构变得越来越复杂,深度也越来越深,在2017年ILSVRC闭
幕之前,网络深度大约停留在了220层左右,这是得益于研究者们发现了更高效地提升深度的方法。
在现在的眼光来看,网络的实际深度一般与数据的复杂程度有关。对于ImageNet这样的数据集,200层
的网络能够实现2.99%的错误率,而对于Fashion-MNIST这样的数据集,可能只需要几十层就能达到很
高的测试准确率(目前为止Github上的Fashion-MNIST最高测试准确率大约在96%)。对于尺寸小于
50x50的图像而言,若追求测试准确率在90%以上,则只需要小于20层左右就足够了。为了计算效率,
不必强行加深网络,若的确追求更高的准确率,则可以考虑换成更高级的架构或者对数据进行预处理。

VGG架构对于神经网络研究和使用都有重要的意义,它不仅简单、有效,而且非常适合用来做各种实验
和测试。在我们已经详细复现AlexNet与LeNet5的基础上,VGG架构的代码就显得异常简单。在这里,
我为大家提供输入为224x224的VGGNet16的详细架构和复现后的代码,大家可以参考。VGG16的架构
用语言来表示则有:
输入→(卷积x2+池化)x2 →(卷积x3+池化)x3 → FC层x3 →输出。

实现代码如下:

import torch
import torch.nn as nn
from torchinfo import summary
from torch.nn import functional as F

data=torch.ones(10,3,224,224)
class Vgg16(nn.Module):
    def __init__(self):
        super().__init__()     
        self.conv1=nn.Sequential(nn.Conv2d(3,64,kernel_size=3,padding=1)
                                ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(64,64,kernel_size=3,padding=1)  
                                ,nn.ReLU(inplace=True) 
                                ,nn.MaxPool2d(kernel_size=2))
        self.conv2=nn.Sequential(nn.Conv2d(64,128,kernel_size=3,padding=1) 
                                ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(128,128,kernel_size=3,padding=1)
                                ,nn.ReLU(inplace=True) 
                                ,nn.MaxPool2d(kernel_size=2))
        self.conv3=nn.Sequential(nn.Conv2d(128,256,kernel_size=3,padding=1)
                                ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(256,256,kernel_size=3,padding=1)
                                ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(256,256,kernel_size=3,padding=1) 
                                ,nn.ReLU(inplace=True) 
                                ,nn.MaxPool2d(kernel_size=2))
        self.conv4=nn.Sequential(nn.Conv2d(256,512,kernel_size=3,padding=1) 
                                 ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(512,512,kernel_size=3,padding=1) 
                                ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(512,512,kernel_size=3,padding=1) 
                                ,nn.ReLU(inplace=True) 
                                ,nn.MaxPool2d(kernel_size=2))
        self.conv5=nn.Sequential(nn.Conv2d(512,512,kernel_size=3,padding=1)
                                ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(512,512,kernel_size=3,padding=1)
                                ,nn.ReLU(inplace=True) 
                                ,nn.Conv2d(512,512,kernel_size=3,padding=1)
                                ,nn.ReLU(inplace=True) 
                                ,nn.MaxPool2d(kernel_size=2))
        self.fc=nn.Sequential(nn.Linear(7*7*512,4096)
                             ,nn.ReLU(inplace=True) 
                             ,nn.Linear(4096,4096)
                             ,nn.ReLU(inplace=True) 
                             ,nn.Linear(4096,1000)
                             ,nn.ReLU(inplace=True) 
                             )
    def forward(self,x):
        x=self.conv1(x)
        x=self.conv2(x)
        x=self.conv3(x)
        x=self.conv4(x)
        x=self.conv5(x)
        x=torch.flatten(x,1)
        x=self.fc(F.dropout( x,0.5))
        out =F.softmax(x)
        return out
    
vgg_=Vgg16()
vgg_(data)
<ipython-input-25-17853c1700ab>:50: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.
  out =F.softmax(x)





tensor([[0.0010, 0.0010, 0.0010,  ..., 0.0010, 0.0010, 0.0010],
        [0.0010, 0.0010, 0.0010,  ..., 0.0010, 0.0010, 0.0010],
        [0.0010, 0.0010, 0.0010,  ..., 0.0010, 0.0010, 0.0010],
        ...,
        [0.0010, 0.0010, 0.0010,  ..., 0.0010, 0.0010, 0.0010],
        [0.0010, 0.0010, 0.0010,  ..., 0.0010, 0.0010, 0.0010],
        [0.0010, 0.0010, 0.0010,  ..., 0.0010, 0.0010, 0.0010]],
       grad_fn=<SoftmaxBackward0>)
summary(vgg_,data.shape,depth=3)
<ipython-input-25-17853c1700ab>:50: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.
  out =F.softmax(x)





==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
Vgg16                                    [10, 1000]                --
├─Sequential: 1-1                        [10, 64, 112, 112]        --
│    └─Conv2d: 2-1                       [10, 64, 224, 224]        1,792
│    └─ReLU: 2-2                         [10, 64, 224, 224]        --
│    └─Conv2d: 2-3                       [10, 64, 224, 224]        36,928
│    └─ReLU: 2-4                         [10, 64, 224, 224]        --
│    └─MaxPool2d: 2-5                    [10, 64, 112, 112]        --
├─Sequential: 1-2                        [10, 128, 56, 56]         --
│    └─Conv2d: 2-6                       [10, 128, 112, 112]       73,856
│    └─ReLU: 2-7                         [10, 128, 112, 112]       --
│    └─Conv2d: 2-8                       [10, 128, 112, 112]       147,584
│    └─ReLU: 2-9                         [10, 128, 112, 112]       --
│    └─MaxPool2d: 2-10                   [10, 128, 56, 56]         --
├─Sequential: 1-3                        [10, 256, 28, 28]         --
│    └─Conv2d: 2-11                      [10, 256, 56, 56]         295,168
│    └─ReLU: 2-12                        [10, 256, 56, 56]         --
│    └─Conv2d: 2-13                      [10, 256, 56, 56]         590,080
│    └─ReLU: 2-14                        [10, 256, 56, 56]         --
│    └─Conv2d: 2-15                      [10, 256, 56, 56]         590,080
│    └─ReLU: 2-16                        [10, 256, 56, 56]         --
│    └─MaxPool2d: 2-17                   [10, 256, 28, 28]         --
├─Sequential: 1-4                        [10, 512, 14, 14]         --
│    └─Conv2d: 2-18                      [10, 512, 28, 28]         1,180,160
│    └─ReLU: 2-19                        [10, 512, 28, 28]         --
│    └─Conv2d: 2-20                      [10, 512, 28, 28]         2,359,808
│    └─ReLU: 2-21                        [10, 512, 28, 28]         --
│    └─Conv2d: 2-22                      [10, 512, 28, 28]         2,359,808
│    └─ReLU: 2-23                        [10, 512, 28, 28]         --
│    └─MaxPool2d: 2-24                   [10, 512, 14, 14]         --
├─Sequential: 1-5                        [10, 512, 7, 7]           --
│    └─Conv2d: 2-25                      [10, 512, 14, 14]         2,359,808
│    └─ReLU: 2-26                        [10, 512, 14, 14]         --
│    └─Conv2d: 2-27                      [10, 512, 14, 14]         2,359,808
│    └─ReLU: 2-28                        [10, 512, 14, 14]         --
│    └─Conv2d: 2-29                      [10, 512, 14, 14]         2,359,808
│    └─ReLU: 2-30                        [10, 512, 14, 14]         --
│    └─MaxPool2d: 2-31                   [10, 512, 7, 7]           --
├─Sequential: 1-6                        [10, 1000]                --
│    └─Linear: 2-32                      [10, 4096]                102,764,544
│    └─ReLU: 2-33                        [10, 4096]                --
│    └─Linear: 2-34                      [10, 4096]                16,781,312
│    └─ReLU: 2-35                        [10, 4096]                --
│    └─Linear: 2-36                      [10, 1000]                4,097,000
│    └─ReLU: 2-37                        [10, 1000]                --
==========================================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0
Total mult-adds (G): 154.84
==========================================================================================
Input size (MB): 6.02
Forward/backward pass size (MB): 1084.54
Params size (MB): 553.43
Estimated Total Size (MB): 1643.99
==========================================================================================

以上是关于Python实现Vgg16经典网络架构代码的主要内容,如果未能解决你的问题,请参考以下文章

VGG——CNN经典网络模型(pytorch实现)

经典卷积神经网络——VGG16

经典深度神经网络架构解析 - VGG,ResNet,Inception

tensorflow VGG16 网络精度和损失不会改变

Keras篇---利用keras改写VGG16经典模型在手写数字识别体中的应用

经典分类CNN模型系列其二:VGG