zhaipro / easy12306

使用机器学习算法完成对12306验证码的自动识别
Artistic License 2.0
2.89k stars 736 forks source link

好想抛弃百度,让机器仅仅根据验证码本身来学习 #16

Open zhaipro opened 5 years ago

zhaipro commented 5 years ago

巨大而有趣的挑战再次浮出水面

zhaipro commented 5 years ago

大体思路就是仅仅告诉机器我们12306验证码识别的游戏规则。 已知规则:

  1. 一张验证码需要寻找且只寻找一种图片。
  2. 一张验证码中有8张图片。
  3. 一张验证码中至少有1张是要找的图片,最多2张。
  4. 一共有80种图片。

注意我们只是告诉它游戏规则,而它是否答对了,我们也不知道。

zhaipro commented 5 years ago

关键是我们如何定义损失函数呢。 理论上有实现的可能吗?

zhaipro commented 5 years ago

以违反游戏规则来计算损失,例如:

  1. 它说验证码中没有我们要找的图片,我们就给它扣分。
  2. 它说验证码中全是我们要找的图片,我们给它扣分。

但如果它总是说要找打字机,以及前两张就是打字机,我该如何定义这是错误的呢? 定义它答对的可能性。

zhaipro commented 5 years ago

哎,先想办法收集训练集吧。 10K张验证码够用吗?npz文件都1G啦。 最终决定用2K张验证码。

zhaipro commented 5 years ago

绝对的端到端训练

crazydogen commented 5 years ago

你可能需要聚类 或者其他无监督的技术 目前来讲 半监督的技术(需提供部分带标签数据)可能更适合你 此外有趣的是 百度图片搜索文字得到的图片其实就可以充当训练集

crazydogen commented 5 years ago

不如这样 既然文字也是用图片做载体 那么你的网络直接输入有文字的图片和验证码图片 输出值为三项 第一项(0,1) 第二, 三项为具体位置(row: 2; column: 4) 即可 此时为三输出回归 不过可能需要换更强大的统计学家(可参考MobileNet)

zhaipro commented 5 years ago

你可能需要聚类 或者其他无监督的技术 目前来讲 半监督的技术(需提供部分带标签数据)可能更适合你 此外有趣的是 百度图片搜索文字得到的图片其实就可以充当训练集

  1. 之前我有尝试用KMeans算法来分类文字部分,但是效果没有达到我期望的程度(很差,我觉得)。
  2. 我的目标是让机器根据验证码来学习,而不是去对抗验证码。

其它无监督技术我就没有尝试过了。半监督我也想了解了解,甚至听说可以给每个词标注一次就能让机器学得很好。

zhaipro commented 5 years ago

我突然开始觉得,我可能无法抛弃百度,最多叫出师。

zhaipro commented 5 years ago

如果机器说要找的是打字机,而它只要在图片中找到一个打字机我就不给它扣分,如果它不总是重复说其它全是打字机,我还在给它加点分。

loss = sum(p * mul(1 - q, axis=0))

如果一张验证码中80张图片,且各不相同,那我是不是就无法根据验证码学习了呢?

loss = sum((0.25 + p) * mul(1 - q, axis=0)) acc = any(argmax(p) == argmax(q))

其中:p用来表示文字的识别结果,q表示8张图的识别结果。p.shape = 80; q.shape = 8, 80

zhaipro commented 5 years ago

原来概率论是用来定义损失函数的,在深度学习中。

crazydogen commented 5 years ago

12306-outline

这样应该会清楚点,直接改为dual-input, dual classification

zhaipro commented 5 years ago

哇,画的好漂亮,我就不行啦。

我现在的思路差不多,两个输入,文字部分和图片部分(2*4),两个输出,不过都是softmax。重点是损失函数,我们没有标注后的数据集,只有验证码本身,所以我想用违反游戏规则的方式来定义损失函数。

第一个构思已经出来了,不过感觉成功率还是很低的。

嗯,我先去干活了…

zhaipro commented 5 years ago

我不行啦,先降低难度,准备先抛弃相似图搜索算法,目的是学习深度学习。

crazydogen commented 5 years ago

个人理解 目前深度学习的算法需要引入标记数据才有较高精度, 这个task来说有点像两种图片的匹配并输出文字图在验证码图中的位置。 可以理解成将两个图片输入后编码为一个vector 送到后面的fc之类的层,加权平均出一个代表所需信息的vector,然后设计Loss 最小化或者最大化(用梯度下降这类的优化)。如果单依靠验证码不带任何监督信息的话,感觉有点偏向于强化学习的路线了, 设定一个agent 和 env,loss根据你说的游戏规则来定, 这样可能最后结果没有监督学习来的准确。

zhaipro commented 5 years ago

我觉得是,如果提供的信息量太少会导致凸优化很容易收敛到局部最优解,甚至根本找不到路线。 之前让卷积网络直接学习有噪音文字图时,就像是找不到路线一样无法收敛。必须要先根据无噪音图学一遍之后才能进一步学习。

Huangvivi commented 5 years ago

emmm 谷歌搜图提供的数据源与标签的吻合性要比百度的高呀,推荐谷歌

zhaipro commented 5 years ago

主观感受

  1. 给了模型1800*8张图片,虽然数据量跟原来差不多,但信息量不足。想要训练好一个模型就必须提供足够的训练集。
  2. 另外信息密度也差了很多。我想,即使我们提供了足够的信息也没用。
zhaipro commented 5 years ago

哈哈哈555,我又买了强化深度学习相关的书籍。

crazydogen commented 5 years ago

我觉得是,如果提供的信息量太少会导致凸优化很容易收敛到局部最优解,甚至根本找不到路线。 之前让卷积网络直接学习有噪音文字图时,就像是找不到路线一样无法收敛。必须要先根据无噪音图学一遍之后才能进一步学习。

个人经验 不收敛可以尝试增大FC, 相对来说FCNs收敛性不高。 噪声影响我感觉并没有到那么大,我之前做的项目没有单独去噪, 最后结果也是可以看的。

zhaipro commented 5 years ago

啊,并不是噪音本身带来的影响,是因为我没有人工标注,而是借用了相似图搜索。

例如: 只要文字识别器给出的回答在 电子秤,绿豆,蒸笼,风铃,网球拍 这五个标签中,我就算它答对了。

这就给深度学习带来了一定的压力,损失值就是不动。不过让根据无噪音文字图学习后的模型再学就压力降低了,而且最终的效果也非常好。

zhaipro commented 5 years ago

有了新的想法,如果它只会说验证码中让找的是打字机,那下次训练它只要一说要找的是打字机我就给它扣分,看它以后还敢不敢。

期望文字识别结果分散能带动图片识别的结果也分散。

哎,需要深入了解Keras,我就这点需要咋实现呀。

YwEwanHuang commented 4 years ago

自己学找东西, 可以用Reinforcement Learning (RL)了吧

zhaipro commented 3 years ago

一致性约束和同变性约束?