经典卷积神经网络——VGG16

article/2025/8/30 5:10:48

VGG16

  • 前言
  • 一、VGG发展历程
  • 二、VGG网络模型
  • 三、VGG16代码详解
    • 1.VGG网络架构
    • 2.VGG16网络验证
    • 2.读取数据,进行数据增强
    • 3.训练模型,测试准确率
  • 四、VGG缺点


前言

我们都知道Alexnet是卷积神经网络的开山之作,但是由于卷积核太大,移动步长大,无填充,所以14年提出的VGG网络解决了这一问题


一、VGG发展历程

VGG网络由牛津大学在2014年ImageNet挑战赛本地和分类追踪分别获得了第一名和第二名。研究卷积网络深度对其影响在大规模图像识别设置中的准确性,主要贡献是全面评估网络的深度,使用3*3卷积滤波器来提取特征。解决了Alexnet容易忽略小部分的特征。

二、VGG网络模型

在这里插入图片描述
从这张图中可以看到,VGG网络有11-19层,今天我们主要了解VGG16,VGG网络有一个特点,在每一次池化之后,经过卷积通道数都会翻倍,这样的好处就是为了保留更多的特征。
VGG16一个有13个卷积层3个全连接层。

三、VGG16代码详解

1.VGG网络架构

1.通过上面表格我们可以发现,经过max池化之后,通道数会翻倍,我们可以为了减少代码量,把这一过程封装成一个类,在使用过程中,直接调用就可以了。

class tiao(nn.Module):def __init__(self,shuru):super(tiao, self).__init__()self.conv1=nn.Conv2d(in_channels=shuru,out_channels=shuru*2,kernel_size=(3,3))self.conv2=nn.Conv2d(in_channels=shuru*2,out_channels=shuru*2,kernel_size=(3,3))self.relu=nn.ReLU()def forward(self,x):x1=self.conv1(x)x2=self.relu(x1)x3=self.conv2(x2)x4=self.relu(x3)return x4

这个类,很简单就是两层卷积,加两层激活函数,输出通道数翻倍
2.第二步就可以按照表格实现VGG16网络
2.1
输入三通道,输出64通道,卷积核为3
在这里插入图片描述

self.conv1=nn.Conv2d(in_channels=3,out_channels=64,kernel_size=(3,3))
self.conv2=nn.Conv2d(in_channels=64,out_channels=64,kernel_size=(3,3))

2.2
经过最大池化,通道数翻倍 输入64通道 经过两次卷积 输出通道128
在这里插入图片描述
这里直接调用上面封装好的类就行

self.tiao128=tiao(64)

2.3
经过最大池化,输入128通道 经过两次33卷积一次11卷积 输出通道256
在这里插入图片描述

self.tiao256=tiao(128)
self.conv1_256=nn.Conv2d(in_channels=256,out_channels=256,kernel_size=(1,1))

2.4
经过最大池化,输入256通道 经过两次33卷积一次11卷积 输出通道512
在这里插入图片描述

self.tiao512=tiao(256)
self.conv1_512=nn.Conv2d(in_channels=512,out_channels=512,kernel_size=(1,1))

2.5
经过最大池化,输入512通道,经过两次33卷积一次11卷积 输出通道512
在这里插入图片描述

self.conv512 = nn.Conv2d(in_channels=512, out_channels=512, kernel_size=(3, 3))self.conv1_512=nn.Conv2d(in_channels=512,out_channels=512,kernel_size=(1,1))

2.6
最后的三层全连接,这里要注意,使用自适应池化,池化之后图片尺寸是7*7
在这里插入图片描述

self.zsy=nn.AdaptiveAvgPool2d(7)
self.l1=nn.Linear(512*7*7,4096)
self.l2=nn.Linear(4096,4096)
self.l3=nn.Linear(4096,10)

2.7
还有relu激活函数,dropout随机失活函数,这里为了整洁,图表没有明确指出

self.relu=nn.ReLU()self.dropout=nn.Dropout2d(p=0.2)

2.8
最后就是前向传播

  x1=self.conv1(x)x2=self.relu(x1)x3=self.conv2(x2)x4=self.maxpool(x3)x5=self.tiao128(x4)x6=self.maxpool(x5)x7=self.tiao256(x6)x8=self.conv1_256(x7)x9=self.maxpool(x8)x10=self.tiao512(x9)x11=self.conv1_512(x10)x12=self.maxpool(x11)x13=self.conv512(x12)x14=self.conv512(x13)x15=self.conv1_512(x14)x16=self.zsy(x15)x17=x16.view(x16.size()[0],-1)x18=self.l1(x17)x19 = self.relu(x18)x20=self.dropout(x19)x22 = self.l2(x20)x23=self.relu(x22)x24=self.dropout(x23)x25=self.l3(x24)return x25

到这里VGG16网络就全部完成了

2.VGG16网络验证

这里我们可以进行验证,看网络有没有什么问题

model=VGG16()
input=torch.randn(1,3,224,224)
output=model(input).cuda()
print(output)

在这里插入图片描述

