用 CRNN + CTC 搞定文字验证码!附 PyTorch 训练 + ONNX 加速部署

📌 非恶意自动化提示:本文及配套工具仅供技术学习交流/非敏感场景的合规自动化测试使用,请遵守《网络安全法》及目标网站的 robots 协议/使用条款。

📂 项目地址(注意不是编辑页哦):VerificationCodeRecognition


1. 核心背景回顾

为什么选 CRNN?不是 YOLO 分割字符再识别吗? 文字验证码的字符是粘连、倾斜、无固定分割线的,YOLO+分类的“两步走”方案会因为分割不准导致整体识别率崩。

而文章开头的 CRNN + CTC Loss 刚好是无分割端到端的经典组合:

  • 🧠 CNN 先把图片“拍扁压缩”,提取核心的笔画/色彩特征
  • 🔄 双向 LSTM 接着串起特征,学懂字符之间的“前后依赖”(比如 a-q-q-h 这种组合不能乱拼)
  • 📏 CTC 是“对齐神器”,不用手动把标签对应到图片的某个像素区域,自动算损失就行

2. 开发环境快速搭

基础要求

别找太老的包哦,项目用了新特性:

  • Python: 3.6+
  • 深度学习框架: PyTorch 2.0+(兼容 CUDA 加速,速度快N倍!)
  • 推理加速: ONNX Runtime(CPU/GPU 版都支持)

一键装依赖

# 先克隆仓库到本地
git clone https://github.com/MgArcher/VerificationCodeRecognition.git
cd VerificationCodeRecognition

# 安装所有依赖(如果是GPU版PyTorch提前装好哦,pip会默认找CPU版)
pip install -r requirements.txt

3. 数据集准备三步走

验证码识别是监督学习的活,有多少带清晰标签的高质量数据,决定了识别率的天花板。

3.1 数据获取

作者已经准备了一套预设的4位纯英文小写字母验证码(比如 aqqh_157845.jpg),可以直接拿来练手: 👉 Lanzou云预设数据集

如果要做自己的业务场景,比如数字+大写字母+中文的混合验证码,需要自己生成或爬取脱敏后的合规数据。

3.2 数据存放与命名

别瞎改结构和名字哦! 除非你愿意动读取逻辑:

  1. 把所有图片放到根目录下的 data 文件夹
  2. 命名规则:真实标签_唯一标识.jpg/png(唯一标识可以是时间戳、序号,防止重名覆盖)

举个正确的例子🌰:

data/
├─ aqqh_157845.jpg
├─ bmwx_20240520.jpg
└─ zyzh_9999.png

3.3 自定义读取(可选)

如果业务场景的图片格式/路径/命名完全不一样,修改 tool/dataloader.py 里的 MyDataset 类就行。


4. 模型训练指南

训练过程会自动记录训练集损失值(total_loss)训练集准确率(acc)验证集损失/准确率(如果开启了验证的话)。

4.1 修改核心配置

打开 train.py 开头的 Opt 类,调整几个关键参数:

class Opt():
    trainRoot = r"data"         # 必须改成你的训练集路径!Windows记得加r
    cuda = True                # 有N卡就开!速度从几十分钟降到几分钟
    pretrained = ''            # 断点续训/微调的话填pth模型路径
    alphabet_path = 'tool/charactes_keys.txt' # 字符字典,要改场景的话更重要!

4.2 启动训练

直接敲命令就行啦😎:

python train.py

4.3 什么时候停训?

别一直死等训练到天荒地老,看这两个指标稳定就停:

  • 训练集的 acc 接近 100%(说明模型“背熟”了训练集)
  • 验证集的 val_acc 稳定在95%以上(针对纯字母的预设数据集),不再明显波动(防止过拟合!)

训练好的模型会保存在根目录下的 expr 文件夹里。


5. 推理与生产级部署

A. 原生 PyTorch 推理(开发调试用)

适合在训练阶段快速验证模型效果,不用转格式:

python var_torch.py

耗时参考:CPU环境约 30-35ms/张,N卡(比如RTX 2060)约 3-5ms/张。

B. ONNX 加速推理(生产环境首选)

原生 PyTorch 在 CPU 下的推理太慢了!转成 ONNX 格式可以用 ONNX Runtime 优化,CPU下能提升 3-4 倍速度

1. 导出 ONNX 模型

python export.py

导出成功后会在 expr 文件夹里生成 crnn.onnx

2. 使用 ONNX 推理

python var_onnx.py

耗时参考:CPU环境约 7-10ms/张,几乎和小N卡持平了!


6. 进阶优化小技巧

6.1 字符字典适配

如果你的验证码包含数字、大写字母、特殊符号、中文,必须第一时间更新 tool/charactes_keys.txt!把所有可能出现的字符按顺序写进去,不要有重复。

6.2 数据增强破瓶颈

如果识别率卡在90%左右上不去,试试在 tool/dataloader.py 里的 MyDataset 类的 __getitem__ 方法中加入:

  • 随机旋转
  • 随机加高斯噪声/椒盐噪声
  • 随机对比度/亮度调整
  • 轻微的仿射变换(平移、缩放、倾斜)

6.3 预训练微调省时间

如果从零开始训练太慢,可以先找一套通用的文字识别预训练模型(比如只识别英文的),然后用自己的业务数据微调,收敛速度会快很多!


好了,这套流程走完,你就能拥有一个自己的文字验证码识别小工具啦~如果有问题可以去作者的仓库提 Issue 哦!