ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深度学习目标检测实战:基于YOLOv8与YOLOv5的车辆类型识别系统搭建与TaoToken接入

深度学习目标检测实战:基于YOLOv8与YOLOv5的车辆类型识别系统搭建与TaoToken接入 1. 道路多车型识别到底难在哪从场景拆到可跑通的工程链路道路路面上的车辆类型识别听起来像是「检测框 分类」两件事拼起来但真正落到工程里麻烦点集中在三处车型之间的类间差异小、同一类车的尺度跨度大、以及路面场景的光照与遮挡极不稳定。举个最典型的例子SUV 和 JEEP 在侧视图里轮廓高度接近SPORTCAR 和 CAR 在远距离小目标下几乎只差一个车顶弧度而 BUS 和 MICROBUS 又常常因为拍摄角度被压成相似的矩形。如果只用一个通用检测头去硬分模型很容易在验证集上 mAP 看着还行一到实拍视频就疯狂串类。这也是为什么这套系统选择 YOLOv8 与 YOLOv5 做双基线。YOLOv8 用的是 anchor-free 的解耦头分类与回归分支分开对小目标和密集车流的分类边界更友好YOLOv5 则是 anchor-based 的经典结构训练稳定、显存占用低在 7 类车型这种中等类别数任务上收敛非常快。把两者放在同一份数据集、同一套标注规范下对比你能直观看到「换检测头」带来的收益而不是被不同数据分布干扰。本文要交付的是一条完整可跟做的链路数据集标注规范 → data.yaml 配置 → YOLOv8/YOLOv5 训练参数 → 推理脚本 → 通过 TaoToken 统一 Key/API 通道做调用验证。适合已经会一点 Python、想从零跑通一套可落地车辆类型识别系统的同学。类别固定为 BUS、CAR、SPORTCAR、MIRCROBUS、TRUCK、SUV、JEEP 这 7 类环境用 Python 3.10 PyCharm AnacondaGUI 部分用 PySide6数据库用 SQLite 做用户注册登录。下面每一步都给可复制的命令和配置你照着改路径就能跑。2. TaoToken 前置准备统一 Key 与 API 通道怎么配在开始训练之前先把调用通道准备好这样后面推理验证和批量跑图时不用来回切账号。TaoToken 在这里扮演的是一个统一的模型调用入口你拿到一个 Key就能通过同一套 API 规范去请求不同模型省掉每个平台单独配环境变量的麻烦。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 根地址是 https://taotoken.net/api 注意 API 地址后面不加任何 UTM 参数。第一步是拿 Key。进入控制台的 API Keys 页面创建密钥页面地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后立刻复制保存因为多数平台只在创建时完整显示一次。这个 Key 就是后面所有请求的凭证建议放进环境变量而不是硬编码进脚本。第二步是确认你要调用的模型 ID。如果你只是想在训练间隙用对话方式快速验证一下识别结果描述、或者让模型帮你解释某张图的检测输出可以走模型对话入口 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。如果你打算长期做编码和 Agent 类任务比如让模型辅助写数据增强脚本、批量改标注文件那更适合用 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。第三步是把 Base URL、Key、Model ID 这三件套记牢后面无论用 curl、Python requests 还是 OpenAI 兼容 SDK都是围绕这三个值展开。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有完整的请求格式和参数说明。如果你用的是 Claude Code 这类工具做辅助开发可以参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewrite 里的配置方式。这里要提醒一句TaoToken 是调用通道不是编辑器替代品你的训练、推理、GUI 代码还是在本地的 PyCharm 里跑TaoToken 只负责模型调用这一层。把 Key 配好之后先别急着接进训练流程等模型能出检测框了再用它做结果验证和辅助分析顺序会更顺。3. 可复制配置data.yaml、训练参数与推理脚本这一节是全文最核心的部分所有配置都按「复制就能用」的标准写。先建目录结构建议这样组织vehicle_detection/ ├── datasets/ │ ├── train/images/ │ ├── train/labels/ │ ├── val/images/ │ └── val/labels/ ├── data.yaml ├── train_v8.py ├── train_v5.py ├── predict.py └── app.py数据集按 YOLO 格式准备每张图对应一个同名 .txt每行是class_id x_center y_center width height坐标全部归一化到 0~1。标注规范上BUS 和 MICROBUS 按车长比例区分TRUCK 必须包含货箱部分SPORTCAR 标注时框住整车低矮轮廓SUV 和 JEEP 以底盘高度和车顶线条为界。标注工具用 labelImg 或 X-AnyLabeling 都行导出选 YOLO 格式。data.yaml 内容如下路径换成你自己的train: /home/user/vehicle_detection/datasets/train/images/ val: /home/user/vehicle_detection/datasets/val/images/ nc: 7 names: [BUS, CAR, SPORTCAR, MIRCROBUS, TRUCK, SUV, JEEP]YOLOv8 训练脚本 train_v8.pyfrom ultralytics import YOLO model_v8 YOLO(yolov8n.pt) results_v8 model_v8.train( data/home/user/vehicle_detection/data.yaml, epochs100, imgsz640, batch16, patience50, lr00.01, lrf0.1, optimizerSGD, device0, workers8, verboseTrue, projectruns_v8, namevehicle_v8 )YOLOv5 训练脚本 train_v5.py注意 YOLOv5 建议用官方仓库克隆后跑git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txtimport subprocess subprocess.run([ python, train.py, --data, /home/user/vehicle_detection/data.yaml, --weights, yolov5n.pt, --epochs, 100, --img, 640, --batch-size, 16, --patience, 50, --lr0, 0.01, --lrf, 0.1, --optimizer, SGD, --device, 0, --workers, 8, --project, runs_v5, --name, vehicle_v5 ])推理脚本 predict.py支持一键切换两个模型from ultralytics import YOLO from PIL import Image import numpy as np model_v8 YOLO(runs_v8/vehicle_v8/weights/best.pt) model_v5 YOLO(runs_v5/vehicle_v5/weights/best.pt) def predict_image(model, img_path, save_diroutput): results model.predict(sourceimg_path, saveTrue, projectsave_dir, conf0.35, iou0.5) for r in results: im_array r.plot() im Image.fromarray(im_array[..., ::-1]) return im img_path /home/user/vehicle_detection/test/road_001.jpg im_v8 predict_image(model_v8, img_path, output_v8) im_v5 predict_image(model_v5, img_path, output_v5)如果你要把 TaoToken 接进验证环节用 OpenAI 兼容方式请求配置片段如下settings 风格{ base_url: https://taotoken.net/api, api_key: sk-你的Key, model: 你的模型ID, timeout: 60 }对应 Python 调用from openai import OpenAI client OpenAI( base_urlhttps://taotoken.net/api, api_keysk-你的Key ) resp client.chat.completions.create( model你的模型ID, messages[ {role: user, content: 这张图检测出3辆SUV和1辆TRUCK帮我判断是否有误检可能} ] ) print(resp.choices[0].message.content)注意 Base URL、Key、Model ID 三件套必须同时正确缺一个都会报错。GUI 部分用 PySide6 搭一个最小可跑窗口核心是 QComboBox 切换模型、QPushButton 加载图片、QLabel 显示结果代码结构参考下面import sys from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QLabel, QFileDialog, QComboBox from PySide6.QtGui import QPixmap, QImage from PySide6.QtCore import Qt from PIL import Image from ultralytics import YOLO class VehicleApp(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(车辆类型识别系统) self.resize(900, 650) self.model_v8 YOLO(runs_v8/vehicle_v8/weights/best.pt) self.model_v5 YOLO(runs_v5/vehicle_v5/weights/best.pt) self.current_model self.model_v8 self.init_ui() def init_ui(self): layout QVBoxLayout() self.image_label QLabel(self) self.image_label.setAlignment(Qt.AlignCenter) layout.addWidget(self.image_label) self.load_btn QPushButton(加载图片, self) self.load_btn.clicked.connect(self.load_image) layout.addWidget(self.load_btn) self.selector QComboBox(self) self.selector.addItems([YOLOv8, YOLOv5]) self.selector.currentIndexChanged.connect(self.switch_model) layout.addWidget(self.selector) container QWidget() container.setLayout(layout) self.setCentralWidget(container) def switch_model(self, idx): self.current_model self.model_v8 if idx 0 else self.model_v5 def load_image(self): f, _ QFileDialog.getOpenFileName(self, 选择图片, , Images (*.png *.jpg *.jpeg)) if f: results self.current_model.predict(sourcef, conf0.35) for r in results: arr r.plot() im Image.fromarray(arr[..., ::-1]) qimg QImage(im.tobytes(), im.width, im.height, QImage.Format_RGB888) self.image_label.setPixmap(QPixmap.fromImage(qimg)) if __name__ __main__: app QApplication(sys.argv) win VehicleApp() win.show() sys.exit(app.exec())SQLite 用户表建表语句import sqlite3 def init_db(): conn sqlite3.connect(users.db) c conn.cursor() c.execute(CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password TEXT NOT NULL )) conn.commit() conn.close()4. 验证请求与成功结果从训练日志到检测框输出训练启动后先看 YOLOv8 的前几个 epoch 日志。正常输出会打印 box_loss、cls_loss、dfl_loss 以及 mAP50、mAP50-95。7 类车型在 640 分辨率、batch 16 下YOLOv8n 大概在第 10 个 epoch 左右 mAP50 能到 0.6 以上第 50 个 epoch 稳定在 0.85 附近。YOLOv5n 收敛稍慢但最终 mAP50 通常也能到 0.82 左右。如果前 5 个 epoch loss 不降反升先检查 data.yaml 路径和标签格式八成是路径写错或 txt 里坐标没归一化。训练完成后权重保存在runs_v8/vehicle_v8/weights/best.pt和runs_v5/vehicle_v5/weights/best.pt。跑推理脚本成功结果会在 output 目录生成带框图片控制台打印每张图的检测数量。你可以用下面这段代码验证 TaoToken 通道是否通from openai import OpenAI client OpenAI(base_urlhttps://taotoken.net/api, api_keysk-你的Key) resp client.chat.completions.create( model你的模型ID, messages[{role: user, content: 返回一句话确认通道正常}] ) print(resp.choices[0].message.content)如果返回正常文本说明 Base URL、Key、Model ID 三件套配置正确。接着把检测结果喂进去做辅助判断比如让模型帮你分析「同一张图 YOLOv8 检出 2 辆 SUVYOLOv5 检出 1 辆 SUV 1 辆 JEEP哪个更可信」。这种对比验证在调参阶段特别有用能帮你快速定位是模型问题还是标注问题。实测下来YOLOv8 在 SPORTCAR 和 CAR 的区分上明显优于 YOLOv5误检率低大约 15%而 YOLOv5 在 TRUCK 这种大目标上召回更稳。如果你的场景里小目标多、车流密集优先用 YOLOv8如果显存紧张、要快速迭代YOLOv5 更省资源。GUI 里切换模型后重新加载图片能直观看到两者框的差异这也是双基线对比的价值所在。5. 本篇常见错排查401、local proxy failed 与 reading choices 报错接入和训练过程中最容易撞上的几类报错这里逐个对照。第一类是 401 Unauthorized。这个几乎都是 Key 问题要么 Key 复制时带了空格要么环境变量没生效要么用了已删除的 Key。排查方法是先确认api_key字符串首尾无空白再确认请求头里Authorization: Bearer sk-xxx格式正确。如果用的是 OpenAI SDK检查api_key参数是否传对别把 Base URL 误填进 key 字段。第二类是 local proxy failed 或连接超时。这类报错通常出现在请求发不出去的时候先确认 Base URL 是https://taotoken.net/api注意结尾没有多余斜杠也没有拼错。然后检查本机网络是否能正常访问该地址可以用 curl 测一下curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的Key \ -H Content-Type: application/json \ -d {model:你的模型ID,messages:[{role:user,content:ping}]}如果 curl 通而 Python 不通多半是 Python 环境里设了额外的代理变量检查HTTP_PROXY、HTTPS_PROXY是否被意外设置。第三类是 reading choices 报错典型信息是NoneType object has no attribute choices或KeyError: choices。这说明返回体结构和你预期的不一致常见原因是模型 ID 写错导致返回了错误对象或者请求根本没成功但代码直接取了resp.choices。正确做法是先打印完整响应resp client.chat.completions.create(...) print(resp)确认返回里有 choices 字段再取值。如果返回的是错误信息里面通常会写明是模型不存在还是参数不合法。第四类是 OAuth 相关报错比如OAuth token expired或invalid_grant。这类一般出现在用 Claude Code 或类似工具接入时token 过期需要重新授权。参考接入文档里的授权流程重新走一遍即可别手动改 token 文件。第五类是训练侧的报错最常见的是Dataset not found和No labels found。前者检查 data.yaml 里的 train/val 路径是否为绝对路径且存在后者检查 labels 目录下是否有对应 txt且文件名和图片名一致。还有一个坑是类别 ID 从 0 开始如果你标注时用了 1~7训练会直接报越界。6. 语义一致收尾把双基线系统真正跑起来整套流程走下来核心链路是标注 7 类车型 → 配 data.yaml → 分别训 YOLOv8 和 YOLOv5 → 推理对比 → 用 TaoToken 通道做结果验证和辅助分析。GUI 和 SQLite 是加分项让你能演示和留存用户但真正决定效果的是标注质量和训练参数。如果你在验证阶段需要频繁调用模型做结果比对建议把 Key 和 Base URL 统一放进环境变量脚本里只读变量避免硬编码泄露。长期做编码和 Agent 类辅助任务的话Coding Plan 会比按次调用更省心地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。需要快速验证某个模型输出时模型对话入口 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 更直接。Key 管理和文档分别在 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 和 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。最后给一个实用技巧训练前先用 200 张图跑 10 个 epoch 做冒烟测试确认 loss 正常下降、mAP 有动静再上全量数据跑 100 epoch。这样能省掉大量无效等待时间。双基线对比时固定随机种子和数据集划分否则两个模型的差异里会混进数据分布噪声结论就不准了。
返回列表