VGG16模型详解 and 代码搭建

article/2025/8/30 5:15:08

目录

一. VGG 网络模型

二. 代码复现

1. 网络搭建

2.数据集制作(pkl)

3.源码地址


一. VGG 网络模型

         Alexnet是卷积神经网络的开山之作,但是由于卷积核太大,移动步长大,无填充,所以14年提出的VGG网络解决了这一问题。而且VGG网络结构简单,以 基础卷积和池化组成,非常适合用作CNN的入门学习。 通过卷积,池化 不断将图片 的尺寸减小, 维度升高, 提取特征。
        VGG的主要贡献是全面评估网络的深度,使用3*3卷积滤波器来提取特征。解决了Alexnet容易忽略小部分的特征。目前常用的有VGG13\VGG16网络,本文实例部分以VGG16为例。VGG模型如下:

        如图所示,一共列出了VGG11、VGG13、VGG16、VGG19等6种VGG模型, 以VGG16为例, 因为其具有16个网络层,主要注意的是这其中不包括pooling(池化层)如maxpool,avgpool等,本文以上图中的VGG16(第D列)为例进行讲解。

二. 代码复现

1. 网络搭建

        以上图中的(D列)VGG16为例, 构建模型, train.py训练代码如下,其中模型搭建如network = Sequential所示。

import tensorflow as tf
import numpy as np
import os
import cv2
from tensorflow.keras import layers, optimizers, datasets, Sequential
import sys
from six.moves import cPickle# 调用 GPU
gpu = tf.config.experimental.list_physical_devices('GPU')
if len(gpu) > 0:tf.config.experimental.set_memory_growth(gpu[0], True)def main():######第一步,train, test # 加载数据#  batchsize 指每次 用作训练样本数, 比如训练样本总数为10000, 其中 训练集 8000张  验证集2000#  Train_batchsize = 80 ,则说明将所有数据训练一轮需要 8000/80 = 100 步 (step = 100) 也称一轮训练迭代100次#  训练时 还有一个参数 epoch, 表示整个训练 需要轮几次, 如epoch = 100 , 则表示 需要将整个 数据集训练100轮#  则整个训练 需要 迭代 epoch * (8000/Train_batchsize) = 10000 次Train_batchsize = 80val_batchsize = 50# 加载 训练集 和 验证集, # x -> 训练用图片数据  x_val -> 验证用图片数据  # y -> 训练用图片标签  y_val -> 验证用图片标签(x, y), (x_val, y_val) = Cap_load_data()# 将标签 进行维度 调整 [n, 1] => [n]y = tf.squeeze(y, axis=1)  # [n, 1] => [n]y_val = tf.squeeze(y_val, axis=1)  # [n, 1] => [n]# 将数据进行打乱,并进行切片train_db = tf.data.Dataset.from_tensor_slices((x, y))train_db = train_db.shuffle(1000).map(preprocess).batch(Train_batchsize).repeat()val_db = tf.data.Dataset.from_tensor_slices((x_val, y_val))val_db = val_db.shuffle(500).map(preprocess).batch(val_batchsize).repeat()# 验证存储的pkl数据是否和 实际图片的一致# print(x.shape,y.shape,x_val.shape,y_val.shape)# print(x[0,0,0,:])## src = cv2.imread(r"XXX.jpg")# src = cv2.resize(src, (64, 64))# src = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)  # 因为cv2.imread  opencv中默认颜色通道为BGR# print(src[0,0,:])######第二步,创建模型# 卷积层取特征# maxpool层强化特征并且把图片尺寸减小一半# 这里如果还是两层conv2d就会无法收敛network = Sequential([    # 64x64layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(64, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.MaxPool2D([2, 2]),  #layers.Conv2D(128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(128, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.MaxPool2D([2, 2]), #32x32,# layers.MaxPool2D([2, 2]),#16x16,layers.Conv2D(256, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(256, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(256, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.MaxPool2D([2, 2]),layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.MaxPool2D([2, 2]),layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.Conv2D(512, kernel_size=[3, 3], padding="same", activation=tf.nn.relu),layers.MaxPool2D([2, 2]),# 转换形状# layers.Reshape((-1, 512), input_shape=(-1, 1, 1, 512)), # 这里加一个 Reshape层就好啦layers.Flatten(),layers.Dense(256, activation=tf.nn.relu),layers.Dense(128, activation=tf.nn.relu),layers.Dense(1, activation=tf.nn.sigmoid),])network.build(input_shape=[None, 64, 64, 3])network.summary()#####第三步,训练参数配置# 用 keras 的高层API直接训练# network.compile(#    optimizer=optimizers.Adam(lr=1e-4),#    loss=tf.losses.categorical_crossentropy, # MSE 是个对象, CategoricalCrossentropy 是个类#    metrics=['accuracy']# )# network.compile(optimizer='adam',#                 loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),#                 metrics=['accuracy'])network.compile(optimizer='rmsprop',loss=tf.losses.binary_crossentropy,metrics=['accuracy'])#####第四步,训练network.fit(train_db, epochs=20, verbose=2, steps_per_epoch=x.shape[0]//Train_batchsize, validation_steps=x_val.shape[0]//val_batchsize, validation_data=val_db, validation_freq=1)# .fit的verbose 输出日志模式network.save('XXX.h5')def preprocess(x, y):   # 数据集处理  把data 和 label 都设置为float型x = tf.cast(x, dtype=tf.float32) / 255.y = tf.cast(y, dtype=tf.int32)return x, ydef Cap_load_data():# path = r'XXXXX'path = r'XXXXXX' # Data1 在Data基础上加了更多的小电容fpath = os.path.join(path, 'train.pkl')x_train, y_train = load_batch(fpath)fpath = os.path.join(path, 'test.pkl')x_val, y_val = load_batch(fpath)y_train = np.reshape(y_train, (len(y_train), 1))  #标签y_val = np.reshape(y_val, (len(y_val), 1))# if K.image_data_format() == 'channels_last':#     x_train = x_train.transpose(0, 2, 3, 1)#     x_val = x_val.transpose(0, 2, 3, 1)return (x_train, y_train), (x_val, y_val)def load_batch(fpath):  # 使用cpick 读取文件# with open(fpath, 'rb') as f:#     if sys.version_info < (3,):#       d = cPickle.load(f)#     else:#       d = cPickle.load(f, encoding='bytes')#       # decode utf8#       d_decoded = {}#       for k, v in d.items():#         d_decoded[k.decode('utf8')] = v#       d = d_decodedwith open(fpath, 'rb') as f:d = cPickle.load(f, encoding='bytes')data = d['data']labels = d['labels']data = data.reshape(data.shape[0], 64, 64, 3)return data, labelsif __name__ == "__main__":main()

