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

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

📂 项目地址:VerificationCodeRecognition


1. 核心背景回顾

文字验证码通常具有字符粘连、倾斜、没有固定分割线的特点,传统的“先分割再分类”方案(比如 YOLO 切割 + 单字符识别)在这类场景下很容易翻车——一旦分割出现偏差,后续识别就会一错到底。

相比之下,CRNN + CTC Loss 是一种无分割、端到端的经典方案,尤其擅长处理序列化的视觉识别任务。三个核心组件分工明确:

  • 🧠 CNN(卷积神经网络):把输入图像“拍扁压缩”,提取笔画、纹理等局部视觉特征,生成高度抽象的特征图。
  • 🔄 双向 LSTM(循环神经网络):在特征序列上建模字符间的上下文依赖,避免出现类似 “a-q-q-h” 这样不合逻辑的组合。
  • 📏 CTC Loss:免去人工标注每个字符的位置,直接根据预测序列和标签序列自动对齐并计算损失,完美解决不定长序列的训练问题。

2. 开发环境快速搭建

基础要求

别用太老的版本,本项目用到了新特性:

  • Python: 3.6+
  • 深度学习框架: PyTorch 2.0+(建议安装 CUDA 版本,训练速度提升巨大)
  • 推理加速: ONNX Runtime(CPU / GPU 均可)

一键安装依赖

# 克隆项目到本地
git clone https://github.com/MgArcher/VerificationCodeRecognition.git
cd VerificationCodeRecognition

# 安装所有依赖(若需要 GPU 版 PyTorch 请提前手动安装)
pip install -r requirements.txt

3. 数据集准备三步走

验证码识别是一个标准的监督学习任务,数据质量直接决定识别率的上限

3.1 获取数据

仓库作者提供了一套预设的 4 位纯英文小写字母验证码(例如 aqqh_157845.jpg),可以直接用于练习:
👉 蓝奏云预设数据集

如果你要针对自己的业务场景(如数字 + 大写字母 + 中文混合),则需要自行生成或收集合规的脱敏数据。

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                # 有 NVIDIA 显卡就打开,训练从几十分钟缩短到几分钟
    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/张,使用 NVIDIA 显卡(如 RTX 2060)约 3-5ms/张。

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

原生 PyTorch 在 CPU 上的推理速度较慢,但导出为 ONNX 格式后,配合 ONNX Runtime 可以获得 3-4 倍 的加速。

1. 导出 ONNX 模型

python export.py

导出成功后,在 expr 目录下会生成 crnn.onnx 文件。

2. 使用 ONNX 推理

python var_onnx.py

耗时参考:纯 CPU 环境约 7-10ms/张,几乎可以媲美中低端显卡的推理速度。


6. 进阶优化小技巧

6.1 字符字典适配

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

6.2 数据增强突破瓶颈

当识别率卡在 90% 左右难以提升时,试试在 tool/dataloader.pyMyDataset 类中的 __getitem__ 方法里加入以下增强操作:

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

6.3 预训练微调省时省力

如果从头开始训练收敛太慢,可以先找一个通用文字识别预训练模型(例如只识别英文的 CRNN 模型),再用你自己的业务数据进行微调,收敛速度会明显加快。


搞定!按照这套流程走下来,你就能拥有一个属于自己的文字验证码识别小工具了。如果在使用中遇到问题,欢迎去项目的 GitHub 仓库提 Issue~