2.读取数据,进行数据增强

 transform=transforms.Compose([#图像增强transforms.Resize(120),transforms.RandomHorizontalFlip(),transforms.RandomCrop(224),transforms.ColorJitter(brightness=0.5,contrast=0.5,hue=0.5),#转变为tensor 正则化transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)) #正则化])

读取数据时,可以调整线程数,batch_size可以使代码跑起来更快,提高GPU利用率,这里要注意一个问题,线程数过大新手会出现页面太小报错,这时候调整虚拟内存就可以了

trainset=tv.datasets.CIFAR10(root=r'E:\桌面\资料\cv3\数据集\cifar-10-batches-py',train=True,download=True,transform=transform)trainloader=data.DataLoader(trainset,batch_size=8,drop_last=True,shuffle=True, #乱序num_workers=4,)testset=tv.datasets.CIFAR10(root=r'E:\桌面\资料\cv3\数据集\cifar-10-batches-py',train=False,download=True,transform=transform)testloader=data.DataLoader(testset,batch_size=4,drop_last=True,shuffle=False,num_workers=2)

3.训练模型,测试准确率

数据读取完成,我们就可以训练模型,以及测试模型准确率

 for i in range(3):running_loss=0for index,data in enumerate(trainloader):x,y=datax=x.cuda()y=y.cuda()x,y=Variable(x),Variable(y)opt.zero_grad()h=model(x)loss1=loss(h,y)loss1.backward()opt.step()running_loss+=loss1.item()if index % 10 == 9:avg_loss = running_loss/ 10.running_loss = 0print('avg_loss', avg_loss)if index%1000==99:acc=0total=0for data  in testloader:images,labels=dataoutputs=model(Variable(images.cuda()))_,predicted=torch.max(outputs.cpu(),1)total+=labels.size(0)bool_tensor=(predicted==labels)acc+=bool_tensor.sum()print("1000张精度为 %d  %%"%(100*acc/total))

四、VGG缺点

在vgg网络中,按照道理来说,随着层数的不断提高,网络模型会越来越好,但是研究发现,随着层数的不断提高,准确率缺不断下降,为了这个问题,随后提出的残差网络,解决了这一问题。


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

相关文章

VGG16网络模型的原理与实现

VGG 最大的特点就是通过比较彻底地采用 3x3 尺寸的卷积核来堆叠神经网络,这样也加深整个神经网络的深度。这两个重要的改变对于人们重新定义卷积神经网络模型架构也有不小的帮助,至少证明使用更小的卷积核并且增加卷积神经网络的深度,可以更有…

深度学习——VGG16模型详解

1、网络结构 VGG16模型很好的适用于分类和定位任务,其名称来自牛津大学几何组(Visual Geometry Group)的缩写。 根据卷积核的大小核卷积层数,VGG共有6种配置,分别为A、A-LRN、B、C、D、E,其中D和E两种是最…

RK3399平台开发系列讲解(PCI/PCI-E)5.54、PCIE INTx中断机制

文章目录 一、PCIe中断过程二、PCIE 控制器支持的中断三、PCIE 控制器注册中断四、PCIe设备中断号分配沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章将介绍RK3399平台PCIE总线中断INTx相关内容。 一、PCIe中断过程 层级结构为:PCIe设备 => PCIe控制器 =&g…

RK3399—中断

中断是操作系统最常见的事件之一,无论是系统层的“软中断”还是CPU底层的“硬中断”都是编程时常用的。中断的作用之一是充分利用CPU资源,正常情况下,CPU执行用户任务,当外设触发中断产生时,CPU停止当前任务&#xff0…

基于RK3399分析Linux系统下的CPU时钟管理 - 第3篇

1. 时钟系统结构 rockchip的时钟系统代码位于drivers/clk/rockchip,目录整体结构如下: ├── rockchip │ ├── clk.c---------------时钟系统注册 │ ├── clk-cpu.c-----------CPU调频 │ ├── clk-ddr.c-----------DDR调频 │ ├──…

基于RK3399+PID的手持稳定云台的设计与实现

手持稳定云台的主要作用是将外界环境因数引起的相机姿态变化进行隔离。如因操作者运动造成的机体震动、风阻力矩等,为了确保工作中相机的视轴始终保持期望的姿态不动。云台相机要拍摄出高质量的影像最重要的就是保证相机的视轴相对目标保持稳定。因此在相机拍摄的过…

RK3399学习

RK3399学习 韦东山rk3399:http://dev.t-firefly.com/forum-460-1.html firefly官网教程:http://wiki.t-firefly.com/zh_CN/Firefly-RK3399/started.html firefly官网3399资料:http://dev.t-firefly.com/forum-263-1.html 100ask 3399-pc教…

RK3399平台开发系列讲解(内核入门篇)1.53、platform平台设备

🚀返回专栏总目录 文章目录 一、设备配置-非设备树1.1、资源1.2、平台数据1.3、声明平台设备二、设备配置 - DTS沉淀、分享、成长,让自己和他人都能有所收获!😄 📢平台设备在内核中表示为struct platform_device的实例。 有两种方法可以把有关设备所需的资源(IRQ、DMA…

RK3399 Android7.1 编译

RK3399 Android7.1 编译 文章目录 RK3399 Android7.1 编译前言设置 Linux 编译环境安装 JDK可选- 更新默认的 Java 版本 安装所需的程序包(Ubuntu 14.04) 下载 Android SDK 前言 RK官网编译 Android搭建编译环境 设置 Linux 编译环境 使用的环境Linux 16.0.4 安装 JDK 如…

基于RK3399+5G的医用视频终端设计

当前在各种先进的信息通信技术的驱动下,医疗行业已呈现出信息化、移动化、智能化的发展趋势。特别是 5G 通信技术的落地应用推动了智慧医疗行业的 蓬勃发展,涌现出大量基于 5G 技术的医疗健康应用与服务,进一步融合了 5G 、 物联网与大数据…

RK3399平台开发系列讲解(PCI/PCI-E)PCIE相关配置说明

🚀返回专栏总目录 文章目录 一、DTS 配置二、menuconfig 配置三、cmdline 配置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍在使用 RK3399 平台 PCIE 时候的配置。 一、DTS 配置 ep-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; 此项是设置 PCIe…

RK3399快速上手 | 02-rockchip rk3399 linux sdk的使用(编译内核、编译uboot)

更新时间更新内容2022-09-15增加内核编译方法2022-10-21增加uboot编译方法和sdk开发版配置链路分析一、sdk区别 瑞芯微提供了两套sdk,一套是通过官方git仓库释放,适合于项目使用,另一套是通过github释放,适合于爱好者。 本文中使用从瑞芯微官方释放的正式linux sdk 2.7版…

RK3399平台开发系列讲解(中断篇)中断控制器驱动初始化

🚀返回专栏总目录 文章目录 一、设备树源文件1.1、gic控制器节点1.2、timer节点二、中断控制器匹配表三、中断控制器初始化3.1、函数of_irq_init3.2、函数gicv3_of_init3.3、函数gic_init_bases沉淀、分享、成长,让自己和他人都能有所收获!😄 一、设备树源文件 ARM64架构…

RK3399平台开发系列讲解(内存篇)15.34、 Linux 进程内存布局

🚀返回专栏总目录 文章目录 一、抽象内存布局二、32位机器 Linux 进程内存布局三、64位机器 Linux 进程内存布局沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 我们一起来看下进程内部的虚拟内存布局,或者说单一进程是如何安排自己的各种数据的。 一、抽象内存布…

RK3399平台开发系列讲解(内核调试篇)2.50、嵌入式产品启动速度优化

平台内核版本安卓版本RK3399Linux4.4Android7.1🚀返回专栏总目录 沉淀、分享、成长,让自己和他人都能有所收获!😄 📢启动速度是嵌入式产品一个重要的性能指标,更快的启动速度会让客户有更好的使用体验,在某些方面还会节省能耗,因为可以直接关机而不需要休眠。 启动速…

钉钉F1 RK3399 咸鱼80元板子使用记录

1.简单介绍 12V电源&#xff0c;建议2A&#xff0c; 默认插电不开机&#xff0c;有大佬找到金属罩下的焊盘&#xff0c;短接可上电开机。 在usb旁边的旁边有个端子接口&#xff0c;短接就可以开机&#xff0c;建议找个一样大的接口接个开关&#xff0c;到目前为止还未测试需要…

RK3399平台开发系列讲解(网络篇)7.38、网卡驱动程序数据结构

平台内核版本安卓版本RK3399Linux4.4Android7.1🚀返回专栏总目录 文章目录 一、套接字缓冲区结构:sk_buff二、网络接口结构:net_device沉淀、分享、成长,让自己和他人都能有所收获!😄 📢处理网卡设备时需要使用两种数据结构。 struct sk_buff结构在include/linux/skb…

RK3399平台开发系列讲解(中断篇)中断控制器(Generic Interrupt Controller)

🚀返回专栏总目录 文章目录 一、GIC硬件的实现形态二、主要的功能块三、中断类型四、中断状态沉淀、分享、成长,让自己和他人都能有所收获!😄 📢外围设备不是把中断请求直接发给处理器,而是发给中断控制器,由中断控制器转发给处理器。ARM公司提供了一种标准的中断控制…

RK3399平台开发系列讲解(DMA篇)深刻理解DMA

🚀返回专栏总目录 文章目录 一、什么是DMA二、DMA的产生:背景三、理解 DMA:协处理器沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将带领大家深刻理解DMA。 一、什么是DMA DMA (Direct Memory Access) is used to copy data directly between devices and R…

RK3399——裸机大全

CSDN仅用于增加百度收录权重&#xff0c;排版未优化&#xff0c;日常不维护。请访问&#xff1a;www.hceng.cn 查看、评论。 本博文对应地址: https://hceng.cn/2018/08/16/RK3399——裸机大全/#more 以64位的RK3399为例&#xff0c;实现裸机的启动、中断、串口(printf移植)、…