vlambda博客
学习文章列表

「CV」End2End搞定变长验证码识别

在上一篇)中介绍召回层常用的效果评估方法。本文将介绍之前做过的变长验证码识别的实验(最近身体不太好,避免断更,就搬出以前写的文章了!祝大家节日快乐)。

预告:

下一篇将聊聊鹅厂的秋招面试流程,感兴趣的同学别忘了点个关注哦!

泛函的范
记录和分享作者在鹅厂搬砖过程中对业务问题的思考和解决方案,以及积累在推荐领域的知识。工作日得搬砖,一般周末更新。关键词:推荐系统、机器学习、经验总结、面试技巧
16篇原创内容
Official Account

传统验证码识别方法主要通过:a)图像预处理、b)字符切割、c)特征提取、d)模型设计与训练、e)模型预测等步骤来实现验证码识别。识别过程被分割成相互独立的子过程,而各子过程在设计过程中无法相互调整,导致很难得到理想识别效果。

不同于传统验证码识别方法,本文尝试采用端到端思想来设计变长验证码的识别模型。该模型能直接识别包含字母(a-z, A-Z)和数字(0-9)的4到8位验证码。模型在1W张测试集中对单个字符识别正确率达到98%以上,全部识别(所有字符均正确识别)准确率达到92.77%,实验结果表明这种简单的端到端模型已经能有效解决验证码识别问题。

识别正确的验证码样例(label-predict):

「CV」End2End搞定变长验证码识别

没有正确识别验证码的样例(label-predict):

「CV」End2End搞定变长验证码识别

变长验证码数据集

为了获取足够多的验证码数据集,我采用Python的Captcha包来自动生成变长验证码数。具体验证码生成器类代码如下

「CV」End2End搞定变长验证码识别

生成的变长验证码样例如下图所示:

「CV」End2End搞定变长验证码识别

本文生成了10W张验证码作为训练和验证集,1W张作为独立的测试集。验证码数据集信息为:

  • 尺寸:
  • 字符集: a-z, A-Z, 0-9
  • 最小长度:4
  • 最大长度:8
  • 训练样本:8w
  • 验证样本:2w
  • 测试样本:1w

传统验证码识别流程

传统验证码识别的基本流程下图所示:

「CV」End2End搞定变长验证码识别

主要包括如下步骤:a) 图像预处理; b) 字符切割; c) 特征提取; d) 模型设计与训练; e) 模型预测。

从流程中可以看到,传统验证码识别的各阶段是相互独立的,比如在特征提取时无法通过特征提取效果来自动调整字符切割算法,在模型训练时也无法调整特征提取算法。

由于各阶段相互独立,前一阶段的效果对后续阶段具有较大影响,这使得传统验证码识别方法在识别较复杂验证码时效果不佳。

为了解决这个问题,我尝试采用深度学习模型来实现验证码的端到端识别,将数据预处理、字符切割、特征提取以及字符识别通过一个网络实现,无需人工干预各阶段的具体过程。

端到端验证码识别模型

下面来介绍端到端验证码识别模型具体设计思路。由于各字符在同一张图片中具有同源数据结构,因此在设计端到端验证码识别模型时采用CNN来构建共享特征提取层。在识别不同位置的字符时,采用全链接层来分别设计相应位置的字符识别层。

在训练过程中,模型根据所有字符数据优化共享特征提取模层权值,依据各字符自身特点(如字符所在位置、字符顺序等)来优化相应的字符识别层权值。模型结构如下图所示:

「CV」End2End搞定变长验证码识别

字符识别层c1c8分别用于识别验证码中第1到8个字符。假设字符识别层c1c8输出为 ,其中 为要识别的字符类别数(本文中验证码类别数为36=26个英文字母+10个数字), 用于表征验证码中该位置是否存在字符从而实现变长验证码识别。训练集数据可以表示为 ,其中 表示高和宽分别为 的RGB验证码图片, 表示验证码中第 个字符码labelone-hot编码,若最后一维为1则表示该位置无字符。模型目标函数如下:

其中 表示第j个字符识别模型的权重,通过调整 可以使模型更关注于识别相应位置的字符。需要说明的是,为了简单起见,本文将权重设为相等,即 。为了方便搭建模型,采用以Tensorflow的Keras来构造模型。与模型对应的主要Python代码如下所示:

「CV」End2End搞定变长验证码识别

实验与结果

采用8W训练样本和2W验证样本来训练模型,最后在1W张验证码构成的测试集中测试模型最终性能。模型在训练集中的loss:

「CV」End2End搞定变长验证码识别

模型下验证集中的loss:

「CV」End2End搞定变长验证码识别

从图中可以看出,各字符识别子模型具有较好的收敛性。

字符识别模型在训练集和测试集上的识别精度(%)如下表所示:

「CV」End2End搞定变长验证码识别

可以看出,模型在训练集和测试集上均具有较好的识别效果。

模型在1W张测试集中所有字符全部正确识别准确率为92.77%,能够有效满足验证码识别准确率的需求。下面给出几种常见的错误识别样例。

  • 数字0和字母O错误识别:

    「CV」End2End搞定变长验证码识别

  • 大写的I(i)和小写的l(L)和数字1错误识别

    「CV」End2End搞定变长验证码识别

  • 字符数识别错误

    「CV」End2End搞定变长验证码识别

  • 其他类型错误

从识别错误类型中可以看出:

  • 第 1 和 2 类错误属于字符本身的相似度,就算人眼也很难将他们区分。
  • 第 3 类将字符数字识别错误的情况极少,在1W 张测试图片中仅出现了一次,主要是由于字符重叠过多,如图中字母 Je过度重叠,导致模型很难正确区分。这也充分说明了我们的端到端识别模型在无需字符分割情况下验证码字符数识别的有效性。
  • 第 4 类其他类型错误主要是模型很难区分经过噪声干扰和形变之后的字符(值得注意的是这些字符就算人也很难轻易区分开)。

总结

从识别结果来看,目前端到端验证码识别模型具有很强的验证码识别能力,单个字符识别 准确率达到 98%以上,且能完全正确识别92.77%以上的字母+数字的验证码。这表明通过设计 端到端的模型能够在不需要任何额外先验信息(如数据预处理、字符切割、特征提取等)情况 下,仅通过样本 label 就够达到较好的识别效果。需要说明的是本文另一目的是给出一种采用 端到端思想解决实际问的思路,通过合理设计网络结构,有效地将数据预处理、特征提取等过 程融合到模型训练中,从而利用大量训练样本有效提升模型的性能。

参考文献

[1] Captcha 包: https://pypi.org/project/captcha/

[2] K. Simonyan, A. Zisserman. Very deep convolutional networks for large-scale image recognition. arXiv preprint arXiv:1409.1556, 2014.

[3] M. Chew, J.D. Tygar. Image recognition captchas. International Conference on Information Security. 268-279, 2004.

[4] F. Chollet, et al. Keras, Github:[https://github.com/keras-team/keras]. 2015.

泛函的范
记录和分享作者在鹅厂搬砖过程中对业务问题的思考和解决方案,以及积累在推荐领域的知识。工作日得搬砖,一般周末更新。关键词:推荐系统、机器学习、经验总结、面试技巧
16篇原创内容
Official Account