上一篇实现softmax,整个网络只有输入层和softmax分类,作者说那不算是神经网络。而这一篇实现多层感知机实际上是在上一篇的网络中,添加了一层隐含层。
首先总结这一章学到的知识点。
一.知识点汇总
1. 稀疏编码:早年学者发现,几乎所有的图像碎片都可以由64种正交的边组合得到,并且组合出一张图像碎片的边的数量是很少的,即稀疏的。学者们同时从大量未标注音频中发现了20种基本结构,绝大多数声音可以由这些基本结构线性组合得到。
特征可以不断抽象,转为高一级的特征。边可以看做成初级特征,碎片可以看做是从初级特征抽象出的高一级特征,往高一级抽象,即可抽象出各种照片。
2. 隐含层:指输入层和输出层以外,中间的那些层。输入层和输出层是可见的,且层的结构是相对固定的,而隐含层结构不固定,相当于不可见。
只要隐含的节点足够多,即是只有一个隐含层的神经网络也可以拟合任意函数。
隐含层层数越多,越容易拟合复杂的函数。拟合复杂函数需要的隐含节点数目随着层数的增多而呈指数下降。
即层数越深,概念越抽象,这就是深度学习。
3. 过拟合:指模型预测准确率在训练集上升高,但在测试集上反而下降。这是模型的泛化性不好,只记住了当前数据的特征。
4. Dropout:防止过拟合的一种方法。将神经网络某一层的输出节点数据随机丢弃一部分。可以理解为是对特征的采样。
5. 优化函数:优化调试网络中的参数。通常,在调参时,学习率的设置会导致最后结果差异很大。神经网络通常不是凸优化,充满局部最优。但,神经网络可能有很多个局部最优都能达到良好效果,反而全局最优容易出现过拟合。
对于SGD,通常一开始学习率大一些,可以快速收敛,但是训练的后期,希望学习率可以小一些,可以比较稳定地落到一个局部最优解。
除了SGD,还有Adagrad、Adam、Adadelta等自适应调节学习率的优化函数。
6. 激活函数:
Sigmoid函数的输出在(0,1),最符合概率输出的定义,但局限性较大。
ReLU,当x<=0时,y=0;当x>0时,y=x。这非常类似于人类的阈值响应机制。ReLU的3个显著特点:单侧抑制;相对宽阔的兴奋边界;稀疏激活性。它是目前最符合实际神经元的模型。
二.Multilayer_perceptron网络结构
在上一篇训练网络的基础上加入了一个300cell的隐含层。
三. 程序解析
# coding: utf-8
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
sess = tf.InteractiveSession()
#输入层cell数量
in_units = 784
#隐含层数量,可以是自定义的,一般比输入层少。
h1_units = 300
#输入层W1的shape从[784, 10]改为[784,300],b1也从10改为300
W1 = tf.Variable(tf.truncated_normal([in_units, h1_units], stddev=0.1))
b1 = tf.Variable(tf.zeros([h1_units]))
W2 = tf.Variable(tf.zeros([h1_units, 10]))
b2 = tf.Variable(tf.zeros([10]))
x = tf.placeholder(tf.float32, [None, in_units])
#dropout的保留百分比,用一个placeholder占位,使其可以自由配置。
#如果keep_prob被设为0.75,那么随机选择75%的节点信息有效,25%的节点的信息丢弃。
keep_prob = tf.placeholder(tf.float32)
#input->hidden采用relu激活。
hidden1 = tf.nn.relu(tf.matmul(x, W1) + b1)
#input->hidden启用dropout
hidden1_dropout = tf.nn.dropout(hidden1, keep_prob)
y = tf.nn.softmax(tf.matmul(hidden1_dropout, W2) + b2)
y_=tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
train_step = tf.train.AdagradOptimizer(0.3).minimize(cross_entropy)
tf.global_variables_initializer().run()
for i in range(3000):
x_batches, y_batches = mnist.train.next_batch(100)
#训练数据、标签、dropout百分比输入。
train_step.run({x:x_batches, y_:y_batches, keep_prob:0.75})
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
#训练时,一般dropout百分比小于1,测试时,一般等于1.
print accuracy.eval({x:mnist.test.images, y_:mnist.test.labels, keep_prob:1.0})