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中黄金分割法实现方法
May 06 Python
python实现的希尔排序算法实例
Jul 01 Python
python中hashlib模块用法示例
Oct 30 Python
Python中对象的引用与复制代码示例
Dec 04 Python
Python使用Phantomjs截屏网页的方法
May 17 Python
python实现烟花小程序
Jan 30 Python
python3编写ThinkPHP命令执行Getshell的方法
Feb 26 Python
python列表生成器迭代器实例解析
Dec 19 Python
python 轮询执行某函数的2种方式
May 03 Python
如何理解Python中的变量
Jun 01 Python
浅谈TensorFlow中读取图像数据的三种方式
Jun 30 Python
聊聊基于pytorch实现Resnet对本地数据集的训练问题
Mar 25 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
解析argc argv在php中的应用
2013/06/24 PHP
Yii获取当前url和域名的方法
2015/06/08 PHP
php关键字仅替换一次的实现函数
2015/10/29 PHP
jQuery中的siblings()是什么意思(推荐)
2016/12/29 Javascript
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
JavaScript继承定义与用法实践分析
2018/05/28 Javascript
Vue动态控制input的disabled属性的方法
2018/06/26 Javascript
小程序视频列表中视频的播放与停止的示例代码
2018/07/20 Javascript
vue 监听屏幕高度的实例
2018/09/05 Javascript
vue + typescript + video.js实现 流媒体播放 视频监控功能
2019/07/07 Javascript
微信小程序调用后台service教程详解
2020/11/06 Javascript
解决vue项目中出现Invalid Host header的问题
2020/11/17 Javascript
Vue 打包的静态文件不能直接运行的原因及解决办法
2020/11/19 Vue.js
对vue生命周期的深入理解
2020/12/03 Vue.js
Python3处理文件中每个词的方法
2015/05/22 Python
详解Python安装scrapy的正确姿势
2018/06/26 Python
浅析Python 实现一个自动化翻译和替换的工具
2019/04/14 Python
使用python判断jpeg图片的完整性实例
2019/06/10 Python
利用Python实现手机短信监控通知的方法
2019/07/22 Python
Python selenium使用autoIT上传附件过程详解
2020/05/26 Python
Manjaro、pip、conda更换国内源的方法
2020/11/17 Python
python 删除系统中的文件(按时间,大小,扩展名)
2020/11/19 Python
日本酒店、民宿、温泉旅馆、当地旅行团中文预订:e路东瀛
2019/12/09 全球购物
全球异乡人的跨境社交电商平台:Kouhigh口嗨网
2020/07/24 全球购物
Python里面search()和match()的区别
2016/09/21 面试题
Java Servlet的主要功能和作用是什么
2014/02/14 面试题
办公室内勤工作职责
2013/12/11 职场文书
五型班组建设方案
2014/02/10 职场文书
化妆师职业生涯规划书
2014/02/16 职场文书
幼儿园保育员岗位职责
2014/04/13 职场文书
2015年宣传部工作总结范文
2015/03/31 职场文书
入党转正申请报告
2015/05/15 职场文书
烈士陵园扫墓感想
2015/08/07 职场文书
课题研究阶段性总结
2015/08/13 职场文书
python实现的人脸识别打卡系统
2021/05/08 Python
WINDOWS下安装mysql 8.x 的方法图文教程
2022/04/19 MySQL