ypwhs / captcha_break

验证码识别
MIT License
2.72k stars 685 forks source link

你好,cnn模型不加BN层不收敛 #16

Open chrisyoung2017 opened 6 years ago

chrisyoung2017 commented 6 years ago

你好,我使用你的cnn模型时并不能收敛,loss越来越高。我加了BN解决了问题,但是我不太明白为什么一定需要加BN。 此外,我发现在使用ImageCaptcha生成验证码的时候,当使用单一字体验证码时,模型能够很好的学习,但我使用20种不同字体去生成验证码,训练集能够很好的学习,但是验证集一直的loss一直没有下降,样本数量30000,这种过拟合的情况需要怎么解决呢?谢谢。

ypwhs commented 6 years ago

可能是因为图像是 0~255的范围,所以要加 BN。

ypwhs commented 6 years ago

我使用过很多字体去生成数据,训练集和验证集的表现是接近的。

chrisyoung2017 commented 6 years ago

请问 “我使用过很多字体去生成数据,训练集和验证集的表现是接近的。” 这里的很多字体去训练,是每次训练和测试用的是同一字体生成的数据集是吗?我想知道能否混合多种字体一起训练。 因为我遇到的问题是训练集25000张验证码(每种字体大约1300张),然后固定切分5000张做验证集(每种字体大约250张)。在这个数据集下,模型能很好在训练集收敛,但是训练出来的模型目前看来只能记住训练集那部分的样本,对和训练集同种方式生成的验证码却不能识别。因为算力有限,我也不确定继续加大验证码的样本集会不会work。感谢回复,祝好。

ouyangde commented 6 years ago

我之前做过一个,能识别不定长的最大10位数字验证码,也是用ImageCaptcha生成验证码的。经验就是不限制训练集数量;结构合理的情况下,最终一定会收敛。因为本来就没有限制训练集,收敛后对新样本的识别率不会有变化。

ypwhs commented 6 years ago

@tmpacc1 不是的,是按图片随机字体的混合训练,具体你可以参考这个地址:https://github.com/ypwhs/baiduyun_deeplearning_competition

chrisyoung2017 commented 6 years ago

@ypwhs 可能我没表述清楚我的问题,我看到你的代码中都是这么写的,并没有定义fonts参数。 generator = ImageCaptcha(width=width, height=height) 其中ImageCaptcha类是如下定义的

class ImageCaptcha(_Captcha): """Create an image CAPTCHA. 省略一些注释 """ def init(self, width=160, height=60, fonts=None, font_sizes=None): self._width = width self._height = height self._fonts = fonts or DEFAULT_FONTS self._font_sizes = font_sizes or (42, 50, 56) self._truefonts = []

缺省了fonts参数后直接用的是DroidSansMono.ttf字体的验证码 DEFAULT_FONTS = [os.path.join(DATA_DIR, 'DroidSansMono.ttf')] 我现在假设真实场景是有20种不同字体的验证码,这个时候在用你的模型就只能在训练集上收敛,在验证集完全没学到,我想弄明白这个有没有什么解决方案?感谢耐心的回答。

ypwhs commented 6 years ago

https://github.com/ypwhs/baiduyun_deeplearning_competition/blob/master/初赛代码/四则混合运算识别%20深度学习应用大赛3.ipynb

oneoy commented 6 years ago

我怎么看不懂cnn.ipynb文件里的代码呢 有直接改好的.py文件吗

kwaneGX commented 5 years ago

请问怎么设置不同的字体,怎么修改呢?

LIMU2 commented 5 years ago

您好,请问怎么加入BN层,初学,不太懂,loss一直不收敛

oloeye commented 5 years ago

您好,请问怎么加入BN层,初学,不太懂,loss一直不收敛

主要是图片的数据是 0~255,在梯度进行更新时候,loss = (y - wx+b)^2,当 输入 x 比较大的时候,那么w就需要变化很小范围就可以达到最优的权重,但是当输入的 x 比较小时候,那么 w 需要更新比较大的范围达到最优解。(注意:初始化 权重 的时候,几乎所有权重都是接近的 )更新梯度的学习率是几乎不变,那么对于当输入的 x 比较小时候,需要很长时间来更新 w,所以你会看到很久没有收敛。如果进行 BN, 那么输入对更新 w 的影响都一样,所以比较快收敛。BN 层一般都是加在输入前,或者在激活函数前。

ypwhs commented 5 years ago

2019 年更新的代码已经添加了预处理,所有的图片都是以 [0, 1] 的浮点数输入到模型中。另外每一层 Conv 后面都加了 BN,既能在一定程度上防止过拟合问题,又极大加速了模型的训练。