使⽤MATLAB进⾏⽬标检测

目录

  • 数据准备
  • 定义模型并训练
  • 用测试集评估性能
  • 推理过程
  • ⼀⾏代码查看⽹络结构
  • ⼀⾏代码转onnx
  • 结语

⼈⽣苦短,我⽤MATLAB。
Pytorch在深度学习领域占据了半壁江⼭,最主要的原因是⽣态完善,⽽且api直观易⽤。但谁能想到现在MATLAB⽤起来⽐Pytorch还好⽤。从数据集划分到训练,再到性能验证和画图,仅仅使⽤了⼏⼗⾏代码。炼丹师们终于可以解放编码时间,把⾃⼰的精⼒放在摸⻥(划掉)算法本身上了。
下⾯⽤⾃⼰的数据集训练⼀个YOLOv4,看看MATLAB到底怎么个事。

数据准备

我的数据内容是⾦属锻件磁粉探伤所显示的零件缺陷。如下例所示,轴孔上有⼀处明显缺陷:
在这里插入图片描述
数据集格式为Pascal VOC格式(详⻅http://host.robots.ox.ac.uk/pascal/VOC/)。⾸先要将格式的标签转换为MATLAB能够使⽤的格式。使⽤以下函数:

function convertXMLtoMAT(xmlFolder, outputMATFile)% xmlFolder: 存放所有XML⽂件的⽂件夹% outputMATFile: 输出的MAT⽂件名xmlFiles = dir(fullfile(xmlFolder, '*.xml')); imageFilenames = {};boundingBoxes = {};for i = 1:length(xmlFiles) tryxmlFilePath	fullfile(xmlFiles(i).folder, xmlFiles(i).name); xmlDoc = xmlread(xmlFilePath);filenameNode = xmlDoc.getElementsByTagName('filename').item(0);filename = char(filenameNode.getFirstChild.getData); pathNode = xmlDoc.getElementsByTagName('path').item(0); newPath = fullfile(pwd, 'img', filename);xminNode = xmlDoc.getElementsByTagName('xmin').item(0); yminNode = xmlDoc.getElementsByTagName('ymin').item(0); xmaxNode = xmlDoc.getElementsByTagName('xmax').item(0); ymaxNode = xmlDoc.getElementsByTagName('ymax').item(0); xmin = str2double(xminNode.getFirstChild.getData);ymin = str2double(yminNode.getFirstChild.getData); xmax = str2double(xmaxNode.getFirstChild.getData); ymax = str2double(ymaxNode.getFirstChild.getData);width = xmax - xmin; height = ymax - ymin;bbox = [xmin, ymin, width, height];imageFilenames{end+1, 1} = newPath; boundingBoxes{end+1, 1} = bbox;catch% passendend% 创建table并保存为MAT⽂件myDataset = table(imageFilenames, boundingBoxes, ... 'VariableNames', {'imageFilename', 'defect'});save(outputMATFile, 'myDataset');% 输出MAT⽂件的前⼏⾏disp('数据集的前⼏⾏:');disp(myDataset(1:4, :));end

转换后的标签⽂件就变成⼀个mat⽂件,加载后就是以下的样⼦:

data = load("my_dataset.mat"); 
defectDataset = data.myDataset;
% 显示数据
disp(defectDataset(1:5, :));
table sample_num * 2 :imageFilename					defect---------------------		---------------------{'img/00001.jpg'}			{[2635 435 133 682]}{'img/00001_z0.jpg'}		{[2574 1086 125 561]}{'img/00001_z1.jpg'}		{[2569 720 386 596]}{'img/00001_z2.jpg'}		{[2608 951 303 647]}{'img/00001_z3.jpg'}		{[1748 947 303 606]}

第⼆步,划分数据集。⼀般来讲,按照7:2:1的⽐例拆分训练集、测试集和验证集。

trainingRatio = 0.7;
validationRatio = 0.1;rng("default");
shuffledIndices = randperm(height(defectDataset));
idx = floor(trainingRatio * length(shuffledIndices) );trainingIdx = 1:idx;
trainingDataTbl = defectDataset(shuffledIndices(trainingIdx),:);validationIdx = idx+1 : idx + 1 + floor(validationRatio * length(shuffledIndices) );
validationDataTbl = defectDataset(shuffledIndices(validationIdx),:);testIdx = validationIdx(end)+1 : length(shuffledIndices); 
testDataTbl = defectDataset(shuffledIndices(testIdx),:);

第三步,创建 Datastore Datastore 是MATLAB特有的⼀个概念,作⽤类似于Pytorch中的DataLoader 。它集成了⼀些常⽤的操作,如计数,按序读取,打乱顺序,合并数据集等⽅法。MATLAB的Datastore ⽐torch的DataLoader 更⽅便,⼀般⽆需⾃⼰定义,拿来就⽤。

imdsTrain = imageDatastore(trainingDataTbl{:,"imageFilename"}); 
bldsTrain = boxLabelDatastore(trainingDataTbl(:,"defect"));imdsValidation = imageDatastore(validationDataTbl{:,"imageFilename"}); 
bldsValidation = boxLabelDatastore(validationDataTbl(:,"defect"));imdsTest = imageDatastore(testDataTbl{:,"imageFilename"}); 
bldsTest = boxLabelDatastore(testDataTbl(:,"defect"));
% 合并
trainingData = combine(imdsTrain,bldsTrain); 
validationData = combine(imdsValidation,bldsValidation); 
testData = combine(imdsTest,bldsTest);

最后,为了验证数据是否正确,可以画⼀个样本检查⼀下:

data = read(trainingData); 
I = data{1};
bbox = data{2};
annotatedImage = insertShape(I,"Rectangle",bbox,LineWidth=10); 
annotatedImage = imresize(annotatedImage,2);figure 
imshow(annotatedImage); 
reset(trainingData);

在这里插入图片描述

定义模型并训练

这部分是本⽂的重点,但是却很短,因为MATLAB的流程太简洁了,狠狠爱了。

⾸先定义模型的主要参数:

optimizer = "adam"; % 优化器
gradientDecayFactor = 0.9; % 梯度衰减因⼦ 
squaredGradientDecayFactor = 0.999; % 平⽅梯度衰减因⼦ 
initialLearnRate = 0.001; % 初始学习率 
learnRateSchedule = 'none'; % 学习率衰减策略 
miniBatchSize = 4; % 批⼤⼩
L2Regularization = 0.0005; % L2正则化 
MaxEpochs = 100; % 迭代轮数
inputSize = [416 416 3]; 
className = "defect";

第⼆步,设置yolov4的Anchors

rng("default") 
trainingDataForEstimation =transform(trainingData,@(data)preprocessData(data,inputSize)); 
numAnchors = 6;
[anchors,meanIoU] = estimateAnchorBoxes(trainingDataForEstimation,numAnchors);area = anchors(:, 1).*anchors(:,2);
[~,idx] = sort(area,"descend");anchors = anchors(idx,:); 
anchorBoxes = {anchors(1:3,:)
anchors(4:6,:)};

最后开始训练模型就ok了:

detector = yolov4ObjectDetector("tiny-yolov4-coco", ... 
className,anchorBoxes,InputSize=inputSize);
%  如果你选择了从头开始训练,那么就得定义⼀⼤堆参数
options = trainingOptions(optimizer, ...GradientDecayFactor=gradientDecayFactor, ... SquaredGradientDecayFactor=squaredGradientDecayFactor, ... InitialLearnRate=initialLearnRate, ...LearnRateSchedule=learnRateSchedule, ... MiniBatchSize=miniBatchSize, ...L2Regularization=L2Regularization, ... MaxEpochs=MaxEpochs, ...DispatchInBackground=true, ... ResetInputNormalization=true, ... Shuffle="every-epoch", ...VerboseFrequency=20, ... ValidationFrequency=1000, ... CheckpointPath=tempdir, ...ValidationData=validationData, ... OutputNetwork="best-validation-loss");% 开始训练
[detector,info] = trainYOLOv4ObjectDetector(augmentedTrainingData,detector,options);
% 保存
save('yolov4_detector.mat',"detector"); % 模型
save('yolov4_detector_info.mat',"info"); % 训练过程

训练时会有如下输出:

Computing Input Normalization Statistics.
*************************************************************************  
Training a YOLO v4 Object Detector for the following object classes:* defect正在使⽤  'Processes' 配置⽂件启动并⾏池(parpool)...
已连接到具有 8 个⼯作进程的并⾏池。Epoch	Iteration	TimeElapsed	LearnRate TrainingLoss	ValidationLoss1	1		00:00:10		0.001		1174.1	1124.1
1	20		00:00:36		0.001		80.843	
1	40		00:00:52		0.001		30.598	
1	60		00:01:08		0.001		20.106	
1	80		00:01:21		0.001		86.183	
1	100		00:01:34		0.001		14.755	
2	120		00:01:53		0.001		13.844	
2	140		00:02:06		0.001		13.443	
2	160		00:02:19		0.001		12.067	
2	180		00:02:32		0.001		10.023	
2	200		00:02:45		0.001		11.157	
2	220		00:02:59		0.001		11.613	*************************************************************************  
Detector training complete.
*************************************************************************

训练完成后,模型和相关的记录会分别保存在yolov4_detector.matyolov4_detector_info.mat中。

用测试集评估性能

⽤来评估性能的

detectionResults = detect(detector,testData,Threshold=0.01); 
metrics = evaluateObjectDetection(detectionResults,testData); 
AP = averagePrecision(metrics);
[precision,recall] = precisionRecall(metrics,ClassName=className);% 画pr图
figure 1 
plot(recall{:},precision{:}) 
xlabel("Recall") 
ylabel("Precision")
grid on
title(sprintf("Average Precision = %.2f",AP)) 
imshow(I);% 再画个loss曲线
figure 2 
plot(info.TrainingLoss)
xlabel("迭代次数")
ylabel("loss") title('Loss曲线')

在这里插入图片描述
在这里插入图片描述

你可以说我练的不怎么样,但不能说MATLAB不⾏,因为在torch上也是⼀样的效果(哭…

推理过程

I = imread("img/00029.jpg"); 
[bboxes,scores,labels] = detect(detector,I);
I = insertObjectAnnotation(I,"rectangle",bboxes,scores, ...LineWidth=10,FontSize=72); figure
imshow(I)

在这里插入图片描述

⼀⾏代码查看⽹络结构

MATLAB⾥⾯⼀⾏代码可以做到图形化的查看⽹络结构,更专注于分析算法。

net = detector.Network 
analyzeNetwork(net)

在这里插入图片描述

⼀⾏代码转onnx

exportONNXNetwork(net,'yolov4.onnx')

导出⽹络后,可以将该⽹络导⼊到其他深度学习框架中进⾏推理。妈妈再也不⽤担⼼我的部署了。

结语

MATLAB完全解放了炼丹师的编码时间,让炼丹师能够专注于算法本身,我愿称之为最好的深度学习框架(如果你有licence的话)

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

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

相关文章

【Java】实战:多数元素

一、题目描述 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums [3,2,3] 输出&#x…

JAVA:探索 PDF 文字提取的技术指南

1、简述 随着信息化的发展,PDF 文档成为了信息传播的重要媒介。在许多应用场景下,如数据迁移、内容分析和信息检索,我们需要从 PDF 文件中提取文字内容。JAVA提供了多种库来处理 PDF 文件,其中 PDFBox 和 iText 是最常用的两个。…

vue3+vant实现弹幕循环播放~

1、效果图 <!-- 弹幕 --> <div style"height: 88px"><van-barragev-model"list"duration"5000":rows"rows":gap"gap":loop"loop"style"--move-distance: -345px" ><div class&quo…

南京邮电大学算法设计-二叉树先序遍历算法动态演示

二叉树先序遍历算法动态演示 一、课题内容和要求 (1)实验目的&#xff1a; 本实验通过手动输入二叉树结点信息&#xff0c;构建相应的二叉树&#xff0c;并通过图形化界面动态演示先序遍历算法的过程。通过本次实验&#xff0c;我可以深入理解二叉树的数据结构、先序遍历算法…

大数据挖掘期末复习

大数据挖掘 数据挖掘 数据挖掘定义 技术层面&#xff1a; 数据挖掘就是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中&#xff0c;提取隐含在其中、人们事先不知道的、但又潜在有用的信息的过程。 数据准备环节 数据选择 质量分析 数据预处理 数据仓库 …

【Anomaly Detection论文阅读记录】Resnet网络与WideResNet网络

Resnet网络 网络结构&#xff1a;(层数计算不包括max pool、average pool、softmax等操作) 层数计算&#xff08;以Resnet-18为例子&#xff09;&#xff1a; conv1conv2_xconv3_xconv4_xconv5_xfc1(22)(22)(22)(22)118 WideResNet网络 WideResNet提出了一种新的体系结构&#…

基于YOLOv8深度学习的汽车车身车损检测系统研究与实现(PyQt5界面+数据集+训练代码)

本文研究并实现了一种基于YOLOV8深度学习模型的汽车车身车损检测系统&#xff0c;旨在解决传统车损检测中效率低、精度不高的问题。该系统利用YOLOV8的目标检测能力&#xff0c;在单张图像上实现了车身损坏区域的精确识别和分类&#xff0c;尤其是在车身凹痕、车身裂纹和车身划…

【前端学习笔记】Javascript学习二(运算符、数组、函数)

一、运算符 运算符&#xff08;operator&#xff09;也被称为操作符&#xff0c;是用于实现赋值、比较和执行算数运算等功能的符号。 JavaScript中常用的运算符有&#xff1a; 算数运算符、递增和递减运算符、比较运算符、逻辑运算符、赋值运算符 算数运算符&#xff1a; 、-…

python实战案例----使用 PyQt5 构建简单的 HTTP 接口测试工具

python实战案例----使用 PyQt5 构建简单的 HTTP 接口测试工具 文章目录 python实战案例----使用 PyQt5 构建简单的 HTTP 接口测试工具项目背景技术栈用户界面核心功能实现结果展示完整代码总结 在现代软件开发中&#xff0c;测试接口的有效性与响应情况变得尤为重要。本文将指导…

网络安全之信息收集-实战-1

请注意&#xff0c;本文仅供合法和授权的渗透测试使用&#xff0c;任何未经授权的活动都是违法的。 实战&#xff1a;补天公益src“吉林通用航空职业技术学院” 奇安信&#xff5c;用户登录https://www.butian.net/Loo/submit?cid64918 域名或ip&#xff1a;https://www.jlth…

鸿蒙实战:使用隐式Want启动Ability

文章目录 1. 实战概述2. 实现步骤2.1 创建鸿蒙应用项目2.2 修改Index.ets代码2.3 创建LuzhouAbility2.4 创建Luzhou页面2.5 设置模块配置文件 3. 测试效果4. 实战总结 1. 实战概述 本次鸿蒙应用实战&#xff0c;先创建项目“ImplicitWantStartAbility”&#xff0c;接着修改In…

STM32低功耗设计NFC与无线距离感应智能钥匙扣-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 智能钥匙扣作为一种小巧而实用的智能设备&#xff0c;凭借其便携性…

【Node.js】Node.js 和浏览器之间的差异

Node.js 是一个强大的运行时环境&#xff0c;它在现代 JavaScript 开发中扮演着重要角色。然而&#xff0c;许多开发者在使用 Node.js 时常常会感到困惑&#xff0c;尤其是与浏览器环境的对比。本文将深入探讨 Node.js 和浏览器之间的差异&#xff0c;帮助你全面理解两者的设计…

qt之telnet连接目标设备在线调试功能

一、前言 在QT下使用telnet连接目标设备&#xff0c;进行在线命令调试&#xff0c;也可配合ftp或ssh使用。 telnet某些库在qt5下不可用&#xff0c;无法获取登录信息&#xff0c;只能获取到连接信息&#xff0c;这里我用自己的方式判断是否成功登录 二、环境 window qt5.7…

小熊派Nano接入华为云

一、华为云IoTDA创建产品 创建如下服务&#xff0c;并添加对应的属性和命令。 二、小熊派接入 根据小熊派官方示例代码D6完成了小熊派接入华为云并实现属性上传命令下发。源码&#xff1a;小熊派开源社区/BearPi-HM_Nano 1. MQTT连接代码分析 这部分代码在oc_mqtt.c和oc_mq…

Hbuilder X/Uniapp 关于app运行调试及mumu模拟器运行问题

Hbuilder X 关于app调试问题及mumu模拟器链接问题 Hbuilder 关于app调试问题1. app运行配置2. adb路径配置3. 模拟器端口查询4. 运行 Hbuilder 关于app调试问题 1. app运行配置 Hbuilder > 工具 > 设置 > 运行配置 adb路径配置&#xff08;见2&#xff09; Android模…

MySQL-关键字执行顺序

&#x1f496;简介 在MySQL中&#xff0c;SQL查询语句的执行遵循一定的逻辑顺序&#xff0c;即使这些关键字在SQL语句中的物理排列可能有所不同。 &#x1f31f;语句顺序 (8) SELECT (9) DISTINCT<select_list> (1) FROM <left_table> (3) <join_type> JO…

【SpringBoot】26 实体映射工具(MapStruct)

Gitee 仓库 https://gitee.com/Lin_DH/system 介绍 现状 为了让应用程序的代码更易于维护&#xff0c;通常会将项目进行分层。在《阿里巴巴 Java 开发手册》中&#xff0c;推荐分层如下图所示&#xff1a; 每层都有对应的领域模型&#xff0c;即不同类型的 Bean。 DO&…

RPC-健康检测机制

什么是健康检测&#xff1f; 在真实环境中服务提供方是以一个集群的方式提供服务&#xff0c;这对于服务调用方来说&#xff0c;就是一个接口会有多个服务提供方同时提供服务&#xff0c;调用方在每次发起请求的时候都可以拿到一个可用的连接。 健康检测&#xff0c;能帮助从连…

Enterprise Architect 16 下载、安装与无限30天操作

文章目录 Enterprise Architect 16 简介&#xff08;一&#xff09;支持多种建模语言和标准&#xff08;二&#xff09;强大的版本控制、协作和文档管理功能&#xff08;三&#xff09;增强的技术和用户体验&#xff08;四&#xff09;高级功能和扩展性 一&#xff0c;下载软件…