TensorFlow学习笔记(二)深层神经网络
一、深度学习与深层神经网络
深层神经网络是实现“多层非线性变换”的一种方法。
深层神经网络有两个非常重要的特性:深层和非线性。

1.1线性模型的局限性
线性模型:y =wx+b
线性模型的最大特点就是任意线性模型的组合仍然还是线性模型。
如果只通过线性变换,任意层的全连接神经网络和单层神经网络模型的表达能力没有任何的区别,它们都是线性模型。然而线性模型能够解决的问题是有限的。
如果一个问题是线性不可分的,通过线性模型就无法很好的去分类这些问题。
1.2激活函数实现去线性化
神经元的输出为所有输入的加权和,所以整个神经网络就是一个线性模型。如果将每个神经元的输出通过一个激活函数,那么整个神经网络就变成了一个非线性的模型。

几种常用的非线性激活函数及其图像。

TF提供了7中不同的非线性激活函数,relu,sigmod和tanh是其中最常用的。TF还支持使用自己定义的激活函数。

这是一个加入了偏置项和激活函数的网络结构。
那么,怎么用TF实现这个网络结构的前向传播算法呢。
import tensorflow as tf #声明w1,w2 两个变量,通过seed设定随机种子 w1 = tf.Variable(tf.random_normal([2,3],stddev=1.0 ,seed =1 ))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1.0 ,seed =1 ))
bias1 = tf. Variable(tf.random_normal([3,1],stddev=1.0 ,seed =1 ))
bias2 = tf. Variable(tf.random_normal([1,1],stddev=1.0 ,seed =1 ))
#暂时将输入的誊正向量定义为一个常量,这里的X是一个【1,2】矩阵 x = tf.constant([[0.7,0.9]]) #通过前向传播算法得到输出y h = tf.nn.relu( tf.matmul(x,w1)+bias1) y =tf.nn.relu( tf.matmul(h,w2)+bias2)
二 损失函数的定义
神经网络的模型的效果及优化的目标是通过损失函数来定义的。
2.1经典的损失函数
通过神经网络解决多分类问题最常用的方法就是设置n个输出节点,n为类别的个数。神经网络可以得到一个n维数组作为结果输出。数组中的每一个维度对应一个类别。理想情况,如果一个样本属于类别k,那么这个节点对应的维度为1,其他维度为0.如何判断一个输出向量和期望向量有多接近?可以用交叉熵来判断。
交叉熵的公式: 
交叉熵刻画的是两个概率分布之间的距离。将前向计算得到的output经过Softmax优化成一个0~1之间的概率分布。
这样p代表标签值,q代表输出的预测值。
根据公式用TF定义交叉熵的计算图:
cross_entropy = - tf.reduce_mean(y_* tf.log(tf.clip_by_value(y,1e-10,1)))
其中y_表示真实值,y表示模型的预测值。tf.clip_by_value将y的值限制在e^-10 到 1 之间
因为交叉熵损失一般与softmax回归一起使用,所以TF对这两个功能进行了统一的封装,提供了softmax_cross_entropy_with_logits函数
tf.nn.softmax_cross_entropy_with_logits(y,y_)#y代表原始神经网络的预测输出,y_代表标准答案
那么,对于回归问题一般采用什么样的损失函数?
回归问题一般只有一个输出节点,这个节点就是预测值。对于回归问题,最常用的损失函数就是均方误差(MSE),公式如下:

假设一个batch包含n个样本,其中yi是batch中第i个样本的正确答案,yi ‘ 是神经网络输出的预测值。
TF实现MSE:
mse= tf.reduce_mean(tf.square(y_ - y))
均方误差也是分类中一种常用的损失函数。
2.2自定义损失函数
例如我们定义的损失函数为

