关于VGGNet网络结构浅谈(主要是VGG16结构)

article/2025/4/22 17:55:45

文章目录

    • 1.首先看一下论文中一张表:
    • 2.VGG16网络结构解释:
    • 3.网络构成详解:
    • 4.VGG16使用的卷积核大小都是3x3的,使用比之前小的卷积核有什么作用:
    • 5.Tensorflow2.6.0实现VGG16网络结构:

1.首先看一下论文中一张表:

在这里插入图片描述
注解:
(1)可以看到表中从左->右网络结构逐渐变得更深和复杂;层数从11->11->13->16->16->19;
(2)所有的激活函数使用的都是ReLU函数;
(3)层与层之间的间隔使用Max Pool(最大池化);
(4)使用的卷积核大小都是3*3的卷积,通道数逐渐增加(因为宽和高在变小,所以通道数增加对特征的保留更好);
(5)根据卷积层来设计其中子层的数量;
(6)最后接的都是全连接层,神经元为4096->4096->1000,最后使用softmax函数输出1000类别概率;


VGG16之特征提取和网络参数的查看(偏置和权重):
https://mydreamambitious.blog.csdn.net/article/details/123928764(其中包含了详细的网络结构)

2.VGG16网络结构解释:

以下两幅图都是VGG16结构:
在这里插入图片描述
在这里插入图片描述
图片来源:
https://blog.csdn.net/xiaobumi123/article/details/105550967
https://blog.csdn.net/qq_37939213/article/details/90380639
注解:
(1)VGG16包含16个层,其中第一个卷积层是由:2个conv3-64组成,后接一个maxpool层;
(2)第二层由两个:conv3-128组成,后接一个maxpool层;
(3)第三层由三个:conv3-256组成,后接一个maxpool层;
(4)第四层由三个:conv3-512组成,后接一个maxpool层;
(5)第五层由三个:conv3-512组成,后接一个maxpool层;
(6)最后是三个全连接层:其中包含两个FC4096和一个FC1000(类别数)。
所以这就是VGG16名字的由来。

3.网络构成详解:

首先是输入层:2242443
(一)第一层:
在这里插入图片描述

注解:
(1)首先输入图片大小为224x224x3(这个可以通过成剪裁实现);

img_path='images/train/dog/1.jpg'
#导入图片并将图像剪裁为299*299img=image.load_img(img_path,target_size=(224,224))

(2)输入图片时候使用64个3x3(kernel_size)的卷积核大小进行卷积,得到的特征图大小为224x224x64。
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(224+21-3)/1+1=224.所以最后得到的特征图大小为224x224x64.
甚至我们的高宽步长可以不用设置一样,当然这里需要一样。
(3)使用激活函数ReLU进非线性变换。
(4)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(224+21-3)/1+1=224.所以最后得到的特征图大小为224x224x64.
(5)再进行激活:ReLU
(6)最后就是最大池化:
使用大小为2x2,步长为strides=2的池化单元进行最大池化。input_size+2padding-kernel_size)/strides+1=(224+20-2)/2+1=112.
输出的特征图大小为:112x112x64.


(二):输入特征图大小112x112x64:
在这里插入图片描述

(1)输入图片时候使用128个3x3(kernel_size)的卷积核大小进行卷积,得到的特征图大小为112x112x128。
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(112+21-3)/1+1=112.所以最后得到的特征图大小为112x112x128.
甚至我们的高宽步长可以不用设置一样,当然这里需要一样。
(2)使用激活函数ReLU进非线性变换。
(3)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(112+21-3)/1+1=112.所以最后得到的特征图大小为112x112x128.
(4)再进行激活:ReLU
(5)最后就是最大池化:
使用大小为2x2,步长为strides=2的池化单元进行最大池化。input_size+2padding-kernel_size)/strides+1=(112+20-2)/2+1=56.
输出的特征图大小为:56x56x256.


