YOLOv5+Android交通标志识别:从tt100k训练到移动端部署全流程 简介基于YOLOv5与Android Studio开发的tt100k交通标志识别检测项目面向具备一定Android和深度学习基础的开发者帮助解决YOLOv5模型在移动端移植与实时推理问题。项目经tt100k 17G数据集训练可识别184类交通标志效果良好并已通过测试运行成功。项目压缩包共1096个文件约350.8MB涵盖Android工程源码h/hpp/cpp/java等、CMake/Gradle构建脚本、转换好的yolov5s.param与bin模型文件、ncnn与OpenCV预编译库a/so、以及可直接安装的APK。用户可在Android Studio 4.2.2中打开构建支持前后置摄像头实时识别并可选CPU或GPU推理。目前已有628人学习下载。对于想要掌握YOLOv5安卓移植、tt100k数据集应用或进行交通标志识别二次开发的开发者可直接上手参考省去模型转换与环境配置的大量工作。1. 项目概述一套能跑的交通标志识别全链路方案拿到这个标题的时候我大概猜到了是什么样的项目——深度学习目标检测 移动端部署 国产交通标志数据集这三个关键词组合在一起基本就是近两年计算机视觉方向毕设和课设的“标准豪华套餐”。但说实话真正吸引我的不是YOLOv5本身而是这个项目把完整的链路都打通了从tt100k数据集的训练到模型文件的转换压缩再到Android Studio里做App并打包出APK。很多同学做到模型训练完就卡住了能把模型塞进手机里并流畅跑起来的确实值得拆开聊聊。这个项目适合谁来参考如果你是计算机视觉、软件工程、电子信息相关专业的学生正在为毕业设计发愁或者你是刚入门深度学习、想找一个“从训练到部署”完整闭环的练手项目这个源码包里的思路和踩坑记录比代码本身更有价值。它能帮你解决的核心问题是在算力有限的移动设备上如何实时识别国内道路场景下的交通标志并且不依赖云服务器、完全离线运行。接下来我会从方案选型、核心原理、实操细节、常见坑点四个维度把整个项目拆开揉碎来讲。2. 方案选型为什么是YOLOv5、tt100k和Android这套组合2.1 目标检测框架的取舍逻辑交通标志识别属于典型的小目标检测任务标志在画面中的占比通常只有几个百分点。初学者可能会纠结为什么不用Faster R-CNN这种两阶段检测器为什么不用SSD或者更轻量的EfficientDet我的经验是在毕业设计这个场景下选型的第一优先级不是精度上限而是生态成熟度和可复现性。YOLOv5在这两点上几乎是无敌的。它的代码结构极为清晰训练、验证、导出脚本分门别类官方文档对新手友好到可以直接照着跑社区资料极多任何报错信息基本都能搜到解决方案自带模型压缩和导出工具从PyTorch到ONNX再到NCNN/TFLite的转换链路成熟可靠。而且YOLOv5s这个版本参数量只有大概700万在手机CPU上能跑到单帧几十到上百毫秒的推理速度兼顾了精度和实时性。相比之下Faster R-CNN虽然在小目标上有精度优势但推理速度完全不适合移动端SSD虽然快但后处理代码要自己写转换到移动端的坑也更多。2.2 tt100k数据集为什么适合作为毕设切入点tt100kTsinghua-Tencent 100K是清华大学与腾讯联合发布的大规模交通标志数据集采集自腾讯街景的中国城市道路场景。它包含10万张分辨率高达2048x2048的街景图像其中标注了约3万个交通标志实例覆盖221个类别。这个数据集最大的价值在于场景真实——国内道路上常见的限速牌、禁止停车、注意行人、方向指示等标志都有覆盖比国外的德国GTSRB数据集更贴合国内实际应用场景。但用这个数据集有一个必须注意的坑221个类别里长尾分布极其严重有些类别只有几张样本直接训练会严重过拟合。项目源码里的做法是筛选出样本数量大于100的类别来训练通常能得到一个几十类别的子集这个思路非常明智。我在实际项目中还建议进一步做类别合并比如把不同样式的“限速”标志统一映射到一个大类既是工程技术上的务实选择也能在答辩时讲出你自己的思考。2.3 Android端部署选型NCNN还是TFLite模型训练完成后怎么塞进手机里是这个项目的分水岭。常见的移动端推理框架有腾讯的NCNN、谷歌的TFLite、阿里的MNN、百度的Paddle Lite等。就这个项目而言我首推NCNN原因有三第一NCNN对YOLOv5的支持极其成熟网上可以找到大量现成的yolov5_ncnn示例工程几乎可以直接套用第二NCNN在ARM CPU上的优化做得非常好支持vulkan GPU加速对中低端安卓机也很友好第三NCNN是纯C实现JNI封装简单与Android Studio的集成交档资料丰富。TFLite也是个不错的选择特别是如果你后续想用Google的MediaPipe做更复杂的流水线。但TFLite在转换YOLOv5时需要处理NMS非极大值抑制算子的兼容问题稍麻烦一些。这个项目的源码既然给出了完整的模型文件和APK大概率是在NCNN或者TFLite之间二选一打通了你可以直接参考它的集成方式省去自己啃框架源码的时间。3. 核心原理与关键路径从PyTorch模型到手机App3.1 tt100k的数据特点怎样影响模型设计交通标志识别在计算机视觉里是个很有意思的分支它和通用物体检测有显著差异。首先是目标尺度极小在2048x2048的原图上一个标志牌往往只有几十乘几十像素占比不到5%。针对这一点通常需要把输入图像切块或者使用多尺度训练策略。YOLOv5的Mosaic数据增强和自适应锚框计算能在一定程度上帮助模型适应小目标但如果直接拿原图训练小目标特征经过多次下采样后会几乎消失。实际项目中比较稳妥的做法是训练时将原图按一定步长裁剪成若干640x640的patch或者直接用官方预训练权重做迁移学习冻结前几层只微调后面几层。tt100k的另一个问题前面提过——类别不平衡。交通标志本身就符合长尾分布少数常见标志占据了绝大多数样本。训练时可以通过类别权重、focal loss或者数据增强对少样本类别多做旋转、亮度变化、加噪声来缓解。3.2 模型转换链路PyTorch、ONNX与NCNN三端打通训练好的YOLOv5权重是PyTorch格式.pt安卓端无法直接识别需要先转到ONNX再由ONNX转到NCNN格式.param和.param.bin。这一步是整个项目里最容易出问题的地方我把关键命令和注意事项整理如下。第一步PyTorch导出ONNX。YOLOv5官方仓库自带export.py脚本导出时建议设成opset11因为NCNN对更高版本opset的支持可能不完整同时要带上NMS算子还是去掉NMS算子这是个关键选择——NCNN的yolov5示例工程通常在后处理里自己写NMS所以导出时可以不带NMS但需要在端侧实现解码和去重逻辑。# 在YOLOv5仓库目录下执行示例 python export.py --weights best.pt --img 640 --batch 1 --include onnx --opset 11 --simplify第二步ONNX转NCNN。使用腾讯开源的ncnn工具链先编译出onnx2ncnn可执行文件然后执行转换./onnx2ncnn best.onnx yolov5s.param yolov5s.bin这一步大概率会遇到Unspported operator的报错比如Einsum、ReduceMax等这通常是因为ONNX导出的计算图里包含了NCNN不支持的算子。解决办法是修改YOLOv5的检测头代码把一些不规范的算子替换成NCNN支持的等价实现或者使用python tools/onnx/optimize.py做图优化。源码包里既然提供了品类齐全的bin文件说明这些坑作者已经趟过一遍你可以直接比对它的param文件里的网络结构来理解处理方式。3.3 Android端实时识别的后处理逻辑模型部署到Android后工作并没有结束。NCNN模型输出的是原始张量——三个尺度下的预测框坐标、置信度和类别概率必须经过后处理才能得到最终的框选结果。后处理流程包括解码边界框把偏移量还原到原图坐标、根据置信度过滤低质量框、按类别做NMS去除重复框。这一段的代码逻辑很像但很容易写错建议直接用NCNN官方yolov5示例里的Yolov5.h/cpp做适配。后处理的一个细节是输出张量维度的解析。YOLOv5有三个检测头分别对应80x80、40x40、20x20的特征图输入640x640时每个特征图上的每一个锚点会预测若干个候选框所以最后输出的shape通常是(1, 25200, 类别数5)。25200就是三个尺度预测框的总数80x80x3 40x40x3 20x20x3。代码里需要把类别数从85改成你训练时使用的类别数量比如筛选后tt100k有42类那就是47维4个坐标加1个置信度加42个类别概率这个参数不改的话会直接导致内存越界或结果错乱。3.4 Android工程结构assets放模型JNI负责桥接Android Studio里集成NCNN的常规做法是把.param、.bin文件放在assets目录下App启动时拷贝到私有目录通过JNI调用C封装的NCNN接口完成模型加载和推理渲染部分使用自定义View在PreviewCallback里接收相机帧调用native方法返回识别结果然后用Canvas画框。源码包里APK能直接安装运行说明工程级的集成已经完成你拿到手后可以重点看几个关键文件MainActivity里的权限申请和相机初始化逻辑、YOLOv5.java里的JNI声明、以及C侧的yolov5ncnn_jni.cpp。这里要提醒一点JNI层的数据传递效率很容易被忽略。如果每帧都在Java层和Native层之间反复拷贝Bitmap或者byte数组帧率会掉得吓人。高效的方案是直接用OpenCV的Mat作为载体把相机帧的NV21数据转成Mat后传递Mat的native地址到C侧处理避免多余拷贝。4. 实操全流程从零复现这个毕设项目的五个阶段4.1 环境准备显卡、Python与深度学习库训练YOLOv5的硬件门槛其实不算高。一张6GB以上显存的显卡就能跑yolov5s的batch size设到16左右如果你的显卡只有4GB那就把图像尺寸降到416或者批量大小调到8。推荐直接使用项目源码里的requirements.txt安装依赖核心库包括torch、torchvision、opencv-python、numpy、matplotlib、pandas、tensorboard、seaborn、pyyaml等。Python版本建议3.8到3.10之间PyTorch用2.x版本即可不必追新。安装慢是常见痛点国内环境建议配置清华或阿里云的pip镜像源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple4.2 数据准备筛选类别、划分训练集与标注格式转换tt100k官方发布的数据集标注是JSON格式而YOLOv5需要的是每个图片对应一个txt文件每行格式为类别id x_center y_center width height坐标值是归一化到0~1之间的浮点数。所以第一步要写个脚本把tt100k的JSON转成YOLO格式。转换时要注意坐标换算tt100k的标注给出的是左上角和右下角坐标要先转成中心点加宽高的格式再除以图片宽高归一化。数据划分直接按tt100k官方提供的train/val列表即可。我在项目里还会做一步数据清洗——剔除标注框太小或者明显标注错误的样本这对后期训练稳定性的提升非常明显。4.3 训练配置YOLOv5s预训练模型、超参数与类别文件训练前需要修改三个文件data/tt100k.yaml、models/yolov5s.yaml和训练入口参数。数据配置文件里写入训练集和验证集的路径以及筛选后的类别名称列表网络结构文件里把nc改成实际类别数。使用官方预训练权重做迁移学习是关键技巧它能显著加速收敛python train.py --data tt100k.yaml --cfg yolov5s.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --img 640几个超参数的经验值供参考lr0初始学习率0.01lrf最终学习率系数0.1到0.2momentum0.937weight_decay0.0005。这些参数在YOLOv5的data/hyps/hyp.scratch-low.yaml里有默认值一般不需要大动。训练过程中强烈建议打开--cos-lr余弦退火学习率并定期用--save-period 10保存中间权重。TensorBoard在训练监控里非常好用loss曲线和mAP曲线能帮你及时发现问题。4.4 模型转换与压缩实操训练完成后先挑选验证集上mAP最高的权重然后做转换。模型压缩这个环节比较容易被忽略我在项目里实测过FP32转FP16精度几乎无损模型体积直接减半再转INT8量化大概会掉1到2个点的mAP但体积再减一半推理速度可以提升一到两倍。毕设阶段建议至少做到FP16冲击高分再做INT8。NCNN里做量化可以使用ncnnoptimize工具先生成FP16模型再用ncnn2table和ncnn2int8做INT8量化后者需要准备校准图片集。实际部署中还有一个技巧用ncnnoptimize对模型做算子融合能减少内存访问、轻微提速。4.5 Android Studio集成与APK打包Android Studio开发环境的搭建本身也有几个坑要提前规避。Gradle下载慢的问题可以通过配置阿里云镜像解决AGP版本和Gradle版本必须匹配官方文档里有兼容表编译NCNN时如果出现tag number over 30 is not supported这类protobuf相关报错通常是NCNN依赖的flatbuffer或protobuf版本冲突升级NDK版本或者更换NCNN release版本即可。把一个YOLOv5 NCNN示例工程迁移为自己的项目主要步骤包括在build.gradle里配置CMake和NDK、把models文件夹的param和bin文件拷到assets、修改MainActivity的相机参数和画框逻辑、调整类别名称列表。最后用Build菜单下的Generate Signed Bundle or APK打包签名APK注意创建好keystore并保管好密码不然升级版本时会出麻烦。5. 常见问题与排坑实录5.1 CUDA out of memory显存不足这个报错在训练时太常见了。我的解决办法优先级依次是降低batch size比如16改8、降低图片尺寸640改512、开启梯度累积--accumulate 12相当于把batch size等效放大12倍。如果显存只有4GB建议直接使用yolov5n这个更小的模型版本或者在配置里把模型宽度因子改小比如depth_multiple: 0.33, width_multiple: 0.25就是yolov5n的配置——我在旧显卡上实测它仍然能保持不错的精度只是小目标检测能力会弱一些。5.2 ONNX导出或转换NCNN报Unsupported operator这是模型部署环节的“劝退坑”。常用的对策包括升级ONNX版本到1.12以上、导出时加--simplify用onnx-simplifier做图优化、修改YOLOv5检测代码里的forward方法把cat、view等算子组合替换为更简单的等价实现。还有一个终极兜底方案先升级NCNN到最新版本再试因为NCNN社区几乎每个版本都在补充算子支持。5.3 Android端APK安装后闪退可能原因有两个方向。一是模型文件路径错误assets里的文件没有正确释放到私有目录读取失败后native层崩溃二是NCNN的bitcode或ABI架构不匹配比如只为arm64-v8a编译了so库但手机是armeabi-v7a的旧机型。排查方法很简单先看Logcat里的崩溃堆栈如果指向libncnn.so大概率是ABI问题如果指向JNI_OnLoad大概率是模型路径问题。经验之谈android:extractNativeLibstrue这个属性在低版本Android上能解决一部分so库释放引起的诡异闪退。5.4 推理速度不理想与帧率掉点实测中我发现很多人卡在这里模型跑通了但每秒只有几帧完全无法实时。优化思路从重到轻依次是开启NCNN的vulkan GPU加速只需要加载模型时指定ncnn::OPT_USE_VULKAN、输入图像从640降到416或320、把相机预览分辨率从1080p降到720p、Java层减少Bitmap相关对象创建、避免在UI线程做耗时操作。还有一个冷门但很有效的手段给App的activity开启android:hardwareAcceleratedtrue利用硬件加速完成画框渲染。5.5 检测不准小目标和远距离标志漏检如果你训练完发现近距离标志检测良好但远距离小标志频频漏检这不是训练代码问题而是目标尺度的固有问题。改进方案包括训练时使用多尺度训练YOLOv5默认已经开启了、提高输入分辨率到960但推理时用640、或者增加一个专门检测小目标的检测头。做一个注意力机制模块比如SE或者CBAM加进C3结构里是毕设答辩的加分项实测对小目标检测有一定提升代码量也不大。关于模型的P-R曲线和F1曲线建议训练后认真看一下results.png它反映了模型在哪个置信度阈值下最平衡。6. 拿到这个项目源码后建议你按什么顺序阅读和修改如果这个源码包是在你手上最合理的拆解顺序是先看README确认环境要求和运行步骤把APK装到手机里跑一遍看效果建立“成品应该长什么样”的直观认知然后打开Android工程源码从MainActivity和JNI层入手理解App的工作流程再读C侧的后处理逻辑与实际部署时的难点一一对应之后再看训练相关的代码和目录结构确认数据集格式、训练脚本和权重文件。不要按源码目录的顺序从头看到尾那样很容易在细节里迷路。修改方向可以从这几个点入手做成自己的东西加入一个数据库模块识别到标志后自动保存历史记录把模型的NMS后处理再度优化降低误检替换成更轻量化的骨干网络比如MobileNetV3做消融实验对比——这类工作放到论文里都是能写进“创新点”的实打实内容。如果学有余力还可以试试把YOLOv7或YOLOv8的Tiny版本替换进去对比推理速度和精度形成一个完整的对比实验章节。7. 写在最后这个项目教会我的三件事第一次把这个项目从头到尾跑通时我最大的感受是深度学习部署没有想象中那么玄乎但也没有任何一步能侥幸蒙混过关。第一数据集决定上限。tt100k质量的参差和长尾分布直接影响模型表现提前花时间做数据清洗和类别筛选比事后反复调参有用十倍。第二模型能跑和能上线之间隔着一整个部署工程。训练时一个毫不起眼的算子到了NCNN转换就可能变成拦路虎这逼着你去理解网络结构的每一层到底在算什么——从长远看这是好事。第三移动端AI真正稀缺的是工程化能力你既得懂训练也得出得了JNI的bug、调得了Gradle的依赖冲突。如果你正准备拿这个项目做毕设或者在简历上写“熟悉YOLOv5和移动端部署”我的建议是不要把目光只停留在“代码能跑”上而是把模型转换的每一步、每个参数调整背后的原因都弄明白。面试官真正感兴趣的不是你跑通了一个现成项目而是你是否理解为什么这样设计、出了问题时怎么排查。把这些过程写进项目文档再准备几张过程截图和对比实验图表这个项目就能从“复制来的源码”变成“属于你自己的作品”。本文还有配套的精品资源点击获取