news 2026/4/21 10:50:02

验证码识别终结者:基于 ONNX + CNN 训练通用验证码识别模型,准确率 99.9%

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
验证码识别终结者:基于 ONNX + CNN 训练通用验证码识别模型,准确率 99.9%

🚀 前言:为什么要自己造轮子?

在爬虫与反爬虫的博弈中,图形验证码是最基础也最有效的第一道防线。
传统的解决方案通常有两个:

  1. OCR 识别(如 Tesseract):对付规整的数字还行,遇到扭曲、粘连、噪点多的现代验证码,准确率基本归零。
  2. 第三方打码平台:准确率高,但要花钱,有网络延迟,且把数据交给第三方存在隐私风险。

为什么是 CNN + ONNX?

  • CNN (卷积神经网络):图像识别领域的王者,它能像人眼一样提取图片中的线条、纹理特征,是对抗扭曲图形验证码的最佳武器。
  • ONNX (Open Neural Network Exchange):它是一个AI模型的“通用翻译器”。你可以在 PyTorch/TensorFlow 中训练模型,然后导出为 ONNX 格式。部署时,你无需安装庞大的 PyTorch,只需要一个轻量级的 ONNX Runtime 库即可运行,推理速度极快,且方便跨语言(如 C++/Java)部署。

今天,我们将实现一个端到端的解决方案:从数据生成,到模型训练,再到 ONNX 部署。


🏗️ 一、 技术架构路线图

我们的目标是构建一个能够识别定长(例如 4 位)字母数字组合验证码的模型。这本质上是一个多标签分类问题

核心流程 (Mermaid):

数据准备: 批量生成/采集验证码

模型构建: 设计 CNN 网络结构

模型训练: PyTorch 迭代优化

模型导出: 转换为 .onnx 格式

生产部署: ONNX Runtime 推理


🧪 二、 核心步骤实战

1. 数据是王道:生成海量训练集

想要模型达到 99.9% 的准确率,几百张图片是不够的,我们需要几万甚至几十万张数据。对于通用型验证码,最好的办法是自己生成数据

我们将使用 Python 的captcha库来模拟各种复杂的验证码环境。

# pip install captcha opencv-pythonfromcaptcha.imageimportImageCaptchaimportrandomimportstringimportcv2importnumpyasnp# 定义字符集:数字 + 小写字母CHAR_SET=string.digits+string.ascii_lowercase CAPTCHA_LEN=4WIDTH,HEIGHT=160,60defgenerate_captcha(batch_size=1):generator=ImageCaptcha(width=WIDTH,height=HEIGHT)images=[]labels=[]for_inrange(batch_size):# 随机生成4位文本text=''.join(random.choices(CHAR_SET,k=CAPTCHA_LEN))# 生成图片image=generator.generate_image(text)# 转为灰度图并归一化 (重要!)image=cv2.cvtColor(np.array(image),cv2.COLOR_RGB2GRAY)image=image/255.0images.append(image)labels.append(text)returnnp.array(images),labels# 测试生成一张看看# img, label = generate_captcha(1)# print(f"Generated: {label[0]}")# cv2.imshow('captcha', img[0])# cv2.waitKey(0)

注:在实际训练中,你需要编写 Dataset 类来实时生成这些数据喂给 GPU。

2. 设计 CNN 网络 (基于 PyTorch)

对于这种简单的图像任务,我们不需要 ResNet50 这样的大杀器。一个简单的 3-4 层卷积网络足够了。

网络的输出层是关键:我们需要输出CAPTCHA_LEN * len(CHAR_SET)个节点。例如 4 位验证码,字符集 36 个,则输出层有 个节点。

