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

article/2025/4/22 18:06:21

VGG16网络结构及代码

下图为VGG网络结构图,最常用的就是表中的D结构,16层结构(13层卷积+3层全连接层),卷积的stride为1,padding为1,maxpool的大小为2,stride为2(池化只改变图像的大小,不改变图像的深度)
在这里插入图片描述
vgg网络结构可以看作两部分:特征提取网络(连接层之前)+分类网络(3层全连接层)

VGG模型搭建

VGG模型一共分为两部分,特征提取部分和分类网络部分,我们分别进行搭建

特征提取网络

1、定义字典文件,定义了四个网络结构

cfgs = {  'vgg11': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'], # 列表的数字代表卷积层卷积核的个数,字符M代表池化层的结构'vgg13': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],'vgg16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],'vgg19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}

2、定义一个函数,生成vgg网络第一部分:特征提取网络

def make_features(cfg: list): # 传入一个配置变量layers = []  # 定义一个空列表in_channels = 3for v in cfg:if v == "M": # 判断是否是池化层layers += [nn.MaxPool2d(kernel_size=2, stride=2)]else:conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1) # v表示输出通道layers += [conv2d, nn.ReLU(True)]in_channels = v # 卷积之后,输出通道变为vreturn nn.Sequential(*layers) # *layers代表通过非关键字参数的形式传入进去

分类网络

1、定义VGG类

# vgg类
class VGG(nn.Module):  # features代表提取特征网络def __init__(self, features, num_classes=1000, init_weights=False):super(VGG, self).__init__()self.features = featuresself.classifier = nn.Sequential(nn.Dropout(p=0.5), # 减少过拟合,50%比例随机失活神经元nn.Linear(512*7*7, 4096),nn.ReLU(True),nn.Dropout(p=0.5),nn.Linear(4096, 4096),nn.ReLU(True),nn.Linear(4096, num_classes))if init_weights:self._initialize_weights()def forward(self, x):# N x 3 x 224 x 224x = self.features(x)# N x 512 x 7 x 7 展平操作x = torch.flatten(x, start_dim=1) # 从第一个维度开始展平,第0个维度是batch# N x 512*7*7x = self.classifier(x)return x# 初始化权重函数,会便利网络的每一个子模块,也就是遍历每一层def _initialize_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d): # 如果当前层为卷积层# nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')nn.init.xavier_uniform_(m.weight) # 初始化卷积核参数if m.bias is not None: # 如果卷积核有偏置,设置偏置为0nn.init.constant_(m.bias, 0)elif isinstance(m, nn.Linear): # 如果当前层为全连接层nn.init.xavier_uniform_(m.weight)# nn.init.normal_(m.weight, 0, 0.01)nn.init.constant_(m.bias, 0)

2、实例化vgg

# 实例化vgg
def vgg(model_name="vgg16", **kwargs):try:cfg = cfgs[model_name]except:print("Warning: model number {} not in cfgs dict!".format(model_name))exit(-1)model = VGG(make_features(cfg), **kwargs) # **kwargs可变长度的字典变量return modelvgg_model = vgg(model_name='vgg13')

VGG训练

import os
import jsonimport torch
import torch.nn as nn
from torchvision import transforms, datasets
import torch.optim as optim
from tqdm import tqdmfrom model import vggdef main():device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")print("using {} device.".format(device))
# 数据预处理data_transform = {"train": transforms.Compose([transforms.RandomResizedCrop(224), # 随即裁剪transforms.RandomHorizontalFlip(), # 随机翻转transforms.ToTensor(), # 转为tensortransforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]),# 标准化处理"val": transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])}data_root = os.path.abspath(os.path.join(os.getcwd(), "../.."))  # get data root pathimage_path = os.path.join(data_root, "data_set", "flower_data")  # flower data set pathassert os.path.exists(image_path), "{} path does not exist.".format(image_path)train_dataset = datasets.ImageFolder(root=os.path.join(image_path, "train"),transform=data_transform["train"])train_num = len(train_dataset)# {'daisy':0, 'dandelion':1, 'roses':2, 'sunflower':3, 'tulips':4}flower_list = train_dataset.class_to_idxcla_dict = dict((val, key) for key, val in flower_list.items())# write dict into json filejson_str = json.dumps(cla_dict, indent=4)with open('class_indices.json', 'w') as json_file:json_file.write(json_str)batch_size = 32nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8])  # number of workersprint('Using {} dataloader workers every process'.format(nw))train_loader = torch.utils.data.DataLoader(train_dataset,batch_size=batch_size, shuffle=True,num_workers=nw)validate_dataset = datasets.ImageFolder(root=os.path.join(image_path, "val"),transform=data_transform["val"])val_num = len(validate_dataset)validate_loader = torch.utils.data.DataLoader(validate_dataset,batch_size=batch_size, shuffle=False,num_workers=nw)print("using {} images for training, {} images for validation.".format(train_num,val_num))# test_data_iter = iter(validate_loader)# test_image, test_label = test_data_iter.next()model_name = "vgg16"net = vgg(model_name=model_name, num_classes=5, init_weights=True)net.to(device)loss_function = nn.CrossEntropyLoss()optimizer = optim.Adam(net.parameters(), lr=0.0001)epochs = 30best_acc = 0.0save_path = './{}Net.pth'.format(model_name)train_steps = len(train_loader)for epoch in range(epochs):# trainnet.train()running_loss = 0.0train_bar = tqdm(train_loader)for step, data in enumerate(train_bar):images, labels = dataoptimizer.zero_grad()outputs = net(images.to(device))loss = loss_function(outputs, labels.to(device))loss.backward()optimizer.step()# print statisticsrunning_loss += loss.item()train_bar.desc = "train epoch[{}/{}] loss:{:.3f}".format(epoch + 1,epochs,loss)# validatenet.eval()acc = 0.0  # accumulate accurate number / epochwith torch.no_grad():val_bar = tqdm(validate_loader)for val_data in val_bar:val_images, val_labels = val_dataoutputs = net(val_images.to(device))predict_y = torch.max(outputs, dim=1)[1]acc += torch.eq(predict_y, val_labels.to(device)).sum().item()val_accurate = acc / val_numprint('[epoch %d] train_loss: %.3f  val_accuracy: %.3f' %(epoch + 1, running_loss / train_steps, val_accurate))if val_accurate > best_acc:best_acc = val_accuratetorch.save(net.state_dict(), save_path)print('Finished Training')if __name__ == '__main__':main()

