如何使用 YOLO V8 训练出自己的模型数据,并运用到目标检测中?
- 本案例尝试训练并识别 "FC经典游戏 超级玛丽" 中的 Player1
前言
- 最近正在着手学习 AI 相关技术,有了一些小创意和小想法
- 先记录下来自己学习过程中的重点内容,顺便分享
- 本篇文章仅为初学记录,并不一定详细且完美,但我会尽量完整,也会抽空随着自己的学习和练习对此进行更改
- 本文若写的有问题,欢迎友好评论,谢谢
后续计划
后续我的初步计划是:会出一篇文章,以经典游戏“贪吃蛇”为目标对象,通过 YOLO V8 进行模型训练并目标识别,从而实现让 AI 控制小蛇自动游戏,如果你对此感兴趣,可以持续关注我哦
目标实现思路
- 收集训练模型所需的图片素材
- 利用 labelimg 标注图片素材(保存输出符合 YOLOV8 模型结构要求的数据文件)
- 利用 YOLO V8 训练模型(生成数据模型文件)
- 通过 YOLO V8 读取训练好的模型文件进行目标检测
本人系统及配置
- Windows 11
- GPU: NVIDIA RTX 4060 8G (利用 GPU 训练模型数据)
环境准备
- 安装 Anaconda
- 本机安装 python,并配置环境变量
- ---(这里不作详述,因为网上教程很多,本篇重点是记录训练和检测目标的过程)---
安装 labelimg
- (安装说明:由于 labelimg 对 python 版本有要求,我目前安装的 labelimg 需要基于 python 3.9 版本,但我宿主机环境里装的是 python 3.10,为了不影响宿主机环境,我选择在 Anaconda 虚拟环境中安装并使用 labelimg)
-
- 开始安装:
- 打开 Anaconda Prompt 终端,创建 python 3.9 的虚拟环境,并激活
# 创建名为 python39 的虚拟环境
conda create -n python39 python=3.9.16
# 激活已经创建的环境
conda activate python39
- 安装 labelimg:
# 记录在 Anaconda Prompt 终端窗口中依次输入下列代码,这些是 labelimg 依赖的第三方库
pip install PyQt5
pip install pyqt5-tools
pip install lxml
# 然后安装 labelimg
pip install labelimg
- 安装完成后,在 Anaconda Prompt 终端窗口中输入 labelimg,回车,即可打开 labelimg 软件
labelimg
操作开始!!!
1 - 项目目录准备
- 创建一个文件夹,比如我的项目文件夹名为:fc_mario_game
2 - 收集训练模型所需的图片素材
- 收集素材图片的方式有很多(爬虫、自己截图、网上找之类的),这份案例仅仅是初步学习,为的就是能够成功搞出一份自定义训练模型且能够成功使用,所以尽量简单些,用最简单的方式收集了一些素材图片(网上找的素材包)

