实战:利用pytorch搭建VGG-16实现从数据获取到模型训练的猫狗分类网络

在这里插入图片描述

在学习了卷积神经网络的理论基础和阅读了VGG的论文之后,对卷积有了大致的了解,但这都只是停留在理论上,动手实践更为重要,于是便开始了0基础学习pytorch、图像处理,搭建模型。
pytorch学习视频 https://www.bilibili.com/video/BV1hE411t7RN
代码参考https://blog.csdn.net/aa330233789/article/details/106411301
数据集来源https://www.cnblogs.com/xiximayou/p/12372969.html

  • 收获最大的是对于pycharm的了解更进一步,利用help 和 ?? 在python console 中查看帮助文档,是一个很实用的技巧,并且这也是离线操作,不会就查,函数的参数、参数的含义、数学原理等等一应俱全,配上Makedown的编辑器,绝了。
  • 惊讶于pytorch的封装能力,就从一个BP函数来说,简单的几个参数,包含了 L 2 L^2 L2正则化(权重衰减)、动态学习率调整,对于一个萌新来说,大概连原理也不要明白,只需要知道参数的作用便可以搭建网络。
  • 实际上这个实战还有很多地方没有完善,比如数据增强部分,数据可视化,模型的训练(没算力啥也不是),还有很多地方值得进一步挖掘。
  • 整体搭建一个类似的项目,虽然伤眼睛、废手,收获确实很大,对于Pytorch的理解比上一个星期的视频可要来得深刻,当然如果想要深入学习pytorch那又是另一个问题。

话不多说,细节全在注释中。
show the code
read_data.py

from torch.utils.data import Dataset
import cv2
import os
import numpy as np
import torch
from torchvision import transforms
class Mydata(Dataset):def __init__(self,img_path):# 用于设置类中的变量self.img_path=img_pathself.img_list=os.listdir(img_path)print(self.img_list[0])def __getitem__(self, idx):img_name = self.img_list[idx]img_item_path = os.path.join(self.img_path,img_name)img = cv2.imread(img_item_path)img = cv2.resize(img,(224,224),interpolation=cv2.INTER_LINEAR)# 这里需要注意opencv独特图像存储方式trans = transforms.ToTensor()img = trans(img)#img = torch.from_numpy(img)#print(img.shape)label = 0if img_name[0]=='c':label=1return img,labeldef __len__(self):return len(self.img_list)

model