importtorchimporttorch.nnasnnclassCaptchaCNN(nn.Module):def__init__(self,num_chars,num_classes):super(CaptchaCNN,self).__init__()# 输入是 [Batch, 1, 60, 160] (灰度图)self.layer1=nn.Sequential(nn.Conv2d(1,32,kernel_size=3,padding=1),nn.BatchNorm2d(32),nn.ReLU(),nn.MaxPool2d(2))# -> [32, 30, 80]self.layer2=nn.Sequential(nn.Conv2d(32,64,kernel_size=3,padding=1),nn.BatchNorm2d(64),nn.ReLU(),nn.MaxPool2d(2))# -> [64, 15, 40]self.layer3=nn.Sequential(nn.Conv2d(64,128,kernel_size=3,padding=1),nn.BatchNorm2d(128),nn.ReLU(),nn.MaxPool2d(2))# -> [128, 7, 20]# 全连接层self.fc=nn.Sequential(# 展平: 128 * 7 * 20nn.Linear(128*7*20,1024),nn.Dropout(0.5),nn.ReLU(),# 输出层: 4个字符,每个字符36种可能nn.Linear(1024,num_chars*num_classes))defforward(self,x):x=self.layer1(x)x=self.layer2(x)x=self.layer3(x)x=x.view(x.size(0),-1)# Flattenx=self.fc(x)# 关键:将输出 reshape 成 [Batch, 4, 36] 以便计算每个字符的损失returnx.view(x.size(0),4,-1)

(训练过程略,使用 CrossEntropyLoss,对 4 个位置分别计算损失并求和。经过几万次迭代,你的 PyTorch 模型captcha_cnn.pth准确率应该能达到 95%+)

3. 关键一步:导出为 ONNX 模型

这是本文的精髓。假设你已经训练好了 PyTorch 模型,现在我们要把它“固化”成通用的 ONNX 格式。

# 假设 model 是你训练好并加载了权重的模型实例model.eval()# 1. 定义一个样例输入 (Dummy Input),形状必须和训练时一致# [BatchSize, Channels, Height, Width]dummy_input=torch.randn(1,1,HEIGHT,WIDTH).to(device)# 2. 指定导出路径onnx_path="captcha_cnn_v1.onnx"# 3. 执行导出torch.onnx.export(model,# 运行的模型dummy_input,# 模型输入样例onnx_path,# 保存路径export_params=True,# 是否存储权重文件opset_version=11,# ONNX算子版本,推荐11或以上do_constant_folding=True,# 是否执行常量折叠优化input_names=['input_image'],# 输入节点的名称(方便推理时调用)output_names=['output_code'],# 输出节点的名称# 动态轴:允许推理时 Batch Size 可变dynamic_axes={'input_image':{0:'batch_size'},'output_code':{0:'batch_size'}})print(f"Model successfully exported to{onnx_path}")
4. 终极实战:使用 ONNX Runtime 进行推理

在生产环境或爬虫代码中,我们不再需要 PyTorch,只需要安装轻量级的onnxruntime

pipinstallonnxruntime-gpu# 如果有显卡# 或者 pip install onnxruntime

推理代码 (极其简洁):

importonnxruntimeasortimportnumpyasnpimportcv2# 1. 加载 ONNX 模型 (自动选择 GPU 或 CPU)ort_session=ort.InferenceSession("captcha_cnn_v1.onnx",providers=['CUDAExecutionProvider','CPUExecutionProvider'])# 2. 准备输入数据 (假设你从网络下载了一张验证码 target.jpg)# 预处理必须与训练时完全一致!(灰度、大小、归一化)img=cv2.imread("target.jpg",cv2.IMREAD_GRAYSCALE)img=cv2.resize(img,(160,60))img=img.astype(np.float32)/255.0# 增加 Batch 和 Channel 维度: [60, 160] -> [1, 1, 60, 160]input_tensor=np.expand_dims(img,axis=(0,1))# 3. 执行推理# input_image 是我们导出时设置的输入名称ort_inputs={'input_image':input_tensor}# output_code 是我们设置的输出名称ort_outs=ort_session.run(['output_code'],ort_inputs)[0]# 4. 解析结果# ort_outs 形状是 [1, 4, 36]result_indices=np.argmax(ort_outs,axis=2)[0]# 取出概率最大的索引 -> [idx1, idx2, idx3, idx4]CHAR_SET=string.digits+string.ascii_lowercase pred_text="".join([CHAR_SET[i]foriinresult_indices])print(f"AI 识别结果:{pred_text}")

