TensorFlow实现MLP多层感知机模型


Posted in Python onMarch 09, 2018

一、多层感知机简介

Softmax回归可以算是多分类问题logistic回归,它和神经网络的最大区别是没有隐含层。理论上只要隐含节点足够多,即时只有一个隐含层的神经网络也可以拟合任意函数,同时隐含层越多,越容易拟合复杂结构。为了拟合复杂函数需要的隐含节点的数目,基本上随着隐含层的数量增多呈指数下降的趋势,也就是说层数越多,神经网络所需要的隐含节点可以越少。层数越深,概念越抽象,需要背诵的知识点就越少。在实际应用中,深层神经网络会遇到许多困难,如过拟合、参数调试、梯度弥散等。

过拟合是机器学习中的一个常见问题,是指模型预测准确率在训练集上升高,但是在测试集上的准确率反而下降,这通常意味着模型的泛化能力不好,过度拟合了训练集。针对这个问题,Hinton教授团队提出了Dropout的解决办法,在使用CNN训练图像数据时效果尤其有效,其大体思路是在训练时将神经网络某一层的输出节点数据随机丢失一部分。这种做法实质上等于创造出了许多新的随机样本,通过增大样本量、减少特征数量来防止过拟合。

参数调试问题尤其是SGD(StochasticGradient Descent)的参数,对SGD设置不同的学习率learning rate,最后得到的结果可能差异巨大。神经网络的优化通常不是一个简单的凸优化问题,它处处充满了局部最优。有理论表示,神经网络可能有很多个局部最优解都可以达到比较好的分类效果,而全局最优很可能造成过拟合。对SGD,我们希望一开始学习率大一些,加速收敛,在训练的后期又希望学习率小一些,这样可以低速进入一个局部最优解。不同的机器学习问题的学习率设置也需要针对性的调试,像Adagrad、Adam、Adadelta等自适应的方法可以减轻调试参数的负担。对于这些优化算法,通常我们使用其默认的参数设置就可以得到比较好的效果。

梯度弥散(Gradient Vanishment)是另一个影响深层神经网络训练的问题,在ReLU激活函数出现之前,神经网络训练是使用Sigmoid作为激活函数。非线性的Sigmoid函数在信号的特征空间映射上,对中央区的信号增益较大,对两侧区的信号增益小。当神经网络层数较多时,Sigmoid函数在反向传播中梯度值会逐渐减小,到达前面几层的梯度值就变得非常小了,在神经网络训练的时候,前面几层的神经网络参数几乎得不到训练更新。指导ReLU,y = max(0, x),的出现才比较完美的解决了梯度弥散的问题。信号在超过某个阈值时,神经元才会进入兴奋和激活的状态,否则会处于抑制状态。ReLU可以很好的反向传递梯度,经过多层的梯度反向传播,梯度依旧不会大幅减小,因此非常适合深层神经网络的训练。ReLU对比于Sigmoid的主要特点有以下几点:(1)单侧抑制;(2)相对宽阔的兴奋边界;(3)稀疏激活性。目前,ReLU及其变种EIU、PReLU、RReLU已经成为最主流的激活函数。实践中大部分情况下(包括MLP、CNN、RNN)将隐含层的激活函数从Sigmoid替换为ReLU都可以带来训练速度和模型准确率的提升。当然神经网络的输出层一般都是Sigmoid函数,因为它最接近概率输出分布。

二、TensorFlow实现过程

完整代码:

import tensorflow as tf 
from tensorflow.examples.tutorials.mnist import input_data 
 
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 
in_units = 784 #输入节点数 
h1_units = 300 #隐含层节点数 
W1 = tf.Variable(tf.truncated_normal([in_units, h1_units], stddev=0.1)) #初始化隐含层权重W1,服从默认均值为0,标准差为0.1的截断正态分布 
b1 = tf.Variable(tf.zeros([h1_units])) #隐含层偏置b1全部初始化为0 
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) #Dropout失活率 
 
#定义模型结构 
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) 
 
#训练部分 
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) 
 
#定义一个InteractiveSession会话并初始化全部变量 
sess = tf.InteractiveSession() 
tf.global_variables_initializer().run() 
correct_prediction = tf.equal(tf.arg_max(y, 1), tf.arg_max(y_, 1)) 
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 
for i in range(3001): 
  batch_xs, batch_ys = mnist.train.next_batch(100) 
  train_step.run({x: batch_xs, y_: batch_ys, keep_prob: 0.75}) 
  if i % 200 ==0: 
    #训练过程每200步在测试集上验证一下准确率,动态显示训练过程 
    print(i, 'training_arruracy:', accuracy.eval({x: mnist.test.images, y_: mnist.test.labels,  
               keep_prob: 1.0})) 
