保姆级教程:用YOLOv5训练自己的水下生物检测模型(附12444张数据集)
从零构建水下生物检测模型YOLOv5实战指南水下世界的神秘与复杂一直吸引着科学家和探险家。在这个充满未知的领域人工智能技术正逐渐成为探索海洋生物多样性的重要工具。本文将带你一步步完成从环境配置到模型部署的完整流程使用YOLOv5构建一个能够识别螃蟹、鱼类、水母等常见水下生物的目标检测系统。1. 环境准备与数据集处理1.1 搭建深度学习环境构建YOLOv5模型的第一步是配置合适的开发环境。推荐使用Python 3.8和PyTorch 1.7的组合这是经过验证的稳定搭配。以下是关键组件的安装步骤conda create -n yolo_env python3.8 conda activate yolo_env pip install torch1.8.1cu111 torchvision0.9.1cu111 -f https://download.pytorch.org/whl/torch_stable.html pip install opencv-python matplotlib tqdm pandas seaborn注意CUDA版本需要与你的NVIDIA显卡驱动兼容。使用nvidia-smi命令查看支持的CUDA版本。常见环境问题解决方案CUDA版本不匹配重新安装对应版本的PyTorch显存不足减小batch_size或使用更小的模型变体(yolov5s)依赖冲突建议使用conda或venv创建独立环境1.2 数据集结构与格式转换假设你已经获得了标注好的水下生物数据集通常会有两种常见格式VOC格式Annotations/ ├── image1.xml ├── image2.xml └── ... JPEGImages/ ├── image1.jpg ├── image2.jpg └── ...YOLO格式images/ ├── image1.jpg ├── image2.jpg └── ... labels/ ├── image1.txt ├── image2.txt └── ...如果原始数据是VOC格式可以使用以下Python脚本转换为YOLO格式import xml.etree.ElementTree as ET import os def convert_voc_to_yolo(xml_file, classes): tree ET.parse(xml_file) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) yolo_lines [] for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) xmlbox obj.find(bndbox) b (float(xmlbox.find(xmin).text), float(xmlbox.find(xmax).text), float(xmlbox.find(ymin).text), float(xmlbox.find(ymax).text)) bb convert((w,h), b) yolo_lines.append(f{cls_id} { .join([str(a) for a in bb])}\n) return yolo_lines 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)2. YOLOv5模型配置2.1 下载与准备YOLOv5从官方仓库克隆最新代码git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txtYOLOv5提供了多个预训练模型变体根据硬件条件选择模型类型参数量(M)推理速度(ms)mAP0.5适用场景yolov5n1.96.328.0移动端/嵌入式yolov5s7.26.437.4入门级GPUyolov5m21.28.245.4中等配置yolov5l46.510.149.0高性能GPUyolov5x86.712.150.7服务器级对于水下生物检测建议从yolov5s开始在验证集上评估后再决定是否需要更大模型。2.2 自定义数据集配置创建数据集描述文件underwater.yaml# 训练和验证图像路径 train: ../underwater_dataset/train/images val: ../underwater_dataset/valid/images # 类别数量 nc: 6 # 类别名称 names: [crab, fish, jellyfish, shrimp, small_fish, starfish]关键参数说明nc: 类别数量与你的数据集一致names: 类别标签顺序与标注文件中的class_id对应路径建议使用相对路径便于项目迁移3. 模型训练与调优3.1 启动训练过程基础训练命令python train.py --img 640 --batch 16 --epochs 100 --data underwater.yaml --cfg models/yolov5s.yaml --weights yolov5s.pt --name underwater_detection常用训练参数解析--img: 输入图像尺寸保持640x640的默认值即可--batch: 根据GPU显存调整显存不足时减小此值--epochs: 训练轮数水下生物检测通常需要100-300轮--weights: 预训练权重使用官方提供的yolov5s.pt可以加速收敛--name: 实验名称用于区分不同训练运行3.2 训练监控与问题排查训练开始后YOLOv5会自动生成以下监控文件runs/train/underwater_detection/ ├── weights/ # 保存的模型权重 ├── events.out.tfevents # TensorBoard日志 ├── results.png # 训练指标可视化 ├── train_batch0.jpg # 训练批次示例 └── val_batch0_labels.jpg # 验证集标注可视化常见训练问题及解决方案损失不下降检查学习率是否合适(默认0.01)确认数据标注是否正确尝试更小的模型或增加数据增强显存不足(OOM)减小batch_size(如从16降到8)使用更小的模型变体(yolov5n)尝试混合精度训练(添加--device 0 --half)过拟合增加数据增强参数(添加--augment True)提前停止训练(观察验证集指标)使用更大的数据集3.3 高级训练技巧数据增强策略修改data/hyps/hyp.scratch-low.yaml中的增强参数hsv_h: 0.015 # 色调增强 hsv_s: 0.7 # 饱和度增强 hsv_v: 0.4 # 明度增强 degrees: 10.0 # 旋转角度 translate: 0.1 # 平移比例 scale: 0.9 # 缩放比例 shear: 0.0 # 剪切变换 perspective: 0.0 # 透视变换 flipud: 0.0 # 上下翻转概率 fliplr: 0.5 # 左右翻转概率 mosaic: 1.0 # mosaic增强概率 mixup: 0.0 # mixup增强概率学习率调度YOLOv5默认使用余弦退火学习率调度。可以通过修改train.py中的优化器配置进行调整optimizer torch.optim.SGD(pg0, lrhyp[lr0], momentumhyp[momentum], nesterovTrue) lf lambda x: ((1 math.cos(x * math.pi / epochs)) / 2) * (1 - hyp[lrf]) hyp[lrf] # cosine scheduler torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambdalf)4. 模型评估与部署4.1 性能评估指标训练完成后使用验证集评估模型性能python val.py --weights runs/train/underwater_detection/weights/best.pt --data underwater.yaml --img 640关键评估指标解读mAP0.5: IoU阈值为0.5时的平均精度主要指标mAP0.5:0.95: IoU阈值从0.5到0.95的平均精度更严格Precision: 查准率预测为正样本中实际为正的比例Recall: 查全率实际正样本中被预测为正的比例水下生物检测的典型性能目标类别合理mAP0.5优秀mAP0.5螃蟹0.65-0.750.80鱼类0.70-0.800.85水母0.60-0.700.75虾类0.55-0.650.704.2 模型导出与优化将PyTorch模型导出为ONNX格式便于跨平台部署python export.py --weights runs/train/underwater_detection/weights/best.pt --include onnx --img 640 --dynamic导出后的模型可以使用ONNX Runtime进行加速推理import onnxruntime as ort ort_session ort.InferenceSession(best.onnx) outputs ort_session.run(None, {images: processed_image})模型量化减小模型大小提升推理速度from onnxruntime.quantization import quantize_dynamic, QuantType quantize_dynamic(best.onnx, best_quant.onnx, weight_typeQuantType.QUInt8)4.3 实际应用示例使用训练好的模型进行实时检测import cv2 import torch model torch.hub.load(ultralytics/yolov5, custom, pathruns/train/underwater_detection/weights/best.pt) cap cv2.VideoCapture(underwater_video.mp4) while cap.isOpened(): ret, frame cap.read() if not ret: break results model(frame) rendered_frame results.render()[0] cv2.imshow(Underwater Detection, rendered_frame) if cv2.waitKey(1) ord(q): break cap.release() cv2.destroyAllWindows()对于边缘设备部署可以考虑使用TensorRT进一步优化trtexec --onnxbest.onnx --saveEnginebest.trt --fp165. 进阶优化策略5.1 类别不平衡处理水下数据集中常见类别不平衡问题例如鱼类样本远多于海星。解决方法重采样策略过采样稀有类别欠采样常见类别损失函数加权 修改YOLOv5的损失计算为稀有类别分配更高权重# 在utils/loss.py中修改ComputeLoss类 class ComputeLoss: def __init__(self, model, autobalanceFalse): self.cls_weight torch.tensor([1.0, 1.0, 2.0, 1.5, 1.0, 2.0]) # 各类别权重 # ...其余初始化代码数据增强侧重 对稀有类别使用更强的数据增强5.2 水下图像增强水下图像常受颜色失真和模糊影响预处理方法def underwater_image_enhancement(image): # 颜色校正 image cv2.cvtColor(image, cv2.COLOR_BGR2LAB) l, a, b cv2.split(image) clahe cv2.createCLAHE(clipLimit3.0, tileGridSize(8,8)) l clahe.apply(l) image cv2.merge((l,a,b)) image cv2.cvtColor(image, cv2.COLOR_LAB2BGR) # 去模糊 kernel np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]]) image cv2.filter2D(image, -1, kernel) return image5.3 模型融合与集成提升模型鲁棒性的高级技术TTA(Test-Time Augmentation)python detect.py --weights best.pt --source test_images/ --augment模型融合 训练多个不同初始化的模型融合预测结果models [ torch.hub.load(ultralytics/yolov5, custom, pathmodel1.pt), torch.hub.load(ultralytics/yolov5, custom, pathmodel2.pt), torch.hub.load(ultralytics/yolov5, custom, pathmodel3.pt) ] def ensemble_predict(image): results [model(image) for model in models] # 实现加权框融合算法(WBF) return final_results多尺度训练与测试 在训练时使用不同输入尺寸提升模型尺度不变性python train.py --img 320 640 --multi-scale