[VGG16]——网络结构介绍及搭建(PyTorch)

article/2025/4/22 18:17:41

一、VGG16的结构层次

VGG16总共有16层,13个卷积层和3个全连接层,第一次经过64个卷积核的两次卷积后,采用一次pooling,第二次经过两次128个卷积核卷积后,采用pooling;再经过3次256个卷积核卷积后。采用pooling,再重复两次三个512个卷积核卷积后,再pooling,最后经过三次全连接。

1、附上官方的vgg16网络结构图:

  • conv3-64的全称就是convolution kernel_size=3, the number of kernel=64,也就是说,这一层是卷积层,卷积核尺寸是3x3xn(n代表channels,是输入该层图像数据的通道数),该卷积层有64个卷积核实施卷积操作。
  • FC4096全称是Fully Connected 4096,是输出层连接4096个神经元的全连接层。
  • maxpool就是最大池化操作。最大值池化的窗口尺寸是2×2,步长stride=2

在这里插入图片描述

2、 VGG模型所需的内存容量:

在这里插入图片描述

 二、模型搭建

VGG16实现,基于CIFAR-10数据集

  • CIFAR-10:该数据集共有60000张彩色图像,这些图像是32*32,分为10个类,每类6000张图,50000 training images and 10000 test images.
  • CIFAR-10:CIFAR-10 and CIFAR-100 datasets (toronto.edu)

1、数据加载

#加载数据
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
#训练集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=100, shuffle=True)
#测试集
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False)
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

2、VGG16网络实现

