一、准备数据集

分为测试集和训练集,文件如下排放

二、开始识别

数据集准备好后,即可导入到模型开始训练,运行下列代码

import time
from torch.utils.tensorboard import SummaryWriter
from torchvision.datasets import ImageFolder
from torchvision import transforms
from torch.utils.data import DataLoader
import torchvision.models as models
import torch.nn as nn
import torch print("是否使用GPU训练:{}".format(torch.cuda.is_available())) #打印是否采用gpu训练
if torch.cuda.is_available:
print("GPU名称为:{}".format(torch.cuda.get_device_name())) #打印相应的gpu信息
#数据增强太多也可能造成训练出不好的结果,而且耗时长,宜增强两三倍即可。
normalize=transforms.Normalize(mean=[.5,.5,.5],std=[.5,.5,.5]) #规范化
transform=transforms.Compose([ #数据处理
transforms.Resize((64,64)),
transforms.ToTensor(),
normalize
])
dataset_train=ImageFolder('modelphotos/train',transform=transform) #训练数据集
# print(dataset_tran[0])
dataset_valid=ImageFolder('modelphotos/valid',transform=transform) #验证或测试数据集
# print(dataset_train.classer)#返回类别
print(dataset_train.class_to_idx) #返回类别及其索引
# print(dataset_train.imgs)#返回图片路径
print(dataset_valid.class_to_idx)
train_data_size=len(dataset_train) #放回数据集长度
test_data_size=len(dataset_valid)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))
#torch自带的标准数据集加载函数
dataloader_train=DataLoader(dataset_train,batch_size=4,shuffle=True,num_workers=0,drop_last=True)
dataloader_test=DataLoader(dataset_valid,batch_size=4,shuffle=True,num_workers=0,drop_last=True) #2.模型加载
model_ft=models.resnet18(pretrained=True)#使用迁移学习,加载预训练权重
# print(model_ft) in_features=model_ft.fc.in_features
model_ft.fc=nn.Sequential(nn.Linear(in_features,36),
nn.Linear(36,6))#将最后的全连接改为(36,6),使输出为六个小数,对应六种植物的置信度
#冻结卷积层函数
# for i,para in enumerate(model_ft.parameters()):
# if i<18:
# para.requires_grad=False # print(model_ft) # model_ft.half()#可改为半精度,加快训练速度,在这里不适用 model_ft=model_ft.cuda()#将模型迁移到gpu
#3.优化器
loss_fn=nn.CrossEntropyLoss() loss_fn=loss_fn.cuda() #将loss迁移到gpu
learn_rate=0.01 #设置学习率
optimizer=torch.optim.SGD(model_ft.parameters(),lr=learn_rate,momentum=0.01)#可调超参数 total_train_step=0
total_test_step=0
epoch=30 #迭代次数
writer=SummaryWriter("logs_train_yaopian")
best_acc=-1
ss_time=time.time() for i in range(epoch):
start_time = time.time()
print("--------第{}轮训练开始---------".format(i+1))
model_ft.train()
for data in dataloader_train:
imgs,targets=data
# if torch.cuda.is_available():
# imgs.float()
# imgs=imgs.float()#为上述改为半精度操作,在这里不适用
imgs=imgs.cuda()
targets=targets.cuda()
# imgs=imgs.half()
outputs=model_ft(imgs)
loss=loss_fn(outputs,targets) optimizer.zero_grad() #梯度归零
loss.backward() #反向传播计算梯度
optimizer.step() #梯度优化 total_train_step=total_train_step+1
if total_train_step%100==0:#一轮时间过长可以考虑加一个
end_time=time.time()
print("使用GPU训练100次的时间为:{}".format(end_time-start_time))
print("训练次数:{},loss:{}".format(total_train_step,loss.item()))
# writer.add_scalar("valid_loss",loss.item(),total_train_step)
model_ft.eval()
total_test_loss=0
total_accuracy=0
with torch.no_grad(): #验证数据集时禁止反向传播优化权重
for data in dataloader_test:
imgs,targets=data
# if torch.cuda.is_available():
# imgs.float()
# imgs=imgs.float()
imgs = imgs.cuda()
targets = targets.cuda()
# imgs=imgs.half()
outputs=model_ft(imgs)
loss=loss_fn(outputs,targets)
total_test_loss=total_test_loss+loss.item()
accuracy=(outputs.argmax(1)==targets).sum()
total_accuracy=total_accuracy+accuracy
print("整体测试集上的loss:{}(越小越好,与上面的loss无关此为测试集的总loss)".format(total_test_loss))
print("整体测试集上的正确率:{}(越大越好)".format(total_accuracy / len(dataset_valid))) writer.add_scalar("valid_loss",(total_accuracy/len(dataset_valid)),(i+1))#选择性使用哪一个
total_test_step = total_test_step + 1
if total_accuracy > best_acc: #保存迭代次数中最好的模型
print("已修改模型")
best_acc = total_accuracy
torch.save(model_ft, "best_model_yaopian.pth")
ee_time=time.time()
zong_time=ee_time-ss_time
print("训练总共用时:{}h:{}m:{}s".format(int(zong_time//3600),int((zong_time%3600)//60),int(zong_time%60))) #打印训练总耗时
writer.close()

上述采用的迁移学习直接使用resnet18的模型进行训练,只对全连接的输出进行修改,是一种十分方便且实用的方法,同样,你也可以自己编写模型,然后使用自己的模型进行训练,但是这种方法显然需要训练更长的时间才能达到拟合。如图所示,只需要修改矩形框内部分,将‘model_ft=models.resnet18(pretrained=True)'改为自己的模型‘model_ft=model’即可。

三、模型应用测试

经过上述的步骤后,我们将会得到一个‘best_model_yaopian.pth’的模型权重文件,最后运行下列代码就可以对图片进行识别了

import os
import torch
import torchvision
from PIL import Image
from torch import nn
i=0 #识别图片计数
root_path="测试_data" #待测试文件夹
names=os.listdir(root_path)
for name in names:
print(name)
i=i+1
data_class=['cat','dog','duck','mouse'] #按文件索引顺序排列
image_path=os.path.join(root_path,name)
image=Image.open(image_path)
print(image)
transforms=torchvision.transforms.Compose([torchvision.transforms.Resize((64,64)),
torchvision.transforms.ToTensor()])
image=transforms(image)
print(image.shape) model_ft=torchvision.models.resnet18() #需要使用训练时的相同模型
# print(model_ft)
in_features=model_ft.fc.in_features
model_ft.fc=nn.Sequential(nn.Linear(in_features,36),
nn.Linear(36,6)) #此处也要与训练模型一致 model=torch.load("best_model_yaopian.pth",map_location=torch.device("cpu")) #选择训练后得到的模型文件
# print(model)
image=torch.reshape(image,(1,3,64,64)) #修改待预测图片尺寸,需要与训练时一致
model.eval()
with torch.no_grad():
output=model(image)
print(output) #输出预测结果
# print(int(output.argmax(1)))
print("第{}张图片预测为:{}".format(i,data_class[int(output.argmax(1))])) #对结果进行处理,使直接显示出预测的植物种类

 这里需要注意一下索引顺序,可以通过训练模型时的输出来查看并填入

可以更换标签来改变输出结果

最后,通过上述步骤我们可以得到一个简单的猫狗鸭鼠的智能识别程序,如下图是识别结果说明。

基于pytorch的图像训练识别的更多相关文章

  1. Java基于opencv实现图像数字识别(二)—基本流程

    Java基于opencv实现图像数字识别(二)-基本流程 做一个项目之前呢,我们应该有一个总体把握,或者是进度条:来一步步的督促着我们来完成这个项目,在我们正式开始前呢,我们先讨论下流程. 我做的主要 ...

  2. Java基于opencv实现图像数字识别(五)—投影法分割字符

    Java基于opencv实现图像数字识别(五)-投影法分割字符 水平投影法 1.水平投影法就是先用一个数组统计出图像每行黑色像素点的个数(二值化的图像): 2.选出一个最优的阀值,根据比这个阀值大或小 ...

  3. Java基于opencv实现图像数字识别(四)—图像降噪

    Java基于opencv实现图像数字识别(四)-图像降噪 我们每一步的工作都是基于前一步的,我们先把我们前面的几个函数封装成一个工具类,以后我们所有的函数都基于这个工具类 这个工具类呢,就一个成员变量 ...

  4. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  5. Java基于opencv实现图像数字识别(一)

    Java基于opencv实现图像数字识别(一) 最近分到了一个任务,要做数字识别,我分配到的任务是把数字一个个的分开:当时一脸懵逼,直接百度java如何分割图片中的数字,然后就百度到了用Buffere ...

  6. Java基于opencv实现图像数字识别(五)—腐蚀、膨胀处理

    腐蚀:去除图像表面像素,将图像逐步缩小,以达到消去点状图像的效果:作用就是将图像边缘的毛刺剔除掉 膨胀:将图像表面不断扩散以达到去除小孔的效果:作用就是将目标的边缘或者是内部的坑填掉 使用相同次数的腐 ...

  7. 基于Pytorch的简单小案例

    神经网络的理论知识不是本文讨论的重点,假设读者们都是已经了解RNN的基本概念,并希望能用一些框架做一些简单的实现.这里推荐神经网络必读书目:邱锡鹏<神经网络与深度学习>.本文基于Pytor ...

  8. 基于卷积神经网络的面部表情识别(Pytorch实现)----台大李宏毅机器学习作业3(HW3)

    一.项目说明 给定数据集train.csv,要求使用卷积神经网络CNN,根据每个样本的面部图片判断出其表情.在本项目中,表情共分7类,分别为:(0)生气,(1)厌恶,(2)恐惧,(3)高兴,(4)难过 ...

  9. Pytorch实现基于卷积神经网络的面部表情识别(详细步骤)

    文章目录 一.项目背景 二.数据处理 1.标签与特征分离 2.数据可视化 3.训练集和测试集 三.模型搭建 四.模型训练 五.完整代码 一.项目背景数据集cnn_train.csv包含人类面部表情的图 ...

  10. 基于CNN网络的汉字图像字体识别及其原理

    现代办公要将纸质文档转换为电子文档的需求越来越多,目前针对这种应用场景的系统为OCR系统,也就是光学字符识别系统,例如对于古老出版物的数字化.但是目前OCR系统主要针对文字的识别上,对于出版物的版面以 ...

随机推荐

  1. CF1829H Don't Blame Me

    题目链接 题解 知识点:线性dp,位运算. 考虑设 \(f_{i,j}\) 表示考虑了前 \(i\) 个数字,与和为 \(j\) 的方案数.转移方程显然. 注意初值为 \(f_{0,63} = 1\) ...

  2. STM32F407VET6 / BLACK_F407VE开发板间隔0.5秒不断重启

    有一块 STM32F407VET6 的故障开发板, 之前的问题是经常无法烧录, 必须reset之后才能连接, 具体查看这篇 STM32F407VET6烧录出现flash download failed ...

  3. 编译静态库遇到的 LNK2019 报错

    前文提到了 CMake 学习 文末基本涵盖了我遇到的编译问题,但是在得到一个编译好的 .lib 文件后,还需要放到项目中引用成功后才算真正的完成静态库的编译 嗯,我之所以说这些是因为我在项目中链接静态 ...

  4. heapq.merge()高效合并有序序列

    import heapq import random # 针对较大的数据集,采用heapq中的merge()方法 # merge()不是对整个合并后的序列排序,而是使用一个堆一次一个元素的生成一个新序 ...

  5. 国内如何快速访问GitHub

    1.国内如何快速访问gibhub -FQ的方法无非就是用软件,这种就不介绍了 -本次介绍的是修改本地系统主机hosts文件,绕过国内dns解析,达到快速访问github 打开https://tool. ...

  6. 【系统选型】OA需求分析,OA系统选型及各供应商对比。

    去年公司内部做OA信息化升级,需要更新换代一下OA系统,当时OA选型整理下来的资料分享一下. 需求调研整理后如下: 一共四个模块需要更新&升级 :  OA模块(包括行政) + 合同模块 + 费 ...

  7. 【算法day2】复杂度和简单排序算法(2)

    插入排序 有以下数组 数组:[2,4,3,6,1] 序号:[0,1,2,3,4] 第一次排序(范围0~0):2左边没东西,不动 第二次排序(范围0~1):4左边是2,4大不动 第三次排序(范围0~2) ...

  8. Avalonia 跨平台框架中如何以正确的姿势使用 OpenGL ES 渲染。

    前言 这是一篇很水的文章,没有任何技术含量,在 Github 已经有很多人对 Avalonia 的 OpenGL ES 支持进行了讨论,但是我还是想写一篇文章来记录一下我是如何在 Avalonia 中 ...

  9. 探索浏览器录屏Web API 接口的应用前景与限制

    一.浏览器录屏Web API 接口的优点: 简化录屏流程:浏览器录屏Web API 接口可以直接在网页中调用,无需安装额外的插件或软件,简化了录屏的流程. 实时录制与传输:Web API 接口可以实时 ...

  10. FolkMQ 作个简单的消息中间件(最简单的那种), v1.3.1 发布

    功能简介 角色 功能 生产端(或发起端) 发布消息.定时消息(或叫延时).顺序消息.可过期消息.事务消息.发送消息(rpc)支持 Qos0.Qos1 消费端(或接收端) 订阅.取消订阅.消费-ACK( ...