from torch import nnclass VGG16Net(nn.Module):# 继承父类nn.Moduledef __init__(self):super(VGG16Net,self).__init__()'''如果不用super,每次调用父类的方法是需要使用父类的名字使用super就避免这个麻烦super()实际上的含义远比这个要复杂。有兴趣可以通过这篇博客学习:https://blog.csdn.net/zhangjg_blog/article/details/83033210''''''A sequential container.Modules will be added to it in the order they are passed in theconstructor. Alternatively, an ``OrderedDict`` of modules can bepassed in. The ``forward()`` method of ``Sequential`` accepts anyinput and forwards it to the first module it contains. It then"chains" outputs to inputs sequentially for each subsequent module,专业术语:一个有序的容器,神经网络模块将按照在传入构造器的顺序依次被添加到计算图中执行,同时以神经网络模块为元素的有序字典也可以作为传入参数这是一个有序模型容器,输入会按照顺序逐层通过每一模型,最终会返回最后一个模型的输出。实现原理:利用for循环 将所有的参数(即子模块)加入到self._module,然后在__call__中调用forward(),而forward()函数则会将self.module中的子模块推理一遍,返回值也就是最终结果。参考博客:https://blog.csdn.net/dss_dssssd/article/details/82980222 '''# 第一层,2个卷积层和一个最大池化层self.layer1 = nn.Sequential(# 输入3通道,输出64通道。卷积核大小3,填充1,步长默认为1(输入224*224*3的样本图片,输出为224*224*64)nn.Conv2d(3,64,3,padding=1),# 对数据做归一化,这是由于经过训练后的数据分布改变,需要将其拉回到N(1,0)的正态分布,防止梯度消失,读入的参数是通道数。nn.BatchNorm2d(64),# 激活函数。参数inplace =false 是默认返回对象,需要重开地址,这里True返回地址,为了节省开销nn.ReLU(inplace=True),# 输入为224*224*64,输出为224*224*64nn.Conv2d(64,64,3,padding=1),nn.BatchNorm2d(64),nn.ReLU(inplace=True),# 进行卷积核2*2,步长为2的最大池化,输入224*224*64,输出112*112*64nn.MaxPool2d(kernel_size=2,stride=2))# 第二层,2个卷积层和一个最大池化层self.layer2 = nn.Sequential(# 输入为112*112*64,输出为112*112*128nn.Conv2d(64,128,3,padding=1),nn.BatchNorm2d(128),nn.ReLU(inplace=True),# 输入为112*112*128,输出为112*112*128nn.Conv2d(128,128,3,padding=1),nn.BatchNorm2d(128),nn.ReLU(inplace=True),# 112*112*128 --> 56*56*128nn.MaxPool2d(kernel_size=2,stride=2))#第三层,3个卷积层和一个最大池化self.layer3 = nn.Sequential(# 56*56*128 --> 56*56*256nn.Conv2d(128,256,3,padding=1),nn.BatchNorm2d(256),nn.ReLU(inplace=True),# 56*56*256 --> 56*56*256nn.Conv2d(256, 256, 3, padding=1),nn.BatchNorm2d(256),nn.ReLU(inplace=True),# 56*56*256 --> 56*56*256nn.Conv2d(256, 256, 3, padding=1),nn.BatchNorm2d(256),nn.ReLU(inplace=True),# 56*56*256 --> 28*28*256nn.MaxPool2d(kernel_size=2,stride=2))#第四层,3个卷积层和一个最大池化self.layer4=nn.Sequential(# 28*28*256 --> 28*28*512nn.Conv2d(256,512,3,padding=1),nn.BatchNorm2d(512),nn.ReLU(inplace=True),# 28*28*512 --> 28*28*512nn.Conv2d(512, 512, 3, padding=1),nn.BatchNorm2d(512),nn.ReLU(inplace=True),# 28*28*512 --> 28*28*512nn.Conv2d(512, 512, 3, padding=1),nn.BatchNorm2d(512),nn.ReLU(inplace=True),# 28*28*512 --> 14*14*512nn.MaxPool2d(kernel_size=2,stride=2))#第五层,3个卷积层和一个最大池化self.layer5=nn.Sequential(# 14*14*512 --> 14*14*512nn.Conv2d(512,512,3,padding=1),nn.BatchNorm2d(512),nn.ReLU(inplace=True),# 14*14*512 --> 14*14*512nn.Conv2d(512, 512, 3, padding=1),nn.BatchNorm2d(512),nn.ReLU(inplace=True),# 14*14*512 --> 14*14*512nn.Conv2d(512, 512, 3, padding=1),nn.BatchNorm2d(512),nn.ReLU(inplace=True),# 14*14*512 --> 7*7*512nn.MaxPool2d(kernel_size=2,stride=2))# 将卷积层打包self.conv_layer = nn.Sequential(self.layer1,self.layer2,self.layer3,self.layer4,self.layer5)# 全连接层self.fc = nn.Sequential(# 1*1*25088 --> 1*1*4096nn.Linear(25088,4096),nn.ReLU(inplace=1),nn.Dropout(),# 1*1*4096 --> 1*1*4096nn.Linear(4096,4096),nn.ReLU(inplace=1),nn.Dropout(),# 1*1*4096 --> 1*1*1000nn.Linear(4096,1000))def forward(self,x):x = self.conv_layer(x)# 7*7*512 --> 1*1*25088x=x.view(-1,25088)x=self.fc(x)return x

train.py

import torch
from read_data import Mydata
from torch.utils.data import DataLoader
from torch import nn
from torch import optim
from model import VGG16Net
import time#超参数设置
batch_size  = 8 # 每次训练的数据量
learn_rate = 0.01 # 学习率
step_size = 10 # 控制学习率变化
epuch_num = 1 # 总的训练次数
num_print = 10 # 每n个batch打印一次mydata = Mydata(r"D:\machine learning\deep learning\VGG16\data\train")# 利用dataloader加载数据集
train_loader = torch.utils.data.DataLoader(mydata,batch_size=batch_size,shuffle=True,drop_last=True)# 生成驱动器
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")# 利用驱动器驱动模型
model = VGG16Net().to(device=device)# 损失函数
get_loss = nn.CrossEntropyLoss()# SGD优化器  第一个参数是输入需要优化的参数,第二个是学习率,第三个是动量,大致就是借助上一次导数结果,加快收敛速度。
'''
这一行代码里面实际上包含了多种优化:
一个是动量优化,增加了一个关于上一次迭代得到的系数的偏置,借助上一次的指导,减小梯度震荡,加快收敛速度
一个是权重衰减,通过对权重增加一个(正则项),该正则项会使得迭代公式中的权重按照比例缩减,这么做的原因是,过拟合的表现一般为参数浮动大,使用小参数可以防止过拟合
'''
optimizer = optim.SGD(model.parameters(),lr=learn_rate,momentum=0.8,weight_decay=0.001)# 动态调整学习率 StepLR 是等间隔调整学习率,每step_size 令lr=lr*gamma
# 学习率衰减,随着训练的加深,目前的权重也越来越接近最优权重,原本的学习率会使得,loss上下震荡,逐步减小学习率能加快收敛速度。
scheduler = optim.lr_scheduler.StepLR(optimizer,step_size=step_size,gamma=0.5,last_epoch=-1)loss_list=[]
start=time.time()for epoch in range(epuch_num):running_loss = 0.0# enumerate()是python自带的函数,用于迭代字典。参数1,是需要迭代的对象,第二参数是迭代的起始位置for i,(inputs,labels) in enumerate(train_loader,0):inputs,labels = inputs.to(device), labels.to(device)optimizer.zero_grad()# 将梯度初始化为0outputs = model(inputs)# 前向传播求出预测的值loss = get_loss(outputs,labels).to(device)# 求loss,对应loss +=loss.backward() # 反向传播求梯度optimizer.step() # 更新所有参数running_loss += loss.item()# loss是张量,访问值时需要使用item()loss_list.append(loss.item())if i % num_print == num_print - 1:print('[%d epoch, %d] loss: %.6f' % (epoch + 1, i + 1, running_loss / num_print))running_loss = 0.0lr = optimizer.param_groups[0]['lr']# 查看目前的学习率print('learn_rate : %.15f'% lr)scheduler.step()# 根据迭代epoch更新学习率end = time.time()
print('time:{}'.format(end-start))torch.save(model,'./model.pth')

