基于VGG16的猫狗分类实战

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_url

model_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 = features
        self.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 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')
                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 = 3
    for 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 = v
    return 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 = 0
    for data in train_loader:
        img, label = data
        with 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_loss

    print("Epoch:{}, Loss of training set:{:.5f}".format(epoch, total_train))

def val(model, device, test_lodaer, optimizer):
    total_test = 0
    total_accuracy = 0
    total_num = len(test_lodaer.dataset)
    for data in test_lodaer:
        img, label = data
        with 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_loss
            accuracy = (output.argmax(1) == label).sum()
            total_accuracy += accuracy

    print("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 Image

classes = ('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%,能够基本完成项目目标。

  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
课程导语:    人工智能可谓是现阶段最火的行业,在资本和技术协同支持下正在进入高速发展期。当今全球市值前五大公司都指向同一发展目标:人工智能。近几年,人工智能逐渐从理论科学落地到现实中,与生活越来越息息相关,相关的各种职位炙手可热,而深度学习更是人工智能无法绕开的重要一环。 从AlphaGo打败李世石开始,深度学习技术越来越引起社会各界的广泛关注。不只学术界,甚至在工业界也取得了重大突破和广泛应用。其中应用最广的研究领域就是图像处理和自然语言处理。而要入门深度学习,CNN和RNN作为最常用的两种神经网络是必学的。网上关于深度学习的资料很多,但大多知识点分散、内容不系统,或者以理论为主、代码实操少,造成学员学习成本高。本门课程将从最基础的神经元出发,对深度学习的基础知识进行全面讲解,帮助大家迅速成为人工智能领域的入门者,是进阶人工智能深层领域的基石。 讲师简介:赵辛,人工智能算法科学家。2019年福布斯科技榜U30,深圳市海外高层次人才(孔雀人才)。澳大利亚新南威尔士大学全奖博士,SCI收录其发表过的10篇国际期刊学术文章。曾任深圳市微埃智能科技有限公司联合创始人。CSDN人工智能机器学习、深度学习方向满分级精英讲师。授课风格逻辑严谨、条理清晰、循序渐进、循循善诱,化枯燥为如沐春风,所教学生人数过万。 课程设计: 本课程分为5大模块,19小节,共计540时长(约9小时): 第一部分,课程介绍、目标与内容概览。主要学习人工智能深度学习应用场景;熟悉深度学习主流技术;掌握使用keras解决深度学习主要问题(神经网络、卷积神经网络、循环神经网络),以及深度学习主要内容:神经网络、卷积神经网络、循环神经网络;案例简介。 第二部分,深度学习之多层感知器(MLP)。主要学习多层感知器(MLP);MLP实现非线性分类深度学习实战准备;Python调用keras实现MLP。 MLP技术点实战案例:第三部分,深度学习之卷积神经网络(CNN)。主要学习卷积神经网络 ; CNN模型分析;主流CNN模型; Python调用keras实现CNN; CNN技术点实战案例:第四部分,深度学习之循环神经网络(RNN)。主要学习循环神经网络;RNN模型分析;Python调用keras实现RNN。 RNN技术点实战案例: 第五部分,综合提升。主要进行迁移学习;混合模型;实战准备+综合实战,以及最后进行课程内容总结。 混合模型技术点实战案例
根据引用\[1\]中的代码,可以看出在使用OpenCV和PyTorch导入VGG16模型时,需要进行以下步骤: 1. 首先,确保你的CMakeLists.txt文件中已经包含了正确的库和路径配置,包括OpenCV和PyTorch的路径和库文件。 2. 使用find_package命令找到并导入OpenCV和PyTorch的库。 3. 在include_directories中添加OpenCV和PyTorch的头文件路径。 4. 使用target_link_libraries命令将gpucode可执行文件与PyTorch和OpenCV的库文件链接起来。 5. 设置C++标准为11。 接下来,根据引用\[2\]中的提示,确保在序列化模型时,不需要指定在GPU上进行计算,即不需要使用device="gpu"、model=model.to(device)和x=x.cuda()这些语句。 此外,还需要检查训练PyTorch模型的版本是否与libtorch版本一致,以确保兼容性。 如果以上步骤都正确无误,但导入模型仍然无反应或导入失败,可以尝试使用cmake进行编译,根据引用\[3\]中的提示进行调试。 总结起来,导入VGG16模型的步骤包括正确配置CMakeLists.txt文件、导入OpenCV和PyTorch的库、设置头文件路径、链接库文件、设置C++标准、确保不需要在GPU上计算、检查版本兼容性,并尝试使用cmake进行编译。 #### 引用[.reference_title] - *1* *2* *3* [VS2019使用C++调用并部署pytorch VGG模型全过程(libtorch+opencv)(cpu+gpu)](https://blog.csdn.net/W9XM96/article/details/120731048)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芝芝士Clim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值