从零到一搭建YOLOv11汽车品牌识别系统
引言
在计算机视觉领域,目标检测是一项基础且重要的任务。YOLO(You Only Look Once)系列算法因其出色的速度和精度平衡而广受欢迎。本文将详细介绍如何使用最新的YOLOv11框架从零开始构建一个汽车品牌识别系统,涵盖环境搭建、数据准备、模型训练的全过程。
一、环境搭建
1.1 硬件准备
汽车品牌识别是一个中等复杂度的目标检测任务,建议使用以下硬件配置:
- GPU:NVIDIA GTX 1660及以上(推荐RTX 3060及以上)
- 内存:16GB及以上
- 存储:至少50GB可用空间(用于存储数据集和模型)
1.2 软件环境配置
我们使用Python 3.8和PyTorch框架:
# 创建conda虚拟环境conda create-nyolov11python=3.8-yconda activate yolov11# 安装PyTorch(根据CUDA版本选择)pipinstalltorch==1.12.1+cu113torchvision==0.13.1+cu113torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113# 安装YOLOv11及相关依赖gitclone https://github.com/WongKinY/yolov11.gitcdyolov11 pipinstall-rrequirements.txt1.3 验证安装
importtorchprint(torch.__version__)print(torch.cuda.is_available())# 应返回True二、数据准备
2.1 数据收集
汽车品牌识别需要收集包含各种品牌汽车的图片,可通过以下途径:
- 公开数据集:Stanford Cars、CompCars等
- 网络爬取(注意版权)
- 自行拍摄
2.2 数据标注
使用LabelImg工具进行标注:
pipinstalllabelImg labelImg# 启动标注工具标注时需注意:
- 每张图片中包含的汽车都要标注
- 标注框应紧密贴合汽车
- 品牌名称作为类别标签(如"Toyota", "BMW"等)
2.3 数据格式转换
YOLOv11使用YOLO格式的标注:
- 每张图片对应一个.txt文件
- 每行格式:
class_id x_center y_center width height(归一化坐标)
可使用以下脚本转换VOC格式到YOLO格式:
importxml.etree.ElementTreeasETimportosdefconvert_voc_to_yolo(voc_dir,output_dir,class_list):os.makedirs(output_dir,exist_ok=True)forfileinos.listdir(voc_dir):iffile.endswith('.xml'):tree=ET.parse(os.path.join(voc_dir,file))root=tree.getroot()img_name=root.find('filename').text img_width=int(root.find('size/width').text)img_height=int(root.find('size/height').text)yolo_lines=[]forobjinroot.iter('object'):cls=obj.find('name').textifclsnotinclass_list:continuecls_id=class_list.index(cls)xmlbox=obj.find('bndbox')x1=float(xmlbox.find('xmin').text)y1=float(xmlbox.find('ymin').text)x2=float(xmlbox.find('xmax').text)y2=float(xmlbox.find('ymax').text)# 转换坐标x_center=(x1+x2)/2/img_width y_center=(y1+y2)/2/img_height w=(x2-x1)/img_width h=(y2-y1)/img_height yolo_lines.append(f"{cls_id}{x_center}{y_center}{w}{h}")# 写入YOLO格式文件output_path=os.path.join(output_dir,img_name.replace('.jpg','.txt'))withopen(output_path,'w')asf:f.write('\n'.join(yolo_lines))2.4 数据集划分
将数据集划分为训练集、验证集和测试集(建议比例7:2:1):
importosimportrandomimportshutildefsplit_dataset(data_dir,output_dir,train_ratio=0.7,val_ratio=0.2):images_dir=os.path.join(data_dir,'images')labels_dir=os.path.join(data_dir,'labels')# 创建输出目录os.makedirs(os.path.join(output_dir,'train/images'),exist_ok=True)os.makedirs(os.path.join(output_dir,'train/labels'),exist_ok=True)os.makedirs(os.path.join(output_dir,'val/images'),exist_ok=True)os.makedirs(os.path.join(output_dir,'val/labels'),exist_ok=True)os.makedirs(os.path.join(output_dir,'test/images'),exist_ok=True)os.makedirs(os.path.join(output_dir,'test/labels'),exist_ok=True)# 获取所有图片文件all_files=[fforfinos.listdir(images_dir)iff.endswith('.jpg')]random.shuffle(all_files)# 划分数据集train_count=int(len(all_files)*train_ratio)val_count=int(len(all_files)*val_ratio)train_files=all_files[:train_count]val_files=all_files[train_count:train_count+val_count]test_files=all_files[train_count+val_count:]# 复制文件forphase,filesin[('train',train_files),('val',val_files),('test',test_files)]:forfileinfiles:# 复制图片shutil.copy(os.path.join(images_dir,file),os.path.join(output_dir,phase,'images',file)# 复制标签label_file=file.replace('.jpg','.txt')shutil.copy(os.path.join(labels_dir,label_file),os.path.join(output_dir,phase,'labels',label_file))print(f"数据集划分完成: 训练集{len(train_files)}张, 验证集{len(val_files)}张, 测试集{len(test_files)}张")三、模型训练
3.1 配置文件准备
YOLOv11需要两个主要配置文件:
- 模型配置文件(如
yolov11s.yaml) - 数据配置文件(如
car_brand.yaml)
数据配置文件示例:
# car_brand.yamlpath:../datasets/car_brand# 数据集根目录train:train/images# 训练集路径val:val/images# 验证集路径test:test/images# 测试集路径# 类别数量和名称nc:10# 汽车品牌数量names:['Toyota','Honda','BMW','Mercedes','Audi','Ford','Chevrolet','Nissan','Volkswagen','Hyundai']3.2 开始训练
使用以下命令启动训练:
python train.py\--batch-size16\--epochs100\--img640\--datadata/car_brand.yaml\--cfgmodels/yolov11s.yaml\--weights''\--device0\--nameyolov11s_car_brand\--hypdata/hyps/hyp.scratch-low.yaml关键参数说明:
--batch-size: 根据GPU内存调整--epochs: 训练轮次--img: 输入图像尺寸--data: 数据配置文件路径--cfg: 模型配置文件路径--device: 使用GPU编号
3.3 训练监控
YOLOv11会自动记录训练日志,可以使用TensorBoard监控训练过程:
tensorboard--logdirruns/train监控指标包括:
- 损失函数变化
- mAP(mean Average Precision)
- 精确率和召回率
3.4 模型评估
训练完成后,使用以下命令评估模型性能:
python val.py\--weightsruns/train/yolov11s_car_brand/weights/best.pt\--datadata/car_brand.yaml\--img640\--batch-size16\--tasktest\--nameyolov11s_car_brand_eval四、模型优化技巧
4.1 数据增强
在hyp.scratch-low.yaml中调整数据增强参数:
# 颜色空间增强hsv_h:0.015# 色调hsv_s:0.7# 饱和度hsv_v:0.4# 亮度# 平移、缩放、旋转translate:0.1scale:0.5flipud:0.0fliplr:0.5mosaic:1.0mixup:0.04.2 模型微调
对于预训练模型,可以:
- 冻结部分层进行微调
- 调整学习率策略
- 使用更小的学习率
python train.py\--weightsyolov11s.pt\--freeze10\# 冻结前10层--lr00.01\# 初始学习率--lrf0.01\# 最终学习率...4.3 类别不平衡处理
对于样本数量差异大的品牌:
- 使用过采样/欠采样
- 调整损失函数的类别权重
- 使用Focal Loss
五、模型部署与应用
5.1 模型导出
导出为ONNX格式以便部署:
python export.py\--weightsruns/train/yolov11s_car_brand/weights/best.pt\--includeonnx\--img640\--device05.2 使用训练好的模型进行推理
fromyolov11.models.experimentalimportattempt_loadfromyolov11.utils.generalimportnon_max_suppression,scale_boxesfromyolov11.utils.torch_utilsimportselect_deviceimportcv2importtorch# 加载模型device=select_device('0')model=attempt_load('runs/train/yolov11s_car_brand/weights/best.pt',device=device)# 图像预处理defpreprocess(image,img_size=640):# 调整大小、归一化等pass# 推理defdetect(image):img=preprocess(image)img=torch.from_numpy(img).to(device)img=img.float()/255.0ifimg.ndimension()==3:img=img.unsqueeze(0)# 推理pred=model(img,augment=False)[0]pred=non_max_suppression(pred,conf_thres=0.25,iou_thres=0.45)# 解析结果results=[]fordetinpred:ifdetisnotNoneandlen(det):det[:,:4]=scale_boxes(img.shape[2:],det[:,:4],image.shape).round()for*xyxy,conf,clsindet:results.append({'bbox':[int(x)forxinxyxy],'conf':float(conf),'class':int(cls),'class_name':model.names[int(cls)]})returnresults# 使用示例image=cv2.imread('test.jpg')results=detect(image)forrinresults:print(f"检测到:{r['class_name']}, 置信度:{r['conf']:.2f}, 位置:{r['bbox']}")六、常见问题解决
CUDA内存不足:
- 减小batch size
- 减小输入图像尺寸
- 使用混合精度训练(
--half)
过拟合:
- 增加数据增强
- 使用早停(early stopping)
- 添加正则化
训练不收敛:
- 检查学习率设置
- 检查数据标注是否正确
- 尝试预训练模型
类别识别错误:
- 增加困难样本
- 调整类别权重
- 检查相似品牌间的区分度
结语
通过本文的步骤,我们完成了从零开始搭建YOLOv11汽车品牌识别系统的全过程。实际应用中,还可以进一步优化:
- 收集更多样化的数据
- 尝试更大的模型(yolov11m/yolov11l)
- 集成多个模型提升性能
- 开发友好的用户界面
目标检测技术在实际场景中有广泛应用,掌握YOLOv11的使用方法将为解决各类视觉识别问题提供有力工具。