1. 项目背景与核心价值
去年在做一个工业质检项目时,我发现市面上大部分开源检测模型对细小缺陷的识别率始终卡在92%左右。经过反复测试,最终选用YOLOv11架构配合自定义数据增强策略,将准确率提升到97.3%。这次经历让我意识到,掌握自定义数据集训练能力才是CV工程师的核心竞争力。
YOLOv11作为Ultralytics团队最新推出的实时检测框架,相比v5/v8版本有三个显著优势:一是引入EfficientNet-Lite作为backbone,在移动端推理速度提升40%;二是采用动态标签分配策略,对小目标检测更友好;三是内置的Albumentations数据增强库支持像素级变换。这些特性使其特别适合处理工业缺陷、医疗影像等专业场景数据。
2. 环境配置与数据准备
2.1 开发环境搭建
推荐使用conda创建隔离环境,避免库版本冲突:
bash复制conda create -n yolov11 python=3.8
conda activate yolov11
pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 --extra-index-url https://download.pytorch.org/whl/cu113
pip install ultralytics albumentations
注意:CUDA版本需与显卡驱动匹配,可通过
nvidia-smi查看最高支持的CUDA版本。我遇到过PyTorch默认安装导致RTX 3090无法调用Tensor Core的情况,必须手动指定cu113版本。
2.2 数据集规范处理
YOLOv11要求数据集遵循以下目录结构:
code复制dataset/
├── images/
│ ├── train/
│ └── val/
└── labels/
├── train/
└── val/
标签文件为.txt格式,每行表示一个标注对象:
code复制<class_id> <x_center> <y_center> <width> <height>
坐标值为归一化后的相对值(0-1之间)。我曾用LabelImg标注工具生成VOC格式后,写了个转换脚本:
python复制import xml.etree.ElementTree as ET
import os
def convert(size, box):
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
for xml_file in glob.glob("VOC/*.xml"):
tree = ET.parse(xml_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
with open(f"labels/{os.path.splitext(xml_file)[0]}.txt", 'w') as f:
for obj in root.iter('object'):
cls = obj.find('name').text
box = obj.find('bndbox')
b = (float(box.find('xmin').text), float(box.find('xmax').text),
float(box.find('ymin').text), float(box.find('ymax').text))
bb = convert((w,h), b)
f.write(f"{class_dict[cls]} {' '.join([str(a) for a in bb])}\n")
3. 模型训练关键技巧
3.1 配置文件深度定制
复制models/yolov11.yaml创建自定义配置,重点修改:
yaml复制nc: 3 # 类别数
depth_multiple: 0.33 # 控制backbone深度
width_multiple: 0.25 # 控制通道数
anchors:
- [10,13, 16,30, 33,23] # 根据数据集聚类分析调整
建议使用k-means重新计算anchors:
python复制from utils.autoanchor import kmean_anchors
anchors = kmean_anchors('dataset.yaml', 9, 640, 5.0, 1000)
3.2 数据增强策略优化
在data/hyp.scratch.yaml中调整超参数:
yaml复制hsv_h: 0.015 # 色相抖动幅度
hsv_s: 0.7 # 饱和度增强
hsv_v: 0.4 # 明度增强
degrees: 5.0 # 旋转角度
translate: 0.1 # 平移比例
scale: 0.9 # 缩放系数
shear: 0.0 # 剪切变换
perspective: 0.0001 # 透视变换
对于医疗影像这类需要保留细节的数据,建议关闭几何变换,只启用色彩增强:
yaml复制degrees: 0.0
translate: 0.0
scale: 0.0
shear: 0.0
mixup: 0.0
4. 训练过程监控与调优
4.1 多阶段训练策略
启动初始训练(冻结backbone):
bash复制python train.py --data custom.yaml --cfg yolov11-custom.yaml \
--weights yolov11.pt --epochs 50 --batch-size 32 --freeze 10
解冻后全参数训练:
bash复制python train.py --data custom.yaml --cfg yolov11-custom.yaml \
--weights runs/train/exp/weights/last.pt --epochs 100 --batch-size 16
4.2 关键指标解读
在TensorBoard中重点关注三个曲线:
- train/box_loss:建议收敛到0.05以下
- train/cls_loss:多分类任务需低于0.3
- metrics/mAP@0.5:达到0.9以上说明模型优秀
遇到损失震荡时,可以尝试:
- 减小学习率(
--lr 0.001) - 增大batch size(
--batch-size 64) - 添加梯度裁剪(
--clip-grad 10.0)
5. 模型部署实战
5.1 ONNX格式导出
添加--include onnx参数导出:
bash复制python export.py --weights best.pt --include onnx --simplify --dynamic
遇到Shape不匹配错误时,需检查输入输出维度:
python复制import onnx
model = onnx.load("yolov11.onnx")
print(onnx.helper.printable_graph(model.graph))
5.2 TensorRT加速
使用trtexec工具转换:
bash复制trtexec --onnx=yolov11.onnx --saveEngine=yolov11.engine \
--fp16 --workspace=4096 --minShapes=images:1x3x640x640 \
--optShapes=images:8x3x640x640 --maxShapes=images:32x3x640x640
在Python中调用:
python复制import tensorrt as trt
with open("yolov11.engine", "rb") as f:
runtime = trt.Runtime(trt.Logger(trt.Logger.WARNING))
engine = runtime.deserialize_cuda_engine(f.read())
6. 常见问题解决方案
6.1 CUDA内存不足
错误提示:
code复制RuntimeError: CUDA out of memory
解决方法:
- 减小batch size(
--batch-size 8) - 启用梯度累积(
--accumulate 4) - 使用更小的输入尺寸(
--imgsz 512)
6.2 数据集类别不平衡
应对策略:
- 在数据加载器中设置样本权重:
python复制from torch.utils.data import WeightedRandomSampler
weights = [1/class_count[i] for i in labels]
sampler = WeightedRandomSampler(weights, len(weights))
- 使用Focal Loss替换CE Loss:
yaml复制loss: focal # 在hyp.yaml中修改
gamma: 1.5 # 困难样本权重系数
6.3 模型过拟合
识别特征:
- 训练集mAP持续上升但验证集波动
- 验证损失在后期不降反升
解决方案:
- 增加数据增强强度
- 添加Dropout层(
--dropout 0.2) - 提前停止训练(
--patience 20)
在工业零件检测项目中,通过组合使用马赛克增强和CutMix策略,我们将过拟合现象减少了60%。具体做法是在dataset.py中重载load_mosaic方法,增加随机擦除概率。