基于VGG16的猫狗分类实战

article/2025/8/30 4:01:33

1 使用卷积神经网络识别猫和狗数据集

1.1 理论基础

1.1.1  VGG架构

VGG16是由Karen Simonyan和Andrew Zisserman于2014年在论文“VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE SCALE IMAGE RECOGNITION”中提出的一种处理多分类、大范围图像识别问题的卷积神经网络架构,成功对ImageNet数据集的14万张图片进行了1000个类别的归类并有92.7%的准确率。

本项目即对Pytorch官方预训练的VGG16网络进行微调并完成了猫狗分类任务。实际的微调方法也十分简单,仅需将分类层的最后一层修改为(1x1x2)即可将分类结果从1000类修改为二分类。

图1 VGG16架构图

1.1.2  卷积神经网络

      卷积神经网络是在深度神经网络的基础上改进的专用于图像识别的神经网络模型,其拥有四个主要特征层:卷积层、池化层、激活层、全连接层(深度神经网络)。其中卷积层通过采用卷积核对输入数据进行处理,提取输入数据的特定特征;池化层通过压缩图像数据大小实现神经网络运算的加速;激活层的作用与其在深度神经网络中一致,用于模拟人脑神经元的刺激结果;全连接层实际上即是深度神经网络,即图像数据经卷积层、池化层、激活层处理后输入深度神经网络进行分类运算。

1.1.3  深度神经网络

      深度神经网络是深度学习的基础算法,下图为深度神经网络的部分介绍。

 

图2 深度神经网络的结构

图3 深度神经网络节点内部算法

2 代码

2.1 main.py

import torch
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
from training_settings import train, val
from vgg16 import vgg16
import os# BATCH大小
BATCH_SIZE = 20
# 迭代次数
EPOCHS = 40
# 采用cpu还是gpu进行计算
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 学习率
modellr = 1e-4# 数据预处理path = "D:\\Storage\\ProgramData\\Python\\DistingushCD\\net\\data\\dc_2000"
transform = transforms.Compose([transforms.CenterCrop(224), transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])# 数据加载dataset_train = datasets.ImageFolder(path + '\\' + 'train', transform)
print('trainset:{}'.format(dataset_train.class_to_idx))dataset_test = datasets.ImageFolder(path + '\\' + 'test', transform)
print('testset:{}'.format(dataset_test.class_to_idx))train_loader = DataLoader(dataset_train, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(dataset_test, batch_size=BATCH_SIZE, shuffle=False)# 设置模型
model = vgg16(pretrained=True, progress=True, num_classes=2)
model = model.to(DEVICE)# 设置优化器
optimizer = torch.optim.Adam(model.parameters(), lr=modellr)
# sculer = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1)# 训练
for epoch in range(1, EPOCHS + 1):train(model, DEVICE, train_loader, optimizer, epoch)  # 训练过程函数val(model, DEVICE, test_loader, optimizer)  # 测试过程函数# 储存模型
torch.save(model, 'D:\\Storage\\ProgramData\\Python\\DistingushCD\\netmodel.pth')

2.2 VGG16.py

import torch
import torch.nn as nn
from torch.hub import load_state_dict_from_urlmodel_urls = {'vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth',
}  # 下载模型class VGG(nn.Module):def __init__(self,features: nn.Module,num_classes: int = 1000,init_weights: bool = True):super(VGG, self).__init__()self.features = featuresself.avgpool = nn.AdaptiveAvgPool2d((7, 7))self.classifier = nn.Sequential(nn.Linear(512 * 7 * 7, 4096),nn.ReLU(True),nn.Dropout(),nn.Linear(4096, 4096),nn.ReLU(True),nn.Dropout(),nn.Linear(4096, num_classes),)if init_weights:self._initialize_weights()def forward(self, x):x = self.features(x)x = self.avgpool(x)x = torch.flatten(x, 1)x = self.classifier(x)return xdef _initialize_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')if m.bias is not None:nn.init.constant_(m.bias, 0)elif isinstance(m, nn.BatchNorm2d):nn.init.constant_(m.weight, 1)nn.init.constant_(m.bias, 0)elif isinstance(m, nn.Linear):nn.init.normal_(m.weight, 0, 0.01)nn.init.constant_(m.bias, 0)def make_layers(cfg, batch_norm=False):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)if batch_norm:layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]else:layers += [conv2d, nn.ReLU(inplace=True)]in_channels = vreturn nn.Sequential(*layers)cfgs = {'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
}def vgg16(pretrained=True, progress=True, num_classes=2):model = VGG(make_layers(cfgs['D']))if pretrained:state_dict = load_state_dict_from_url(model_urls['vgg16'], model_dir='./model',progress=progress)model.load_state_dict(state_dict)if num_classes != 1000:model.classifier = nn.Sequential(nn.Linear(512 * 7 * 7, 4096),nn.ReLU(True),nn.Dropout(p=0.5),nn.Linear(4096, 4096),nn.ReLU(True),nn.Dropout(p=0.5),nn.Linear(4096, num_classes),)return model

