随着深度学习技术的不断发展,目标检测作为计算机视觉领域的重要任务之一,已经取得了显著的进步。YOLO(You Only Look Once)系列算法作为实时目标检测的代表性方法,凭借其出色的性能和速度,在学术界和工业界都受到了广泛关注。本文将介绍如何使用YOLOv4算法,结合自己标注的数据集进行训练,并最终使用测试图片对训练好的模型进行结果检测与展示。
YOLOv4是一种目标检测算法,全称为You Only Look Once v4。它是YOLO系列算法的新版本,于2020年发布。YOLOv4通过使用深度卷积神经网络来实现实时目标检测。与其他目标检测算法相比,YOLOv4的主要优势在于速度快且准确率高。YOLOv4采用了许多创新的技术,包括CSPDarknet53架构、PANet、SAM、YOLOv4head等。这些技术的结合使得YOLOv4在目标检测任务上取得了很好的效果。YOLOv4在训练数据集上进行训练后,可以通过输入一张图片,输出图片中所有检测到的目标的类别、位置和置信度。这种实时的目标检测能够应用于许多领域,如智能监控、自动驾驶、机器人等。
在本文中,我将分享如何使用YOLOv4代码和自己标注的数据集进行训练,以及展示训练好的模型在测试图片上进行目标检测的结果。YOLOv4是一种高效的目标检测算法,具有快速和准确的特点,能够在实时场景中实现目标检测任务。
数据集是机器学习模型训练的基础,特别是对于目标检测任务来说,一个高质量、标注准确的数据集对模型性能的提升至关重要。在开始训练之前,首先需要收集并标注一个适用于目标检测任务的数据集。标注工具可以选择开源的LabelImg、LabelMe等,这个数据集对于模型的训练和性能评估至关重要。我们可以使用一些标注工具手动绘制边界框并指定类别标签,确保每个目标类别都有准确的边界框标注,完成数据的标注工作。
数据集的收集是目标检测任务的第一步。根据任务需求,我们需要从各种来源收集相关的图片,这些图片应该包含目标检测任务中所关心的目标对象。在收集图片时,应确保图片的多样性,包括不同场景、不同角度、不同光照条件下的图片,以提高模型的泛化能力。
数据集的质量直接影响到模型训练的效果,因此在标注过程中需要尽量准确地标注出每个目标的位置和类别。我们是通过在网上收集了100张人像图片。把自己下载的jpg图片文件放在VOCdevkit文件夹下的VOC2007文件夹下的JPEGImages文件夹中(如图所示:)
收集到图片后,接下来需要对这些图片进行标注。标注的目的是为每个目标对象提供精确的位置信息和类别标签。在这个过程中,我们选择了开源的标注工具LabelImg来进行标注工作。LabelImg是一个图形界面的标注工具,可以方便地绘制边界框并指定类别标签。
使用LabelImg进行标注时,我们首先打开一张图片,然后手动绘制出每个目标对象的边界框。在绘制过程中,可以调整边界框的大小和位置,以确保其准确地包围住目标对象。绘制完边界框后,需要为每个边界框指定一个类别标签。类别标签应该根据任务需求进行定义,我们定义了“eye”、“nose”、“ear”等类别。(如图所示:)
完成一张图片的标注后,LabelImg会将标注信息保存为一个XML文件。这个XML文件包含了图片的路径、尺寸信息以及每个目标对象的边界框坐标和类别标签。通过重复这个过程,我们可以为整个数据集的所有图片完成标注工作。把训练自己的数据集时xml标签文件放入VOCdevkit文件夹下的VOC2007文件夹下的Annotations文件夹中。(如图所示:)
完成数据集的标注后,下一步是将标注信息转换为YOLOv4算法所需的格式。YOLOv4算法通常使用Darknet框架进行训练和测试,而Darknet框架对数据集格式有特定的要求。
具体来说,Darknet框架需要的数据集格式包括一个文本文件列表,其中每一行对应一张图片的路径;以及一个包含所有标注信息的文本文件,其中每一行对应一个目标对象的类别标签、边界框坐标等信息。
为了将数据集转换为这种格式,我们需要编写一个转换脚本。这个脚本会遍历所有标注好的XML文件,提取出每张图片的路径、尺寸信息以及每个目标对象的边界框坐标和类别标签,然后将这些信息按照Darknet框架要求的格式写入到相应的文本文件中。
在转换过程中,还需要注意一些细节问题。例如,Darknet框架对边界框坐标的格式有特定的要求,通常需要使用相对于图片宽高的比例来表示边界框的左上角和右下角坐标。此外,类别标签也需要进行编码,通常使用一个整数来表示每个类别。
完成数据集的格式转换后,我们就可以将转换后的数据集用于YOLOv4算法的训练和测试了。通过正确地准备数据集,我们可以为后续的模型训练奠定坚实的基础。
在开始使用YOLOv4进行模型训练之前,我们首先需要在计算机上安装必要的软件和依赖库。这涉及到深度学习框架、GPU加速库以及一些辅助工具的安装和配置。
首先,我们需要安装一个python、深度学习框架。在这个实验中,我们将使用Darknet框架,因为它是YOLO系列算法的原生框架,能够很好地支持YOLOv4的训练和推理。Darknet是一个轻量级的深度学习框架,专注于实时目标检测任务。
除了Darknet框架外,我们还需要安装CUDA和cuDNN这两个GPU加速库。CUDA是NVIDIA推出的并行计算平台和API,它允许开发者使用NVIDIA的GPU进行高性能计算。cuDNN则是NVIDIA专为深度神经网络设计的一套GPU加速库,能够显著提高深度学习算法的计算效率。
在安装这些软件和库时,我们需要确保计算机的硬件支持GPU加速。通常,这意味着计算机需要配备NVIDIA的GPU,并且安装了相应的驱动程序。
安装过程可能因操作系统和具体需求的不同而有所差异,但一般可以通过访问相关官方网站或查阅文档来获取详细的安装指南。
安装好必要的软件和库后,我们需要准备YOLOv4的代码。这可以通过下载官方代码或开源实现来完成。在这个实验中,我们选择的是课上老师所提供的代码进行实现的,它包含了完整的训练、验证和推理代码,以及预训练的权重文件。
下载代码后,我们需要根据自己的需求进行适当的修改。这主要涉及到配置文件的修改,包括指定数据集路径、设置训练参数等。配置文件通常是一个文本文件,其中包含了训练过程中所需的各种参数和设置。
例如,在配置文件中,我们需要指定数据集的路径,以便训练时能够正确加载图片和标注信息。同时,我们还需要设置学习率、批次大小、训练轮数等超参数,以控制训练过程的进行。
此外,我们还可以根据需要修改模型文件。这包括加载预训练的权重文件作为初始化,或者调整模型的结构以适应特定的任务需求。
完成代码准备后,我们就可以开始使用YOLOv4进行模型训练了。通过正确的环境搭建和代码准备,我们可以为后续的训练和推理工作奠定坚实的基础。部分代码展示:
import os
import random
import xml.etree.ElementTree as ET
import numpy as np
from utils.utils import get_classes
annotation_mode = 2
classes_path = 'model_data/voc_classes.txt'
trainval_percent = 0.9
train_percent = 0.9
VOCdevkit_path = 'VOCdevkit'
VOCdevkit_sets = [('2007', 'train'), ('2007', 'val')]
classes, _ = get_classes(classes_path)
photo_nums = np.zeros(len(VOCdevkit_sets))
nums = np.zeros(len(classes))
def convert_annotation(year, image_id, list_file):
in_file = open(os.path.join(VOCdevkit_path, 'VOC%s/Annotations/%s.xml'%(year, image_id)), encoding='utf-8')
tree=ET.parse(in_file)
root = tree.getroot()
for obj in root.iter('object'):
difficult = 0
if obj.find('difficult')!=None:
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 = (int(float(xmlbox.find('xmin').text)), int(float(xmlbox.find('ymin').text)), int(float(xmlbox.find('xmax').text)), int(float(xmlbox.find('ymax').text)))
list_file.write(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))
nums[classes.index(cls)] = nums[classes.index(cls)] + 1
if __name__ == "__main__":
random.seed(0)
if " " in os.path.abspath(VOCdevkit_path):
raise ValueError("数据集存放的文件夹路径与图片名称中不可以存在空格,否则会影响正常的模型训练,请注意修改。")
if annotation_mode == 0 or annotation_mode == 1:
print("Generate txt in ImageSets.")
xmlfilepath = os.path.join(VOCdevkit_path, 'VOC2007/Annotations')
saveBasePath = os.path.join(VOCdevkit_path, 'VOC2007/ImageSets/Main')
temp_xml = os.listdir(xmlfilepath)
total_xml = []
for xml in temp_xml:
if xml.endswith(".xml"):
total_xml.append(xml)
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)
print("train and val size",tv)
print("train size",tr)
ftrainval = open(os.path.join(saveBasePath,'trainval.txt'), 'w')
ftest = open(os.path.join(saveBasePath,'test.txt'), 'w')
ftrain = open(os.path.join(saveBasePath,'train.txt'), 'w')
fval = open(os.path.join(saveBasePath,'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()
print("Generate txt in ImageSets done.")
if annotation_mode == 0 or annotation_mode == 2:
print("Generate 2007_train.txt and 2007_val.txt for train.")
type_index = 0
for year, image_set in VOCdevkit_sets:
image_ids = open(os.path.join(VOCdevkit_path, 'VOC%s/ImageSets/Main/%s.txt'%(year, image_set)), encoding='utf-8').read().strip().split()
list_file = open('%s_%s.txt'%(year, image_set), 'w', encoding='utf-8')
for image_id in image_ids:
list_file.write('%s/VOC%s/JPEGImages/%s.jpg'%(os.path.abspath(VOCdevkit_path), year, image_id))
convert_annotation(year, image_id, list_file)
list_file.write('n')
photo_nums[type_index] = len(image_ids)
type_index += 1
list_file.close()
print("Generate 2007_train.txt and 2007_val.txt for train done.")
def printTable(List1, List2):
for i in range(len(List1[0])):
print("|", end=' ')
for j in range(len(List1)):
print(List1[j][i].rjust(int(List2[j])), end=' ')
print("|", end=' ')
print()
str_nums = [str(int(x)) for x in nums]
tableData = [
classes, str_nums
]
colWidths = [0]*len(tableData)
len1 = 0
for i in range(len(tableData)):
for j in range(len(tableData[i])):
if len(tableData[i][j]) > colWidths[i]:
colWidths[i] = len(tableData[i][j])
printTable(tableData, colWidths)
if photo_nums[0] <= 500:
print("训练集数量小于500,属于较小的数据量,请注意设置较大的训练世代(Epoch)以满足足够的梯度下降次数(Step)。")
if np.sum(nums) == 0:
print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
print("在数据集中并未获得任何目标,请注意修改classes_path对应自己的数据集,并且保证标签名字正确,否则训练将会没有任何效果!")
print("(重要的事情说三遍)。")
在开始训练之前,我们需要设置一系列训练参数,这些参数将直接影响模型的训练效果和收敛速度。通常情况下,这些参数会在一个配置文件中指定,如
主要的训练参数包括:
学习率(Learning Rate):决定了模型参数在训练过程中的更新步长。过高的学习率可能导致训练不稳定,而过低的学习率则可能导致训练速度过慢。批次大小(Batch Size):每次迭代中用于计算梯度并更新模型权重的样本数量。增大批次大小可以加速训练,但也可能增加内存消耗。训练轮数(Epochs):整个数据集将被用于训练的完整次数。足够的训练轮数可以确保模型充分学习数据特征,但过多的轮数可能导致过拟合。优化器(Optimizer):用于更新模型权重的算法,如SGD、Adam等。权重衰减(Weight Decay):用于防止模型过拟合的正则化项。在配置好这些参数后,我们就可以开始训练过程了。
运行训练脚本,开始模型的训练过程。在训练过程中,可以观察损失函数的变化以及验证集上的性能表现,以便及时调整训练策略。
训练完成后,保存训练好的模型权重文件,以便后续进行推理和测试。
dn.save_weights(net, 'yolov4_trained.weights')
在保存权重文件后,我们就可以使用这个模型进行目标检测任务了。后续步骤通常包括加载模型权重、处理输入图像、进行前向传播以获取检测结果,并对结果进行可视化或进一步分析。
模型测试阶段,首先需要加载之前训练好的模型权重文件。这通常涉及到使用相应的深度学习框架提供的函数或方法,来读取权重文件并初始化模型。加载模型后,我们还需要准备用于测试的图片数据集。部分代码如下:
加载模型后,我们可以使用它对测试图片进行推理。推理过程通常包括预处理图像(如调整大小、归一化等)、前向传播获取检测结果,以及后处理(如非极大值抑制NMS)来消除冗余的边界框。
推理完成后,我们可以将检测结果绘制在原始图片上,生成带有边界框和类别标签的可视化结果。这可以通过使用OpenCV等库来完成,将边界框绘制在图片上,并在每个边界框旁边添加类别标签和置信度分数。
def evaluate_model(detections, annotations):
mAP = calculate_mAP(detections, annotations)
accuracy = calculate_accuracy(detections, annotations)
return mAP, accuracy
mAP, accuracy = evaluate_model(detections_list, annotations_list)
print(f'mAP: {mAP:.2f}, Accuracy: {accuracy:.2f}')
本文大概讲述了基于YOLOv4算法的目标检测任务,从数据集的准备、环境的搭建、模型的训练、测试到结果的展示与评估,为读者提供了一个简要的流程。通过实践,我们深入了解了目标检测任务中的关键步骤和技术要点。
在数据集的准备阶段,我们学习了如何收集、标注和处理图像数据,以构建符合任务需求的数据集。在环境搭建阶段,我们介绍了如何安装必要的依赖库和工具,并配置了适合YOLOv4训练的运行环境。在模型训练阶段,我们详细探讨了训练参数的配置、训练过程的监控以及模型权重的保存。而在模型测试和结果展示阶段,我们学习了如何加载训练好的模型,对测试图片进行推理,并将结果可视化呈现出来。
通过这一系列步骤,我们成功地训练出了一个能够在自定义数据集上进行目标检测的模型,并通过评估指标验证了模型的性能。这为我们后续的目标检测任务提供了宝贵的经验和参考。我们可以对检测结果进行分析和优化。通过观察检测结果,可以发现模型可能存在的一些问题如漏检、误检等,然后可以针对性地调整模型的参数或者进行进一步的数据增强来提升模型的性能和鲁棒性。同时,我也不是特别懂这些算法,还希望你们能给我提意见,我会好好看、好好学的。
虽然本文已经展示了基于YOLOv4的目标检测任务的基本流程,但仍有许多可以改进和优化的地方。例如,可以尝试使用更先进的数据增强技术来提高模型的泛化能力;也可以探索不同的模型优化策略来提升检测性能。此外,随着新的目标检测算法和技术的不断涌现,未来还可以考虑将这些新方法与YOLOv4进行结合,以进一步提升目标检测的准确性和效率。
首先,我们可以尝试使用更先进的数据增强技术。数据增强是一种通过对原始图像进行变换来生成更多训练样本的方法,可以有效地提高模型的泛化能力。未来,我们可以探索更多种类的数据增强方法,如旋转、缩放、裁剪、颜色变换等,以进一步扩充数据集并提升模型的性能。
其次,我们可以探索不同的模型优化策略。在模型训练过程中,优化器的选择和学习率的调整对模型的收敛速度和性能有着重要影响。未来,我们可以尝试使用不同的优化器以及学习率调度策略,便于找到更适合我们任务的训练策略。
此外,随着深度学习技术的不断发展,新的目标检测算法和框架不断涌现。未来,我们可以考虑将这些新方法与YOLOv4进行结合,以进一步提升目标检测的准确性和效率。
最后,我们还可以考虑将目标检测任务与其他计算机视觉任务进行结合,以实现更复杂的场景理解和应用。例如,我们可以将目标检测与实例分割、语义分割或行为识别等任务进行融合,以构建更全面的视觉感知系统。
总的来说,基于课上的YOLOv4代码,结合自己标注的数据集进行训练,得到训练好的模型,并使用测试图片对结果进行检测展示是一个非常有趣和实用的实践项目。通过这样的实践,可以更深入地理解目标检测算法的原理和实现细节,并且可以应用于实际的项目中,如智能监控、无人驾驶等领域。
相关知识
基于YOLOv4的目标检测模型训练与测试
基于深度学习的高精度狗狗检测识别系统(PyTorch+Pyside6+YOLOv5模型)
基于yolov8、yolov5的鸟类检测系统(含UI界面、数据集、训练好的模型、Python代码)
毕业设计:基于计算机视觉的遛狗牵绳识别系统 目标检测
用于宠物规范行为检测的目标检测模型及方法与流程
基于YOLOv8深度学习的200种鸟类智能检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战
基于YOLOv8深度学习的120种犬类检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战、狗类检测、犬种识别
一种基于深度残差网络的宠物图像情绪识别方法与流程
基于YOLO特征检测模型的非法溜宠物识别
(转载)YOLOv5 实现目标检测(训练自己的数据集实现猫猫识别)
网址: 基于YOLOv4的目标检测模型训练与测试 https://m.mcbbbk.com/newsview485629.html
上一篇: [YOLOv8] 缺陷检测之使用 |
下一篇: 一种检测宠物健康的监测服 |