在上一篇csdn博客中我们使用Tensorflow实现简单的Softmax Regression模型,这个线性模型简单易用,但是拟合能力不强。它和传统意义上的神经网络最大的区别是没有隐含层。
引入非线性的隐含层后,理论上只要隐含节点足够多,即使只有一个隐含层的神经网络也可以拟合任意的函数。同时隐含层数越多,越容易拟合复杂函数。
基本上随着隐含层数量的增多,拟合复杂函数需要的隐含节点的数目就越少(指数趋势)。
MLP(Multi-Layer Perception),即多层感知器,是一种趋向结构的人工神经网络,映射一组输入向量到一组输出向量。MLP可以被看做是一个有向图,由多个节点层组成,每一层全连接到下一层。除了输入节点,每个节点都是一个带有非线性激活函数的神经元(或称处理单元)。一种被称为反向传播算法的监督学习方法常被用来训练MLP。MLP是感知器的推广,克服了感知器无法实现对线性不可分数据识别的缺点。
在使用较深的神经网络时会遇到很多困难:
可以使用许多ticks来解决这些问题,如Dropout、Adagrad、Relu等。
我们使用Tensorflow实现神经网络步骤如下:
接下来我们仅加入一个隐含层,神经网络对MNIST数据集的分类性能就能显著提高到98%的准确率。当然,其中使用了Dropout、Adagrad、Relu等辅助手段。
首先载入Tensorflow和加载MNIST数据集,创建Tensorflow默认的Interactive Session:
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()
tf.Session()和tf.InteractiveSession()区别在于,后者加载自身作为默认的Session
接下来对隐含层参数设置进行初始化
偏置b1全设为0,权重W1设置为截断的正态分布,标准差为0.1(第三行程序)。
而对于最后的输出层Softmax,直接将权重W2和偏置b2全部初始化为0即可。
in_units = 784
h1_units = 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输出y_:
x = tf.placeholder(tf.float32, [None, in_units])
y_ = tf.placeholder(tf.float32, [None, 10])
Dropout比率keep_prob(保留节点的概率)通常在训练时小于1,在预测时等于1,所以吧它也作为计算图的输入,定义成placeholder。
keep_prob = tf.placeholder(tf.float32)
定义模型结构:
首选定义隐含层hadden1,实现一个激活函数为Relu1的隐含层。
接下来调用dropout,用以制造随机,防止过拟合。 而在预测时,该参数应为1,即,使用全部特征Kauai预测样本的类别。
最后是输出层,Softmax。
hidden1 = tf.nn.relu(tf.matmul(x, W1) + b1)
hidden1_drop = tf.nn.dropout(hidden1, keep_prob)
y = tf.nn.softmax(tf.matmul(hidden1_drop, W2) + b2)
定义损失函数和选择优化器来优化loss,这里损失函数继续使用 交叉信息熵,和前一篇博客内容一致,但是优化器选择自适应优化器Adagrad,并把学习速率设为0.3。
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)
训练过程中,加入了keep_prob作为计算图的输入,并且在训练时设为0.75,即保留75%的节点,其余25%为0.一般来说,对越复杂的网络,dropout效果越显著。另外,因为加入了隐含层,我们需要更多的训练迭代来优化模型参数。
一共采用3000个batch,每个batch100个样本,一共30W样本,相当于对全数据集进行了5轮(epoch)迭代。
# Train
tf.global_variables_initializer().run()
for i in range(3000):
batch_xs, batch_ys = mnist.train.next_batch(100)
train_step.run({x: batch_xs, y_: batch_ys, keep_prob: 0.75})
最后是对模型准确率进行评测,需要注意的是,预测部分,keep_prob=1,可以是模型预测达到最好的预测结果。
# Test trained model
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
最终我们的预测结果达到了98%,相比之前的Softmax,我们的误差率由8%下降到了2%
而这一提升单单加了一个隐含层就实现了,因此可以想象多隐含层的效果将会十分显著。
在此过程中我们也使用了一些tricks进行辅助,如Dropout、Adagrad、Relu等。但是起决定性作用的还是隐含层本身,它对特征进行抽象与转化。
# Create the model
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()
in_units = 784
h1_units = 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])
keep_prob = tf.placeholder(tf.float32)
hidden1 = tf.nn.relu(tf.matmul(x, W1) + b1)
hidden1_drop = tf.nn.dropout(hidden1, keep_prob)
y = tf.nn.softmax(tf.matmul(hidden1_drop, W2) + b2)
# Define loss and optimizer
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)
# Train
tf.global_variables_initializer().run()
for i in range(3000):
batch_xs, batch_ys = mnist.train.next_batch(100)
train_step.run({x: batch_xs, y_: batch_ys, keep_prob: 0.75})
# Test trained model
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
运行结果:
0.9795
1.《TensorFlow 实战》 黄文坚 第四章
2. TensorFlow官方教程
3. github:https://github.com/ShuaiWang-Code/Tensorflow-study/blob/master/Rudiment/MLP.ipynb