class Vgg16_net(nn.Module):def __init__(self):super(Vgg16_net, self).__init__()self.layer1=nn.Sequential(nn.Conv2d(in_channels=3,out_channels=64,kernel_size=3,stride=1,padding=1), #(32-3+2)/1+1=32   32*32*64nn.BatchNorm2d(64),#inplace-选择是否进行覆盖运算#意思是是否将计算得到的值覆盖之前的值,比如nn.ReLU(inplace=True),#意思就是对从上层网络Conv2d中传递下来的tensor直接进行修改,#这样能够节省运算内存,不用多存储其他变量nn.Conv2d(in_channels=64,out_channels=64,kernel_size=3,stride=1,padding=1), #(32-3+2)/1+1=32    32*32*64#Batch Normalization强行将数据拉回到均值为0,方差为1的正太分布上,# 一方面使得数据分布一致,另一方面避免梯度消失。nn.BatchNorm2d(64),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=2,stride=2)   #(32-2)/2+1=16         16*16*64)self.layer2=nn.Sequential(nn.Conv2d(in_channels=64,out_channels=128,kernel_size=3,stride=1,padding=1),  #(16-3+2)/1+1=16  16*16*128nn.BatchNorm2d(128),nn.ReLU(inplace=True),nn.Conv2d(in_channels=128,out_channels=128,kernel_size=3,stride=1,padding=1), #(16-3+2)/1+1=16   16*16*128nn.BatchNorm2d(128),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)    #(16-2)/2+1=8     8*8*128)self.layer3=nn.Sequential(nn.Conv2d(in_channels=128,out_channels=256,kernel_size=3,stride=1,padding=1),  #(8-3+2)/1+1=8   8*8*256nn.BatchNorm2d(256),nn.ReLU(inplace=True),nn.Conv2d(in_channels=256,out_channels=256,kernel_size=3,stride=1,padding=1),  #(8-3+2)/1+1=8   8*8*256nn.BatchNorm2d(256),nn.ReLU(inplace=True),nn.Conv2d(in_channels=256,out_channels=256,kernel_size=3,stride=1,padding=1),  #(8-3+2)/1+1=8   8*8*256nn.BatchNorm2d(256),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)     #(8-2)/2+1=4      4*4*256)self.layer4=nn.Sequential(nn.Conv2d(in_channels=256,out_channels=512,kernel_size=3,stride=1,padding=1),  #(4-3+2)/1+1=4    4*4*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),   #(4-3+2)/1+1=4    4*4*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),   #(4-3+2)/1+1=4    4*4*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)    #(4-2)/2+1=2     2*2*512)self.layer5=nn.Sequential(nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),   #(2-3+2)/1+1=2    2*2*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),  #(2-3+2)/1+1=2     2*2*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.Conv2d(in_channels=512,out_channels=512,kernel_size=3,stride=1,padding=1),  #(2-3+2)/1+1=2      2*2*512nn.BatchNorm2d(512),nn.ReLU(inplace=True),nn.MaxPool2d(2,2)   #(2-2)/2+1=1      1*1*512)self.conv=nn.Sequential(self.layer1,self.layer2,self.layer3,self.layer4,self.layer5)self.fc=nn.Sequential(#y=xA^T+b  x是输入,A是权值,b是偏执,y是输出#nn.Liner(in_features,out_features,bias)#in_features:输入x的列数  输入数据:[batchsize,in_features]#out_freatures:线性变换后输出的y的列数,输出数据的大小是:[batchsize,out_features]#bias: bool  默认为True#线性变换不改变输入矩阵x的行数,仅改变列数nn.Linear(512,512),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(512,256),nn.ReLU(inplace=True),nn.Dropout(0.5),nn.Linear(256,10))def forward(self,x):x=self.conv(x)#这里-1表示一个不确定的数,就是你如果不确定你想要reshape成几行,但是你很肯定要reshape成512列# 那不确定的地方就可以写成-1#如果出现x.size(0)表示的是batchsize的值# x=x.view(x.size(0),-1)x = x.view(-1, 512)x=self.fc(x)return x

3、模型训练

mini-batch设置为100,每加载50个mini-batch,统计一次数据(5000张图)

'''
模型训练
'''
def net_train():epoch = 10  # 训练次数learning_rate = 1e-4  # 学习率net = Vgg16_net()criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(net.parameters(), lr=learning_rate)print('start Training.......')print("print msg : 50 mini-batches per time")for epoch in range(epoch):  # 迭代running_loss = 0.0running_acc = 0.0print('*' * 25, 'epoch {}'.format(epoch + 1), '*' * 25, "——> ")for i, data in enumerate(trainloader, 0):inputs, labels = data#print("i: {}, inputs: {}, labels: {}".format(i, len(inputs), len(labels)))# 向前传播out = net(inputs)loss = criterion(out, labels)running_loss += loss.item() * labels.size(0)_, pred = torch.max(out, 1)  # 预测最大值所在的位置标签num_correct = (pred == labels).sum()# 初始化梯度optimizer.zero_grad()outputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 打印loss 和 accrunning_acc += num_correct.item()running_loss += loss.item()if i % 50 == 49:  # print every 5000 mini-batchesprint('[%d, %5d] loss: %.5f Acc:%.5f' %(epoch + 1, i + 1, running_loss / 5000, running_acc / 5000))running_loss = 0.0running_acc = 0.0print('Finished Training')return net

4、模型测试

'''
模型测试
'''
def net_test(model):model.eval()  # 模型评估criterion = nn.CrossEntropyLoss()eval_loss = 0eval_acc = 0for data in testloader:  # 测试模型img, label = dataout = model(img)loss = criterion(out, label)eval_loss += loss.item() * label.size(0)_, pred = torch.max(out, 1)num_correct = (pred == label).sum()eval_acc += num_correct.item()print('Test Loss: {:.6f}, Acc: {:.6f}'.format(eval_loss / (len(testset)), eval_acc / (len(testset))))


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

相关文章

VGG预训练模型网络结构详解——以VGG16为例

VGG卷积神经网络是牛津大学在2014年提出来的模型。当这个模型被提出时,由于它的简洁性和实用性,马上成为了当时最流行的卷积神经网络模型。它在图像分类和目标检测任务中都表现出非常好的结果。在2014年的ILSVRC比赛中,VGG 在Top-5中取得了92…

卷积神经网络模型之——VGG-16网络结构与代码实现

文章目录 VGGNet简介VGG16网络结构使用pytorch搭建VGG16featuresclassifier完整代码 VGGNet简介 VGG原文:Very deep convolutional networks for large-scale image recognition:https://arxiv.org/pdf/1409.1556.pdf VGG在2014年由牛津大学Visual Geom…

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

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

深度学习之学习(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是单分支选择语句&…