- 把收集的素材图片,放到项目文件夹里,比如我这样
-- fc_mario_game
|__ source_imgs
|__ mario_players.png
3 - 利用 labelimg 对图片进行打标签
(标签打好之后,保存输出符合 YOLOV8 模型结构要求的数据文件)
-
打标签的目的是为了,在训练模型的时候,让 YOLO V8 对相应的一系列图片做标记,从而让 YOLO V8 在目标检测的时候,识别出正确的目标
-
3.1 - 在 Anaconda Prompt 终端的 python 3.9 虚拟环境中通过 labelimg 指令启动软件
- 打开 labelimg 软件后,点击“Open Dir”按钮,选择刚才准备好的素材图片文件夹,即 source_imgs/
- 【重点】:把左侧操作列中的模式改成 YOLO,即上图中用箭头圈出来的位置,默认是别的格式的,鼠标点击一下就会切换到 YOLO 模式,这样最后保存输出的文件就是满足 YOLO V8 模型结构要求的数据文件了(即 txt 文件)
- 再选择 Change save dir 按钮,选择我们希望输出文件的保存位置,比如我这样:
-- fc_mario_game
|__ source_imgs
|__ mario_players.png
|__ labelimg_output (我希望输出文件的保存位置)
- 然后点击“Create rect box”按钮,在弹出的窗口中,选择“Create new shape”,开始对对应的区域画格子,画好格子会让你为标签命名,比如上图中我都命名为 p1 表示这是player1(该案例目的只是为了识别出人物就行,如果往复杂了想,不同的一系列动作都要命名为不同的标签名称,这样就能识别得更精确,比如死亡状态的超级玛丽,当然我们这案例里不需要这么复杂,先感受明白整个训练过程即可)
- 最后格子都画完了,点击“Save”按钮,保存好标签文件,就会在目录里看到输出的标签数据文件了,比如我这样:
└─fc_mario_game
├─ source_imgs
│ mario_players.png
├─ labelimg_output (输出文件的保存位置)
│ mario_players.txt (记录了相应图片上画格子的坐标数据和相应的标签索引数据)
│ classes.txt (记录了所有的标签命名)
4 - 代码开始!!! -- 训练模型
4.1 -- 目录准备
- 【注】:yolov8n.pt 这个文件是官方提供的,在我们调用 YOLO('yolov8n.pt') 这行代码的时候,若目录下没有这个文件,会自动去下载,所以不用提前下载好
- 下面这份目录说明是用于参照的一个参考标准,本文章中的目录会也是参照这个来的
│ test.png (用于测试模型实际效果的图片)
│ yolo_predit.py (执行测试效果的脚本)
│ yolo_train.py (执行模型训练的脚本)
│ yolov8n.pt (训练模型时使用的官方模型文件[执行训练脚本时会自动下载])
└─data
│ mario.yaml (自己手动创建并编写的训练模型配置文件[对应下面的几个目录和前面 labelimg 生成的标签名称])
│ yolov8n.yaml
│
├─test
│ ├─images
│ │ 1.jpg
│ │
│ └─labels
│ 1.txt
│
├─train (目录:放置用于训练的图片和 labelimg_output 里复制过来的文件,每一张图片对应一个 labelimg_output 里打好标签的 txt 文件[])
│ │
│ ├─images
│ │ 1.jpg
│ │ 2.jpg
│ │ 3.jpg
│ │ ...
│ │
│ └─labels
│ 1.txt
│ 2.txt
│ 3.txt
│ ...
│
└─val
│
├─images
│ 3.jpg
│
└─labels
3.txt
- mario.yaml 配置
train: D:/code_workspace/ai_traning_model/ai_traing_studio/data/train/images
val: D:/code_workspace/ai_traning_model/ai_traing_studio/data/val/images
test: D:/code_workspace/ai_traning_model/ai_traing_studio/data/test/images
# number of classes
nc: 1
# class names
names: ['player']
- mario.yaml 配置说明:
配置【train, val, test】:
这三个参数指定了训练集、验证集和测试集的路径。这些路径指向包含图像文件的文件夹。在训练过程中,模型将使用训练集的图像来学习,验证集用于在训练过程中评估模型的性能,而测试集则用于最终评估模型的泛化能力。
配置【nc】:
nc代表“number of classes”,即类别的数量。在这个配置中,它被设置为1,这意味着模型将被训练来识别单一类别的对象。这通常适用于单一类别的对象检测任务。
配置【names】:
names是一个列表,包含了所有类别的名称。在这个例子中,只有一个类别,名为'player'。这意味着模型将被训练来检测图像中的“player”对象。在多类别检测任务中,这个列表会包含所有需要检测的类别名称。
- 【train, val, test】三个目录的说明
训练集(Training Set)、验证集(Validation Set)和测试集(Test Set)是机器学习和深度学习项目中用于不同阶段评估和改进模型性能的数据集。
【训练集(Training Set)】:
- **图像文件**:存放所有用于训练的图像,这些图像包含了需要被模型学习识别的对象。图像格式通常为`.jpg`、`.png`等。
- **标签文件**:与图像文件一一对应的文本文件,包含了每个图像中对象的类别和位置信息。这些文件通常包含对象的边界框坐标和类别索引,格式可能因使用的框架而异。对于YOLO,每行可能包含类别索引和归一化的边界框坐标。
【验证集(Validation Set)】:
- **图像文件**:与训练集类似,验证集目录中也存放图像文件。这些图像用于在训练过程中定期评估模型的性能,帮助调整模型参数。
- **标签文件**:与验证集图像对应的标签文件,包含对象的类别和位置信息。这些文件用于在验证阶段与模型的预测结果进行比较,以评估模型的泛化能力。
【测试集(Test Set)】:
- **图像文件**:测试集目录中存放的图像文件用于最终评估模型的性能。这些图像在训练过程中从未被模型见过,因此它们提供了一个独立的评价标准。
- **标签文件**:与测试集图像对应的标签文件,包含了真实对象的类别和位置信息。在测试阶段,这些标签用于与模型的预测结果进行比较,以计算模型的准确性和其他性能指标。
【文件命名和组织】:
- **命名规则**:为了确保模型能够正确读取和处理数据,图像和标签文件通常遵循一致的命名规则。例如,如果图像文件名为`image001.jpg`,对应的标签文件可能是`image001.txt`。
- **目录结构**:图像和标签文件通常放在各自的目录中,保持结构清晰。例如,训练集的图像和标签文件可能分别存放在`train/images`和`train/labels`目录下。
- **一致性**:验证集和测试集的结构应与训练集保持一致,以便于模型在不同阶段的评估中能够无缝切换。
确保这些数据集的质量和组织结构对于训练出高性能的模型至关重要。在实际操作中,可能还需要进行数据预处理,如图像大小调整、归一化、数据增强等,以提高模型的训练效率和性能。
4.2 -- 训练图片材料准备
- 下面这几张是我从游戏里截图并通过工具粗略裁剪处理的,以及从网上找的素材,主要是为了标注时图片较清晰明显,这有助于提高训练后的识别准确度
- 我的这几张图片也是直接存放在项目目录下的,为了方便使用
-
- 1
-
- 2
- 2
-
- 3
- 3
4.3 -- 使用前面说到的 labelimg 对图片打标注,保存后会输出标注文件
- 我的标注后保存输出文件如下
4.4 -- 把标注输出的“txt 标注文本”和“对应的图片”复制到 data 目录下
-
我的 data 目录里是这样放的
-
data/images/ 放所有标注对应的原始图片
-
data/labels/ 放所有标注的 txt 文本
-
data/train/ 同 data/images/ 和 data/labels/ 一模一样,即让其录入所有训练数据
-
data/val/ 放任意几份标注的 txt 文本和对应的原始图片
-
data/test/ 同 data/val/ 一样玩法,但是要尽量放与 data/val/ 不同 txt 文本和对应的原始图片,有助于训练过程中进行测试
-
mario.yaml 是配置文件,会在后续的训练脚本中被调用到,用于通过该配置文件,读取此 data/ 目录下的相关文件,至于打的标签就根据自己而定,主要是为了后续识别时对物体的识别名称而已(等后续写对识别到的对象进行相关操作时,那这些标注的 label 名称就需要好好规范了,识别到不同的的 label 需要做不同的操作,比如遇到敌人了需要做跳跃操作等,本文只是初步尝试,所以标签的 label 名字比较随意,主要是实现最后能识别出来就行)
-
我的配置如下:
train: D:/你的完整项目目录/fc_mario_game/data/train/images
val: D:/你的完整项目目录/fc_mario_game/data/val/images
test: D:/你的完整项目目录/fc_mario_game/data/test/images
# number of classes
nc: 3
# class names
names: ['player1_1','player1_r','player1_end']
- [附]:这部分操作我为了后续方便,后来写了一个一键转移 labelimg 文件脚本,详情请见文章 # Yolo V8 模型训练初学者笔记(番外篇)-- 一键转移labalimg标签文件
4.5 -- 训练和检测脚本
- 训练和预测脚本执行后,输出的文件会生成在终端执行脚本时的所在目录下,会自动创建一个 run/detect 目录,后续输出的训练文件都会在在此目录中追加,就像下面这样
- 训练脚本 yolo_train.py
from ultralytics import YOLO
# Load a model
model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training)
# Train the model
model.train(data='./data/mario.yaml', epochs=100, imgsz=640)
- 检测脚本 yolo_predit.py(这里的 fcmario_last.pt 会在下一步提到)
from ultralytics import YOLO
from PIL import Image
import cv2
model = YOLO("fcmario_last.pt")
#from PIL
im1 = Image.open("test.png")
results = model.predict(source=im1, save=True) # save plotted images
4.5 -- 执行训练脚本
python yolo_train.py
- 得到如下训练文件
- 其中 last.pt 就是下一步执行检测脚本 yolo_predit.py 所需要用到的 yolo 模型文件
4.5 -- 执行检测脚本
yolo_predit.py
- 把刚才训练得到的 last.pt 复制到 yolo_predit.py 同目录下
- 再拿一张用来测试实际识别效果的图片,也复制到 yolo_predit.py 同目录下
- test.png
- 执行脚本后输出的结果如下
- 可以看到这张测试图片是我从实际游戏画面里截图的,与我训练所用的图片都是不完全一样的,但是也精确识别出来了人物了
##【附(重要提示)】:
- 对于上述步骤,要想能够更加精确识别到目标物体,需要经历很多轮模型训练,因为其中的训练算法是需要一轮又一轮的训练才能让程序意识到想要找的目标,所以我们第一次模型训练后得到的无论是 best.pt 还是 last.pt 在执行预测脚本时都几乎无法成功识别的
- 这里我说下自己的训练过程以供参考:第一次模型训练时提供的图片尽量完整一些,把想识别的目标都涉及到,用 labelimg 打标签进行训练;经过一次模型训练后,要继续添加一些不一样的图片,可以是背景不同的之类的图片,再继续打标签训练;接下来的几次模型训练也是以此类推,每次模型训练之后可以通过预测脚本查看检测结果是否满足需求了,若已经能几乎每次都可以稳定识别到目标了,那训练得就差不多了,这个训练多少轮是没有定论的,简单的场景下当然训练几轮就可以了,越是复杂的就需要训练更多回了
- (以上的核心其实就是统计学的知识点,这方面我也正在学习中,所以说的也都是大白话,并不能加入理论知识,比如准确率、精确率、召回率等等之类的专业参数)
总结学习感悟
- AI 模型训练的第一步终于成功了,其实这第一步也挺不容易的,后续要继续加油了!
- 每一次对新上手的技术第一次初步成功时,总是那么兴奋,以后就有动力进击下一个小目标了!
- 其实我们每次学习新技术不用心高气傲目标定得太大,一步跨太大容易扯蛋,扯蛋了多疼啊,很容易放弃的,一步小一点,一步一步来,慢慢进击,说不定哪天就能有所成就了。