资讯动态

Caffe实战车牌识别:从SSD检测到多标签分类的完整部署指南

发布时间:2026/10/14 10:24:19 来源:尧图企业网站定制
1. 为什么在深度学习框架百花齐放的今天还要聊Caffe如果你是在2015年前后入行计算机视觉的Caffe这个名字大概率是你接触的第一个深度学习框架。那时候PyTorch还没发布TensorFlow刚开源不久学术界和工业界做图像分类、目标检测Caffe几乎是默认选项。现在回头看Caffe的生态确实老了Python 2的支持、Protobuf的版本冲突、编译时各种依赖报错每一条都够让人头疼半天。但有一个场景我至今仍然觉得Caffe有它的独到之处——车牌识别这类结构相对固定、对推理速度要求高、部署环境受限的工业级任务。车牌识别这个任务本身很有意思。它不像通用目标检测那样需要处理千变万化的类别也不像自然语言处理那样模型结构日新月异。它的核心流程非常清晰先定位车牌在图像中的位置再对车牌区域做字符分割或序列识别最后输出车牌号码。整个pipeline的每一环都有成熟的技术方案而Caffe在这个链条里的优势在于模型结构定义直观Prototxt、C推理接口成熟、内存占用可控、在嵌入式设备上部署方便。我见过不少做智能交通的团队至今仍在用Caffe训练的车牌检测模型跑在工控机上稳定运行了好几年。这篇文章适合两类人看一类是手里有Caffe遗留项目需要维护或优化的开发者另一类是想理解车牌识别完整技术链路、不满足于只调库的学生和工程师。我会从数据准备开始一路讲到模型训练、调参、部署推理把每个环节里我踩过的坑和总结的经验都摊开来说。文章里涉及的代码和配置都是可以直接参考的但具体参数需要根据你的数据集做调整。注意Caffe的安装本身就是一个大坑不同版本的CUDA、cuDNN、Protobuf组合会产生各种奇怪的编译错误。如果你还没装好环境建议先用Docker镜像跑通流程再考虑本地编译。2. 车牌识别任务的拆解与Caffe的适配逻辑2.1 车牌识别的两阶段与端到端之争车牌识别在技术路线上一直有两派做法。一派是两阶段方案先用目标检测网络比如SSD、YOLO的Caffe版本把车牌框出来再把车牌区域送进一个字符识别网络比如CRNN或者简单的多标签分类网络得到号码。另一派是端到端方案直接输入整张图网络同时输出车牌位置和号码类似OCR里的检测识别联合训练。两阶段方案的好处是每一环都可以独立调试和替换。检测不准就换检测模型识别不准就换识别模型互不影响。端到端方案理论上更优雅但训练数据要求高调参难度大而且在Caffe里实现复杂的端到端结构比较费劲。我个人的经验是在Caffe框架下两阶段方案是更务实的选择。原因很简单Caffe的Layer定义是静态图自定义Loss Layer和复杂的后处理逻辑写起来不如PyTorch灵活两阶段方案可以把复杂度分散到两个相对独立的模型里每个模型的结构都更简单、更容易收敛。具体来说检测阶段我推荐用SSDSingle Shot MultiBox Detector的Caffe实现。SSD在Caffe社区有比较成熟的代码输入分辨率可以灵活调整对小目标车牌在整张图里通常只占很小一块的检测效果经过调参后可以做到很好。识别阶段可以用多标签分类的思路把车牌号码的每一位当作一个独立的分类任务比如中国蓝牌是7位就设计7个分类头每个头负责预测对应位置的字符。这种做法的好处是训练简单、推理速度快缺点是对车牌字符分割的精度有一定依赖。2.2 为什么Caffe适合做车牌识别的推理部署说一个实际场景。我之前参与过一个停车场出入口的识别系统硬件是一台低功耗的工控机没有独立显卡只有Intel的集成显卡。这种环境下PyTorch的推理速度惨不忍睹TensorFlow也好不到哪去。最后换成Caffe用C接口加载模型单张图片的检测识别总耗时控制在80毫秒以内满足了实时性要求。Caffe之所以在推理端有优势核心原因有几个。第一Caffe的Blob内存管理是预分配的推理过程中不会频繁申请和释放内存这在嵌入式环境里非常重要。第二Caffe的Layer实现是高度优化的C代码尤其是卷积层Intel的MKL和开源的OpenBLAS都能直接对接。第三Caffe模型可以很方便地转成其他推理引擎的格式比如通过ONNX转到TensorRT或者OpenVINO进一步加速。当然Caffe的缺点也很明显。训练的时候没有TensorBoard那样的可视化工具loss曲线要靠自己解析日志画图。数据增强的灵活性不如PyTorch的DataLoader需要自己写Python Layer或者提前把增强后的图片存到磁盘。但这些缺点在车牌识别这个任务里是可以接受的因为车牌识别的数据增强手段相对固定亮度调整、对比度调整、轻微旋转、加噪声不需要太复杂的增强策略。2.3 整体技术链路概览我把整个车牌识别项目拆成以下几个环节后面的章节会逐一展开环节主要工作产出物数据准备收集车牌图片、标注检测框和号码LMDB数据集检测模型训练用SSD训练车牌检测器检测模型caffemodel识别模型训练用多标签分类训练字符识别器识别模型caffemodel推理部署C接口集成、后处理逻辑可执行程序调优难例挖掘、模型压缩、加速优化后的模型这个链路看起来清晰但每个环节都有不少细节需要注意。比如数据准备阶段车牌的标注格式和普通目标检测不太一样需要同时标注框的位置和号码内容。检测模型训练时SSD的默认anchor设置对车牌这种长条形目标不太友好需要调整aspect ratio。识别模型训练时字符类别的不平衡问题很突出数字和字母的出现频率远高于省份简称汉字。3. 数据准备从原始图片到LMDB的完整流程3.1 车牌数据的采集与标注规范车牌识别的数据来源主要有几个渠道公开数据集比如CCPD、CRPD、自己采集的监控截图、合成数据。公开数据集的好处是标注质量高、数量大但场景可能和你的实际应用有差异。自己采集的数据更贴近实际场景但标注工作量大。合成数据可以用工具生成但域适应问题需要额外处理。我建议的做法是先用公开数据集训练一个基础模型再用自己采集的数据做fine-tune。这样既能保证模型有足够的泛化能力又能适应特定场景。标注的时候每张图片需要记录两个信息车牌框的坐标xmin, ymin, xmax, ymax和车牌号码字符串。标注格式我习惯用类似VOC的XML格式每个图片对应一个XML文件。车牌号码的标注要注意几点省份简称要用正确的汉字字母要统一大小写建议全大写新能源车牌是8位不要漏掉最后一位。提示标注车牌框的时候建议框稍微放大一点把车牌边缘的铆钉和边框都包含进去。这样训练出来的检测器对边缘的鲁棒性更好不会因为框太紧导致字符被切掉。3.2 检测数据集的LMDB生成Caffe最常用的数据格式是LMDB生成检测数据集的LMDB需要把图片和标注框转换成SSD要求的格式。SSD的Caffe实现通常要求一个txt文件每行包含图片路径和对应的标注信息。格式大概是这样的# 图片路径 图片宽 图片高 类别数 xmin ymin xmax ymax ... /path/to/image1.jpg 1920 1080 1 100 200 300 250 /path/to/image2.jpg 1280 720 1 50 60 200 120然后写一个Python脚本用Caffe提供的convert_annoset工具或者自己用caffe.proto里的Datum结构生成LMDB。这里有个坑SSD的Caffe版本对LMDB的生成方式有特定要求不同fork的代码可能不一样。我用的那个版本要求LMDB里存储的是Datum但标注信息是通过一个额外的txt文件在训练时读取的。所以实际上LMDB里只存了图片数据标注信息走的是另一个通道。生成LMDB的脚本核心逻辑是这样的import caffe import numpy as np import cv2 def generate_lmdb(image_list, output_path): # 初始化LMDB环境 map_size int(1e12) env lmdb.open(output_path, map_sizemap_size) with env.begin(writeTrue) as txn: for i, (img_path, labels) in enumerate(image_list): # 读取图片 img cv2.imread(img_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 构造Datum datum caffe.io.array_to_datum(img) datum.label 0 # 检测任务不用这个label # 写入LMDB txn.put({:08d}.format(i).encode(), datum.SerializeToString()) env.close()这段代码看起来简单但实际跑的时候要注意图片的通道顺序。Caffe默认是BGR但OpenCV读进来也是BGR所以如果你用cv2.imread读图不需要做通道转换。但如果你用PIL读图PIL是RGB就需要转成BGR再存。3.3 识别数据集的制作与字符类别映射识别模型的数据集制作是另一个重点。我采用的多标签分类方案需要把车牌号码的每一位拆开每一位对应一个类别。首先需要统计所有出现过的字符建立一个字符到索引的映射表。中国车牌用到的字符包括31个省份简称汉字、26个大写字母I和O通常不用避免和1、0混淆、10个数字。总共大约67个类别。但实际项目中如果你只做某个省份的车牌汉字类别可以缩减到1个。映射表建好之后每个车牌号码就转换成一个整数数组。比如京A12345转换成[0, 10, 1, 2, 3, 4, 5]假设京的索引是0A的索引是10。然后把这个数组作为标签和车牌区域的裁剪图片一起存入LMDB。这里有个细节车牌区域的裁剪要留一点边距。如果严格按照检测框裁剪有时候会把字符的边缘切掉。我通常会在检测框的基础上向外扩5%到10%的像素保证字符完整。3.4 数据增强策略与Caffe的实现方式Caffe的数据增强不如PyTorch方便但可以通过几种方式实现。第一种是在生成LMDB之前做增强把增强后的图片也存进去。这种方式的缺点是数据集会膨胀好几倍LMDB文件可能大到几百GB。第二种是写Python Layer在训练时实时做增强。这种方式灵活但Python Layer的速度是瓶颈可能会拖慢训练。我一般采用折中方案对训练集做适度的离线增强对验证集不做增强。离线增强的手段包括亮度调整随机乘以0.8到1.2之间的系数对比度调整随机乘以0.8到1.2之间的系数轻微旋转-5度到5度之间高斯噪声标准差在5到15之间运动模糊模拟车辆运动造成的模糊这些增强手段在OpenCV里都有对应的函数写一个脚本批量处理即可。注意增强后的图片要重新生成标注框因为旋转会改变框的位置。如果嫌麻烦可以只做不改变几何位置的增强亮度、对比度、噪声这样标注框不用重新计算。4. SSD检测模型的训练与调参实战4.1 SSD网络结构的修改要点SSD的原始版本是基于VGG16的输入分辨率300x300。但车牌检测有几个特殊之处车牌是长条形目标宽高比通常在3:1到5:1之间车牌在整张图里占比很小尤其是远距离拍摄的场景车牌的角度可能有倾斜。针对这些特点需要对SSD做几处修改。第一调整anchor的aspect ratio。原始SSD的aspect ratio是[1, 2, 3, 1/2, 1/3]对车牌来说不够用。我改成[1, 2, 3, 4, 5, 1/2, 1/3, 1/4, 1/5]增加长条形的anchor。同时把anchor的scale范围也调整一下让更小的anchor覆盖远距离的小车牌。第二修改输入分辨率。300x300对车牌来说太低了字符会糊成一团。我通常用512x512或者600x600。分辨率提高会增加计算量但检测小目标的效果会明显改善。如果硬件条件允许用800x800效果更好。第三调整特征图的选取。SSD从多个尺度的特征图上做预测浅层特征图负责小目标深层负责大目标。车牌通常是小目标所以浅层特征图的权重更重要。我在修改的时候会确保conv4_3这一层被包含在预测层里并且给它分配足够的anchor数量。4.2 训练参数配置与loss曲线解读SSD的solver配置里几个关键参数需要根据数据集规模调整。假设你的训练集有5万张图片batch size设为16那么一个epoch大约需要3125次迭代。初始学习率我一般设0.001用step策略在80%和95%的迭代次数时各降一次学习率降为原来的0.1倍。# solver.prototxt base_lr: 0.001 lr_policy: step gamma: 0.1 stepsize: 100000 max_iter: 200000 momentum: 0.9 weight_decay: 0.0005 batch_size: 16训练过程中要盯着loss曲线看。SSD的loss由两部分组成分类lossconf loss和定位lossloc loss。正常情况下两个loss都应该稳步下降。如果分类loss下降但定位loss不降说明模型在学分类但没学好定位可能是anchor设置有问题。如果两个loss都震荡可能是学习率太大或者batch size太小。我遇到过一个典型问题训练到中期loss突然变成NaN。排查后发现是某张图片的标注框坐标超出了图片边界导致计算loss时出现异常值。解决办法是在生成LMDB之前检查所有标注框把超出边界的坐标裁剪到边界内。4.3 难例挖掘与数据平衡车牌检测的一个难点是正负样本极度不平衡。一张1920x1080的图片里车牌可能只占100x30像素其余全是背景。SSD默认使用hard negative mining在训练时挑选loss最高的负样本参与梯度更新。这个策略在Caffe的SSD实现里通常已经内置了但参数需要调整。具体来说MultiBoxLoss层里有一个neg_pos_ratio参数控制负样本和正样本的比例。默认是3:1我一般调到5:1或者7:1让模型看到更多的负样本减少误检。但也不能调太高否则正样本的梯度会被淹没导致漏检增加。另外如果某些场景的误检特别严重比如把广告牌上的文字误认为车牌可以专门收集这些误检的图片作为负样本加入训练集。这种针对性负样本挖掘的效果比盲目增加数据量要好得多。4.4 检测效果评估与常见问题排查评估检测模型的时候不能只看mAP。车牌检测有它的特殊性漏检的代价比误检高。漏检意味着系统完全没看到车牌误检还可以通过后续的识别模型过滤掉识别模型对非车牌区域的输出置信度通常很低。所以我在评估时会单独看recall确保recall在95%以上。常见的检测问题和对策问题现象可能原因解决思路远距离车牌漏检anchor太小或特征图分辨率不够增加小anchor、提高输入分辨率倾斜车牌漏检anchor角度单一增加旋转增强、用旋转框检测误检广告牌文字负样本不足加入针对性负样本框位置不准定位loss权重太低提高loc loss的权重系数训练不收敛学习率太大或数据标注错误降低学习率、检查标注5. 字符识别模型的设计与训练细节5.1 多标签分类 vs 序列识别为什么选前者字符识别这块主流方案有两种。一种是序列识别用CRNNCNNRNNCTC直接输入车牌图片输出字符序列。另一种是多标签分类把每一位字符当作独立的分类任务。CRNN的好处是不需要字符分割对不定长车牌更友好。但在Caffe里实现CRNN比较麻烦因为Caffe对RNN的支持很有限CTC Loss也没有官方实现。多标签分类在Caffe里实现起来就简单多了。网络结构就是一个普通的CNN最后接一个全连接层输出维度是7×67假设7位车牌67个字符类别。训练时每一位独立计算softmax loss然后求和。推理时每一位取argmax拼起来就是车牌号码。这种方案的缺点是对字符分割有隐式依赖。如果车牌图片里字符粘连严重或者有倾斜导致字符位置偏移分类准确率会下降。解决办法是在训练数据里加入各种粘连和倾斜的样本让模型学会处理这些情况。另外可以在网络里加入空间注意力机制让模型自动关注到每一位字符的位置。5.2 识别网络的结构设计与字符类别处理识别网络我通常用一个轻量级的CNN比如MobileNet的Caffe版本或者自己搭一个5层卷积2层全连接的小网络。输入尺寸统一resize到96x32宽x高这个尺寸对车牌来说刚好既能保留字符细节又不会太大影响速度。字符类别的处理有几个细节要注意。第一省份简称汉字的样本量通常远少于字母和数字。比如京的出现频率可能只有1的十分之一。这种类别不平衡会导致模型对汉字的识别率偏低。解决办法是对汉字类别的loss加权在SoftmaxWithLoss层里设置class_weighting参数给汉字更高的权重。第二容易混淆的字符要特别处理。比如0和O、1和I、2和Z、8和B。虽然车牌规范里通常不用I和O但实际图片里因为字体和模糊的原因这些字符看起来很像。我通常会在训练数据里故意加入一些模糊的样本让模型学会区分。第三新能源车牌是8位比普通车牌多一位。如果两种车牌都要支持网络输出维度要设成8×67普通车牌的最后一位用padding填充。或者训练两个独立的识别模型分别处理7位和8位车牌。5.3 训练技巧学习率策略与正则化识别模型的训练比检测模型容易收敛但也有一些技巧。学习率我一般从0.01开始用poly策略衰减lr_policy: poly power: 0.9 max_iter: 100000poly策略的好处是学习率平滑下降不会像step策略那样在切换点产生震荡。对于识别这种相对简单的任务poly策略通常能收敛到更好的局部最优。正则化方面Dropout是必须的。我在全连接层前面加一个Dropout层dropout ratio设0.5。另外权重衰减weight decay设0.0001到0.0005防止过拟合。如果训练集比较小少于1万张还可以加L2正则化或者用数据增强来增加样本多样性。还有一个容易被忽略的点Batch Normalization的位置。我习惯在每个卷积层后面加BN层但BN层的参数在训练初期会剧烈变化可能导致loss震荡。解决办法是在训练初期冻结BN层的参数等loss稳定后再放开。Caffe里可以通过设置lr_mult为0来冻结BN层的参数。5.4 识别准确率的提升路径识别准确率从90%提升到99%的过程往往比从0到90%更费劲。我总结了几条有效的提升路径第一条是增加难例样本。把识别错误的样本收集起来人工检查后加入训练集。这种迭代式的难例挖掘通常能在两三轮之后把准确率提升2到3个百分点。第二条是调整输入分辨率。96x32的输入对清晰的车牌够用但对模糊的车牌就力不从心了。可以尝试把输入提高到128x48看看准确率有没有提升。但要注意分辨率提高会增加计算量需要权衡。第三条是模型融合。训练多个识别模型推理时取平均或者投票。这种方法能稳定提升1到2个百分点但推理时间会成倍增加。如果对速度要求不高可以考虑。第四条是后处理规则。利用车牌号码的先验知识做校正。比如中国车牌第一位必须是省份简称第二位必须是字母后面五位是字母或数字。如果模型输出的第一位是数字就可以根据置信度选择次优的汉字。这种规则后处理能纠正一部分明显的错误。6. C推理部署与性能优化6.1 Caffe C接口的集成方式Caffe的C接口用起来比Python接口麻烦一些但性能更好而且不依赖Python环境。集成的基本流程是加载模型、构造Blob、前向传播、读取输出。#include caffe/caffe.hpp // 初始化网络 caffe::Netfloat net(deploy.prototxt, caffe::TEST); net.CopyTrainedLayersFrom(model.caffemodel); // 构造输入Blob caffe::Blobfloat* input_blob net.input_blobs()[0]; input_blob-Reshape(1, 3, 512, 512); // 填充数据 float* input_data input_blob-mutable_cpu_data(); // ... 把图片数据拷贝到input_data // 前向传播 net.Forward(); // 读取输出 const caffe::Blobfloat* output_blob net.output_blobs()[0]; const float* output_data output_blob-cpu_data();这段代码看起来简单但实际集成时有几个坑。第一Caffe的编译选项要和你的项目一致比如是否用GPU、是否用OpenBLAS、Protobuf的版本。如果编译选项不一致链接时会报各种奇怪的错误。第二多线程环境下要小心Caffe的Net对象不是线程安全的每个线程需要独立的Net实例。第三内存管理要手动处理Caffe的Blob不会自动释放需要自己管理生命周期。6.2 检测与识别的串联逻辑检测和识别两个模型串联的时候有几个工程上的细节需要处理。首先是检测框的筛选。SSD会输出很多框需要根据置信度阈值通常0.5到0.7和NMS非极大值抑制来筛选。NMS的IoU阈值我一般设0.45既能去掉重复框又不会把相邻的车牌误删。然后是车牌区域的裁剪和校正。检测框可能是倾斜的直接裁剪会导致字符变形。我通常会用仿射变换把车牌旋转到水平。旋转角度可以通过检测框的四个角点计算或者用最小外接矩形。校正后的车牌再送进识别模型。最后是识别结果的拼接和后处理。识别模型输出每一位的字符和置信度如果某一位的置信度低于阈值比如0.8可以标记为不确定或者用语言模型做校正。中国车牌有固定的格式可以用正则表达式做初步校验。6.3 推理速度的优化手段推理速度的优化可以从几个层面入手。模型层面可以用更轻量的网络结构比如把VGG换成MobileNet参数量减少一个数量级速度提升明显。计算层面可以用Intel MKL或者OpenBLAS加速矩阵运算GPU环境下用cuDNN。工程层面可以用多线程并行处理多路视频流或者用批处理batch inference提高GPU利用率。我实测过的一组数据在Intel i7-8700 CPU上SSD 512x512的检测模型单张推理约45毫秒识别模型约15毫秒加上前后处理总共约80毫秒。如果用GPUGTX 1060检测降到8毫秒识别降到3毫秒总共约20毫秒。这个速度对于25fps的视频流来说足够了。还有一个容易被忽略的优化点图片预处理的速度。图片的缩放、归一化、通道转换这些操作如果都用CPU做可能比模型推理还慢。可以用OpenCV的UMat或者GPU加速或者用Intel IPP库优化。6.4 实际部署中的稳定性问题部署到生产环境后稳定性问题比精度问题更让人头疼。我遇到过几个典型情况第一个是内存泄漏。Caffe的Blob在每次Forward之后不会自动释放中间结果如果循环调用Forward内存会持续增长。解决办法是定期重建Net对象或者用net.ClearParamDiffs()清理中间变量。第二个是多线程竞争。如果多个线程共用一个Net对象会出现数据竞争导致结果错乱甚至崩溃。解决办法是每个线程维护独立的Net实例或者加锁串行化。第三个是异常输入的处理。如果输入的图片损坏、尺寸异常、或者全黑全白模型可能会输出奇怪的结果。需要在预处理阶段做校验过滤掉异常输入。第四个是模型版本管理。生产环境可能同时运行多个版本的模型需要有一套版本管理机制确保加载的模型和配置文件匹配。我通常会在模型文件名里加入版本号和日期部署时通过配置文件指定。7. 项目复盘那些文档里不会写的经验7.1 数据质量比模型结构更重要这个道理听起来像废话但我在车牌识别项目里体会特别深。早期我花了很多时间调网络结构尝试各种trick准确率提升缓慢。后来把精力转到数据清洗上把标注错误的样本修正、把模糊到无法辨认的样本剔除、把重复的样本去重准确率一下子提升了5个百分点。具体来说标注错误的样本危害极大。一张标注错误的车牌图片会让模型学到错误的映射关系。如果这种错误样本占比超过1%模型的准确率上限就会被拉低。我建议在训练之前至少抽样检查5%的标注数据确保标注质量。7.2 学习率是最重要的超参数如果只能调一个超参数我会选学习率。学习率太大loss震荡不收敛学习率太小收敛慢且容易陷入局部最优。我的经验是先用一个较大的学习率跑几百次迭代观察loss曲线如果loss下降很快但后期震荡就减小学习率如果loss几乎不降就增大学习率。另外warmup策略对车牌识别这种小数据集特别有效。在训练的前几千次迭代里学习率从很小的值线性增加到初始学习率可以避免训练初期的不稳定。Caffe里可以通过修改solver的lr_policy为poly并设置合适的power来实现类似效果。7.3 不要忽视后处理的作用很多人把精力全放在模型上忽略了后处理。实际上合理的后处理能纠正不少模型错误。比如车牌号码的格式校验中国车牌第一位必须是汉字第二位必须是字母后面是字母或数字。如果模型输出的第一位是数字就可以根据置信度选择次优的汉字。这种规则后处理在实测中能提升1到2个百分点的准确率。还有一个后处理技巧是多帧投票。视频流里同一辆车会出现很多帧把多帧的识别结果做投票取出现次数最多的号码。这种方法对静态场景特别有效能过滤掉偶发的识别错误。7.4 模型更新与迭代的节奏车牌识别系统上线后模型需要持续迭代。新的车牌样式比如新能源车牌、新的拍摄场景比如夜间红外、新的干扰因素比如雨雪天气都会导致模型性能下降。我建议建立一个反馈闭环系统运行时记录低置信度的样本定期人工审核后加入训练集重新训练模型。迭代的节奏不用太频繁一般一个月一次就够了。太频繁会导致模型不稳定太慢又跟不上场景变化。每次迭代后要做A/B测试确保新模型在各项指标上都不差于旧模型。7.5 一些零散但有用的技巧最后分享几个零散但很实用的技巧。图片的EXIF信息要处理有些相机会在EXIF里记录旋转角度如果不处理读进来的图片可能是旋转的。OpenCV的imread默认是BGR但Caffe的Blob期望的也是BGR所以不需要转换但如果你用其他库读图就要注意。LMDB的map_size要设得足够大否则写入时会报错我一般设1TB。训练日志要定期备份Caffe的日志默认输出到stderr重定向到文件后可以用Python脚本解析出loss曲线。还有一个关于Caffe编译的经验Protobuf的版本一定要和Caffe匹配。我遇到过因为Protobuf版本不一致导致模型加载失败的情况排查了很久。建议用Caffe自带的Protobuf版本或者用conda安装指定版本的Protobuf。这个项目后续还可以往几个方向扩展一是加入车牌颜色识别区分蓝牌、黄牌、绿牌二是支持多角度车牌用旋转框检测三是模型量化把float32的模型转成int8进一步加速推理。这些方向都有实际需求值得深入探索。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