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爬虫代理IP快速增加博客阅读量
Dec 14 Python
python实现单链表中删除倒数第K个节点的方法
Sep 28 Python
python将控制台输出保存至文件的方法
Jan 07 Python
python中正则表达式与模式匹配
May 07 Python
django框架使用方法详解
Jul 18 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
Sep 20 Python
Python进程,多进程,获取进程id,给子进程传递参数操作示例
Oct 11 Python
python实现KNN分类算法
Oct 16 Python
VSCode中自动为Python文件添加头部注释
Nov 14 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
Aug 28 Python
python 模拟登录B站的示例代码
Dec 15 Python
python数据抓取3种方法总结
Feb 07 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
PHP中文分词 自动获取关键词介绍
2012/11/13 PHP
WordPress中注册菜单与调用菜单的方法详解
2015/12/18 PHP
详解WordPress中提醒安装插件以及隐藏插件的功能实现
2015/12/25 PHP
yii2超好用的日期组件和时间组件
2016/05/05 PHP
php连接微软MSSQL(sql server)完全攻略
2016/11/27 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
js getBoundingClientRect() 来获取页面元素的位置
2010/11/25 Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
2011/03/12 Javascript
使用Javascript接收get传递的值的代码
2011/11/30 Javascript
js编码之encodeURIComponent使用介绍(asp,php)
2012/03/01 Javascript
不使用jquery实现js打字效果示例分享
2014/01/19 Javascript
javascript实现数独解法
2015/03/14 Javascript
JS显示日历和天气的方法
2016/03/01 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
2016/11/07 Javascript
AngularJS Select(选择框)使用详解
2017/01/18 Javascript
使用jQuery实现简单的tab框实例
2017/08/22 jQuery
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
2017/10/20 jQuery
React 无状态组件(Stateless Component) 与高阶组件
2018/08/14 Javascript
vue 循环加载数据并获取第一条记录的方法
2018/09/26 Javascript
快速解决layui弹窗按enter键不停弹窗的问题
2019/09/18 Javascript
使用Vue.set()方法实现响应式修改数组数据步骤
2019/11/09 Javascript
js仿京东放大镜效果
2020/08/09 Javascript
OpenLayers3实现地图鹰眼以及地图比例尺的添加
2020/09/25 Javascript
跟老齐学Python之坑爹的字符编码
2014/09/28 Python
Python中的下划线详解
2015/06/24 Python
详解tensorflow实现迁移学习实例
2018/02/10 Python
python几种常用功能实现代码实例
2019/12/25 Python
Python如何执行精确的浮点数运算
2020/07/31 Python
全球销量第一生发产品:Viviscal
2017/12/21 全球购物
英国电子产品购物网站:Tech in the basket
2019/11/08 全球购物
学校消防安全制度
2014/01/30 职场文书
销售主管竞聘书
2014/03/31 职场文书
垃圾桶标语
2014/06/24 职场文书
2014年教师个人工作总结
2014/11/10 职场文书
golang DNS服务器的简单实现操作
2021/04/30 Golang
关于maven依赖 ${xxx.version}报错问题
2022/01/18 Java/Android