一、深度学习与深层神经网络

深层神经网络是实现“多层非线性变换”的一种方法。

深层神经网络有两个非常重要的特性:深层和非线性。

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学习笔记(二)深层神经网络的更多相关文章

  1. tensorflow学习笔记二:入门基础 好教程 可用

    http://www.cnblogs.com/denny402/p/5852083.html tensorflow学习笔记二:入门基础   TensorFlow用张量这种数据结构来表示所有的数据.用一 ...

  2. Tensorflow学习笔记03-使用神经网络做线性回归

    import tensorflow as tf import numpy as np #input就是输入数据,输入矩阵,in_size就是输入矩阵的列数(数据属性数量),out_size输出矩阵列数 ...

  3. tensorflow学习笔记七----------卷积神经网络

    卷积神经网络比神经网络稍微复杂一些,因为其多了一个卷积层(convolutional layer)和池化层(pooling layer). 使用mnist数据集,n个数据,每个数据的像素为28*28* ...

  4. tensorflow学习笔记二:入门基础

    TensorFlow用张量这种数据结构来表示所有的数据.用一阶张量来表示向量,如:v = [1.2, 2.3, 3.5] ,如二阶张量表示矩阵,如:m = [[1, 2, 3], [4, 5, 6], ...

  5. Tensorflow学习笔记二

    现在来开始安装Tensorflow吧 Tensorflow有两种模式, 一种GPU支持, 另外一种仅CPU支持 虚拟机仅有CPU支持, 那就第一种模式吧 有4种途径去安装 virtualenv &qu ...

  6. tensorflow学习笔记二----------变量

    tensorflow里面的变量表示,需要使用特定的语法进行.如果想构造一个行(列)向量,需要调用Variable函数进行.对两个变量进行操作,也要调用相应的函数. import tensorflow ...

  7. tensorflow学习笔记——自编码器及多层感知器

    1,自编码器简介 传统机器学习任务很大程度上依赖于好的特征工程,比如对数值型,日期时间型,种类型等特征的提取.特征工程往往是非常耗时耗力的,在图像,语音和视频中提取到有效的特征就更难了,工程师必须在这 ...

  8. tensorflow学习笔记——VGGNet

    2014年,牛津大学计算机视觉组(Visual Geometry Group)和 Google DeepMind 公司的研究员一起研发了新的深度卷积神经网络:VGGNet ,并取得了ILSVRC201 ...

  9. tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)

    tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...

  10. TensorFlow学习笔记——LeNet-5(训练自己的数据集)

    在之前的TensorFlow学习笔记——图像识别与卷积神经网络(链接:请点击我)中了解了一下经典的卷积神经网络模型LeNet模型.那其实之前学习了别人的代码实现了LeNet网络对MNIST数据集的训练 ...

随机推荐

  1. JAVA设置HttpOnly Cookies

    HttpOnly Cookies是一个cookie安全行的解决方案. 在支持HttpOnly cookies的浏览器中(IE6+,FF3.0+),如果在Cookie中设置了"HttpOnly ...

  2. Oracle常用命令大全

    一.ORACLE的启动和关闭 1.在单机环境下 要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下 su - oracle a.启动ORACLE系统 oracle>svrmgrl ...

  3. struts2中,OGNL访问值栈的时候查找的顺序是什么?请排序:模型对象、临时对象、固定名称的对象、Action对象

    struts2中,OGNL访问值栈的时候查找的顺序是什么?请排序:模型对象.临时对象.固定名称的对象.Action对象 解答:struts2的值栈排列顺序为:1).临时对象:2).模型对象:3).Ac ...

  4. windows下解决mysql忘记password

    windows下解决mysql忘记password   mysql有时候忘记password了怎么办?我给出案例和说明!一下就攻克了!    Windows下的实际操作例如以下    1.关闭正在执行 ...

  5. jqgrid的search

    2015-04-19 本人近期的博客都是和之前的随笔相关联的. 今天想和大家分享的是jqgrid中的search. 相信大家写代码用到jqgrid的时候都可能会在jqgrid中涉及查询,其实查询和 增 ...

  6. PANDAS 数据合并与重塑(join/merge篇)

    pandas中也常常用到的join 和merge方法 merge pandas的merge方法提供了一种类似于SQL的内存链接操作,官网文档提到它的性能会比其他开源语言的数据操作(例如R)要高效. 和 ...

  7. C#实现动态编译代码

    /*------------------------------------------------------------------------------ * Copyright (C) 201 ...

  8. Adapter适配器 final int Id 导致选中的Item不在当前界面

    写了上面这么一个横向混动,点击切换到,哪个的Item上就会有一个  常用  的小图标.但是我每次滑动切换到后面   成龙9这个Item,这个 常用的图片,也在 这个上面了,但是他一更新,就变成 等你再 ...

  9. EF 更新操作 lambda解释+=

    我曾写过一个EF批量更新.删除的博客,后来操作的过程中经常遇到更新字段,但是要在原来的基础上计算的情况,我就先去获取一遍数据然后再计算,最后再去更新,显然这个操作是很复杂的 var guest = d ...

  10. javajava持有对象(容器类)

    数组是固定的长度去保存对象,还有一些集合类如基本的List.Set.Quene.Map可以存储不固定长度的对象.