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

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

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

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. python 练习题练习题2--多分支选择

    题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:20万到40万之 ...

  2. 【活动】上线了|带你直击react年度盛会

    明后两天,ReactEurope 2016大会在巴黎举行,本次大会演讲主题有: React Native(动画及运行性能优化) Flux-like 数据架构(GraphQL 最佳实践与展望.Redux ...

  3. 使用AccessibilityService实现微信自己主动抢红包

    近期要实现微信自己主动抢红包的功能.使用AccessibilityService来开发,这里主要写一下逻辑以及注意点. 注意点 1.搜索keyword 我们实现某个功能比方点击等须要找到相应的对象然后 ...

  4. tomcat修改默认端口

    1.webserver: tomcat2.version:   Apache Tomcat/7.0.293.operation: 修改默认端口 3.1 修改tomcat目录下的/conf/server ...

  5. win10执行shell脚本

    我们在win10如何执行以.sh文件的脚本呢? 开发步骤:1.写脚本b2q_goods.sh #!/bin/bashsql="select * from b2q.goods where go ...

  6. 蓝桥杯 第四届C/C++预赛真题(1) 高斯日记(数学题,年份处理)

    题目标题: 高斯日记 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯 ...

  7. Extjs4 中date时间格式的问题

    在Grid中显示时间,后台传过来的是date格式的数据(PHP date('Y-m-d', time()),一般在Ext model中定义数据的类型和格式: {name:'birth', type:' ...

  8. trait优先级 与 使用

    之前一直沒有讲到trait,在此我不得不提一下trait中的优先级: 在trait继承中,优先顺序依次是:来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法. For e ...

  9. Ubuntu14.04编译Android5.1.1源码

    1.Ubuntu环境配置 硬盘:120G 内存:4G 注:配置很重要,直接影响能否编译成功. 2.安装JDK sudo apt-get update sudo apt-get install open ...

  10. js封装日历控件

    最终效果 代码实现 <script> $(function () { $(".j-calendar").calendar({ date: '2017-08-03', c ...