1、YOLOv8深度学习环境搭建及安装
1.1. Yolov8介绍
设置操作类型
YOLOv8模型可用于各种任务,包括检测、分割和分类。这些任务的不同之处在于它们产生的输出类型和它们要解决的特定问题。
**检测:**检测任务涉及识别和定位图像或视频中感兴趣的对象或区域。YOLO模型通过预测图像中物体的边界框和类标签,可以用于物体检测任务。
**分割:**分割任务包括将图像或视频划分为对应于不同对象或类的区域或像素。
**分类:**分类任务包括为输入(如图像或文本)分配类标签。YOLO模型可以通过预测输入图像的类别标签来进行图像分类任务
根据你要解决的特定问题,YOLOv8模型可以在不同的模式下使用。这些模式包括train、val和predict。
**训练(Train)😗*训练模式用于在数据集上训练模型。这种模式通常在模型的开发和测试阶段使用。
Val: Val模式用于评估模型在验证数据集上的性能。这种模式通常用于调整模型的超参数和检测过拟合。
Predict: Predict模式用于在新数据上使用模型进行预测。这种模式通常用于生产环境或将模型部署给用户时。
Key | Value | Description |
---|---|---|
task | detect | 可选择:detect, segment, classify |
mode | train | 可选择: train, val, predict |
resume | False | 当设置为True时,恢复上一次的任务。当设置为False时,从给定的model.pt中恢复。 |
model | null | 设置模型。格式因任务类型而异。支持model_name, model.yaml,model.pt |
data | null | 设置数据,支持多数类型 data.yaml, data_folder, dataset_name |
模型结构图:
1.2.环境详细配置
运行平台为联通云服务器,显卡配置为:T4(16GB),可设置单块和多块GPU
具体环境:
PyTorch 1.9.1
Python 3.8
Cuda 11.1
依赖库按照requirements.txt文件安装即可。在YOLOv8代码包目录:pip install -r requirements.txt
1.3.安装YOLOv8所需要的ultralytics库
安装YOLOv8所需要的ultralytics库,在1.2的环境中,执行下述代码:
pip install ultralytics
1.4.下载YOLOv8代码包
下载YOLOv8代码,执行代码如下:
git clone https://github.com/ultralytics/ultralytics.git
自动下载
将服务器的文件目录cd到 path/your/ultralytics,激活配置的深度学习环境,至此,环境搭建结束!可开始模型的训练了。
YOLOv8代码包的内容如下图所示:
2、数据准备
2.1.数据集介绍及其结构
印刷电路板(PCB)瑕疵数据集:数据下载链接,是一个公共的合成PCB数据集,由北京大学发布,其中包含1386张图像以及6种缺陷(缺失孔,鼠标咬伤,开路,短路,杂散,伪铜),用于检测,分类和配准任务。
├── data
│ ├── Annotations 进行 detection 任务时的标签文件,xml 形式,文件名与图片名一一对应
│ ├── images 存放 .jpg 格式的图片文件
│ ├── ImageSets 存放的是分类和检测的数据集分割文件,包含 train.txt,val.txt,trainval.txt,test.txt
│ ├── labels 存放label标注信息的txt文件,与图片一一对应├── ImageSets(train,val,test建议按照8:1:1比例划分)
│ ├── train.txt 写着用于训练的图片名称
│ ├── val.txt 写着用于验证的图片名称
│ ├── trainval.txt train与val的合集
│ ├── test.txt 写着用于测试的图片名称
2.2.数据集划分
用途:主要是将数据集分类成训练数据集和测试数据集,默认train,val,test按照比例进行随机分类,运行后ImagesSets文件夹中会出现四个文件,主要是生成的训练数据集和测试数据集的图片名称,如下图。同时data目录下也会出现这四个文件,内容是训练数据集和测试数据集的图片路径。
import os
import randomtrainval_percent = 0.9
train_percent = 0.9
xmlfilepath = '/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/Annotations'
txtsavepath = '/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/ImageSets'
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)ftrainval = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/ImageSets/trainval.txt', 'w')
ftest = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/ImageSets/test.txt', 'w')
ftrain = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/ImageSets/train.txt', 'w')
fval = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/ImageSets/val.txt', 'w')for i in list:name = total_xml[i][:-4] + '\n'if i in trainval:ftrainval.write(name)if i in train:ftrain.write(name)else:fval.write(name)else:ftest.write(name)ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
- 运行代码后,在VOC_PCB/ImageSets文件夹下生成下面四个txt文档:
- txt文件里面的内容如下:
2.3.数据集格式转换
用途:用于yolo训练的txt格式代码。主要是将图片数据集标注后的xml文件中的标注信息读取出来并写入txt文件,运行后在labels文件夹中出现所有图片数据集的标注信息
# xml解析包
import xml.etree.ElementTree as ET
import pickle
import os
# os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表from os import listdir, getcwd
from os.path import joinsets = ['train', 'test', 'val']
classes = ['missing_hole', 'mouse_bite', 'open_circuit', 'short', 'spur', 'spurious_copper']# 进行归一化操作def convert(size, box): # size:(原图w,原图h) , box:(xmin,xmax,ymin,ymax)dw = 1./size[0] # 1/wdh = 1./size[1] # 1/hx = (box[0] + box[1])/2.0 # 物体在图中的中心点x坐标y = (box[2] + box[3])/2.0 # 物体在图中的中心点y坐标w = box[1] - box[0] # 物体实际像素宽度h = box[3] - box[2] # 物体实际像素高度x = x*dw # 物体中心点x的坐标比(相当于 x/原图w)w = w*dw # 物体宽度的宽度比(相当于 w/原图w)y = y*dh # 物体中心点y的坐标比(相当于 y/原图h)h = h*dh # 物体宽度的宽度比(相当于 h/原图h)return (x, y, w, h) # 返回 相对于原图的物体中心点的x坐标比,y坐标比,宽度比,高度比,取值范围[0-1]# year ='2012', 对应图片的id(文件名)def convert_annotation(image_id):'''将对应文件名的xml文件转化为label文件,xml文件包含了对应的bunding框以及图片长款大小等信息,通过对其解析,然后进行归一化最终读到label文件中去,也就是说一张图片文件对应一个xml文件,然后通过解析和归一化,能够将对应的信息保存到唯一一个label文件中去labal文件中的格式:calss x y w h 同时,一张图片对应的类别有多个,所以对应的bunding的信息也有多个'''# 对应的通过year 找到相应的文件夹,并且打开相应image_id的xml文件,其对应bund文件in_file = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/Annotations/%s.xml' % (image_id), encoding='utf-8')# 准备在对应的image_id 中写入对应的label,分别为# <object-class> <x> <y> <width> <height>out_file = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/labels/%s.txt' % (image_id), 'w', encoding='utf-8')# 解析xml文件tree = ET.parse(in_file)# 获得对应的键值对root = tree.getroot()# 获得图片的尺寸大小size = root.find('size')# 如果xml内的标记为空,增加判断条件if size != None:# 获得宽w = int(size.find('width').text)# 获得高h = int(size.find('height').text)# 遍历目标objfor obj in root.iter('object'):# 获得difficult ??difficult = obj.find('difficult').text# 获得类别 =string 类型cls = obj.find('name').text# 如果类别不是对应在我们预定好的class文件中,或difficult==1则跳过if cls not in classes or int(difficult) == 1:continue# 通过类别名称找到idcls_id = classes.index(cls)# 找到bndbox 对象xmlbox = obj.find('bndbox')# 获取对应的bndbox的数组 = ['xmin','xmax','ymin','ymax']b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),float(xmlbox.find('ymax').text))print(image_id, cls, b)# 带入进行归一化操作# w = 宽, h = 高, b= bndbox的数组 = ['xmin','xmax','ymin','ymax']bb = convert((w, h), b)# bb 对应的是归一化后的(x,y,w,h)# 生成 calss x y w h 在label文件中out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
# 返回当前工作目录
wd = getcwd()
print(wd)
for image_set in sets:'''对所有的文件数据集进行遍历做了两个工作:1.将所有图片文件都遍历一遍,并且将其所有的全路径都写在对应的txt文件中去,方便定位2.同时对所有的图片文件进行解析和转化,将其对应的bundingbox 以及类别的信息全部解析写到label 文件中去最后再通过直接读取文件,就能找到对应的label 信息'''# 先找labels文件夹如果不存在则创建if not os.path.exists('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/labels/'):os.makedirs('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/labels/')# 读取在ImageSets/Main 中的train、test..等文件的内容# 包含对应的文件名称image_ids = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/ImageSets/%s.txt' % (image_set)).read().strip().split()# 打开对应的2012_train.txt 文件对其进行写入准备list_file = open('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/%s.txt' % (image_set), 'w')# 将对应的文件_id以及全路径写进去并换行for image_id in image_ids:list_file.write('/home/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/images/%s.jpg\n' % (image_id))# 调用 year = 年份 image_id = 对应的文件名_idconvert_annotation(image_id)# 关闭文件list_file.close()
-
labels文件夹里面的内容如下:
-
txt文件每一行为一个目标的信息,包含class, x_center, y_center, width, height。格式如下:
3、模型训练
3.1.新建一个PCB数据集yaml文件—PCB.yaml
train: /home/xuh/AI_Industrial_Internet/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/train.txt
val: /home/xuh/AI_Industrial_Internet/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/val.txt
test: /home/xuh/AI_Industrial_Internet/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/test.txt# number of classes
nc: 6# class names
names: ['missing_hole', 'mouse_bite', 'open_circuit', 'short', 'spur', 'spurious_copper']
3.2 训练代码
YOLOv8模型的训练设置是指用于在数据集上训练模型的各种超参数和配置。这些设置会影响模型的性能、速度和精度。一些常见的YOLO训练设置包括批量大小、学习率、动量和权重衰减。其他可能影响训练过程的因素包括优化器的选择、损失函数的选择、训练数据集的大小和组成。重要的是要仔细调整和试验这些设置,以实现给定任务的最佳性能。
YOLOv8关于模型训练和预测的超参数在ultralytics/yolo/cfg/default.yaml中设置,这是与先前版本的最大的不同,通过使用这些指令我们就可以实现各种我们所需的操作。
default.yaml内容
#只展示了一部分超参数task: detect # (str) YOLO task, i.e. detect, segment, classify, pose
mode: train # (str) YOLO mode, i.e. train, val, predict, export, track, benchmark# Train settings -------------------------------------------------------------------------------------------------------
model: # (str, optional) path to model file, i.e. yolov8n.pt, yolov8n.yaml
data: # (str, optional) path to data file, i.e. coco128.yaml
epochs: 100 # (int) number of epochs to train for
patience: 50 # (int) epochs to wait for no observable improvement for early stopping of training
batch: 16 # (int) number of images per batch (-1 for AutoBatch)
imgsz: 640 # (int | list) input images size as int for train and val modes, or list[w,h] for predict and export modes
save: True # (bool) save train checkpoints and predict results
save_period: -1 # (int) Save checkpoint every x epochs (disabled if < 1)
cache: False # (bool) True/ram, disk or False. Use cache for data loading
device: # (int | str | list, optional) device to run on, i.e. cuda device=0 or device=0,1,2,3 or device=cpu
workers: 8 # (int) number of worker threads for data loading (per RANK if DDP)
project: # (str, optional) project name
name: # (str, optional) experiment name, results saved to 'project/name' directory
exist_ok: False # (bool) whether to overwrite existing experiment
pretrained: True # (bool | str) whether to use a pretrained model (bool) or a model to load weights from (str)
optimizer: auto # (str) optimizer to use, choices=[SGD, Adam, Adamax, AdamW, NAdam, RAdam, RMSProp, auto]
verbose: True # (bool) whether to print verbose output
seed: 0 # (int) random seed for reproducibility
deterministic: True # (bool) whether to enable deterministic mode
single_cls: False # (bool) train multi-class data as single-class
rect: False # (bool) rectangular training if mode='train' or rectangular validation if mode='val'
cos_lr: False # (bool) use cosine learning rate scheduler
close_mosaic: 10 # (int) disable mosaic augmentation for final epochs (0 to disable)
resume: False # (bool) resume training from last checkpoint
amp: True # (bool) Automatic Mixed Precision (AMP) training, choices=[True, False], True runs AMP check
fraction: 1.0 # (float) dataset fraction to train on (default is 1.0, all images in train set)
profile: False # (bool) profile ONNX and TensorRT speeds during training for loggers
freeze: None # (int | list, optional) freeze first n layers, or freeze list of layer indices during training
# Segmentation
overlap_mask: True # (bool) masks should overlap during training (segment train only)
mask_ratio: 4 # (int) mask downsample ratio (segment train only)
# Classification
dropout: 0.0 # (float) use dropout regularization (classify train only)
YOLOv8提供CLI和python两种训练方式
CLI就是直接在终端运行指令
python需要新建一个python文件,然后运行代码
yolov8命令行的统一运行格式为:
yolo TASK MODE ARGS
其中主要是三部分传参:
TASK(可选) :含义是选择任务类型,从[detect、segment、classification]中选一个。如果没有显式传递,YOLOv8将尝试从模型类型中猜测TASK。
MODE(必选) :是训练、验证还是预测的任务,可从[train, val, predict, export]中选一个
ARGS(可选) : 是任意数量的自定义arg=value对,如imgsz=320,覆盖默认值。
1.CLI指令
命令行中执行代码:
yolo task=detect mode=train model=/home/xuh/AI_Industrial_Internet/PCB_detect_model/YOLOv8/ultralytics/weights/yolov8s.pt data=/home/xuh/AI_Industrial_Internet/PCB_detect_model/YOLOv8/ultralytics/PCB_dataSets/VOC_PCB/PCB.yaml batch=32 epochs=100 imgsz=640 workers=16 device='0,1'
2.python指令训练方式
在YOLOv8包中,新建train.py,代码如下:
from ultralytics import YOLO# Load a model
# model = YOLO('yolov8n.yaml') # build a new model from YAML 从YAML中构建一个新模型
# model = YOLO('yolov8n.pt') # load a pretrained model (recommended for training) 加载预训练的模型(推荐用于训练)
model = YOLO('yolov8s.yaml').load('ultralytics/weights/yolov8s.pt ') # build from YAML and transfer weights 从YAML构建并传递权重# Train the model
model.train(data='ultralytics/PCB_dataSets/VOC_PCB/PCB.yaml', epochs=100, imgsz=640)
model类方法train(训练)的参数:
Key | Value | Description |
---|---|---|
device | “1” | Cuda设备,即0或0、1、2、3或cpu。选择可用的cuda0设备 |
epochs | 100 | 需要训练的epoch数 |
workers | 8 | 每个进程使用的cpu worker数。使用DDP自动伸缩 |
batch | 16 | Dataloader的batch大小 |
imgsz | 640 | Dataloader中图像数据的大小 |
optimizer | SGD | 支持的优化器:Adam, SGD, RMSProp |
single_cls | False | 将多类数据作为单类进行训练 |
image_weights | False | 使用加权图像选择进行训练 |
rect | False | 启用矩形训练 |
cos_lr | False | 使用cosine LR调度器 |
lr0 | 0.01 | 初始化学习率 |
lrf | 0.01 | 最终的OneCycleLR学习率 |
momentum | 0.937 | 作为SGD的momentum和Adam的beta1 |
weight_decay | 0.0005 | 优化器权重衰减 |
warmup_epochs | 3.0 | Warmup的epoch数,支持分数 |
warmup_momentum | 0.8 | warmup的初始动量 |
warmup_bias_lr | 0.1 | Warmup的初始偏差lr |
box | 0.05 | Box loss gain |
cls | 0.5 | cls loss gain |
cls_pw | 1.0 | cls BCELoss positive_weight |
obj | 1.0 | bj loss gain (scale with pixels) |
obj_pw | 1.0 | obj BCELoss positive_weight |
iou_t | 0.20 | iou训练时的阈值 |
anchor_t | 4.0 | anchor-multiple阈值 |
fl_gamma | 0.0 | focal loss gamma |
label_smoothing | 0.0 | |
nbs | 64 | nominal batch size |
overlap_mask | True | 分割:在训练中使用掩码重叠 |
mask_ratio | 4 | 分割:设置掩码下采样 |
dropout | False | 分类:训练时使用dropout |
4、模型预测
YOLO模型的预测设置是指用于在新数据上使用模型进行预测的各种超参数和配置。这些设置会影响模型的性能、速度和精度。一些常见的YOLO预测设置包括置信度阈值、非最大抑制(NMS)阈值和要考虑的类别数量。其他可能影响预测过程的因素包括输入数据的大小和格式,是否存在额外的特征(如掩码或每个框的多个标签),以及模型正在用于的特定任务。重要的是要仔细调整和试验这些设置,以实现给定任务的最佳性能。
1.predcit方法的参数
Key | Value | Description |
---|---|---|
source | ultralytics/assets | 输入源。支持图片、文件夹、视频、网址 |
show | False | 查看预测图片 |
save_txt | False | 保存结果到txt文件中 |
save_conf | False | 保存condidence scores |
save_crop | Fasle | |
hide_labels | False | 隐藏labels |
hide_conf | False | 隐藏confidence scores |
vid_stride | False | 输入视频帧率步长 |
line_thickness | 3 | 边框厚度(单位:像素) |
visualize | False | 可视化模型特征 |
augment | False | 增强推理 |
agnostic_nms | False | Class-agnostic NMS |
retina_masks | False | 分割:高分辨率掩模 |
1.CLI指令
yolo task=detect mode=predict model=runs/detect/train2/weights/best.pt source=data/images device=0
2.python指令预测方式
在YOLOv8包中,新建predict.py,代码如下:
from ultralytics import YOLO
# Load a model
model = YOLO('runs/detect/train4/weights/best.pt') # load a custom model# Predict with the model
results = model.predict(source='ultralytics/PCB_dataSets/test_img/l_light_01_missing_hole_05_2_600.jpg',save=True) # predict on an image
2. model类predcit方法的返回值
返回值是一个对象列表,具有如下属性:
属性 | 类型 | 描述 |
---|---|---|
orig_img | numpy.ndarray | 原始图像的numpy数组。 |
orig_shape | tuple | 原始图像的形状,格式为(高度,宽度)。 |
boxes | Boxes, 可选 | 包含检测边界框的Boxes对象。 |
masks | Masks, 可选 | 包含检测掩码的Masks对象。 |
probs | Probs, 可选 | 包含每个类别的概率的Probs对象,用于分类任务。 |
keypoints | Keypoints, 可选 | 包含每个对象检测到的关键点的Keypoints对象。 |
speed | dict | 以毫秒为单位的每张图片的预处理、推理和后处理速度的字典。 |
names | dict | 类别名称的字典。 |
path | str | 图像文件的路径。 |
5、模型验证
CLI指令验证方式
yolo task=detect mode=val model=yolov8n.pt
# mode=val 就是看验证集
yolo task=detect mode=val split=val model=runs/detect/train2/weights/best.pt data=ultralytics/datasets/MoonCake.yaml
# mode=test 就是看测试集
yolo task=detect mode=val split=test model=runs/detect/train2/weights/best.pt data=ultralytics/datasets/MoonCake.yaml
Python指令验证方式
在YOLOv8代码包中,新建val.py,代码如下:
from ultralytics import YOLO# Load a model
# model = YOLO('yolov8n.pt') # load an official model
model = YOLO('runs/detect/train4/weights/best.pt') # load a custom model# Validate the model
metrics = model.val() # no arguments needed, dataset and settings remembered
metrics.box.map # map50-95
metrics.box.map50 # map50
metrics.box.map75 # map75
metrics.box.maps # a list contains map50-95 of each category
model类方法val(验证)的参数:
一些比较常用的传参:
model 需要评估的pt模型文件路径
data 需要评估的数据集yaml文件
imgsz 评估图片推理大小,默认640
batch 评估推理批次,默认16
save_json 是否保存评估结果为json输出,默认False
save_hybrid 是否保存混合版本的标签(标签+额外的预测)
conf 模型评估置信度阈值,默认0.001
iou 模型评估iou阈值,默认0.6
max_det 单张图最大检测目标数量,默认300
half 是否使用fp16推理,默认True
device 要运行的设备,即cuda device =0或Device =0,1,2,3或device = cpu
dnn 是否使用use OpenCV DNN for ONNX inference,默认Flase
rect 是否使用矩形推理,默认False
split 数据集分割用于验证,即val、 test、train,默认val
6、参考文章
1.YOLOv8官方文档
2.YOLOv8运行参数解读
3.YOLOV8模型训练+部署(实战)
4.Jetson nano部署YOLOv8
5.YOLOv8训练自己的数据集(超详细)
6.【YOLO】YOLOv8训练自定义数据集(4种方式)
这几篇文章写的都很棒,受益良多。