test.py

import torch
from read_data import Mydata
from torch.utils.data import DataLoader
from torch import nn
from torch import optim
from model import VGG16Nettestdata = Mydata(r'D:\machine learning\deep learning\VGG16\data\test\test')
test_loader = torch.utils.data.DataLoader(testdata,batch_size=1,shuffle=False)device = torch.device('cpu')
model = torch.load('./model.pth')model.eval()
correct = 0.0
total = 0
with torch.no_grad():for input, label in test_loader:inputs = input.to(device)outputs = model(inputs)pred = outputs.argmax(dim=1 )# 返回每一行中最大元素索引total += inputs.size(0)correct += torch.eq(pred,label).sum().item()# 比较实际结果和标签
print('Accuracy of the network on the 10000 test images:%.2f%%'%(100.0*correct/total))
print(total)

ps:其实还有很多问题比如作者在训练是采用贪心式的预训练,如何借助pytorch框架完成,在test.py代码中也存在一些问题。
VGG网络简单、有效,不知道resnet的残差又是怎样的风景。

续:为了验证该网络的有效性,我从kaggle中拿到了猫狗的数据集进行尝试

数据集来源Kaggle : Using a Convolutional Neural Network for classifying Cats vs Dogs
在这里插入图片描述
可以看出训练在有效进行,但可能是学习率等超参数的问题呢,训练loss的跳动过大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/26878.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于pytorch实现猫狗分类系统

本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052 写在前言:本文是一个保姆级的分类教程,旨在让零基础的同学掌握实现一个分类系统的基本要素、通用模板和模块实现。在项目代码中做了非常详细的注释&#xff0c…

从零开始编写一个宠物识别系统(爬虫、模型训练和调优、模型部署、Web服务)

心血来潮,想从零开始编写一个相对完整的深度学习小项目。想到就做,那么首先要考虑的问题是,写什么? 思量再三,我决定写一个宠物识别系统,即给定一张图片,判断图片上的宠物是什么。宠物种类暂定…

python:tflearn训练的猫狗识别模型及其使用

需要下载:pip install tflearn 一些理论知识在前一篇文章中:可以一起阅读学习 https://blog.csdn.net/m0_64596200/article/details/126918240?spm1001.2014.3001.5501 已经处理好的.npy文件: https://download.csdn.net/download/m0_645962…

基于Pytorch实现猫狗分类

文章目录 一、环境配置二、数据集的准备三、猫狗分类的实例四、实现分类预测测试五、参考资料 一、环境配置 安装Anaconda 具体安装过程,请自行百度配置Pytorchpip install -i https://pypi.tuna.tsinghua.edu.cn/simple torch pip install -i https://pypi.tuna.t…

猫狗训练单张图片的测试

猫狗训练的训练模型的建立,模型在整个预测集上的预测效果的测试的程序代码网上或一些书籍上都可查阅,但是对单张或某些图片的分类测试程序不多,这里通过参考博客:https://blog.csdn.net/baidu_35113561/article/details/79371716 …

宠物鼻纹识别及面部识别进一步在城市养犬登记场景落地

最近安阳狗咬人事件造成了极其恶劣的社会影响,大型禁养犬类伤人成为城市治安管理不容忽视的隐患,正威胁人们的生命安全,养犬热潮也给城市管理带来了不小的挑战,粗放式的养犬管理不再适应时代的需求,城市养犬管理改革已…