2.数据集制作(pkl)

import tensorflow as tf
import numpy as np
import cv2
import os
import sys
from six.moves import cPickledef main():pklPath = r"XXX.pkl"input_size = (64, 64)data_oneDim = input_size[0] * input_size[1] * 3# 测试集图片的张数num_trainImage = 4000data = np.array([[0 for x in range(data_oneDim)] for y in range(num_trainImage)])# 就本数据集而言,二分类,正反样例各占50% , 所以每种类设置数量为 num_trainImage/2 标签label1 = [0 for x in range(int(num_trainImage/2))]label2 = [1 for x in range(int(num_trainImage/2))]label = np.array(label1 + label2)# 上下各2000张 每张64*64  3通道# 64*64*3 = 12288   4000*12288 的 numpy的uint8s数组ImageFile1 = r"XXX" + "\\"ImageNames1 = os.listdir(ImageFile1)i = 0for Name1 in ImageNames1:imagePath = ImageFile1 + Name1src = cv2.imread(imagePath)src = cv2.resize(src, (64, 64))src = cv2.cvtColor(src,cv2.COLOR_BGR2RGB)  # 因为cv2.imread  opencv中默认颜色通道为BGR# src_data = np.array([src[:,:,0],src[:,:,1],src[:,:,2]])src_data = np.array(src)src_data = src_data.reshape(12288)data[i] = src_datai = i + 1# print(src[0,:,0])      测试输出  转化后的src_data 第一行的 r 分量是否 和src一致# print(src_data[:64])# print(src.shape)# print(src_data.shape)ImageFile2 = r"XXX" + "\\"ImageNames2 = os.listdir(ImageFile2)for Name2 in ImageNames2:imagePath = ImageFile2 + Name2src = cv2.imread(imagePath)src = cv2.resize(src, input_size)src = cv2.cvtColor(src,cv2.COLOR_BGR2RGB)  # 因为cv2.imread  opencv中默认颜色通道为BGR# src_data = np.array([src[:,:,0],src[:,:,1],src[:,:,2]])src_data = np.array(src)src_data = src_data.reshape(data_oneDim)data[i] = src_datai = i + 1Cap_dict = { 'data': data , 'labels':label }print(Cap_dict['data'].shape)with open(pklPath,'wb') as f:cPickle.dump(Cap_dict,f)if __name__ == "__main__":main()