VGG预测

import os
import jsonimport torch
from PIL import Image
from torchvision import transforms
import matplotlib.pyplot as pltfrom model import vggdef main():device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")data_transform = transforms.Compose([transforms.Resize((224, 224)),transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])# load imageimg_path = "../tulip.jpg"assert os.path.exists(img_path), "file: '{}' dose not exist.".format(img_path)img = Image.open(img_path)plt.imshow(img)# [N, C, H, W]img = data_transform(img)# expand batch dimensionimg = torch.unsqueeze(img, dim=0)# read class_indictjson_path = './class_indices.json'assert os.path.exists(json_path), "file: '{}' dose not exist.".format(json_path)json_file = open(json_path, "r")class_indict = json.load(json_file)# create modelmodel = vgg(model_name="vgg16", num_classes=5).to(device)# load model weightsweights_path = "./vgg16Net.pth"assert os.path.exists(weights_path), "file: '{}' dose not exist.".format(weights_path)model.load_state_dict(torch.load(weights_path, map_location=device))model.eval()with torch.no_grad():# predict classoutput = torch.squeeze(model(img.to(device))).cpu()predict = torch.softmax(output, dim=0)predict_cla = torch.argmax(predict).numpy()print_res = "class: {}   prob: {:.3}".format(class_indict[str(predict_cla)],predict[predict_cla].numpy())plt.title(print_res)print(print_res)plt.show()if __name__ == '__main__':main()

参考视频:https://www.bilibili.com/video/BV1i7411T7ZN?spm_id_from=333.999.0.0


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

相关文章

VGG16网络结构复现(Pytorch版)

VGG有6种子模型,分别是A、A-LRN、B、C、D、E,我们常看到的基本是D、E这两种模型,即VGG16,VGG19 为了方便阅读,并没有加上激活函数层 from torch import nn import torch from torchsummary import summaryclass VGG…

手动搭建的VGG16网络结构训练数据和使用ResNet50微调(迁移学习)训练数据对比(图像预测+前端页面显示)

文章目录 1.VGG16训练结果:2.微调ResNet50之后的训练结果:3.结果分析:4.实验效果:(1)VGG16模型预测的结果:(2)在ResNet50微调之后预测的效果: 5.相关代码和知…

卷积神经网络——vgg16网络及其python实现

1、介绍 VGG-16网络包括13个卷积层和3个全连接层,网络结构较LeNet-5等网络变得十分复杂,但同时也有不错的效果。VGG16有强大的拟合能力在当时取得了非常的效果,但同时VGG也有部分不足:1、巨大参数量导致训练时间过长&#xf…

VGG16系列III: 网络模型结构

目录 Part I: CNN的基础构件 一张图片如何作为输入? 什么是卷积 什么是Padding 什么是池化(pooling) 什么是Flatten 什么是全连接层 什么是Dropout 什么是激活函数 VGG16的整体架构图 Part II: VGG 网络架构 典型VGG网络结构 VGG 网络参数数量计算: P…

VGG网络结构(一)

刚开始接触深度学习、卷积神经网络的时候非常懵逼,不知道从何入手,我觉得应该有一个进阶的过程,也就是说,理应有一些基本概念作为奠基石,让你有底气去完全理解一个庞大的卷积神经网络: 本文思路&#xff1a…

VGG 网络结构

从图中可以看出VGG结构由5层卷积层、3层全连接层、softmax输出层构成,层与层之间使用max-pooling(最大池化)分开,所有隐层的激活单元都采用ReLU函数。VGG最大的贡献就是证明了卷积神经网络的深度增加和小卷积核的使用对网络的最终…

PyTorch之VGG16网络结构详解以及源码解读

论文:Very Deep Convolutional Networks for Large-Scale Image Recognition 简单介绍 意义: 证明了增加小卷积核的个数以及网络深度可以提高分类结果的正确率。 预处理: 各通道减去RGB在训练集上的均值。 特点: 1)使用…

VGG-16网络结构

一、VGG-16网络框架介绍 VGGNet是牛津大学计算机视觉组(Visual Geometry Group)和Google DeepMind公司的研究员一起研发的深度卷积神经网络。 VGGNet探索了卷积神经网络的深度与其性能之间的关系,通过反复堆叠33的小型卷积核和22的最大池化层…

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

一、VGG16的结构层次 VGG16总共有16层,13个卷积层和3个全连接层,第一次经过64个卷积核的两次卷积后,采用一次pooling,第二次经过两次128个卷积核卷积后,采用pooling;再经过3次256个卷积核卷积后。采用pooli…

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; …