print('final_accuracy:', accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

在TensorFlow上实现的Softmax回归模型对MNIST数据集取得了92%的正确率,现在我们给神经网络加上一层隐含层,并使用减轻过拟合的Dropout、自适应学习率的Adagrad以及解决梯度弥散问题激活函数ReLU。

首先,载入TensorFlow的并加载MNIST、数据集。指定输入节点数in_units和隐含层节点数h1_units。初始化隐含层的全中W1和偏置b1,因为模型使用的激活函数是ReLU,需要使用正态分布对W1进行初始化,给权重参数增加一些噪声来打破完全对称并避免0梯度。在其它一些模型中,有时还需要给偏置初始化一些非零初始值来避免dead neuron(死亡神经元)。对于输出层Softmax,直接将全中W2和偏置b2全部初始化为0即可。接下来为输入x设置placeholder,并为不同的Dropout设置一个输入placeholder,通常在训练时小于1,预测时等于1。

下面定义模型结构,首先定义一个隐含层hidden1,通过tf.nn.relu(tf.matmul(x,W1) + b1)实现一个激活函数为ReLU的隐含层,这个隐含层的计算公式就是y = relu(W1x + b1)。接下来调用tf.nn.dropout实现Dropout功能,随机将一部分神经元节点置为0,这里的keep_prob参数是保留的数据比例而不是置为0的比例。在训练的时候应该是小于1用以制造随机性,防止过拟合;在预测的时候应该等于1,即全部特征用来预测样本的类别。

在优化器选择上,我们选择Adagrad并把学习率设置为0.3,这里我们直接使用tf.train.AdagradOptimizer(0.3)就可以了。

接下来的训练部分和预测部分以及定义绘画等请参见另一篇博文MNIST在TensorFLow上的Softmax回归模型实现,有详细介绍。

最终,但隐含层MLP模型在测试集上可以达到98%的准确率,相比之前Softmax回归模型的92%的准确率有了飞跃性的提高。

三、其他补充说明

1. tf.truncated_normal

tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32,seed=None, name=None)

函数功能:返回指定形状的服从指定均值和标准差的截断正态分布的tensor。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 图片验证码代码
Dec 07 Python
学习python的几条建议分享
Feb 10 Python
跟老齐学Python之用while来循环
Oct 02 Python
python实现堆和索引堆的代码示例
Mar 19 Python
详解python里的命名规范
Jul 16 Python
Python实现查找最小的k个数示例【两种解法】
Jan 08 Python
对python中list的拷贝与numpy的array的拷贝详解
Jan 29 Python
pycharm工具连接mysql数据库失败问题
Apr 01 Python
在jupyter notebook中调用.ipynb文件方式
Apr 14 Python
python利用递归方法实现求集合的幂集
Sep 07 Python
教你如何用python操作摄像头以及对视频流的处理
Oct 12 Python
pycharm进入时每次都是insert模式的解决方式
Feb 05 Python
TensorFlow实现Softmax回归模型
Mar 09 #Python
用python实现百度翻译的示例代码
Mar 09 #Python
TensorFlow深度学习之卷积神经网络CNN
Mar 09 #Python
TensorFlow实现卷积神经网络CNN
Mar 09 #Python
新手常见6种的python报错及解决方法
Mar 09 #Python
Python 函数基础知识汇总
Mar 09 #Python
Python 使用with上下文实现计时功能
Mar 09 #Python
You might like
Linux下安装oracle客户端并配置php5.3
2014/10/12 PHP
php语言中使用json的技巧及json的实现代码详解
2015/10/27 PHP
浅谈PHP值mysql操作类
2016/06/29 PHP
Avengerls vs KG BO3 第二场2.18
2021/03/10 DOTA
js trim函数 去空格函数与正则集锦
2009/11/20 Javascript
可以将word转成html的js代码
2010/04/11 Javascript
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
jquery 插件学习(一)
2012/08/06 Javascript
js解决弹窗问题实现班级跳转DIV示例
2014/01/06 Javascript
jquery、js操作checkbox全选反选
2014/03/12 Javascript
node.js适合游戏后台开发吗?
2014/09/03 Javascript
jquery简单的弹出层浮动层代码
2015/04/27 Javascript
Bootstrap Chart组件使用教程
2016/04/28 Javascript
原生js封装的一些jquery方法(详解)
2016/09/20 Javascript
easyui 中的datagrid跨页勾选问题的实现方法
2017/01/18 Javascript
Vue声明式渲染详解
2017/05/17 Javascript
Node.js服务器开启Gzip压缩教程
2017/08/11 Javascript
初识 Vue.js 中的 *.Vue文件
2017/11/22 Javascript
nodeJS模块简单用法示例
2018/04/21 NodeJs
promise和co搭配生成器函数方式解决js代码异步流程的比较
2018/05/25 Javascript
深度了解vue.js中hooks的相关知识
2019/06/14 Javascript
vue计算属性无法监听到数组内部变化的解决方案
2019/11/06 Javascript
微信小程序登录时如何获取input框中的内容
2019/12/04 Javascript
toString.call()通用的判断数据类型方法示例
2020/08/28 Javascript
python设置随机种子实例讲解
2019/09/12 Python
Anaconda+Pycharm环境下的PyTorch配置方法
2020/03/13 Python
利用HTML5 Canvas API绘制矩形的超级攻略
2016/03/21 HTML / CSS
美体小铺美国官网:The Body Shop美国
2017/11/10 全球购物
房地产管理毕业生自荐信
2013/11/04 职场文书
土木工程个人自荐信范文
2013/11/30 职场文书
部队学习十八大感言
2014/01/11 职场文书
协议书模板
2014/04/23 职场文书
2015年教师节活动总结
2015/03/20 职场文书
2015年教师业务工作总结
2015/05/26 职场文书
详解python的异常捕获
2022/03/03 Python
Win11黑色桌面背景怎么办?Win11黑色壁纸解决方法汇总
2022/04/05 数码科技