3.源码地址

https://github.com/mcuwangzaiacm/VGG16_tensorflow2.0
        


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

相关文章

动手学习VGG16

VGG 论文 《Very Deep Convolutional Networks for Large-Scale Image Recognition》 论文地址&#xff1a;https://arxiv.org/abs/1409.1556 使用重复元素的网络(VGG) 以学习VGG的收获、VGG16的复现二大部分&#xff0c;简述VGG16网络。 一. 学习VGG的收获 VGG网络明确指…

VGG16

VGG16模型的学习以及源码分析 part one 主要学习参考 pytorch 英文文档VGG16学习笔记VGG16网络原理分析与pytorch实现【深度学习】全面理解VGG16模型VGG模型的pytorch代码实现VGG16源代码详解【论文】 VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION p…

VGG16 - 用于分类和检测的卷积网络

VGG16是由牛津大学的K. Simonyan和A. Zisserman在“用于大规模图像识别的非常深卷积网络”的论文中提出的卷积神经网络模型。 该模型在ImageNet中实现了92.7&#xff05;的前5个测试精度&#xff0c;这是属于1000个类的超过1400万张图像的数据集。它是ILSVRC-2014提交的着名模型…

VGG-16网络结构详解

VGG&#xff0c;又叫VGG-16&#xff0c;顾名思义就是有16层&#xff0c;包括13个卷积层和3个全连接层&#xff0c;是由Visual Geometry Group组的Simonyan和Zisserman在文献《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷积神经网络模型&…

经典卷积神经网络——VGG16

VGG16 前言一、VGG发展历程二、VGG网络模型三、VGG16代码详解1.VGG网络架构2.VGG16网络验证2.读取数据&#xff0c;进行数据增强3.训练模型&#xff0c;测试准确率 四、VGG缺点 前言 我们都知道Alexnet是卷积神经网络的开山之作&#xff0c;但是由于卷积核太大&#xff0c;移动…

VGG16网络模型的原理与实现

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

深度学习——VGG16模型详解

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

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

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

RK3399—中断

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

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

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

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

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

RK3399学习

RK3399学习 韦东山rk3399&#xff1a;http://dev.t-firefly.com/forum-460-1.html firefly官网教程&#xff1a;http://wiki.t-firefly.com/zh_CN/Firefly-RK3399/started.html firefly官网3399资料&#xff1a;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的医用视频终端设计

当前在各种先进的信息通信技术的驱动下&#xff0c;医疗行业已呈现出信息化、移动化、智能化的发展趋势。特别是 5G 通信技术的落地应用推动了智慧医疗行业的 蓬勃发展&#xff0c;涌现出大量基于 5G 技术的医疗健康应用与服务&#xff0c;进一步融合了 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🚀返回专栏总目录 沉淀、分享、成长,让自己和他人都能有所收获!😄 📢启动速度是嵌入式产品一个重要的性能指标,更快的启动速度会让客户有更好的使用体验,在某些方面还会节省能耗,因为可以直接关机而不需要休眠。 启动速…