
简介面向计算机类毕业设计与课程作业场景这份压缩包提供了一套基于深度学习的高性能中文车牌识别项目涵盖数据预处理、模型构建、训练调优、C推理与Android端部署的完整工程链路。资源共179个文件主要文件类型包括Python训练脚本、C实现、头文件、配置文件、图像样本及说明文档并附有可运行的APK与MNN模型文件压缩包整体约32.91MB。当前已有123人浏览学习。包内代码结构清晰既有hyper_lpr_sdk.cc等核心识别引擎也有inference_helper_mnn.cpp等多平台推理辅助实现同时提供数据集划分、数据增强、字符检测、后处理等关键模块便于读者对照实验。整体而言这套方案不仅能帮助快速复现车牌检测与字符识别流程还能让学习者深入理解深度学习模型在真实系统中的应用方法适合需要完成毕设或课程设计的中高级学习者参考。1. 拿到“基于深度学习高性能中文车牌识别.zip”之后先想清楚这三件事一个写着“基于深度学习高性能中文车牌识别”的zip往往是毕设或课程作业的完整交付里面是训练/推理代码、数据集切片、以及一篇写作范围从模型结构到实验对比的报告。我接过不少这样的包最大的问题不是模型效果差而是“跑不通”和“改不动”。原因是大多数人把精力全放在调网络结构却忽略了环境、数据标注格式和后处理。这篇笔记会把检测、识别、数据、部署四块的关键讲透复现一个能直接交差的方案然后把最容易翻车的五个现场给你提前摆出来。如果你是第一次做CV落地的目标这篇能帮你省下至少三天调细节的时间。2. 两段式架构检测负责找识别负责读为什么这样拆才是“高性能”的起点中文车牌识别看着是一个问题实际是两个紧密耦合的子问题先把车牌从复杂背景里找出来再把车牌区域的字符读出来。用业界话说就是检测加识别。很多毕设为了显得“端到端”硬把两个任务压进一个模型结果训练不稳定、精度还低。我见过的稳定方案绝大多数是两段式检测模型只输出车牌框识别模型只读字符。这样每一段网络都专注自己的边界出了毛病也容易定位。2.1 从车牌检测到车牌识别一条完整推理链路长什么样一张图像进来第一步是检测用目标检测模型把图像里所有可能是车牌的区域框出来。检测结果通常是四个坐标和一个置信度。第二步是矫正和裁剪因为检测框不一定水平车牌可能存在小角度倾斜常见做法是拿框出的区域做透视矫正或者至少做一次扩展裁剪避免边缘字符被切掉。第三步是识别裁剪出来的车牌图块被缩放到固定高度送进序列识别模型输出一串字符。最后一步是后处理去掉重复字符、过滤非法字符、按置信度决定是否输出。这其中“高性能”三个字不是靠某个模型单点突破而是靠整条链路里每一步都不拖后腿。检测模型要快、准识别模型要对中文汉字敏感后处理要能处理模糊和遮挡产生的乱码。有些同学一开始就冲大模型落得在本地跑一轮推理要两三秒实时性完全没法看。如果走两段式每段模型都可以做得轻量总耗时比端到端大模型低一个量级。2.2 检测模块选型和最小复现代码检测模块我在实际工程里用过YOLOv5、YOLOv8、SSD以及一些更轻量的方案。毕设和课程作业场景我优先推荐YOLO系列尤其YOLOv8因为生态成熟、权重好找、训练命令短而且能和后续ONNX/TensorRT部署无缝衔接。如果你的机器性能不怎么样用YOLOv8-s如果是要在CPU上跑用YOLOv8-nano。车牌检测是单类别任务所以训练数据只需要一个class id别把车牌颜色、省份字符这些当成检测类别否则会徒增复杂度。带上训练好的权重最小推理代码就这几行import cv2 from ultralytics import YOLO # 加载zip里的best.pt注意路径别放中文目录否则OpenCV可能读不了 model YOLO(best.pt) # conf是物体置信度阈值iou是NMS阈值classes0表示只取标签为0的“车牌” results model(test_car.jpg, conf0.45, iou0.6, classes0) for r in results: boxes r.boxes.xyxy.cpu().numpy() confs r.boxes.conf.cpu().numpy() for box, conf in zip(boxes, confs): x1, y1, x2, y2 [int(v) for v in box] cv2.rectangle(r.orig_img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(r.orig_img, fplate {conf:.2f}, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) cv2.imwrite(detected.jpg, r.orig_img)conf0.45意思是候选框里目标概率大于0.45才保留。这个值直接决定漏检率。在光线偏暗的监控视频里0.45会漏掉远处的车牌我会降到0.3但降得太低画面里的空调外机、公交站牌也可能被当成车牌。iou0.6是NMS合并阈值两个框重叠面积超过0.6就只保留置信度高的。如果发现同一车牌被重复框出把这值降到0.5。如果两辆车紧挨着且车牌同时被检测阈值太高会把两个框错误合并这时要适当降低。2.3 识别模块选型CRNNCTC 还是 LSTMCTC检测框出来之后识别模型读字符。中文车牌有一套固定的字符结构第一位是省份汉字第二位是发牌机关字母后面是数字和字母组合。字符集不大常见做法是31个省份汉字加24个字母加10个数字再加blank一共70个类别上下。如果你不处理字母“I”和“O”那就是加进去也无妨但要注意它们和数字“1”“0”极其相似容易混淆所以很多数据集干脆不出现这两个字母。识别模型的主流结构是CRNNCNN提取特征RNN建模序列CTC做对齐。也有直接上Transformer做OCR的但对车牌这种短序列、字符排列规整的场景CRNN足够快而且训练数据需求量小。LSTMCTC和CRNN的区别在于特征提取部分是否预先用CNN压缩本质上CRNN包含LSTM所以一般直接叫CRNN。我用PyTorch写过一个精简版本重点是让你看清维度流动import torch.nn as nn class CRNN(nn.Module): def __init__(self, num_classes71, input_h32): super().__init__() # CNN部分把高度信息逐步压缩保留宽度作为时间步 self.cnn nn.Sequential( nn.Conv2d(3, 64, 3, padding1), nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(2), # 高宽减半 nn.Conv2d(64, 128, 3, padding1), nn.BatchNorm2d(128), nn.ReLU(), nn.MaxPool2d(2), # 高宽再减半 nn.Conv2d(128, 256, 3, padding1), nn.BatchNorm2d(256), nn.ReLU(), nn.MaxPool2d(2) # 高宽三减半 ) self.fc nn.Linear(256 * (input_h // 8), 128) # 双向LSTMhidden_size128双向输出256 self.lstm nn.LSTM(input_size128, hidden_size128, bidirectionalTrue, batch_firstTrue) self.out nn.Linear(256, num_classes) def forward(self, x): b, c, h, w x.size() x self.cnn(x) # (b, 256, h/8, w/8) x x.permute(0, 3, 1, 2) # (b, w/8, 256, h/8) T x.size(1) x x.reshape(b, T, -1) # (b, T, 256*(h/8)) x self.fc(x) x, _ self.lstm(x) # (b, T, 256) return self.out(x) # (b, T, num_classes)这里的input_h32是车牌图块统一高度。三次下采样后高度变成4所以fc输入维度是256*41024当input_h不是32时你要跟着改。训练时用torch.nn.functional.ctc_loss需要把logits转成(T, b, num_classes)格式同时给每张图提供时间步长度和目标字符长度。CTC会自己处理字符重复和对齐所以不需要预处理时分割字符。训练识别模型时我最常用Adam优化器初始学习率1e-3batch size 32。如果你发现loss不降检查是不是输入图高度和你模型里的采样倍数对不上导致LSTM输入尺寸是0这种报错最阴间。2.4 用 PyTorch 把检测和识别串起来最小推理代码检测和识别两个模型都就绪后串起来跑一遍最小流程。这里有个容易被忽略的点检测框直接裁剪会切掉汉字边缘因为YOLO框通常紧贴标注而标注里汉字离边界很近。所以裁剪时要外扩。import torch import cv2 import numpy as np def crop_plate(img, box, expand_ratio0.05): x1, y1, x2, y2 box w, h x2 - x1, y2 - y1 ex_x, ex_y int(w * expand_ratio), int(h * expand_ratio) x1 max(0, x1 - ex_x) y1 max(0, y1 - ex_y) x2 min(img.shape[1], x2 ex_x) y2 min(img.shape[0], y2 ex_y) return img[y1:y2, x1:x2] def preprocess_plate(plate_img, input_h32): h, w plate_img.shape[:2] new_w max(1, int(w * input_h / h)) resized cv2.resize(plate_img, (new_w, input_h)) tensor torch.from_numpy(resized.transpose(2, 0, 1)).float() return tensor.unsqueeze(0) # 这里假设detect_model已经给出框中点坐标 box [100, 120, 300, 160] plate crop_plate(cv2.imread(test_car.jpg), box) tensor preprocess_plate(plate) crnn.eval() with torch.no_grad(): logits crnn(tensor) # (1, T, num_classes) _, pred_idx logits.argmax(-1).cpu().numpy()[0] # 把索引映射成字符注意这里没有做CTC去重 charset open(charset.txt).read().strip().splitlines() plate_text .join(charset[i] for i in pred_idx if i ! len(charset) - 1)上面的expand_ratio0.05是经验值视频里车牌框偏紧的话我会调到0.08。preprocess_plate只做了最近邻缩放的效果实际可以用cv2.INTER_LINEAR。还有最后这段字符映射没做CTC去重所以连续重复字符会被打出来。你可以在推理时用最简单的“去重”相邻两个相同索引只保留一个但要注意车牌里允许出现连续相同字符比如“京A66666”所以必须结合CTC逻辑来做不能盲目去重。这就是为什么训练时要用CTC loss推理时也要配套同样的解码方式。3. 中文车牌数据集从哪里来怎么标怎么预处理才不会拖慢训练很多zip里自带的图片和标注打开一看乱七八糟。有的标注是VOC格式有的是YOLO格式还有的是纯文件名加一个JSON。数据这块如果不理顺后面所有模型都是空中楼阁。车牌识别对数据依赖性极强尤其是汉字省份字符样本不均衡会直接反映在识别准确率上。3.1 中文车牌数据结构的先验省份汉字、字母、数字的字符集设计中文蓝牌客车牌有两种传统蓝牌是7位字符新能源绿牌是8位字符。第一位永远是汉字代表省份简称比如“京”“冀”“鲁”“皖”。第二位是英文字母代表城市或发牌机关后面跟着字母和数字混合的序号且字母“I”和“O”一般不出现。所以设计字符集时我的做法是列出31个省份汉字再加24个字母和10个数字最后加一个CTC blank凑成70或71类。截取一个字符集供你参考京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼 ABCDEFGHJKLMNPQRSTUVWXYZ 0123456789每行一个字符顺序固定后不要随意改动。如果你训练完再向这个文件里加新字符模型分类头维度就变了必须重新微调。另外很多数据集里的省份汉字分布极不均衡北京和山东的车牌图片容易刷屏西藏和宁夏的样本可能只有几十张。处理办法是做字符重采样让每个省份汉字在每轮训练里出现次数接近否则模型会默认把不确定的汉字猜成高频省份。3.2 公开数据集与标注格式转换训练检测模型和识别模型用的数据可以分开。检测模型用整车图片识别模型用车牌裁剪图。公开的车牌检测数据集常见有CCPD它自带每张图的标注格式不是标准的VOC/YOLO通常是一个文本文件里写框坐标和车牌内容。课程作业里可能已经提供了一部分图片但标注格式可能是五花八门。常见做法是先统一转换成YOLO检测格式再单独整理识别数据集。我写过一个将VOC格式转YOLO格式的小脚本这是最常踩坑的地方import xml.etree.ElementTree as ET def voc_to_yolo(xml_file, out_txt, class_names): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): cls obj.find(name).text cls_id class_names.index(cls) box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) # 关键把坐标归一化到0-1之间并裁掉越界部分 x1 max(0, min(img_w - 1, x1)) x2 max(0, min(img_w - 1, x2)) y1 max(0, min(img_h - 1, y1)) y2 max(0, min(img_h - 1, y2)) if x2 x1 or y2 y1: continue cx ((x1 x2) / 2) / img_w cy ((y1 y2) / 2) / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) with open(out_txt, w) as f: f.write(\n.join(lines))代码里最关键的三个地方坐标越界截断、宽高小于0的过滤、归一化。很多人写出最终w是负数跑训练崩了多半是框的xmax比xmin还小或者标注字段写错了。class_names列表顺序就是YOLO训练时的类别顺序车牌只有一个类列表就是[plate]。3.3 数据增强和归一化的四个实践参数增强是提升泛化能力最便宜的手段但加过头会训练得很慢。车牌识别场景我常用的增强策略就四个亮度/对比度扰动强度0.2左右模拟白天到傍晚的光线变化。高斯模糊核大小3或5概率0.15模拟车辆运动造成轻微拖影。小角度仿射变换旋转正负5度、透视扭曲0.3以内模拟相机角度。随机遮挡在车牌边缘区域随机切掉1%~3%像素模拟脏污或遮挡。归一化要和模型训练时保持一致。YOLO检测里图像整体除以255就够。CRNN识别模型则常采用ImageNet均值方差均值[0.485, 0.456, 0.406]方差[0.229, 0.224, 0.225]。如果你用PyTorch的预训练权重必须用这套均值方差否则模型输出分布完全不对。我就见过有人加载权重后忘归一化识别结果跟随机一样还怪模型有问题。3.4 训练集和测试集的划分策略划分数据时最忌讳随机打乱。同一车牌在视频里连续几十帧被抽成多张图片随机划分后训练集和测试集都可能包含同一车牌模型记性好的话测试准确率虚高答辩时一测真实场景立刻打回原形。正确做法是按“来源”划分比如按拍摄地点、拍摄时间、或者视频文件来切。最稳妥的办法是先收集所有图片里的车牌号保证测试集里出现的所有车牌号在训练集里完全没出现过。这样测出来的才是真正的泛化能力。如果数据量不足你可以在划分时做分层抽样保证每个省份汉字在训练集和测试集中的数量占比接近。不然测试集里如果恰好只有“京”字哪怕模型只会认“京”也能拿高分这种成绩没有意义。4. 高性能推理从 PyTorch 到 ONNX/TensorRT以及那些“使劲踩油门”的部署细节毕设里“高性能”通常不是指理论复杂度而是指实际推理速度。PyTorch直接部署在CPU上慢到没法看GPU上虽然能跑但重复的前处理调用和动态图开销让延迟虚高。常见的优化路线是PyTorch模型导出ONNX再用ONNX Runtime或TensorRT执行。这里有一套具体的落地操作还有三个很容易被忽略的耗时陷阱。4.1 用 ONNX Runtime 让模型跑起来导出与加速参数ONNX导出是最成熟的“后悔药”方案。你不需要改模型结构优秀权重导出后就能立刻获得一个加速版。导出识别模型CRNN的示例import torch dummy torch.randn(1, 3, 32, 160) crnn.eval() torch.onnx.export(crnn, dummy, crnn.onnx, opset_version12, input_names[input], output_names[output], dynamic_axes{input: {2: height, 3: width}})opset_version12兼容性高老设备上也能跑。dynamic_axes让输入宽度可以变化因为车牌图块宽度不固定这个必须加。如果加了动态轴后发现推理变慢那就固定宽度为160省去动态形状的内存重分配。ONNX导出后用ONNX Runtime做推理import onnxruntime as ort import cv2 import numpy as np # 创建session程序启动时创建一次不要在每帧里重复创建 sess ort.InferenceSession(crnn.onnx, providers[CPUExecutionProvider]) img cv2.imread(plate_crop.jpg) img cv2.resize(img, (160, 32)) img img.astype(np.float32) / 255. input_tensor np.transpose(img, (2, 0, 1))[None, ...] logits sess.run([output], {input: input_tensor})[0]providers[CPUExecutionProvider]是强制CPU跑。如果你装了CUDA版ONNX Runtime可以写[CUDAExecutionProvider, CPUExecutionProvider]优先用GPU。ONNX Runtime默认会做图优化比如算子融合和常量折叠不需要我们额外配置。真正要调的是线程数CPU上有多个核时可以设置session_options.intra_op_num_threads但这个参数调不好反而变慢。4.2 TensorRT 的板子和精度问题TensorRT比ONNX Runtime更快但依赖NVIDIA显卡而且模型转换时有很多版本雷区。常见做法是将ONNX导出为TensorRT enginetrtexec --onnxcrnn.onnx --saveEnginecrnn.engine --fp16--fp16启用半精度推理速度上能提升不少。但车牌识别对细节敏感尤其汉字“白”和“自”这类结构相似的字符半精度可能导致笔划信息损失。我的经验是如果测试集精度掉了超过0.5%就放弃FP16改用--noTF32或者全精度。TensorRT还有固定形状和动态形状两种模式。动态形状对视频流里不定宽度的车牌很友好但配置起来要写profiles调试复杂。毕设场景下直接固定(1,3,32,160)是最省事的代价是宽高比不匹配时要先做resize。4.3 图像预处理和后处理的耗时陷阱推理加速之后你往往会发现整体耗时还是卡在图像读写、缩放、颜色转换上。一个典型问题cv2.resize默认插值算法是INTER_LINEAR速度已经很快但有些同学偏要用INTER_CUBIC精度和速度的平衡反而差。检测模型输入是640x640时分三步做等比缩放、pad到640、记录缩放系数。如果你直接把原图resize到640框坐标换算会变形。还有个容易炸的坑每次推理动态创建一个InferenceSession。这个对象初始化要加载模型、做图优化耗时几百毫秒必须全局复用。后处理画框时直接在原始图像上操作别copy一份不然多出几十毫秒。视频流处理的帧率瓶颈往往不是GPU而是你每帧都用np.copy去保留原图这种细节加一起能占到总时间的三成。5. 排查中文车牌识别最容易出错的 5 个坑模型和数据都准备好后真正开始调试会发现各种各样的玄学问题。我把过去在车牌识别上反复遇到过的五个典型翻车现场整理成“现象-原因-解决”三段式你照着对号入座比瞎调参数管用。5.1 车牌检测框不齐识别置信度全崩现象检测框要么只包住数字区汉字露在外面要么把车牌白色边框也框进去。识别模型对裁出来的图块要么报错要么置信度普遍低于0.5。 原因标注规范不统一。训练检测模型时有人标注蓝色区域有人标注白色边框还有标注时故意留了边距模型学到的“车牌框”定义漂移。 解决重新审视训练标注只标注蓝底文字区也就是车牌字符所在的矩形。如果你不想重新训练就在后处理时加大expand_ratio把裁剪区域向外扩。更可靠的做法是加一个基于角点的透视矫正步骤先把车牌四个角找出来再矫正这样框不齐的问题能被几何变换兜住。5.2 汉字识别老错“皖”和“鲁”现象测试视频里出现“鲁B”车牌识别结果老是“皖B”。训练集里“皖”字符占了大头其他省份少得可怜。 原因数据不均衡。省份汉字分布天然悬殊模型对高频省份的“记忆”太强低频省份的样本一出现就容易被拉偏。 解决在训练识别模型前统计字符频率对低频省份做过采样。具体做法是把包含这些省份的图片复制几份或者用WeightedRandomSampler按字符逆频率抽样。如果你赶时间另一个办法是把车牌图块里的汉字部分单独抠出来做一个分类器用这个分类器的结果去替代CRNN第一位的输出两个结果做加权投票也能把“皖”和“鲁”分开。5.3 新能源绿牌被当成蓝牌处理现象绿色车牌识别出来长度不对要么多一位要么少一位而且字符经常错位。原因是绿牌有8位而训练识别模型的序列长度只有7。模型在输出第7个时间步后被迫结束后面的字符根本没机会输出。 解决把识别模型的输出序列长度从7改成8并在训练集里加入足够多的绿牌图块。更完整的方式是在检测阶段增加一个颜色分类分支先判断车牌颜色再根据颜色选择识别模型或序列长度。如果数据集里绿牌太少可以先做一个基于HSV颜色分割的前置判断把绿色像素占比高的区域单独走8位识别分支。5.4 模糊/反光/小目标导致检测直接漏掉现象监控画面里远处驶来的车车牌在图像里可能只有十几像素宽YOLO置信度始终低于0.2框都出不来。 原因训练时小目标样本少且模型在多层下采样后小目标的特征损失严重。普通YOLO对大目标有效对小目标拉胯是通病。 解决首先降低推理时的conf阈值看看能不能把低置信度的候选框拉回来。接着可以做多尺度推理把图像放大1.5倍再检测或者用SAHI切片把图分成重叠块分别检测再合并结果。这个手段补救效果很明显但耗时成倍增加适合离线处理视频。如果你要实时那就得重新用imgsz960、加入小目标复制增强来训练模型。5.5 标注框坐标越界导致训练 loss 变成 NaN现象训练YOLO检测时loss到某个epoch突然变成nan然后整体崩溃。 原因标注转换时没有做坐标截断有些框的xmax超出了图像宽度归一化后的w大于1回归损失就成了Invalid。 解决在数据加载后加一个坐标合法性校验把越界框裁剪回边界把宽高小于8像素的框直接丢弃。参考代码def sanitize_yolo_box(cx, cy, w, h, img_w, img_h): x1 (cx - w / 2) * img_w y1 (cy - h / 2) * img_h x2 (cx w / 2) * img_w y2 (cy h / 2) * img_h x1 max(0, min(img_w - 1, x1)) x2 max(0, min(img_w - 1, x2)) y1 max(0, min(img_h - 1, y1)) y2 max(0, min(img_h - 1, y2)) if x2 - x1 8 or y2 - y1 8: return None return ((x1 x2) / 2 / img_w, (y1 y2) / 2 / img_h, (x2 - x1) / img_w, (y2 - y1) / img_h)这个坑在课程作业里最隐蔽因为训练前期的loss看起来正常到了中后期突然炸掉。没有良好的数据校验你会怀疑是学习率太高还是模型结构出bug排查半天才发现是数据问题。6. 用帧间平滑把单张准确率拉高以及怎么验证整体效果最后一个技巧不是模型层面的而是把已经训练好的模型用得更稳定。视频识别和单图识别最大的区别是单帧的噪声可以通过时间维度来抵消。同一辆车在连续20帧里车牌不会变但某一帧因为反光、遮挡可能识别出乱七八糟的结果。简单的滑动窗口投票就能把准确率拉高好几个点。from collections import deque, Counter # 保存最近10帧识别结果的队列 result_queue deque(maxlen10) def smooth_plate(pred_str): result_queue.append(pred_str) if len(result_queue) 5: # 样本太少先返回当前结果不投票 return pred_str counter Counter(result_queue) best, best_cnt counter.most_common(1)[0] # 只有当最高频结果超过一半时才信任它 if best_cnt len(result_queue) * 0.5: return best return UNKNOWN这个平滑方法需要你来定义“识别结果”的长度一致性如果某帧识别出7位另一帧识别出8位投票时要按统一长度对齐。我通常会把所有结果按字符切开来逐位投票这样某一位偶尔出错会被邻居纠正。另一个细节是车辆驶出画面后不要立刻清空队列等连续几帧都识别不到车牌后再重置避免短暂遮挡后输出卡在旧结果。验证整体效果时不要只看最终视频里框得准不准。我的习惯是把测试视频分成三类白天、夜间、逆光分别统计检测召回率和字符准确率。检测召回率等于检测到的车牌数量除以人工标注的车牌数量字符准确率等于识别正确的字符总数除以标记字符总数这里的“正确字符”要扣掉检测漏掉的部分否则数字会被弱势场景拖低让你说不清到底是检测问题还是识别问题。分开统计后问题定位就很快白天准确率低多半是检测框不齐夜间低多半是图像过暗导致字符模糊逆光低则是曝光不均匀。我以前总是改完一个参数就重新跑一遍完整视频然后把准确率记在本子上结果改了三次数字忽高忽低根本不知道哪个改动有效。后来我强制自己把每个版本的结果文件都存成带时间戳的日志里面包含每帧的检测框坐标、识别结果和原始图像文件名。改参数后再跑直接和上次日志对比看到底是哪些帧变好了哪些帧变坏了。这个习惯帮我把准确率从91%提到了97%比盲目调模型结构有效得多。希望帮到你。本文还有配套的精品资源点击获取