(三):输入特征图大小为:56x56x256
在这里插入图片描述
(1)输入图片时候使用256个3x3(kernel_size)的卷积核大小进行卷积,得到的特征图大小为56x56x256。
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(56+21-3)/1+1=56.所以最后得到的特征图大小为56x56x256.
甚至我们的高宽步长可以不用设置一样,当然这里需要一样。
(2)使用激活函数ReLU进非线性变换。
(3)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(56+21-3)/1+1=56.所以最后得到的特征图大小为56x56x256.
(4)再进行激活:ReLU
(5)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(56+21-3)/1+1=56.所以最后得到的特征图大小为56x56x256.
(6)再进行激活:ReLU
(7)最后就是最大池化:
使用大小为2x2,步长为strides=2的池化单元进行最大池化。input_size+2padding-kernel_size)/strides+1=(56+20-2)/2+1=28.
输出的特征图大小为:28x28x256.


(四):输入的特征图大小为:28x28x256
在这里插入图片描述
(1)输入图片时候使用512个3x3(kernel_size)的卷积核大小进行卷积,得到的特征图大小为28x28x512。
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(28+21-3)/1+1=28.所以最后得到的特征图大小为28x28x512.
甚至我们的高宽步长可以不用设置一样,当然这里需要一样。
(2)使用激活函数ReLU进非线性变换。
(3)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(28+21-3)/1+1=28.所以最后得到的特征图大小为28x28x512.
(4)再进行激活:ReLU
(5)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(28+21-3)/1+1=28.所以最后得到的特征图大小为28x28x512.
(6)再进行激活:ReLU
(7)最后就是最大池化:
使用大小为2x2,步长为strides=2的池化单元进行最大池化。input_size+2padding-kernel_size)/strides+1=(28+20-2)/2+1=14.
输出的特征图大小为:14x14x512.


(五):输入的特征图大小为:14x14x512
在这里插入图片描述
(1)输入图片时候使用512个3x3(kernel_size)的卷积核大小进行卷积,得到的特征图大小为14x14x512。
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(14+21-3)/1+1=14.所以最后得到的特征图大小为14x14x512.
甚至我们的高宽步长可以不用设置一样,当然这里需要一样。
(2)使用激活函数ReLU进非线性变换。
(3)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(14+21-3)/1+1=14.所以最后得到的特征图大小为14x14x512.
(4)再进行激活:ReLU
(5)再进行卷积:
填充:padding=1(padding=‘same’);步长:strides=[1,1]
计算公式:(input_size+2padding-kernel_size)/strides+1=(14+21-3)/1+1=14.所以最后得到的特征图大小为14x14x512.
(6)再进行激活:ReLU
(7)最后就是最大池化:
使用大小为2x2,步长为strides=2的池化单元进行最大池化。input_size+2padding-kernel_size)/strides+1=(14+20-2)/2+1=7.
输出的特征图大小为:7x7x512.


(六):全连接层(输入的特征图大小为7x7x512):
在这里插入图片描述
(1)改用为4096个神经元,首先经过Dense层;
(2)经过激活函数ReLU层;
(3)使用Dropout:防止过拟合,随机的断开其中的一些连接(只是逻辑上断开)。


(七)全连接层:
在这里插入图片描述

(1)改用为4096个神经元,首先经过Dense层;
(2)经过激活函数ReLU层;
(3)使用Dropout:防止过拟合,随机的断开其中的一些连接(只是逻辑上断开)。


(八)最后一层全连接层:

在这里插入图片描述
(1)改用为1000个神经元,首先经过Dense层;


(九)最后经过softmax层:
在这里插入图片描述
输出1000个类别概率值:

4.VGG16使用的卷积核大小都是3x3的,使用比之前小的卷积核有什么作用:

请看我这篇文章:
https://mydreamambitious.blog.csdn.net/article/details/123027344
其中有一点就是增大感受野:两个3x3的卷积核可以替代一个5x5的卷积核;三个3x3的卷积核可以替代一个7x7的卷积核
在这里插入图片描述
注解:其中VGG16的参数量是非常大的,其中主要的参数都集中在了全连接层:

在这里插入图片描述
如果去掉全连接层的话,参数量为:
在这里插入图片描述
参数近相差十倍。

5.Tensorflow2.6.0实现VGG16网络结构:

import os
import keras
from tensorflow.keras import layers#但是在这里我添加了BatchNormalization
model_vgg16=keras.Sequential([#网络的输入layers.InputLayer(input_shape=(224,224,3)),layers.Conv2D(64,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(64,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2,2]),layers.Conv2D(128,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(128,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2,2]),layers.Conv2D(256,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(256,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(256,kernel_size=[3,3],strides=[1,1],padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2,2]),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2, 2]),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.Conv2D(512, kernel_size=[3, 3], strides=[1, 1], padding='same'),layers.Activation('relu'),layers.BatchNormalization(),layers.MaxPool2D(pool_size=[2, 2]),#这里也可以使用全局平均池化layers.GlobalAveragePooling2D(),# layers.Flatten(),layers.Dense(4096),layers.Activation('relu'),layers.BatchNormalization(),layers.Dropout(0.5),layers.Dense(4096),layers.Activation('relu'),layers.BatchNormalization(),layers.Dropout(0.5),layers.Dense(1000),layers.Activation('softmax'),
])
#输出网络的结构
# model_vgg16.summary()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/VWW3sEB8.shtml

相关文章

深度学习之学习(1-1) VGG16网络结构详解

参见 ​​​​​​【深度学习】全面理解VGG16模型_florrie-CSDN博客_vgg16模型介绍深度学习-VGG16原理详解_£的博客-CSDN博客_vgg16 1、网络结构 根据卷积核大小和卷积层数,VGG共有6中配置,分别为A,A-LRN,B,C,D,E,其中D和E两种最为常…

【深度学习】全面理解VGG16模型

全面理解VGG16模型 VGG16的结构层次介绍结构图VGG16模型所需要的内存容量介绍卷积中的基本概念1.从input到conv1:2.从conv1到conv2之间的过渡:3.conv2到conv3:4.进入conv3:5.从conv3到conv4之间的过渡:6.最后到三层全连…

经典卷积神经网络---VGG16详解

一.VGG概述 VGGNet是牛津大学视觉几何组(Visual Geometry Group)提出的模型,该模型在2014ImageNet图像分类与定位挑战赛 ILSVRC-2014中取得在分类任务第二,定位任务第一的优异成绩。VGGNet突出的贡献是证明了很小的卷积,通过增加网络深度可以…

SpringCloud笔记

Eureka 一、不引入Eureka时 1.引入公共模块依赖 <!-- 引入公共模块依赖 --> <dependency><groupId>niit</groupId><artifactId>springcloud-api</artifactId> </dependency>引入后会发现Maven视图报错&#xff0c;此处需要在父工…

服务链路追踪怎么搞?好搞吗?

微服务架构是一个分布式架构&#xff0c;它按业务划分服务单元&#xff0c;一个分布式系统往往有很多个服务单元。由于服务单元数量众多&#xff0c;业务的复杂性&#xff0c;如果出现了错误和异常&#xff0c;很难去定位。主要体现在&#xff0c;一个请求可能需要调用很多个服…

java小白进阶之基础篇

JAVA基础语法归纳>>小白进阶~~java基础语法 >>Java概述 Java语言的发展历史 1991年出现&#xff0c;1995年正式发布 创始人&#xff1a;James Gosling 出生地&#xff1a;SUN 被Oracle公司在这里插入代码片 最新的JDK的版本&#xff1a; 2020年发布JDK14 Java体系…

WAF绕过总结+工具介绍

什么是WAF Waf是web应用防火墙&#xff08; Web Application Firewa‖l&#xff09;的简称&#xff0c;对来自Web应用程序客户端的各类请求进行内容检测和验证&#xff0c;确保其安全性与合法性&#xff0c;对非法的请求予以实时阻断&#xff0c;为web应用提供防护&#xff0c…

Java基础入门笔记(看到就是赚到)

一、初始java 1. 生活中的程序&#xff1a; 从起床到上班的过程 穿衣打扮—起床—洗漱—吃饭—出门—乘坐交通工具—到公司 2.计算机中的程序: 一组有序指令的集合,需要和计算机交流就要使用计算机语言&#xff0c;java就是计算机语言的一种 3.java能做什么&#xff1a; …

vue-plugin-hiprint vue hiprint vue使用hiprint打印控件VUE HiPrint HiPrint简单使用

vue-plugin-hiprint vue hiprint vue使用hiprint打印控件VUE HiPrint HiPrint简单使用 安装相关依赖安装 vue-plugin-hiprintJQuery安装 打印客户端 引入依赖打印 html 内容 - 简单使用根据模版打印 - 简单使用以下内容 和上面demo 没关系 &#xff01;&#xff01;&#xff01…

