Tensorflow入门2——实现多层感知机

Tensorflow入门——实现多层感知机

  • 推荐阅读入门材料 https://blog.csdn.net/catkin_ws/article/details/96975647
  • 1 多层感知机MLP
  • 2 Tensorflow实现步骤(代码)
    • 2.1 加载MNIST数据集
    • 2.2 隐含层参数初始化
    • 2.3 输入输出
    • 2.4 模型结构、Dropout、Relu
    • 2.5 损失函数和Adagrad优化器
    • 2.6 训练步骤
    • 2.7 准确率评测
    • 2.8 小结
  • 3 拓展
  • 4 代码
  • 5 参考

推荐阅读入门材料 https://blog.csdn.net/catkin_ws/article/details/96975647

1 多层感知机MLP

在上一篇csdn博客中我们使用Tensorflow实现简单的Softmax Regression模型,这个线性模型简单易用,但是拟合能力不强。它和传统意义上的神经网络最大的区别是没有隐含层。

引入非线性的隐含层后,理论上只要隐含节点足够多,即使只有一个隐含层的神经网络也可以拟合任意的函数。同时隐含层数越多,越容易拟合复杂函数。

基本上随着隐含层数量的增多,拟合复杂函数需要的隐含节点的数目就越少(指数趋势)。

MLP(Multi-Layer Perception),即多层感知器,是一种趋向结构的人工神经网络,映射一组输入向量到一组输出向量。MLP可以被看做是一个有向图,由多个节点层组成,每一层全连接到下一层。除了输入节点,每个节点都是一个带有非线性激活函数的神经元(或称处理单元)。一种被称为反向传播算法的监督学习方法常被用来训练MLP。MLP是感知器的推广,克服了感知器无法实现对线性不可分数据识别的缺点。

在使用较深的神经网络时会遇到很多困难

  • 过拟合
  • 参数难以调试
  • 梯度弥散

可以使用许多ticks来解决这些问题,如Dropout、Adagrad、Relu等。

2 Tensorflow实现步骤(代码)

我们使用Tensorflow实现神经网络步骤如下:

  • 定义算法公式,也就是前向传递,神经网络forward的计算
  • 定义loss,选定优化器,并指定优化器优化loss
  • 迭代对数据进行训练
  • 在测试集上对准确率进行评测

接下来我们仅加入一个隐含层,神经网络对MNIST数据集的分类性能就能显著提高到98%的准确率。当然,其中使用了Dropout、Adagrad、Relu等辅助手段。

2.1 加载MNIST数据集

首先载入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

2.2 隐含层参数初始化

接下来对隐含层参数设置进行初始化

  • in_units是输入节点数
  • h1_units是隐含层输出节点数,
  • W1,b1是隐含层的权重和偏置。

偏置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]))

2.3 输入输出

定义样本输入x输出y_:

x = tf.placeholder(tf.float32, [None, in_units])
y_ = tf.placeholder(tf.float32, [None, 10])

2.4 模型结构、Dropout、Relu

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)

2.5 损失函数和Adagrad优化器

定义损失函数和选择优化器来优化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)

2.6 训练步骤

训练过程中,加入了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})

2.7 准确率评测

最后是对模型准确率进行评测,需要注意的是,预测部分,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}))

2.8 小结

最终我们的预测结果达到了98%,相比之前的Softmax,我们的误差率由8%下降到了2%
而这一提升单单加了一个隐含层就实现了,因此可以想象多隐含层的效果将会十分显著
在此过程中我们也使用了一些tricks进行辅助,如Dropout、Adagrad、Relu等。但是起决定性作用的还是隐含层本身,它对特征进行抽象与转化。

3 拓展

  • 没有隐含层的Softmax Regression只能从图像的像素点推断是哪个数字,而没有特征抽象的过程
  • 多层神经网络依靠隐含层,则可以组合出高阶特征,比如横竖撇捺圆圈等,之后可以将高阶特征再组合成数字,就能实现精准的匹配和分类。同时,隐含层的输出可以复用,所以每一个类别的判别、概率输出都共享这些高阶特征,而不是各自连接的独立特征。
  • Tensorflow中,添加新的隐含层和一些辅助手段如Dropout、Adagrad、Relu等,代码没有变化很多,仍然很简洁,没有太多冗余。
  • MLP又可以称为全连接神经网络(fully connected network,FCN),这里使用的隐含层也是有局限的,即便使用很深的网络、很多隐层、很大的迭代次数,也很难在MNIST数据集上达到99%以上的准确率。因此接下里将介绍CNN。

4 代码

# 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

5 参考

1.《TensorFlow 实战》 黄文坚 第四章
2. TensorFlow官方教程
3. github:https://github.com/ShuaiWang-Code/Tensorflow-study/blob/master/Rudiment/MLP.ipynb

你可能感兴趣的:(Python学习,Tensorflow,深度学习)