借助互联网,“宝贝它”欲打造线上宠物交易与服务平台

作为人类忠实的朋友,宠物一直伴随着很多家庭的成长。而随着人们生活节奏的不断加快,电子商务正成为越来越多传统垂直领域的解决方案,宠物交易与服务同样也不例外。上海创业公司宝贝它希望借助互联网,打造线上宠物交易及服务平台。…

小动物领养网站/宠物救助网站

摘 要 本论文对小动物领养网站的开发过程进行了较为详细的论述,采用B/S架构、ssm 框架和 java 开发的 Web 框架,eclipse开发工具。 小动物领养网站,主要的模块包括管理员;首页、个人中心、用户管理、动物展示管理、动物分类管理…

语音合成工具Coqui TTS安装及体验

先介绍两种免费的语音合成工具 balabolka 官网 http://balabolka.site/balabolka.htm 是一种基于微软Speech API (SAPI)的免费语音合成工具,只是简单的发音合成,效果比较生硬 Coqui TTS 官网 https://coqui.ai/ 是基于深度学习的语音合成软件&#x…

音视频进阶教程|如何实现游戏中的实时语音

1 游戏实时语音功能简介 1.1 游戏实时语音概念解释 范围:收听者接收音频的范围。方位:指收听者在游戏世界坐标中的位置和朝向,详情可参考 5.5 初始化设置 中的“步骤 1”。收听者:房间内接收音频的用户发声者:房间内…

通过实时语音驱动人像模拟真人说话

元宇宙的火热让人们对未来虚拟世界的形态充满了幻想,此前我们为大家揭秘了声网自研的 3D 空间音频技术如何在虚拟世界中完美模拟现实听觉体验,增加玩家沉浸感。今天我们暂时离开元宇宙,回到现实世界,来聊聊声网自研的 Agora Lipsy…

聊天语音APP开发|聊天语音软件开发-实时音视频技术

聊天语音软件的开发应该是一个以视频和语音直播为核心的社交系统。对于用户来说,更好的视频和语音直播功能可以增强用户的接受感,让用户持续使用。为了方便视频和语音直播的采用体验,减少直播的延时,聊天语音软件的开发将采用实时…

拿到offer提出离职,公司拖30天才放人,但下家公司等不了30天,怎么办?

拿到offer想跳槽,向公司提出了离职,但公司要拖30天才放人,新公司又等不了30天,offer可能就没有了,这就是一位网友面临的两难局面,这种情况有没有什么解决的好办法呢? 有人安慰楼主,下…

怎么说离职原因新的公司比较能接受?

怎么说离职原因新的公司比较能接受? 我来提供一些格式化的应对方法; 1.实际原因:原单位工资太少。离职原因:我认为我自己已经具备了一定的积累,希望可以迈向一个新的台阶。 2.实际原因:跟同事出不来。离…

我提了离职,公司给我涨薪了,还能待下去吗?

金三银四到了,相信不少同学又开始在物色新的公司。 不少同学反映,在提出离职后,公司给自己加了薪,虽然不多。 那“在职员工,提出辞职被挽留,应该留下吗?” 为什么想要离职? 这个问…

是的,我离职了

终于可以敞开说这件事情了,年后的这一个月,我彻底停更了,并不是偷懒了,而是我要找工作。大家也都知道18年的寒冬,很多大厂开始裁员,所以我要更加认真的学习,毕竟跟大厂出来的相比,自…

办理离职手续流程的详细流程(离职交接的标准流程)

1、正式员工办理离职手续流程 若员工自离,需提前一个月向部门领导提出辞职申请(即时聊天工具或邮件)和《解除劳动合同申请》。 1)面谈:一般领导都会先谈话,确定你离职的时间及安排交接人员进行工作交接。 2…

程序员新公司入职被拒 只因离职证明多了一句话!

程序猿(微信号:imkuqin) 猿妹 整编 新闻报道来自:成都商报 近日,成都一名程序员被新应聘的公司通知入职,然而因为原公司给他出具的一份离职证明上,记载了一句“该员工在项目未完成情况下因个人原…

提交辞职申请时,领导极力挽留,还答应加薪,要不要留下来?

提交辞职申请时,领导极力挽留,还答应加薪,要不要留下来?张工是一名程序员,最近他向领导提交了辞职申请表后,却被领导极力挽留,领导不仅打感情牌,还打加薪牌。就是希望张工能够留下来…

医学影像处理与识别,应用AI模型,探索疾病辅助诊断!

关注公众号,发现CV技术之美 今天(2023.1.9) arXiv.CV 上有7篇医学影像处理与识别相关论文。不过粗略看来,医学影像类的论文,很多都是直接使用已有模型(甚至都不是最先进的模型),加以…