基于PaddleX的YOLOv3目标检测系统
飞浆AI Stdio Fork 网址
https://aistudio.baidu.com/projectdetail/7965484?contributionType=1&sUid=9718239&shared=1&ts=1729516768932
1. 项目背景介绍
本博客介绍一个基于深度学习的物体检测系统,核心是使用PaddleX框架和YOLOv3模型来检测和识别图像中的物体。项目应用于检测五种商品——水、面包、火腿、面条和可乐,并根据识别结果自动计算商品的总价格。
2. 环境准备
需要 pyarrow的降级
,新的 pyarrow
模块没有 default_serialization_context
属性,在终端输入以下命令:
pip install --user --upgrade pyarrow==11.0.0
环境重启后(清除缓存),安装了PaddleX库以及所需的其他依赖:
pip install paddlex==2.0.0
3. 数据集准备
我们使用的数据集包含392张图片,五类商品(“水”、“面包”、“火腿”、“面条”和“可乐”),这些图片通过爬虫从百度图片获取,并使用精灵标注助手为每张图像生成XML标注文件。随后将标注文件转换为YOLOv3模型所需的格式。
4. 图像增强与预处理
为了提高模型的泛化能力,我们对数据集进行多种图像增强。以下是代码示例:
目的:提高图像数据的质量和多样性,从而提升机器学习模型的能力,帮助模型更好地泛化到未见过的数据上,增强模型对噪声和光照变化的鲁棒性,以及改善模型的整体表现。
from paddlex import transforms as T
train_transforms = T.Compose([
T.MixupImage(mixup_epoch=250), # Mixup技术增强图像
T.RandomDistort(), # 随机失真
T.RandomExpand(im_padding_value=[123.675, 116.28, 103.53]), # 随机扩展
T.RandomCrop(), # 随机裁剪
T.RandomHorizontalFlip(), # 随机水平翻转
T.BatchRandomResize( # 批量随机调整大小
target_sizes=[320, 352, 384, 416, 448, 480, 512, 544, 576, 608],
interp='RANDOM'),
T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # 归一化
])
该部分定义了训练时的图像增强过程,如随机失真、水平翻转、随机裁剪等。
5. 模型训练
我们使用YOLOv3模型进行物体检测。YOLOv3是一种实时目标检测算法,能够在单张图像上预测物体边界框和类别。模型的初始化和训练代码如下:
import paddlex as pdx
# 加载训练数据和评估数据
train_dataset = pdx.datasets.VOCDetection(
data_dir='VOC',
file_list='VOC/train_list.txt',
label_list='VOC/labels.txt',
transforms=train_transforms,
shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
data_dir='VOC',
file_list='VOC/val_list.txt',
label_list='VOC/labels.txt',
transforms=eval_transforms)
# 定义YOLOv3模型
model = pdx.det.YOLOv3(num_classes=len(train_dataset.labels), backbone='DarkNet53')
# 开始训练
model.train(
num_epochs=300, # 训练300个epoch
train_dataset=train_dataset,
train_batch_size=16,
eval_dataset=eval_dataset,
learning_rate=0.000125, # 学习率
lr_decay_epochs=[150, 243], # 学习率衰减
warmup_steps=1000,
warmup_start_lr=0.0,
save_interval_epochs=5,
save_dir='output/yolov3_darknet53',
use_vdl=True)
该部分代码定义了YOLOv3模型的训练流程,包括数据集的加载、训练参数的设置(如学习率、训练批次大小、学习率衰减等)。
模型训练中的参数解释:
2024-10-21 20:08:35 [INFO] [TRAIN] Epoch=116/300, Step=25/25, loss_xy=3.701668, loss_wh=1.012433, loss_obj=5.670866, loss_cls=0.964147, loss=11.349114, lr=0.000125, time_each_step=1.04s, eta=1:20:19
2024-10-21 20:08:36 [INFO] [TRAIN] Epoch 116 finished, loss_xy=4.3062954, loss_wh=1.2810763, loss_obj=5.317912, loss_cls=1.1032591, loss=12.008542 .
2024-10-21 20:08:45 [INFO] [TRAIN] Epoch=117/300, Step=10/25, loss_xy=5.175945, loss_wh=1.287346, loss_obj=6.316526, loss_cls=1.921066, loss=14.700883, lr=0.000125, time_each_step=0.93s, eta=1:11:41
2024-10-21 20:08:55 [INFO] [TRAIN] Epoch=117/300, Step=20/25, loss_xy=3.555696, loss_wh=1.063716, loss_obj=4.403270, loss_cls=0.649979, loss=9.672661, lr=0.000125, time_each_step=0.99s, eta=1:16:50
Epoch=116/300
表示当前是第116个训练周期,总共计划进行300个周期
Step=25/25
表示当前Epoch已经处理了25个批次,且这是最后一个批次
loss_xy=3.701668
表示在预测目标位置上的损失值为3.701668
loss=11.349114
表示总损失值为11.349114
lr=0.000125
表示当前的学习率为0.000125
time_each_step=1.04s
表示处理每个批次大约需要1.04秒
eta=1:20:19
表示预计还需要1小时20分钟19秒来完成剩余的训练
6. 模型预测与可视化
在训练完成后,我们可以使用该模型对新的图像进行预测,并输出检测结果:
model = pdx.load_model('output/yolov3_darknet53/best_model')
image_name = 'IMG_20240602_203123.jpg'
# 使用模型进行预测
result = model.predict(image_name)
# 输出检测结果
for item in result:
bbox = item['bbox'] # 边界框坐标
category_id = item['category_id'] # 类别ID
score = item['score'] # 置信度
category = train_dataset.labels[category_id] # 类别名称
print(f"Detected: {category} with confidence {score} at bbox {bbox}")
在这个代码块中,我们加载训练好的模型,并对指定图像进行预测。随后,程序将输出检测到的物体类别及其置信度,并展示物体在图像中的位置。
使用PaddleX自带的可视化功能将检测结果可视化:
pdx.det.visualize(image_name, result, threshold=0.49, save_dir='./output/yolov3_darknet53')
7. 价格计算
根据物品的类别,我们可以进一步计算图像中物品的总价格。我们首先定义一个商品价格字典:
简化代码如下:
label_scores = {
"water": 2,
"bread": 6,
"Ham": 1,
"noodles": 5,
"kola": 3
}
res = 0
confidence_threshold = 0.6 # 置信度阈值
# 根据检测结果计算价格
for item in result:
score = item['score']
category = train_dataset.labels[item['category_id']]
if score > confidence_threshold:
if category in label_scores:
res += label_scores[category]
print(f"商品总价格为: {res}")
这段代码根据预测结果中的类别和预设的价格,计算图像中商品的总价格,输出结果。
8. 总结
在本项目中,我们通过使用PaddleX的YOLOv3模型,成功实现了对特定商品的检测和价格计算。通过合理的数据增强和模型调优策略,模型达到了较高的检测精度。在应用中,该系统可以用于智能零售系统,快速识别商品并自动结算。