ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

YOLOv5猫种类识别实战:数据标注到多平台部署全链路

YOLOv5猫种类识别实战:数据标注到多平台部署全链路 简介本资源是一份基于YOLOv5实现的猫种类识别项目源码面向计算机视觉初学者、深度学习课程学生及期末大作业实践者解决细粒度动物图像分类的实际问题适用于课程设计、AI实训与模型复现场景。压缩包共144个文件包含65个Python脚本含训练/推理/数据预处理核心代码、53个YAML配置文件定义模型结构、超参与数据路径、6个Shell脚本支持一键训练与评估、5个Markdown文档含环境配置说明与使用指南以及Dockerfile系列适配CPU、ARM64等多平台部署整体体积仅1023KB轻量易部署。已有243人学习下载项目经严格调试评审得分95分以上提供完整可运行流程从数据组织、模型微调、可视化检测到结果分析附带Jupyter教程与CITATION规范引用说明目录结构清晰模块职责分明便于理解YOLOv5在小样本细粒度分类任务中的工程落地细节。1. 这不是玩具模型YOLOv5在猫种类识别任务中真正跑通的完整链路你可能见过 dozens 个“YOLOv5猫识别”的 GitHub 仓库点进去却发现只有train.py和一张cat.jpg——训练脚本没配参、数据集路径硬编码、推理时爆KeyError: names。而这个高分95期末大作业项目是少数把「数据准备→模型微调→多平台部署→结果可视化」全闭环走通的实战工程。它不依赖云端标注服务用tutorial.ipynb内置的半自动标注流程30 分钟内就能从原始图片生成符合 YOLO 格式的.txt标签它规避了常见坑点比如Dockerfile-cpu显式禁用 CUDA 加速器检测避免在无 GPU 环境下因torch.cuda.is_available()返回True导致进程卡死它甚至为 ARM64 设备如树莓派 5/ Jetson Orin单独维护Dockerfile-arm64而非简单修改requirements.txt。适合两类人一是需要交差但拒绝糊弄的本科生能直接docker build -f Dockerfile-cpu -t cat-detector . docker run cat-detector跑出带类别置信度的检测框二是想吃透 YOLOv5 工程化细节的开发者从setup.cfg的package_dir配置到CITATION.cff的学术引用规范每一处都经得起答辩质询。2. 数据构建与标签生成从原始图片到YOLOv5可训练格式的确定性转换2.1 猫种类数据集结构设计与边界约束YOLOv5 对数据目录结构有强约定本项目采用datasets/cat_breeds/作为根目录其下必须包含images/和labels/两个平行子目录且images/中的.jpg文件名需与labels/中同名.txt文件严格一一对应。关键约束在于所有图片必须为 RGB 模式、无透明通道、尺寸不限但建议统一缩放至 640×640避免训练时mosaic增强导致边缘畸变。项目未使用公开数据集如 Oxford-IIIT Pets而是要求用户自行采集 12 类猫种如 British Shorthair、Siamese、Maine Coon 等各 150 张图每类图片存于datasets/cat_breeds/images/train/或val/子目录。setup.cfg中通过package_data {: [datasets/**/*]}确保pip install -e .时数据目录被正确打包避免FileNotFoundError。提示若图片含 alpha 通道常见于 PNG 截图需批量转换find datasets/cat_breeds/images -name *.png | xargs -I {} convert {} -background white -alpha remove -alpha off {}.jpg rm datasets/cat_breeds/images/*.png2.2 tutorial.ipynb 中的半自动标注流程实现tutorial.ipynb是本项目核心生产力工具它绕过 LabelImg 等 GUI 工具用 OpenCV Matplotlib 实现键盘驱动的标注闭环。核心逻辑在Cell 3# 加载图片并显示 img cv2.imread(img_path) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) plt.imshow(img_rgb) plt.title(fLabeling: {img_name} (Press n for next, s to save)) plt.axis(off) # 键盘事件绑定 def on_key(event): if event.key n: # 下一张 plt.close() next_image() elif event.key s: # 保存当前标注 # 获取鼠标点击坐标归一化到 [0,1] x_norm event.xdata / img.shape[1] y_norm event.ydata / img.shape[0] # 生成YOLO格式标签class_id center_x center_y width height label_line f{class_id} {x_norm:.6f} {y_norm:.6f} 0.2 0.2\n with open(label_path, a) as f: f.write(label_line) print(fSaved: {label_line.strip()}) plt.connect(key_press_event, on_key)该代码将单次点击转化为中心点坐标并固定宽高为0.2即图像宽高的 20%适用于猫脸区域粗略定位。实际使用时需先在Cell 1设置class_id0-11 对应 12 类猫再运行Cell 2加载图片列表最后执行Cell 3启动交互式标注。注意此流程生成的是单目标标签每张图一个.txt文件仅一行若需多目标检测需修改on_key函数支持矩形框拖拽项目未提供但Dockerfile-cpu中预装了opencv-python-headless可自行扩展。2.3 labels/ 目录生成与 train/val 划分验证标注完成后需确保labels/目录结构与images/完全镜像。项目提供utils/split_dataset.py脚本完成划分import os import random from shutil import copyfile def split_dataset(img_dir, label_dir, train_ratio0.8): all_images [f for f in os.listdir(img_dir) if f.lower().endswith((.jpg, .jpeg, .png))] random.shuffle(all_images) train_size int(len(all_images) * train_ratio) train_files all_images[:train_size] val_files all_images[train_size:] # 创建输出目录 os.makedirs(datasets/cat_breeds/images/train, exist_okTrue) os.makedirs(datasets/cat_breeds/images/val, exist_okTrue) os.makedirs(datasets/cat_breeds/labels/train, exist_okTrue) os.makedirs(datasets/cat_breeds/labels/val, exist_okTrue) # 复制图片和标签 for f in train_files: copyfile(os.path.join(img_dir, f), fdatasets/cat_breeds/images/train/{f}) label_f os.path.splitext(f)[0] .txt copyfile(os.path.join(label_dir, label_f), fdatasets/cat_breeds/labels/train/{label_f}) for f in val_files: copyfile(os.path.join(img_dir, f), fdatasets/cat_breeds/images/val/{f}) label_f os.path.splitext(f)[0] .txt copyfile(os.path.join(label_dir, label_f), fdatasets/cat_breeds/labels/val/{label_f}) if __name__ __main__: split_dataset(raw_images/, raw_labels/)运行后生成datasets/cat_breeds/images/{train,val}/和labels/{train,val}/。验证是否成功# 检查 train/val 图片数是否匹配标签数 ls datasets/cat_breeds/images/train/*.jpg | wc -l ls datasets/cat_breeds/labels/train/*.txt | wc -l # 输出应相等且文件名前缀一致如 cat_001.jpg ↔ cat_001.txt3. YOLOv5模型微调从预训练权重到猫种类专用检测器的参数配置3.1 模型选择与超参数配置文件解析项目采用yolov5s.pt作为基础权重轻量级适合期末作业算力其配置由models/yolov5s.yaml定义。关键修改在data/cat_breeds.yamltrain: ../datasets/cat_breeds/images/train val: ../datasets/cat_breeds/images/val nc: 12 # number of classes (must match your dataset) names: [British_Shorthair, Siamese, Maine_Coon, Persian, Ragdoll, Bengal, Sphynx, Abyssinian, Scottish_Fold, Norwegian_Forest, Devon_Rex, Birman] # class names in ordernc: 12必须与实际类别数严格一致否则训练时model.classifier层维度不匹配会报RuntimeError: mat1 and mat2 shapes cannot be multiplied。names列表顺序需与labels/中class_id0-11完全对应这是 YOLOv5 推理时model.names[class_id]查找类名的唯一依据。3.2 训练命令与关键参数调优策略训练入口为train.py项目推荐命令python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/cat_breeds.yaml \ --weights yolov5s.pt \ --name cat_breeds_exp1 \ --cache \ --workers 4 \ --exist-ok参数说明--img 640输入分辨率640 是yolov5s的默认值增大如 1280会提升精度但显存翻倍--batch 16总 batch size若单卡显存不足需按GPU数量 × 单卡batch调整例如双卡则设--batch 32--cache启用内存缓存避免重复 IO对 SSD 硬盘提速显著实测训练时间减少 22%--workers 4数据加载进程数设为 CPU 核心数的 75%如 8 核 CPU 设 6过高会导致OSError: Too many open files--exist-ok允许覆盖已存在实验目录避免FileExistsError中断训练。注意若使用Dockerfile-cpu需替换--batch为--batch 8并添加--device cpu否则 PyTorch 会尝试调用 CUDA 导致CUDA error: no kernel image for this GPU。3.3 训练过程监控与收敛判断训练日志输出至runs/train/cat_breeds_exp1/关键文件results.csv每 epoch 的metrics/precision,metrics/recall,metrics/mAP_0.5,loss/box,loss/obj,loss/clstrain_batch0.jpg首 batch 的增强效果可视化Mosaic、HSV 调整等val_batch0_pred.jpg验证集首 batch 的预测结果绿色框为真阳性红色为假阳性。收敛判断标准指标健康阈值异常信号mAP_0.5≥0.75猫种类识别合理值0.5 且连续 10 epoch 无提升precision0.80与recall差距 0.3过拟合loss/box0.050.15 且不下降学习率过大若mAP_0.5在 50 epoch 后停滞可尝试--lr0 0.01默认 0.01微调学习率或启用--augment增加 Mosaic 概率。4. 多平台部署与推理CPU/Docker/ARM64环境下的零配置运行4.1 Dockerfile-cpu 的精简设计原理Dockerfile-cpu不是简单删减 CUDA 相关行而是重构依赖链FROM python:3.8-slim # 移除所有 nvidia/cuda 相关层 RUN pip install --no-cache-dir torch1.12.1cpu torchvision0.13.1cpu -f https://download.pytorch.org/whl/torch_stable.html # 替换 requirements.txt 中的 torch 为 cpu 版本 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 关键禁用 CUDA 初始化 ENV CUDA_VISIBLE_DEVICES # 验证 PyTorch 是否正确加载 CPU 后端 RUN python -c import torch; print(torch.__version__); print(torch.cuda.is_available())最后一行print(torch.cuda.is_available())输出False是容器健康的黄金指标。若误用torchGPU 版本torch.cuda.is_available()返回True但后续model.to(cuda)会失败此设计提前暴露问题。4.2 ARM64设备部署实操Jetson Nano 部署全流程Dockerfile-arm64专为 NVIDIA Jetson 系列优化核心差异基础镜像改为nvcr.io/nvidia/l4t-pytorch:r32.7.1-pth1.10-py38JetPack 4.6 官方镜像requirements.txt中numpy替换为numpy1.21.6JetPack 4.6 兼容版本添加RUN apt-get update apt-get install -y libglib2.0-0 libsm6 libxext6 libxrender-dev解决 OpenCV GUI 依赖。部署步骤# 1. 在 Jetson Nano 上克隆项目 git clone https://github.com/xxx/cat-breed-yolov5.git cd cat-breed-yolov5 # 2. 构建 ARM64 镜像耗时约 25 分钟 sudo docker build -f Dockerfile-arm64 -t cat-detector-arm64 . # 3. 运行容器挂载摄像头设备 sudo docker run -it --rm --privileged \ -v /dev/video0:/dev/video0 \ -v $(pwd)/runs:/app/runs \ cat-detector-arm64 \ python detect.py --source 0 --weights runs/train/cat_breeds_exp1/weights/best.pt --conf 0.4--source 0指向/dev/video0--conf 0.4设置置信度阈值猫脸检测常用值输出结果存于runs/detect/exp/。4.3 推理结果后处理与可视化增强detect.py输出的*.txt标签需转为可视化图像项目提供utils/plot_results.pyimport cv2 import numpy as np def plot_detection(img_path, label_path, names, colors): img cv2.imread(img_path) h, w img.shape[:2] with open(label_path) as f: for line in f: cls_id, x_c, y_c, w_n, h_n map(float, line.strip().split()) # 归一化坐标转像素坐标 x1 int((x_c - w_n/2) * w) y1 int((y_c - h_n/2) * h) x2 int((x_c w_n/2) * w) y2 int((y_c h_n/2) * h) # 绘制矩形框和类别文字 color colors[int(cls_id) % len(colors)] cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, names[int(cls_id)], (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) return img # 使用示例 names [British_Shorthair, Siamese, ...] # 同 data/cat_breeds.yaml colors [(255,0,0), (0,255,0), (0,0,255), ...] # 12 种颜色 result_img plot_detection(test.jpg, test.txt, names, colors) cv2.imwrite(result.jpg, result_img)此脚本将 YOLOv5 输出的归一化坐标精确还原为像素坐标避免cv2.resize导致的定位偏移。颜色数组colors采用 HSV 色环生成项目utils/colors.py提供确保 12 类猫在视觉上区分度高。5. 模型性能验证与边界场景测试识别准确率之外的关键指标5.1 混淆矩阵分析与易混淆类别定位单纯看mAP_0.5无法发现模型弱点。项目提供utils/confusion_matrix.py生成混淆矩阵from sklearn.metrics import confusion_matrix import seaborn as sns # 加载真实标签和预测标签 y_true [...] # 所有验证图片的真实 class_id 列表 y_pred [...] # 模型预测的 class_id 列表 cm confusion_matrix(y_true, y_pred, normalizetrue) plt.figure(figsize(10,8)) sns.heatmap(cm, annotTrue, fmt.2f, cmapBlues, xticklabelsnames, yticklabelsnames) plt.title(Normalized Confusion Matrix) plt.ylabel(True Label) plt.xlabel(Predicted Label) plt.show()重点关注对角线外的高亮格若Siamese行中Bengal列值 0.3说明模型常将暹罗猫误判为孟加拉猫二者耳尖相似。此时需针对性增强Siamese数据集中的侧脸样本或在train.py中为Siamese类设置更高class_weights。5.2 小目标与遮挡场景鲁棒性测试猫种类识别的典型难点是小目标远距离猫和遮挡猫脸被爪子/毛发部分覆盖。项目设计三组测试集测试类型构建方法合格标准小目标将验证集图片 resize 到 320×320 后裁剪中心 128×128 区域mAP_0.5_small≥0.55遮挡用黑色矩形随机覆盖猫脸 30% 区域mAP_0.5_occluded≥0.60光照变化对图片应用cv2.convertScaleAbs(img, alpha1.2, beta10)过曝和alpha0.7, beta-20欠曝mAP_0.5_light≥0.65运行命令python test.py --data data/cat_breeds.yaml \ --weights runs/train/cat_breeds_exp1/weights/best.pt \ --img 320 --task test --name small_test # 结果输出至 runs/test/small_test/results.txt5.3 模型轻量化与推理速度实测期末作业需兼顾精度与效率。项目对比三种部署方式的 FPS帧率环境设备模型输入尺寸FPSCPUIntel i5-8250Uyolov5s640×6403.2GPURTX 3060yolov5s640×64048.7ARM64Jetson Nanoyolov5s416×41612.5实测代码utils/benchmark.pyimport time import torch model torch.hub.load(ultralytics/yolov5, custom, pathbest.pt) model.eval() # 预热 for _ in range(10): _ model(torch.randn(1,3,640,640)) # 测速 times [] for _ in range(100): start time.time() _ model(torch.randn(1,3,640,640)) times.append(time.time() - start) fps 100 / sum(times) print(fFPS: {fps:.1f})若需进一步提速可将模型导出为 TorchScriptpython export.py --weights runs/train/cat_breeds_exp1/weights/best.pt --include torchscript # 生成 best.torchscript加载速度提升 18%本文还有配套的精品资源点击获取
返回列表