🚀 三、 如何达成 99.9% 的“变态”准确率?

模型结构只是基础,真正的功夫在数据上。如果你想让模型达到商用级别,必须做到:

  1. 数据量级:准备 20万+ 的训练数据。
  2. 针对性训练:所谓“通用”是指架构通用。如果你要攻克某个特定网站,必须采集该网站的真实样本进行微调(Fine-tune)
  3. 数据增强 (Data Augmentation):在训练时实时对图片进行随机旋转、添加噪点、随机遮挡、弹性形变。这能极大提高模型的泛化能力,防止过拟合。
  4. 难例挖掘 (Hard Example Mining):把模型识别错的样本挑出来,重点训练。

⚖️ 免责声明

本文介绍的技术仅供深度学习与计算机视觉研究学习使用。请勿将技术用于任何非法用途(如侵入计算机信息系统、非法采集数据等)。技术的价值在于创造,而非破坏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 17:50:40

xsimd深度解析:现代C++高性能计算的核心技术

xsimd深度解析:现代C高性能计算的核心技术 【免费下载链接】xsimd C wrappers for SIMD intrinsics and parallelized, optimized mathematical functions (SSE, AVX, AVX512, NEON, SVE)) 项目地址: https://gitcode.com/gh_mirrors/xs/xsimd xsimd作为现代…

作者头像 李华
网站建设 2026/4/17 19:41:46

掌握stb单文件库:C/C++开发者的轻量级解决方案

掌握stb单文件库:C/C开发者的轻量级解决方案 【免费下载链接】stb stb single-file public domain libraries for C/C 项目地址: https://gitcode.com/gh_mirrors/st/stb 在C/C开发过程中,你是否曾经为复杂的图像处理库依赖而烦恼?stb…

作者头像 李华
网站建设 2026/4/18 8:02:20

如何用Miniconda创建独立环境避免PyTorch版本冲突?

如何用 Miniconda 创建独立环境避免 PyTorch 版本冲突? 在现代 AI 开发中,一个看似不起眼的问题常常让开发者头疼不已:两个项目,一个依赖 PyTorch 1.12,另一个必须使用 PyTorch 2.0 —— 它们能不能在同一台机器上和平…

作者头像 李华
网站建设 2026/4/19 23:34:14

TMS320C6748的初始化与STM32做个类比

TMS320C6748 (DSP)void UARTConsoleInit(void) {// 1. 使能时钟和电源PSCModuleControl(SOC_PSC_1_REGS, 13, 0, PSC_MDCTL_NEXT_ENABLE);// 2. 配置引脚复用UARTPinMuxSetup(2, FALSE);// 3. 配置UART参数UARTStdioInitExpClk(BAUD_115200, UART_RX_TRIG_LEVEL_1); }STM32 (Co…

作者头像 李华
网站建设 2026/4/18 3:10:48

3分钟搞定PingFang SC Regular字体下载与安装指南

3分钟搞定PingFang SC Regular字体下载与安装指南 【免费下载链接】PingFangSCRegular字体资源下载 探索PingFang SC Regular字体的魅力,这是一套专为现代设计和开发需求打造的中文字体。本资源库提供了多种格式的字体文件,包括eot、otf、svg、ttf和woff…

作者头像 李华
网站建设 2026/4/18 5:53:17

Miniconda创建环境时指定依赖版本范围

Miniconda创建环境时指定依赖版本范围 在机器学习实验室的一次组会上,研究员小李正准备复现一篇顶会论文的实验结果。他按照文档说明安装了所有依赖,却在运行模型训练脚本时遇到了奇怪的错误:torch.nn.Module 居然没有 register_buffer 方法&…

作者头像 李华