快捷搜索:

百度魅族深度学习大赛初赛冠军作品(图像识别源

  官方提供了10万张图片,我们可以直接使用官方数据进行训练,也可以通过Captcha,参照官方训练集,随机生成更多数据,进而提高准确性。根据题目要求,label 必定是三个数字,两个运算符,一对或没有括号,根据括号规则,只有可能是没括号,左括号和右括号,因此很容易就可以写出数据生成器的代码。

  初赛是非常简单的,因此我们才能得到这么准的分数,之后官方进一步提升了难度,将初赛测试集提高到了20万张,在这个集上我们的模型只能拿到0.999925的成绩,可行的改进方法是将准确率进一步降低,充分训练模型,将多个模型结果融合等。

  我们本地除了会使用官方的准确率作为评估标准以外,还会使用 CTC loss 来评估模型。

  我们可以看到模型先分为四份,在四个显卡上并行计算,然后合并结果,计算最后的 ctc loss,进而训练模型。

  这里我们对生成的数据进行了可视化,可以看到模型基本已经做到万无一失,百发百中。

  文本文件 labels.txt 包含10w行文本,每行文本包含每张图片对应的公式以及公式的计算结果,公式和计算结果之间空格分开,例如图片中的示例图片对应的文本如下所示:

  初赛数据集一共包含10万张180*60的图片和一个labels.txt的文本文件。每张图片包含一个数学运算式,运算式包含:

  官方的评价指标是准确率,初赛只有整数的加减乘运算,所得的结果一定是整数,所以要求序列与运算结果都正确才会判定为正确。

  我们可以看到肉眼基本无法认出这个图,但是经过一定的图像处理,我们可以显现出来它的真实面貌:

  3个运算数:3个0到9的整型数字; 2个运算符:可以是+、-、*,分别代表加法、减法、乘法 0或1对括号:括号可能是0对或者1对

  除了生成算式以外,还有一个值得注意的地方就是初赛所有的减号(也就是“-”)都是细的,但是我们直接用 captcha 库生成图像会得到粗的减号,所以我们修改了 image.py 中的代码,在 _draw_character 函数中我们增加了一句判断,如果是减号,我们就不进行 resize 操作,这样就能防止减号变粗:

  在经过几次测试以后,我已经抛弃了 evaluate 函数,因为在验证集上已经能做到 100% 识别率了,所以只需要看 val_loss 就可以了。在经过之前的几次尝试以后,我发现在有生成器的情况下,训练代数越多越好,因此直接用 adam 跑了50代,每代10万样本,可以看到模型在10代以后基本已经收敛。

  模型结构像之前写的文章一样,只是把卷积核的个数改多了一点,加了一些 BN 层,并且在四卡上做了一点小改动以支持多GPU训练。如果你是单卡,可以直接去掉 base_model2 = make_parallel(base_model, 4) 的代码。

  本次竞赛目的是为了解决一个 OCR 问题,通俗地讲就是实现图像到文字的转换过程。

  图片的名称从0.png到99999.png,下面是一些样例图片(这里只取了一张):

  当然,还有一张图是无法通过预处理得到结果的,142660,这有可能是程序的 bug 造成的小概率事件,所以初赛除了我们跑了一个 docker 得到满分以外,没有第二个人达到满分。

  赛题以识别类似手写体的四则运算式为主题,参赛者需要在充满干扰信息的10万张图片中,设计算法识别图片上数学运算式并计算结果。决赛在初赛的基础上,引入分数和更加复杂的运算,同样以最终的识别率来评判算法。

  打包成 docker 以后提交到比赛系统中,经过十几分钟的运行,我们得到了完美的1分。

您可能还会对下面的文章感兴趣: