赞
踩
4 本文工作
解释了原作者代码注释中提到的关于sigmoid选型的困惑问题并应用到代码中
将原作者的代码进行模块工程化,成为整体项目,方便研究的同学直接进行模式套用
原作者代码中:
def train_crack_captcha_cnn():
output = crack_captcha_cnn()
# loss
#loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output, Y))
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output, labels=Y))
# 最后一层用来分类的softmax和sigmoid有什么不同?
# optimizer 为了加快训练 learning_rate应该开始大,然后慢慢衰
optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
……
作者在代码的注释中出提出了这样的疑问:
对 softmax 和 sigmoid 的使用方式有疑问。
然后在文章下面读者评论区也都提到了此问题,在此进行整体解释一下。
原文中CNN的输出的维度是 MAX_CAPTCHA*CHAR_SET_LEN ,其实这些维度并不都是完全独立分布的, 但是使用sigmoid loss也是仍然可以的,相当于先用sigmoid进行了一次归一化,然后再将各个维度的值向目标值进行 回归 , 最后loss越小,两个向量的对应的值也越接近。 其实sigmoid是可以看成是一个多分类的问题,在这个例子上也能起到比较好的收敛效果。
当然,关于分类的问题,看所有的机器学习框架里面,都是建议使用softmax进行最后的归一化操作,这其实相当于是一种 马太效应 : 让可能性大的分类的值变得更大,让可能性小的分量值变得更小。但是这有个前提,就是参与到softmax运算的一组数据,必须是 相关联 的, 所以如果要使用 softmax_cross_entropy_with_logits ,只需要将网络进行简单修改即可。把输出的维度做成二维[MAX_CAPTCHA, CHAR_SET_LEN], 然后使用softmax loss。
output = crack_captcha_cnn()#36×4
predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]) # 36行,4列
label = tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN])
最后使用GPU训练的实验结果对比:
sigmoid方式。训练6000个step就能达到95%的准确率。
softmax方式。训练8千个step,达到90%的准确率;训练8万个step,达到94.7%(跑了大半天)
使用tensorboard对accuracy进行监控:
sigmoid-6千个step:
softmax-8千个step:
softmax-8万个step:
整体来说,在这个例子里面,好像 sigmoid的收敛速度快些,当然这个可能是本项目里面的外界因素有利于sigmoid吧,至于具体原因,等后续再进行研究和解释吧,当然有可能根本解释不了,因为对于CNN,目前主流的意见都是:,反正效果就是好,但是不知道为啥, 科幻得近于玄幻 的一种技术。
github源码地址:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。