Image source: unsplash.com by Sergey Pesterev
上一篇文章中,我们用Tensorflow搭建了单层神经网络,该网络对MNIST手写识别率能到达90%。如何进一步提高识别率呢?Let’s go deeper, 搭建更多层的神经网络吧。
同样的,为了方便与读者交流,所有的代码都放在了这里:
Repository:
https://github.com/zht007/tensorflow-practice
1. 初始化W和B
权重(Weight)W和偏置(Bias)B的shape,是由每一层神经元的个数决定的,输出层的神经元个数保证与Class的数量一致(10个),输入层和隐藏层的神经元数目是没有固定的要求的。
多层神经网络实际上就像是在单层神经网络的基础上”叠蛋糕”。这里我们设计5层的神经网络,神经元个数从输入到输出分别为200,100,60,30和10个。
1 | L = 200 |
同样的,首先初始化每一层的权重和偏置。注意这里使用tf.truncated_normal方法随机初始化W。偏置B要尽量选择一个较小的非零数值来初始化,以适应激活函数RELU最有效区间。
1 | W1 = tf.Variable(tf.truncated_normal([784, L], stddev=0.1)) # 784 = 28 * 28 |
2. 搭建神经网络
搭建神经网络类似于”叠蛋糕”,copy&paste输出层就好了,与输出层不同的是,在输入层和隐藏层中,我们用了比较流行的RELU激活函数。当然,输入层不要忘了Reshape。
1 | XX = tf.reshape(X,[-1,784]) |
Optimizer的选择已经神经网络的训练与单层神经网络没有任何区别,这里就不讨论了,感兴趣的朋友可以去查看源码,接下来我们来看看这个5层神经网络的表现吧。
3. 识别效果
我们用Adam的优化器,0.005的学习速率,100的batch_size,训练了20000个Iteration。最后我们发现训练组的准确率几乎能达到100%,但是验证组的的准确率却始终在97%附件徘徊
1 | Iteration 19900: loss_train=0.000003: loss_val=0.128829: acc_train=1.000000: acc_val=0.978571 |
是的,这就是深度学习典型的overfitting问题。
4. 可变学习速率
学习速率决定了梯度下降过程中所迈的步子的大小。可以想象,如果迈的步子太大很有可能一步就跨过了最优点,最后只能在最优点附近不停地徘徊;如果步子迈得太小,下降速度又会太慢,会浪费很多训练时间。
学习速率如果可以改变,就能解决这个问题。我们可以在初始的Iteration中选择比较大的学习速率,之后逐渐减小,这就是Learning Rate Decay.
当然我们这里要增加两个palceholder,一个用来存放训练速率,另一个用来存储当前的步数(literation数) ,并最后在Seesion中通过 feed_dict 传到训练中去。
1 | lr = tf.placeholder(tf.float32) |
Tensorflow 提供Learning rate decay的方法,这个表示训练速率随着Iteration的增加从0.003一指数形式下降到0.0001。
1 | lr = 0.0001 + tf.train.exponetial_decay(0.003, step, 2000, 1/math.e) |
5. Dropout
对付overfitting,我们可以在训练中Dropout掉一定的神经元。在Tensorflow中使用Dropout只需要在相应层中”增加”一个Dropout层。
比如第四层
1 | Y4 = tf.nn.relu(tf.matmul(Y3d, W4) + B4) |
注意在验证的时候,drop rate要设置为0
加上learning rate decay 和 dropout之后的训练sesssion如下
1 | history = {'acc_train':list(),'acc_val':list(), |
6. 训练效果
可以看到通过dropout 和 learning rate decay 之后,神经网络对MNIST手写数字的识别率已经能提高到98%了,如何进一步提高识别率呢?我们就必须会引入卷积神经网络了。
参考资料
https://www.kaggle.com/c/digit-recognizer/data
https://codelabs.developers.google.com/codelabs/cloud-tensorflow-mnist/#0
https://www.tensorflow.org/api_docs/
相关文章
Tensorflow入门——单层神经网络识别MNIST手写数字
Tensorflow入门——分类问题cross_entropy的选择
同步到我的简书和Steemit