YOLO(You Only Look Once)系列算法的发展历程堪称计算机视觉领域的一个经典案例。2016年,Joseph Redmon等人首次提出YOLOv1,彻底改变了目标检测的范式。传统方法如R-CNN系列需要先生成候选区域再进行分类,而YOLO创新性地将检测任务转化为单次回归问题,实现了端到端的训练和预测。
YOLOv2(YOLO9000)在2017年推出,主要贡献包括:
2018年的YOLOv3进一步优化了网络结构:
2020年出现的YOLOv4由Alexey Bochkovskiy团队开发,主要创新点包括:
YOLOv5虽然并非官方版本,但由于其易用性和出色的性能,成为工业界最受欢迎的版本:
YOLOv8由Ultralytics公司开发,主要改进包括:
最新的YOLOv10进一步优化了精度与速度的平衡:
YOLO的核心思想是将图像划分为S×S的网格,每个网格负责预测中心落在该区域的物体。对于每个网格,模型会预测:
边界框的预测包含5个值:(x, y, w, h, confidence)。其中:
在YOLOv2及之后的版本中,引入了锚框机制。预先定义一组不同长宽比的锚框,模型预测的是相对于这些锚框的偏移量,这使得模型更容易学习到合理的边界框形状。
YOLO的损失函数由多个部分组成,确保模型能够同时优化定位和分类性能。典型的YOLO损失函数包括:
边界框坐标损失:
置信度损失:
类别损失:
在YOLOv8和v10中,损失函数进一步优化:
网络结构:
训练优化:
工程实现:
骨干网络:
检测头:
任务扩展:
效率优化:
精度提升:
训练策略:
构建海洋动物检测系统的第一步是准备高质量的数据集。理想的数据集应该包含多种海洋动物类别,并在不同环境条件下(如光照、水质、角度等)采集图像。
公开数据集:
网络爬取:
实地采集:
使用LabelImg或CVAT等工具进行标注,保存为YOLO格式的txt文件。每个标注文件对应一张图像,包含多行记录,每行格式为:
code复制<class_id> <x_center> <y_center> <width> <height>
其中坐标值都是相对于图像宽高的比例(0-1之间)。
标注注意事项:
根据实际应用需求设计类别体系,例如:
类别数量不宜过多(通常10-30类),相近物种可以合并。对于稀有物种,确保每类至少有50-100个样本。
完整的数据预处理流程包括图像读取、标注解析、尺寸调整和归一化等步骤。以下是使用Python的实现示例:
python复制import os
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
class YOLODataset:
def __init__(self, img_dir, label_dir, classes, img_size=640):
self.img_dir = img_dir
self.label_dir = label_dir
self.classes = classes
self.img_size = img_size
self.class_to_idx = {name: i for i, name in enumerate(classes)}
self.image_files = [f for f in os.listdir(img_dir) if f.endswith(('.jpg', '.png'))]
# Split dataset
self.train_files, self.val_files = train_test_split(
self.image_files, test_size=0.2, random_state=42)
def __len__(self):
return len(self.image_files)
def load_image(self, img_path):
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
h, w = img.shape[:2]
img = cv2.resize(img, (self.img_size, self.img_size))
img = img / 255.0 # Normalize to [0,1]
return img, (w, h)
def load_labels(self, label_path, original_size):
w, h = original_size
labels = []
if os.path.exists(label_path):
with open(label_path, 'r') as f:
for line in f.readlines():
parts = line.strip().split()
class_id = int(parts[0])
x_center = float(parts[1]) * self.img_size
y_center = float(parts[2]) * self.img_size
box_w = float(parts[3]) * self.img_size
box_h = float(parts[4]) * self.img_size
# Convert to corner coordinates
x_min = x_center - box_w / 2
y_min = y_center - box_h / 2
x_max = x_center + box_w / 2
y_max = y_center + box_h / 2
labels.append([class_id, x_min, y_min, x_max, y_max])
return labels
def __getitem__(self, idx):
img_file = self.image_files[idx]
img_path = os.path.join(self.img_dir, img_file)
label_path = os.path.join(self.label_dir, img_file.replace('.jpg', '.txt').replace('.png', '.txt'))
img, original_size = self.load_image(img_path)
labels = self.load_labels(label_path, original_size)
return img, np.array(labels)
数据增强是提升模型泛化能力的关键。针对水下图像的特点,应采用适合的数据增强方法:
几何变换:
颜色变换:
模拟水下光学效应:
模糊和失真:
YOLOv5采用的Mosaic增强将4张训练图像拼接为1张,大幅提升小目标检测能力:
python复制def mosaic_augmentation(dataset, idx, img_size=640):
indices = [idx] + [random.randint(0, len(dataset)-1) for _ in range(3)]
images, labels = [], []
# Create mosaic canvas
mosaic_img = np.zeros((img_size*2, img_size*2, 3), dtype=np.float32)
mosaic_labels = []
# Center coordinates for each sub-image
centers = [(img_size//2, img_size//2),
(3*img_size//2, img_size//2),
(img_size//2, 3*img_size//2),
(3*img_size//2, 3*img_size//2)]
for i, (center_x, center_y) in enumerate(centers):
img, label = dataset[indices[i]]
h, w = img.shape[:2]
# Place image in mosaic
x1a, y1a = max(0, center_x - w//2), max(0, center_y - h//2)
x2a, y2a = x1a + w, y1a + h
x1b, y1b = w//2 - (center_x - x1a), h//2 - (center_y - y1a)
x2b, y2b = x1b + min(w, img_size), y1b + min(h, img_size)
mosaic_img[y1a:y2a, x1a:x2a] = img[y1b:y2b, x1b:x2b]
# Adjust labels
if len(label) > 0:
label[:, [1,3]] = (label[:, [1,3]] + x1a) / (img_size * 2)
label[:, [2,4]] = (label[:, [2,4]] + y1a) / (img_size * 2)
mosaic_labels.append(label)
if len(mosaic_labels) > 0:
mosaic_labels = np.concatenate(mosaic_labels, axis=0)
# Random perspective transform
mosaic_img, mosaic_labels = random_perspective(
mosaic_img, mosaic_labels, degrees=10, translate=0.1, scale=0.5)
return mosaic_img, mosaic_labels
MixUp将两张图像线性混合,鼓励模型学习更平滑的决策边界:
python复制def mixup_augmentation(img1, labels1, img2, labels2, alpha=0.5):
"""
img1: first image
labels1: first image's labels
img2: second image
labels2: second image's labels
alpha: beta distribution parameter
"""
lam = np.random.beta(alpha, alpha)
mixed_img = lam * img1 + (1 - lam) * img2
mixed_labels = np.concatenate([labels1, labels2], axis=0)
return mixed_img, mixed_labels
YOLOv5的网络结构可以分为三个主要部分:骨干网络(Backbone)、颈部(Neck)和检测头(Head)。
YOLOv5的骨干网络基于CSPDarknet53,主要特点包括:
Focus模块:
CSP结构:
SPPF模块:
颈部网络负责特征融合,YOLOv5采用PANet(Path Aggregation Network)结构:
自顶向下路径:
自底向上路径:
特征金字塔:
YOLOv5的检测头基于锚框机制,每个尺度的特征图预测:
边界框:
类别概率:
YOLOv5提供了完整的训练脚本和配置文件。以下是关键训练配置:
yaml复制# Paths
train: ../datasets/marine_animals/train/images
val: ../datasets/marine_animals/val/images
test: ../datasets/marine_animals/test/images
# Classes
names:
0: shark
1: dolphin
2: turtle
3: jellyfish
4: clownfish
5: stingray
6: octopus
7: whale
8: seal
9: crab
yaml复制# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# Parameters
nc: 10 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
# Anchors
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Focus, [64, 3]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, C3, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 9, C3, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, C3, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 1, SPPF, [1024, 5]], # 9
]
# YOLOv5 head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
bash复制python train.py --img 640 --batch 16 --epochs 100 --data data/marine_animals.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt --name marine_animals_detection
关键参数说明:
--img 640: 输入图像尺寸--batch 16: 批次大小(根据GPU内存调整)--epochs 100: 训练轮次--data: 数据配置文件路径--cfg: 模型配置文件路径--weights: 预训练权重路径--name: 实验名称YOLOv5使用余弦退火学习率调度器,配合线性热身:
热身阶段(前3个epoch):
余弦退火阶段:
lr = lr_final + 0.5*(lr_initial - lr_final)*(1 + cos(π*epoch/epochs))推荐初始学习率:
根据数据集特点调整增强参数(在hyp.scratch.yaml中配置):
yaml复制# Hyperparameters for marine animals detection
lr0: 0.01 # initial learning rate
lrf: 0.2 # final learning rate (lr0 * lrf)
momentum: 0.937
weight_decay: 0.0005
warmup_epochs: 3.0
warmup_momentum: 0.8
warmup_bias_lr: 0.1
box: 0.05 # box loss gain
cls: 0.5 # cls loss gain
cls_pw: 1.0 # cls BCELoss positive_weight
obj: 1.0 # obj loss gain
obj_pw: 1.0 # obj BCELoss positive_weight
iou_t: 0.20 # IoU training threshold
anchor_t: 4.0 # anchor-multiple threshold
fl_gamma: 0.0 # focal loss gamma
# Data augmentation
hsv_h: 0.015 # image HSV-Hue augmentation (fraction)
hsv_s: 0.7 # image HSV-Saturation augmentation (fraction)
hsv_v: 0.4 # image HSV-Value augmentation (fraction)
degrees: 10.0 # image rotation (+/- deg)
translate: 0.1 # image translation (+/- fraction)
scale: 0.5 # image scale (+/- gain)
shear: 0.0 # image shear (+/- deg)
perspective: 0.0 # image perspective (+/- fraction), range 0-0.001
flipud: 0.0 # image flip up-down (probability)
fliplr: 0.5 # image flip left-right (probability)
mosaic: 1.0 # image mosaic (probability)
mixup: 0.1 # image mixup (probability)
copy_paste: 0.0 # segment copy-paste (probability)
YOLOv5提供不同大小的预定义模型:
YOLOv5n(Nano):
YOLOv5s(Small):
YOLOv5m(Medium):
YOLOv5l(Large):
YOLOv5x(Extra Large):
使用TensorBoard监控训练过程:
bash复制tensorboard --logdir runs/train
关键指标解读:
早停策略(Early Stopping):
--patience参数设置模型选择:
冻结骨干网络:
类别不平衡处理:
锚框优化:
测试时增强(TTA):
YOLOv8在架构和训练策略上进行了多项创新,使其在精度和速度上都有显著提升。
无锚框(Anchor-Free)设计:
新的骨干网络:
解耦的检测头:
动态标签分配:
分类损失:
回归损失:
分布焦点损失(DFL):
马赛克增强改进:
自对抗训练(SAT):
更高效的优化器配置:
YOLOv8提供了更简洁的API进行训练和推理。以下是完整的训练示例:
bash复制pip install ultralytics
python复制from ultralytics import YOLO
# 加载预训练模型
model = YOLO('yolov8s.pt') # 加载官方预训练模型
# 训练模型
results = model.train(
data='marine_animals.yaml', # 数据配置文件路径
epochs=100, # 训练轮次
imgsz=640, # 输入图像尺寸
batch=16, # 批次大小
device='0', # 使用GPU 0
name='marine_animals_v8', # 实验名称
optimizer='auto', # 自动选择优化器
lr0=0.01, # 初始学习率
lrf=0.01, # 最终学习率
momentum=0.937, # 动量
weight_decay=0.0005, # 权重衰减
warmup_epochs=3.0, # 热身epoch数
warmup_momentum=0.8, # 热身动量
warmup_bias_lr=0.1, # 热身偏置学习率
box=7.5, # 框损失权重
cls=0.5, # 分类损失权重
dfl=1.5, # DFL损失权重
fl_gamma=0.0, # Focal Loss gamma
label_smoothing=0.0, # 标签平滑
nbs=64, # 名义批次大小
overlap_mask=True, # 训练时掩码重叠
scale=0.5, # 图像缩放
shear=0.0, # 图像剪切
perspective=0.0, # 图像透视
flipud=0.0, # 上下翻转概率
fliplr=0.5, # 左右翻转概率
mosaic=1.0, # 马赛克增强概率
mixup=0.1, # MixUp增强概率
copy_paste=0.0, # 复制粘贴增强概率
erasing=0.4, # 随机擦除概率
crop_fraction=1.0 # 图像裁剪比例
)
yaml复制# YOLOv8 dataset config for marine animals detection
# Paths
path: ../datasets/marine_animals # dataset root dir
train: train/images # train images (relative to 'path')
val: val/images # val images (relative to 'path')
test: test/images # test images (relative to 'path')
# Classes
names:
0: shark
1: dolphin
2: turtle
3: jellyfish
4: clownfish
5: stingray
6: octopus
7: whale
8: seal
9: crab
训练完成后,可以使用验证集评估模型性能:
python复制# 加载训练好的模型
model = YOLO('runs/detect/marine_animals_v8/weights/best.pt')
# 在验证集上评估
metrics = model.val(
data='marine_animals.yaml',
imgsz=640,
batch=16,
conf=0.25, # 置信度阈值
iou=0.6, # IoU阈值
device='0', # 使用GPU 0
split='val', # 在验证集上评估
name='val' # 评估结果保存名称
)
# 打印评估结果
print(f"mAP@0.5: {metrics.box.map}") # mAP@0.5
print(f"mAP@0.5:0.95: {metrics.box.map50_95}") # mAP@0.5:0.95
print(f"Precision: {metrics.box.precision}") # 精确率
print(f"Recall: {metrics.box.recall}") # 召回率
YOLOv8支持导出多种格式的模型,便于部署:
python复制# 导出为ONNX格式
model.export(format='onnx', imgsz=640, simplify=True)
# 导出为TensorRT引擎
model.export(format='engine', imgsz=640, device=0)
# 导出为OpenVINO格式
model.export(format='openvino', imgsz=640)
# 导出为CoreML格式
model.export(format='coreml', imgsz=640)
YOLOv10是最新发布的版本,在精度和效率方面都有显著提升。以下是其主要创新点:
一致性双重分配:
整体效率-精度驱动模型设计:
空间-通道解耦下采样:
秩引导块设计:
大核卷积:
部分自注意力(PSA):
增强的匹配策略:
掩码图像建模预训练:
YOLOv