最近事情比较少,无意间刷到群聊里分享的基于百度飞浆平台的一次性筷子检测,感觉很有意思,恰巧自己最近在学习Yolov8,于是看看能不能复现,自己也是新手小白,会说的比较详细,适合小白入手。
项目运行视频我已上传到我的哔哩哔哩:
一,环境配置对于环境配置,我的是Anaconda虚拟环境,python是3.8(建议大家大于3.7),tensorflow是2.10,GPU版本的,pytorch是1.8.0的,开发平台是pycharm。
教程:
配置Anaconda,CUDN,cudnn:
注意:大家主要看里面配置Anaconda,CUDN,cudnn环境的部分就行,如果你的电脑不支持GPU,那么大家就可以配置cup的版本。怎么看支不支持GPU,看看笔记本有没有贴英伟达的标签就行。
配置pytorch:
GPU版本的PyTorch安装与环境配置_pytorch gpu版_「已注销」的博客-CSDN博客
这里一定要配置好,避免后续出现各种环境问题
一,虚拟环境创建下载好anaconda后,可以专门建一个环境,然后把上述的包配置到虚拟环境中吗,这里有两种方式新建虚拟环境,一是命令行输入,二是图形化界面。
方法一:命令行操作
打开左下角开始键里的Anaconda Powershell Prompt(注意是中间有一个 Powershell,不要误打开第二个,之后对于命令行的操作我们都是在这里进行!!!),打开后默认的是base环境,就是电脑本地环境。
创建Yolov8环境,输入命令:conda create -n yolov8,表示创建一个名字为Yolov8的环境,如果想要指定python版本,可以加上如python=3.9,如果默认创建,会在C盘!
如果想要改盘,可以参考
之后输入:conda activate yolov8,如果成功切换就证明创建成功。
方法二:图形化界面操作
还是在刚才的左下角,点击Anaconda Navigator,打开Environments,这里会看到你电脑里所有的虚拟环境以及该环境中安装的包及其版本。
点击creat,创建新环境,在这里你可以对你的环境进行创建,删除,重命名等。如果上面出现yolov8就证明创建成功。
二,安装资源包yolov8的训练相对于简单了很多,也比其他框架上手要来得快,因为很多东西都封装好了,直接调用或者命令行运行就行,首先需要先把代码git到本地(后续类似命令行操作都在Anaconda Powershell Prompt里输入,大家也可以在pycharm终端里输入,不过记得切换环境):
注意:如果安装过程比较慢,大家可以在命令行后加入清华源,豆瓣源等,教程:
git clone https://github.com/ultralytics/ultralytics.git然后安装ultralytics库,核心代码都封装在这个库里了。
pip install ultralytics再然后需要安装requirements.txt文件里需要安装的库,这里的文本文件就是运行这个项目需要配置的库的版本要求,根据需求配置环境才可以运行项目。
pip install -r requirements.txt接下来我们可以把预训练模型下载下来,通俗来讲就是模型训练好的参数保存在里面的一个文件,使用命令行运行检测命令检查环境是否安装成功,将权重下载下来然后新建weights文件夹存放,项目文件默认的是yolov8n模型,其他的在官网里下载:下载预训练模型,不同的模型代表不同的性能和规模,有的精度低但是速度块,有的模型大有的小。下载好后,我们放置到weights文件中,方便取用(这里我只下载了yolov8n.pt模型,建议大家都下载一下)。
配置完成后,我们在终端运行检测命令,测试yolov8是否可以运行,在项目文件的ultralytics/assets文件中有测试的两张图片。
yolo predict model=./weights/yolov8n.pt source=./ultralytics/assets/bus.jpg save命令详解:
1.yolo predict:选用yolov8的预测模式
2.model=./weights/yolov8n .pt:这是我们训练好模型的路径,这里我用的相对路径,大家根据自己电脑存放的路径进行修改
3.source=./ultralytics/assets/bus .jpg:这里是我们模型预测的样本来源,yolov8原本在/ultralytics(配置文件夹)下的assets(素材文件夹)下有两站自带的测试图片
4.save:这里我们选择将预测后的图片进行保存,默认的参数是ture,需要注意的是:yolov8运行后的文件默认保存在./runs文件夹下,终端也会输出文件保存位置
yolov自带的两个测试图片:
项目运行后终端显示,白色加粗的是预测后保存文件的路径
运行后预测图片,显示标注框内是各个类别,以及预测的准确率,其中这些类别都是yolov8自带的coco数据集里已经标注好的类别,如果在这个数据集之外的类别,是识别不出来的,也不会标注。
至此,如果能够成功输出预测图片,那么就证明你的环境已经配置好了,可以开始我们模型的训练啦!
二,数据集的构建 一.自行下载数据集为了方便大家学习和测试,我这里有一份已经搭建好的测试数据集,在我的主页:,大家可以自行下载,其中数据集里有两个文件,分别是images和labels。其中,images是210个竹签的图片,是我从其他博主哪里买来的,网上不好找,这里免费分享给大家。
labels是每一个图片的标注文件,是xmls格式。但是yolov只支持txt文件格式,这个后面会讲,大家之前下载的数据集就是txt格式文件,不用再进行转化了。
大家自行下载的数据集后,在yolov项目文件夹下构建一个名为datasets的文件夹,我们用来存放数据集,大家也可以存放到其他地方,但是建议都放到项目文件夹下,避免路径出现问题。
注意:大家下载后,根据下面的教程构建数据集文件夹,一定要看下面的构建数据集文件夹的教程!!!
新建的datasets文件夹下面有四个文件:
Annotations xml标注文件
images 训练的图片
ImageSets 用于存放划分的train.txt、test.txt、val.txt文件(初始为空)
labels 用于存放yolo格式的标注txt文件(初始为空)
二,构建自己的数据集这里教大家构建自己的数据集,含标注,划分,方便大家自己学会运用到其他项目中去。
1.数据准备大家可以自己拿手机拍一下数据集,准备大概80-100跟一次性筷子,然后拿手机拍大概200张(数据集越多越好,但是后面文件的标注麻烦),然后上传到电脑,构建一个images的文件夹,放到上面标红说的yolov项目文件夹下的datsets文件夹中,然后统一命名为0-200,注意要从0开始命名,其中我这里图片是jpg格式,有些格式不兼容,建议大家转为jpg或png格式,注意后面命名路路径的问题哦!
2.数据标注这里大家构建好数据集后,我们需要标注,这里用到了一款名为label的标注工具,在终端就可以下载。
在终端输入命令,注意:这里是英文拼写是img,而不是ing哦!:
pip install labelimg
然后我们需要下载一下labelimg所依赖的库,在终端输入:
pip install pyqt=5 pip install pyqt5-tools pip install lxml
如果你之前的一些库和上面的pyqt=5等库不兼容的话,建议你卸载那些不需要的库,否则会出现库之间版本不兼容的bug。
最后在终端出入命令,就会打开如下界面了,:
labelimg
官方自带的是英文的,如果大家喜欢用中文的可以去搜一下安装中文补丁的教程,这里就不赘述了,下面给大家一张中文操作的图,可以自己对照使用,功能按键就那几个,英文不影响使用的。
进入lableimg界面,先把这些选项勾上,便于进行标记,注意:标记模式改为yolo。
之后,点击open dir,打开我们数据集datasets里面images文件夹,选择之后会弹窗让你选择labels所在的文件夹。如果没有弹窗,点change save dir进行修改,选择lables文件夹,存放标签。
然后软件右上角我们打开这个选项,输入标签名称:zhuqian,当我们标记图片后,就会自动帮我们归类到zhuqian类了,这里默认只有一类,如果有多类,可以选择difficult。
现在我们就可以开始进行标记了,常用的快捷键,用主要wad三个键:
Ctrl + u Load all of the images from a directory Ctrl + r Change the default annotation target dir Ctrl + s Save Ctrl + d Copy the current label and rect box Ctrl + Shift + d Delete the current image Space Flag the current image as verified w Create a rect box d Next image a Previous image del Delete the selected rect box Ctrl++ Zoom in Ctrl-- Zoom out ↑→↓← | Keyboard arrows to move selected rect box点击左边工具栏里的Creat Rectbox,通过鼠标拖拽框选即可标注,没标注一个,右面就会出现一个标注信息:
所有都标注好后,我们打开lables文件夹,就会有许多标签的txt文件。大家注意:yolov模型标签文件的格式是txt格式,里面存放的是标注框的坐标信息,如图,第一列是类别,我这里只有一类,所以只有0,每一行代表一个标注框,后面的四列是标框四个角的位置信息。
之后在yolov的项目文件夹下创建一个main.py的文件,方便我们运行python代码
接下来运行如下文件,路径或者类别等参数根据自己的需要修改,运行该文件有两个作用:
划分train、test、val数据集
将voc格式标注转换为yolo格式标注
import os import random import xml.etree.ElementTree as ET from os import getcwd sets = ['train', 'test', 'val'] # 划分的train、test、val txt文件名字 classes = ['lables'] # 数据集类别,这里一定要改,填写xml文件里的类别名字 data_root = r"E:\yolov8\datasets" # 数据集绝对路径 trainval_percent = 0.1 # 测试集验证集比例 train_percent = 0.9 # 训练集比例 xmlfilepath = '{}/Annotations'.format(data_root) txtsavepath = '{}/images'.format(data_root) total_xml = os.listdir(xmlfilepath) num = len(total_xml) list = range(num) tv = int(num * trainval_percent) tr = int(tv * train_percent) trainval = random.sample(list, tv) train = random.sample(trainval, tr) ftest = open('{}/ImageSets/test.txt'.format(data_root), 'w') ftrain = open('{}/ImageSets/train.txt'.format(data_root), 'w') fval = open('{}/ImageSets/val.txt'.format(data_root), 'w') for i in list: name = total_xml[i][:-4] + '\n' if i in trainval: if i in train: ftest.write(name) else: fval.write(name) else: ftrain.write(name) ftrain.close() fval.close() ftest.close() # -------------------------------- voc 转yolo代码 def convert(size, box): dw = 1. / size[0] dh = 1. / size[1] x = (box[0] + box[1]) / 2.0 y = (box[2] + box[3]) / 2.0 w = box[1] - box[0] h = box[3] - box[2] x = x * dw w = w * dw y = y * dh h = h * dh return (x, y, w, h) def convert_annotation(image_id): in_file = open('{}/Annotations/{}.xml'.format(data_root, image_id), encoding='UTF-8') # print(in_file) out_file = open('{}/labels/{}.txt'.format(data_root, image_id), 'w') tree = ET.parse(in_file) root = tree.getroot() size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) for obj in root.iter('object'): difficult = obj.find('difficult').text cls = obj.find('name').text if cls not in classes or int(difficult) == 1: continue cls_id = classes.index(cls) xmlbox = obj.find('bndbox') b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) bb = convert((w, h), b) out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n') wd = getcwd() print(wd) for image_set in sets: if not os.path.exists('{}/labels/'.format(data_root)): os.makedirs('{}/labels/'.format(data_root)) image_ids = open('{}/ImageSets/{}.txt'.format(data_root, image_set)).read().strip().split() list_file = open('{}/{}.txt'.format(data_root, image_set), 'w') for image_id in image_ids: # print(image_id) list_file.write('{}/images/{}.jpg\n'.format(data_root, image_id)) try: convert_annotation(image_id) except: print(image_id) list_file.close()注意:如果上面下载的数据集的lables文件夹内是txt文件格式,需要把上面voc转yolov的代码注释掉,否则会报错。
最后得到如下文件,labels和ImageSets都不再为空:
3.模型训练v8的训练很简单,配置也超级简单,首先第一步在ultralytics/datasets中创建我们数据集的配置文件,这里我创建了一下chopsticks.yaml,内容如下,其实和之前的v5配置文件一样,该文件中修改自己的路径和类别即可:
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license # COCO 2017 dataset by Microsoft # Example usage: python train.py --data coco.yaml # parent # ├── yolov5 # └── data # └── chopsticks ← downloads here # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] path: D:\yolov8\datasets # datasets root dir train: train.txt # train ImageSets (relative to 'path') 118287 ImageSets val: val.txt # val ImageSets (relative to 'path') 5000 ImageSets test: test.txt # 20288 of 40670 ImageSets, submit to https://competitions.codalab.org/competitions/20794 # Classes nc: 1 # number of classes names: ['label'] # class names如果大家不会创建yaml文件,可以看教程:pycharm创建yaml文件 - CSDN文库
也可以在这个链接下载我创建好的yaml文件: 【免费】竹签数据集配置yaml文件资源-CSDN文库
注意!!!这个yaml文件的path是你数据集的绝对路径(根地址),这里填写的是我的,大家需要修改。
然后就可以开始训练了,训练过v5的同学可能记得还要修改一下models里的yaml文件,但是V8完全不用的,V8提供了两种简单的训练方式,一是命令行运行,直接在终端运行命令:
yolo task=detect mode=train model=./weights/yolov8n.pt data=./ultralytics/datasets/chopsticks.yaml epochs=100 batch=16 device=0命令详解:
1.yolo task=detect:这指定要执行的任务是目标检测。
2.mode=train: 这指定要在训练模式下运行。在训练模式下,模型将根据提供的训练数据进行学习。
3.model=./weights/yolov8n.pt: 这指定要使用的模型的路径。在这里,模型的权重文件是 yolov8n.pt,它位于 ./weights/ 目录中。
4.data=./ultralytics/datasets/chopsticks.yaml: 这指定了数据集的配置文件的路径。在这里,数据集的配置文件是 chopsticks.yaml,它应该位于 ./ultralytics/datasets/ 目录中。
5.epochs=100: 这指定了训练的总轮数(epochs)。在这里,你将模型训练了 100 个 epochs。
6.batch=16: 这指定了每个训练批次中包含的图像数量。在这里,每个批次包含 16 张图像。
7.device=0: 这指定了在哪个 GPU 设备上执行训练。在这里,device=0 表示使用第一个 GPU 设备。如果你有多个 GPU,你可以更改此参数以选择不同的 GPU。
也可以用python文件运行,大家可以在项目文件夹建一个train.py的文件,运行python trian.py:
from ultralytics import YOLO # 加载模型 # model = YOLO("yolov8n.yaml") # 从头开始构建新模型 model = YOLO("./weights/yolov8n.pt") # 加载预训练模型(推荐用于训练) # Use the model results = model.train(data="./ultralytics/datasets/chopsticks.yaml", epochs=100, batch=16,device=0) # 训练模型train过程比较顺利,训练默认采用早停法,即50个轮次评估中如果模型没有明显的精度提升的话,模型训练会直接停止,可以通过修改patience=50参数控制早停的观察轮次。
这里模型训练我用的GPU,大家如果没有gpu也可以用cpu,去掉最后的device=0就可以了。同样大家在模型训练中会遇到内存不足等报错的问题,我放到了最后,大家可以自行查看。
训练结束后模型和训练过程保存在runs文件夹中,可以看到精度其实还是不错的,接下来用图片测试一下。
同样的提供两种简单的推理方式,一是命令行,运行:
yolo task=detect mode=predict model=./runs/detect/train/weights/best.pt source=./40.jpg save=True或者创建一个demo.py文件,运行python demo.py:
from ultralytics import YOLO # Load a model # model = YOLO("yolov8n.yaml") # build a new model from scratch model = YOLO("./runs/detect/train/weights/best.pt") # load a pretrained model (recommended for training) # Use the model results = model("./40.jpg ") # predict on an image最后输出的运行效果,还是很不错的。如果大家的标签比较大,遮盖住了样本,可以网上搜索一下教程修改一下边框,这里我就不赘述了。
运行后在runs/detect/train文件夹里有模型训练的结果。
可以看到准确率和召回率都比较高,每一轮的损失函数都在变小,训练的效果还是不错的。
在result.csv文件里存的是每一轮的权重,损失率等参数
三,模型导出与部署模型训练完后,需要部署,V8也提供了直接了如下格式模型的导出(居然也支持paddlepaddle,惊讶),导出后可以摆脱训练框架进行部署:
命令行导出命令如下:
yolo export model=./runs/detect/train/weights/best.pt format=onnxpython文件导出:
from ultralytics import YOLO # Load a model model = YOLO('./runs/detect/train/weights/best.pt') # load a custom trained # Export the model model.export(format='onnx')导出后在.\runs\detect\train\weights文件里面有三个模型文件,而我们一般选用导出的best.pt文件来部署。
模型文件解读:
使用命令导出 YOLOv8 模型时,它会在指定的导出目录中生成三个文件:
1.best.onnx:此文件包含以开放神经网络交换 (ONNX) 格式导出的 YOLOv8 模型。ONNX 是一种用于表示深度学习模型的开放格式,它允许不同深度学习框架之间的互操作性。
2.best.pt:此文件是一个 PyTorch 检查点文件 (.pt),其中包含 YOLOv8 模型的权重和架构。您可以使用此文件在 PyTorch 中进行进一步训练、微调或推理。
3.last.pt:与 类似,此文件也是一个 PyTorch 检查点文件。它表示模型在最后一个训练周期的状态。如果您在训练期间使用该选项,它将定期保存额外的检查点,并且您可能有文件,例如表示纪元 X 的状态。best.pt--save_periodyolov8_last_epoch_X.pt
综上所述:
best.onnx:用于互操作性的模型的 ONNX 格式。
best.pt:包含模型权重和架构的 PyTorch 检查点文件。
last.pt:另一个 PyTorch 检查点文件,表示模型在上一个时期的状态。
上面我的模型训练了一次,在runs里只有一个,如果大家训练了多次,会有多个train,大家找到最新的就好啦
之后,我们在新建的main.py文件中,输入下面的代码,就会打开你本地的摄像头进行实时检测啦,注意加载模型的路径填写你本地保存模型的绝对路径:
import cv2 from ultralytics import YOLO # 加载模型 model = YOLO(model=r"D:\yolov8\runs\detect\train\weights\best.pt") # 摄像头编号 camera_no = 0 # 打开摄像头 cap = cv2.VideoCapture(camera_no) while cap.isOpened(): # 获取图像 res, frame = cap.read() # 如果读取成功 if res: # 正向推理 results = model(frame) # 绘制结果 annotated_frame = results[0].plot() # 获取检测到的物体的数量 num_objects = len(results[0].boxes) if results and results[0].boxes else 0 print(f"竹签个数: {num_objects}") # 在图像左上角显示物体数量 cv2.putText(annotated_frame, f"Number: {num_objects}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) # 显示图像 cv2.imshow(winname="YOLOV8", mat=annotated_frame) # 按ESC退出 if cv2.waitKey(1) == 27: break else: break # 释放链接 cap.release() # 销毁所有窗口 cv2.destroyAllWindows()恭喜你!到这里我们的项目就算运行成功啦,我这里汇集了许多博主的内容,尽可能详细的给大家讲解明白,遇到了问题可以评论区留言,我看到会一一回复的。
四,报错问题汇总 1.pycharm显示运行内存不足如下如,模型训练后因为pycharm内存不足,每次缓存文件放不下会发生崩溃,我们可以把pycharem内存扩大来解决问题。大家可以参考教程:pycharm如何增加运行时内存_提升pycharm占用的cpu核心数量-CSDN博客,这里扩容到了3GB的内存。
2.GPU运行内存不足,模型无法训练报错信息这里我没有截图,但是我们可以这样解决:
对于上面的训练命令:
yolo task=detect mode=train model=./weights/yolov8n.pt data=./ultralytics/datasets/chopsticks.yaml epochs=100 batch=16 device=01. 减小Batch Size: 降低batch size的值,这会减少每个批次处理的图像数量,从而减少GPU内存的需求。
如:我们把batch改为8
2.降低模型复杂度
我们可以更换模型,将yolov8n模型改为规模更小的模型,如yolov8s
3.分布式训练:此方法适用于多个含有多个gpu,每个gpu处理一个子批次。
参考文献:
yolov8训练筷子点数数据集_筷子数据集_三叔家的猫的博客-CSDN博客
再次衷心感谢上面博主的优质内容,供我参考意义很大!!!