Kafka问题整理 (Too many open files等)/kafka重要参数总结

1.Kafka集群搭建好以后&#xff0c;运行一段时间Kafka节点挂掉&#xff0c;程序中出现如下错误 ERROR Error while accepting connection (kafka.network.Acceptor) java.io.IOException: Too many open files 或者 ERROR Error while deleting the clean shutdown file in…

picoCTF,Reverse Engineering,逆向类,42/55

picoCTF&#xff0c;Reverse Engineering&#xff0c;42/55 2019 picoCTF01、vault-door-training&#xff0c;50分02、vault-door-1&#xff0c;100分03、vault-door-3&#xff0c;200分04、vault-door-4&#xff0c;250分05、vault-door-5&#xff0c;300分06、vault-door-6&…

Java学习(12)(String类、String的查找方法、字符串转化、 替换、拆分、截取、trim方法、字符串的不可变性、StringBuilder和StringBuffer)

接上次博客&#xff1a;Java学习&#xff08;11&#xff09;&#xff1a;Java实现图书馆书库管理系统_di-Dora的博客-CSDN博客 目录 String类 构造字符串的方法&#xff1a; String 对象的比较 1、比较是否引用了同一个对象。 2、比较字符串内容是否相同 3、"int co…

渗透测试工具实战技巧合集

本文为作者总结自己在渗透测试中常用的一些小技巧。原文分为两部分&#xff0c;译者将其合二为一&#xff0c;方便大家查阅。 最好的 NMAP 扫描策略 # 适用所有大小网络最好的 nmap 扫描策略# 主机发现&#xff0c;生成存活主机列表 $ nmap -sn -T4 -oG Discovery.gnmap 192.1…

Netty堆外内存泄漏排查,这一篇全讲清楚了

上篇文章介绍了Netty内存模型原理&#xff0c;由于Netty使用不当会导致堆外内存泄漏&#xff0c;网上关于这方面的资料比较少&#xff0c;所以写下这篇文章&#xff0c;基于Netty4.1.43.Final&#xff0c;专门介绍排查Netty堆外内存相关的知识点&#xff0c;诊断工具&#xff0…

分支选择结构

分支语句又被称为选择结构&#xff0c;选择结构就是根据一个boolean表达式,来决定执行哪一些代码(代码块)。比较常见的分支语句有if语句和switch语句&#xff0c;下面将以代码的形式说明if和switch语句的基本构成以及其作用。 1、if语句&#xff1a;if语句作为选择语句&#xf…

选择结构。

1. 掌握if(如果)选择(分支)结构 注意&#xff1a; 经常会用到标志位&#xff0c;定义标志位的时候 也得考虑其位置 是局部变量还是全局变量 掌握基本if if(条件){// 条件成立时执行的内容 }掌握if-else(互斥) if(条件){// 条件成立 }else{// 条件不成立 }一般流程图也是这样…

C#选择结构

选择结构 概述IF选择语句if单分支选择结构if…else双分支选择结构if…else if…else多分支选择结构 switch选择语句基本语法 this关键字 概述 在程序当中&#xff0c;也存在选择语句&#xff0c;C#中共有2个选择语句&#xff1a;if和switch&#xff0c;if是单分支选择语句&…

5、选择结构

什么是选择结构 C程序的执行通常是按照顺序从上到下逐行执行。 而选择结构是根据某个变量或表达式的值来选择哪些语句执行&#xff0c;哪些语句不执行。 选择结构需要先进行条件判断&#xff08;对表达式的值判断&#xff09;&#xff0c;根据表达式的值选择是否执行。 三木运…

Python的选择结构

Python的选择结构—— if 语句 Python 中的选择结构就是判断真假。 Python 中的 if 语句就是选取要执行的结果&#xff0c;从一些备选的操作中进行要选择的语句。 if 语句后面跟着一个或多个可选的 elif &#xff08;“ else if ”&#xff09;&#xff0c;以及一个最终可选的…

初识C语言—— 选择结构程序设计

文章目录 一、if语句二、if语句的基本形式1.if语句形式2.if...else语句形式3.else if语句形式 三、if的嵌套形式四、条件运算符五、switch语句1switch语句的基本形式2.多路开关模式的switch语句 六、if...else语句和switch语句的区别七、总结 一、if语句 在C语言程序中&#x…