2.3 traning_settings.py

import torch
import torch.nn.functional as F# cost函数设置
criterion = torch.nn.CrossEntropyLoss()def train(model, device, train_loader, optimizer, epoch):total_train = 0for data in train_loader:img, label = datawith torch.no_grad():img = img.to(device)label = label.to(device)optimizer.zero_grad()output = model(img)train_loss = criterion(output, label).to(device)train_loss.backward()optimizer.step()total_train += train_lossprint("Epoch:{}, Loss of training set:{:.5f}".format(epoch, total_train))def val(model, device, test_lodaer, optimizer):total_test = 0total_accuracy = 0total_num = len(test_lodaer.dataset)for data in test_lodaer:img, label = datawith torch.no_grad():img = img.to(device)label = label.to(device)optimizer.zero_grad()output = model(img)test_loss = criterion(output, label).to(device)total_test += test_lossaccuracy = (output.argmax(1) == label).sum()total_accuracy += accuracyprint("Loss of testing set:{:.5f}, Accuracy of testing set:{:.1%}\n".format(total_test, total_accuracy/total_num))

2.4 prediction.py

import torch.utils.data.distributed
import torchvision.transforms as transforms
from torch.autograd import Variable
import os
from PIL import Imageclasses = ('cat', 'dog')transform_test = transforms.Compose([transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = torch.load('D:\\Storage\\ProgramData\\Python\\DistingushCD\\netmodel.pth')
model.eval()
model.to(DEVICE)
path = 'D:\\Storage\\ProgramData\\Python\\DistingushCD\\net\\data\\dc_2000\\to_test\\test1\\'
file = '1002.jpg'
img = Image.open(path + file)
img.show()
img = transform_test(img)
img.unsqueeze_(0)
img = Variable(img).to(DEVICE)
out = model(img)
# Predict
_, pred = torch.max(out.data, 1)
print('Image Name: {},\nprediction: It\'s a {}.'.format(file, classes[pred.data.item()]))

3 结果

数据集预处理介绍

图4 测试集路径

图5 测试集图片命名

测试集和训练集路径地址和图片命名规则符合图5、图6,数据集和测试集通过DataLoader函数自动导入训练程序。

 

图6 训练集和测试集标签展示

​​​​​​​定量实验结果展示

 

图7 训练结果展示

训练结果采用测试集总损失值以及精确度衡量,通过图6可以看出模型训练后有较好的预测效果。

​​​​​​​定性实验结果展示

 

图8 在测试集中抽取一张“狗”照片进行预测

      训练完毕后,通过编写新的脚本程序读取已储存的模型,并通过迁移学习预测输入的照片。

图9 图8所示照片的预测结果

        通过已储存模型对图7所展示照片进行预测,可以成功预测出这是一张“狗”的照片。

​​​​​​​分析实验结果

        通过多次实验检测,通过微调VGG16训练的模型对猫狗分类有良好的预测结果,其测试集精确度达95%,能够基本完成项目目标。


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

相关文章

VGG16代码注释

原版代码在这:神经网络学习小记录52——Pytorch搭建孪生神经网络(Siamese network)比较图片相似性 VGG注释: import torch import torch.nn as nn from torchvision.models.utils import load_state_dict_from_urlclass VGG(nn…

VGG16网络结构

VGGNet模型有A-E五种结构网络,深度分别为11,11,13,16,19,其中VGG16和VGG19较为典型。VGG网络结构如下图所示。 VGG16介绍: 在卷积层1(conv3_64),卷积层2(con…

分类网络 VGG16

经典网络VGG16 结构 VGG中根据卷积核大小和卷积层数目的不同,可分为A,A-LRN,B,C,D,E共6个配置(ConvNet Configuration),其中以D,E两种配置较为常用,分别称为VGG16和VGG19。 下图给出了VGG的六种结构配置: 上图中&am…

分类网络:VGG16

VGG16网络的优点: 1.通过堆叠两层3x3的卷积核替代5x5的卷积核, 通过堆叠三层3x3的卷积核替代7x7的卷积核, 原因是拥有相同的感受野,且需要更少的参数:假设输入通道数为C, 则所需要的参数为: 三个3x3的卷积…

VGG16模型

VGG16模型很好的适用于分类和定位任务 其名称来源于作者所在的牛津大学视觉几何组(Visual Geometry Group)的缩写。 1、结构简洁 VGG由5层卷积层、3层全连接层、softmax输出层构成,层与层之间使用max-pooling(最大化池)分开,所有…

VGG16网络结构与代码

VGG16总共有16层(不包括池化层),13个卷积层和3个全连接层,第一次经过64个卷积核的两次卷积后,采用一次pooling,第二次经过两次128个卷积核卷积后,采用pooling;再经过3次256个卷积核卷…

VGG16模型PyTorch实现

1.VGG16 网络简介 VGG16网络模型在2014年ImageNet比赛上脱颖而出,取得了在分类任务上排名第二,在定位任务上排名第一的好成绩。VGG16网络相比于之前的LexNet以及LeNet网络,在当时的网络层数上达到了空前的程度。 2.网络结构 3.创新点 ① 使…

CNN系列学习之VGG16

前言: CNN系列总结自己学习主流模型的笔记,从手写体的LeNet-5到VGG16再到历年的ImageNet大赛的冠军ResNet50,Inception V3,DenseNet等。重点总结每个网络的设计思想(为了解决什么问题),改进点(是怎么解决这…

vgg16猫狗识别

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍦 参考文章:365天深度学习训练营-第8周:猫狗识别(训练营内部成员可读)🍖 原作者:K同学啊|接辅导、项目定制 我的环境&…

VGG16-keras 优化

VGG16-keras 优化 优化结果对比VGG16网络结构VGG16网络结构优化自定义loss训练预测 优化结果对比 原始VGG16 普通调优 使用预训练权重 VGG16网络结构 VGG16网络结构优化 1.增加正则化 2.使用BN/GN层(中间层数据的标准化) 3.使用dropout Net.py i…

VGG16论文解读

VGGNET VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,7x7,5x5)。对于给定的感受野(与输出有关的输入图片的局部大小),采用堆积的小卷积核是优于采用…

VGG16模型详解 and 代码搭建

目录 一. VGG 网络模型 二. 代码复现 1. 网络搭建 2.数据集制作(pkl) 3.源码地址 一. VGG 网络模型 Alexnet是卷积神经网络的开山之作,但是由于卷积核太大,移动步长大,无填充,所以14年提出的VGG网络解决了这一问题。而且VGG网…

动手学习VGG16

VGG 论文 《Very Deep Convolutional Networks for Large-Scale Image Recognition》 论文地址:https://arxiv.org/abs/1409.1556 使用重复元素的网络(VGG) 以学习VGG的收获、VGG16的复现二大部分,简述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%的前5个测试精度,这是属于1000个类的超过1400万张图像的数据集。它是ILSVRC-2014提交的着名模型…

VGG-16网络结构详解

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

经典卷积神经网络——VGG16

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

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…