用TF实现
loss = tf.reduce_mean(tf.select(tf.greater(v1,v2),(v1-v2)*a,(v1-v2)*b))
tf.greater 比较两个张量中的每一个元素大小,返回比较的结果为元素为True或False的张量。
tf.select 有三个参数,第一个参数为选择条件根据。如果第一个参数为true,就选择第二个参数作为返回值,如果为false就选择第三个参数作为返回值。
三、神经网络优化算法
梯度下降算法用于优化参数,反向传播算法是训练神经网络的核心算法。
梯度下降算法存在两个问题:第一,有可能得到的是局部最优解;第二,每一次迭代的时候,需要计算所有训练数据的loss,计算时间太长了。
所有一般采用mini_batch SGD。
用TensorFlow实现神经网络的优化。
一个伪代码
import tensorflow as tf
batch_size = 128
STEPS = 20000
#每次读取一小部分数据作为当前训练数据来进行BP
x = tf.placeholder(tf.float32,shape=(batch_size,2),name="x_input")
y_ = tf.placeholder(tf.float32,shape=(batch_size,1),name="y_input")
#定义神经网络结构和优化算法
loss = tf.nn.sigmoid_cross_entropy_with_logits()
train_step = tf.train.AdamOptimizer(0.01).minimize(loss)
#训练神经网络
with tf.Session() as ss:
#参数初始化
#...
#迭代的更新参数
for i in range(STEPS):
#准备batch_size 个数据
current_x,current_y = (None,None)
ss.run(train_step,feed_dict={x:current_x,y_:current_y})
四、进一步优化神经网络
有了神经网络的基本算法,在训练的过程中还会遇到一些问题。例如学习率怎么设置,怎么解决过拟合等
下面针对几个问题给出解决办法。
4.1学习率的设置
学习率决定了参数每次更新的幅度。如果学习率过大,那么可能导致参数在极优解的周围震荡,学习不到极优解。如果学习率过小,会导致收敛速度太慢。
为了解决学习率的问题,TensorFlow提供了提供了一种更加灵活的学习率设置方法——指数衰减法。tf.train_exponential_decay函数实现了指数衰减学习率。
global_step = tf.Variable(0)
#通过xponential_decay函数生成学习率
learning_rate = tf.train.exponential_decay(0.1,global_step,100,0.96,staircase=True)
#使用指数衰减的学习率,在minimize函数中传入global_step 将自动更新global_step参数,从而使得学习率也得到相应的更新
learning_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
staircase=True时,每训练100轮,学习率乘以0.96
4.2过拟合问题
为了避免过拟合问题,一个非常常用的方法就是正则化。正则化的事项就是在损失函数中加入刻画模型复杂度的指标。常用L1正则化和L2正则化。
w = tf.Variable(tf.random_normal([2,1],stddev=1.0,seed=1.0))
lamda = 0.3
y = tf.matmul(x,w)
#lamda是正则化的惩罚系数
loss = tf.reduce_mean(tf.square(y_-y)+tf.contrib.layers.l2_regularizer(lamda)(w))
通过变量来计算损失函数部署很方便,可以通过TF的集合来保存一组实体。例子如下:
import tensorflow as tf
# 获取一层神经网络的权重,并将其L2正则化损失加入名称为“losses”的集合中
def get_weights(shape,lamda):
#生成变量
var = tf.Variable(tf.random_normal(shape),dtype=tf.float32)
tf.add_to_collection("losses",tf.contrib.layers.regularizar(lamda)(var))
#返回生成的变量
return var
x = tf.placeholder(tf.float32,shape=[None,2])
y_ = tf.placeholder(tf.float32,shape=[None,1])
batch_size = 8
#定义每一次中节点的个数
layer_dimension = [2,10,10,10,1]
#神经网络的层数
n_layer = len(layer_dimension)
#变量维护前向传播是最深层的节点,最开始是输入层
cur_layer = x
#当前层的节点个数
in_dimension = layer_dimension[0] #生成5层全连接网络的结构
for i in range(1,n_layer):
out_diminsion = layer_dimension[i]
weight = get_weights([in_dimension,out_diminsion],0.001)
bias = tf.Variable(tf.constant(0.1,shape=[out_diminsion]))
#使用Relu激活函数
cur_layer = tf.nn.relu(tf.matmul(cur_layer,weight)+bias)
#进入下一层之间将下一层的节点个数更新为当前层的节点个数
in_dimension = layer_dimension[i] mse_loss = tf.reduce_mean(tf.square(y_ - cur_layer))
#将MSE加入损失集合
tf.add_to_collection("losses",mse_loss)
#get_collection 返回一个列表
loss = tf.add(tf.get_collection("losses"))
4.3滑动平均模型
用SGD训练网络时,使用滑动平均模型在很多应用中可以在一定程度提高最终模型在测试数据上的表现。
TF提供了tf.train.ExponentialMovingAverage来实现滑动平均模型。
TensorFlow学习笔记(二)深层神经网络的更多相关文章
- tensorflow学习笔记二:入门基础 好教程 可用
http://www.cnblogs.com/denny402/p/5852083.html tensorflow学习笔记二:入门基础 TensorFlow用张量这种数据结构来表示所有的数据.用一 ...
- Tensorflow学习笔记03-使用神经网络做线性回归
import tensorflow as tf import numpy as np #input就是输入数据,输入矩阵,in_size就是输入矩阵的列数(数据属性数量),out_size输出矩阵列数 ...
- tensorflow学习笔记七----------卷积神经网络
卷积神经网络比神经网络稍微复杂一些,因为其多了一个卷积层(convolutional layer)和池化层(pooling layer). 使用mnist数据集,n个数据,每个数据的像素为28*28* ...
- tensorflow学习笔记二:入门基础
TensorFlow用张量这种数据结构来表示所有的数据.用一阶张量来表示向量,如:v = [1.2, 2.3, 3.5] ,如二阶张量表示矩阵,如:m = [[1, 2, 3], [4, 5, 6], ...
- Tensorflow学习笔记二
现在来开始安装Tensorflow吧 Tensorflow有两种模式, 一种GPU支持, 另外一种仅CPU支持 虚拟机仅有CPU支持, 那就第一种模式吧 有4种途径去安装 virtualenv &qu ...
- tensorflow学习笔记二----------变量
tensorflow里面的变量表示,需要使用特定的语法进行.如果想构造一个行(列)向量,需要调用Variable函数进行.对两个变量进行操作,也要调用相应的函数. import tensorflow ...
- tensorflow学习笔记——自编码器及多层感知器
1,自编码器简介 传统机器学习任务很大程度上依赖于好的特征工程,比如对数值型,日期时间型,种类型等特征的提取.特征工程往往是非常耗时耗力的,在图像,语音和视频中提取到有效的特征就更难了,工程师必须在这 ...
- tensorflow学习笔记——VGGNet
2014年,牛津大学计算机视觉组(Visual Geometry Group)和 Google DeepMind 公司的研究员一起研发了新的深度卷积神经网络:VGGNet ,并取得了ILSVRC201 ...
- tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)
tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...
- TensorFlow学习笔记——LeNet-5(训练自己的数据集)
在之前的TensorFlow学习笔记——图像识别与卷积神经网络(链接:请点击我)中了解了一下经典的卷积神经网络模型LeNet模型.那其实之前学习了别人的代码实现了LeNet网络对MNIST数据集的训练 ...
随机推荐
- 本地运行storm时报错
java.lang.NoClassDefFoundError: backtype/storm/topology/IRichSpout at java.lang.Class.getDeclaredMet ...
- Unix系统编程(六)write系统调用
write系统调用将数据写入一个打开的文件. ssize_t write(int fd, void *buffer, size_t count); write调用的参数含义与read调用相类似.buf ...
- Guardian of Decency UVALive - 3415 最大独立集=结点数-最大匹配数 老师带大学生旅游
/** 题目:Guardian of Decency UVALive - 3415 最大独立集=结点数-最大匹配数 老师带大学生旅游 链接:https://vjudge.net/problem/UVA ...
- java文件对话框操作
完毕文件打开与保存 FileDialog : FileDialog fd = new FileDialog(this); fd.setVisible(true);//或fd.show(); ...
- 关于pom.xml中的MAVEN出错处理
原因:maven与pom的版本不一致 解决方法: 1.升级maven 插件: help--install..... 2.根据出错的信息,找到没有下载成功的本地仓库目录 ,将目录下的文件删除,再在项目上 ...
- String.Join
在指定 String 数组的每个元素之间串联指定的分隔符 String,从而产生单个串联的字符串.(来源于MSDN) 有两个重载函数:[C#]public static string Join( ...
- C++学习之拷贝构造函数篇
一.拷贝构造函数的声明 Array(const Array & arr); 二.拷贝构造函数的实现分为两种,即是深拷贝和浅拷贝. 1.浅拷贝 代码例如以下: class Array { pub ...
- 【python】计算器
from __future__ import division import sys from math import * from PyQt4.QtCore import * from PyQt4. ...
- Linux系统中last命令的用法
1.作用 linux系统中last命令的作用是显示近期用户或终端的登录情况,它的使用权限是所有用户.通过last命令查看该程序的log,管理员可以获知谁曾经或企图连接系统. 2.格式 last [—R ...
- Nginx的安装与基本应用
web服务器软件IIS (windows底下的web服务器软件) Nginx (Linux底下新一代高性能的web服务器) Tengine www.taobao.com 这是淘宝 Apache (Li ...