导图社区 《TensorFlow实战Google深度学习框架》
第三章~第四章;TensorFlow入门和深层神经网络
编辑于2019-08-30 14:50:10TensorFlow基础知识(一)
计算图 Graph
基本概念
节点
运算节点
1. Tensorflow中所有的计算都会被自动转化为计算图上的节点
变量、常量节点
边
每一条边代表了计算之间的依赖关系
功能
隔离张量和计算
不同计算图上的张量和运算都不会共享
提供计算机制
tf.Graph.device函数来指定运算计算的设备-GPU机制
生成新的计算图
得到默认的计算图
tf.get_default_graph()
定义新的计算图
tf.Graph()
资源管理
资源类型:张量、变量、运行tensorflow程序所需要的队列资源
在一个计算图中,通过集合Collection来管理不同类别的资源
将资源加入集合
tf.add_to_collection
从集合中获取资源
tf.get_collection
常用集合
所有变量
tf.GraphKeys.VARIABLES
持久化TensorFlow模型
可学习的变量(一般指神经网络中的参数)
tf.GraphKeys.TRAINABLE_VARIABLES
模型训练、生成模型可视化内容
日志生成相关的变量
tf.GraphKeys.SUMMARIES
TensorFlow计算可视化
处理输入的QueueRunner
tf.GraphKeys.QUEUE_RUNNERS
输入处理
所有计算了滑动平均值的变量
tf.GraphKeys.MOVING_AVERAGE_VARIABLES
计算变量的滑动平均值
张量Tensor
简介
张量是TensorFlow管理数据的形式,多维数组结构
张量的结构
属性名字-name
张量的唯一标识符
张量的维度-shape
可更改,validate_shape=False
类型-dtype
每一个张量只要一种数据类型
通过dtype来明确指定变量或常量的类型
张量与Numpy的区别
在张量中不保存数字,而是对运算结构它保存的是如何得到这些数字的计算过程,即保存的是一个结构;如果要得到计算结果,运行session得到
print('result')Tensor("add:0",shape=(2,),dtype=float32)
Numpy保存数字
张量的用途
对中间计算结果的引用(包括生成常量函数的引用)
张量可以用来获得计算结果
张量本身不存储具体数字,但是通过会话就可以计算得到具体的数字
第一阶段:定义计算图中所有的计算
会话Session
简介
会话拥有并管理Tensorflow程序运行时的所有资源
所有计算完成后需要关闭会话来帮助系统回收资源,否则可能会出现资源泄露的问题
创建会话的两种模式
显示调用会话生成函数和关闭函数
sess = tf.Session()sess.run(result)sess.close()
Python上下文来管理会话
with tf.Session() as sess: sess.run(...)
会话机制
Tensorflow不会生成默认的会话,需要手动指定。
sess = tf.Session()with sess.as_default() print(result.eval())
当默认的会话被指定后,可以通过tf.Tensor.eval()来计算一个张量的取值
原来获取值的方式
sess.run(result)
现在获取值的方式
result.eval() 或result.eval(session=sess)
Tips
通过设置默认会话的方式来获取张量的取值更加方便
直接构建默认会话的函数
tf.InteractiveSession()
使用这个函数会自动讲生成的会话注册为默认会话
配置会话
ConfigProto Protocol Buffer
配置参数
运算超时时间
GPU分配策略
并行的线程数
常用案例
config = tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)sess1 = tf.InteractiveSession(config=config)|sess2 = tf.Session(config=config)
allow_soft_placement=True增强移植性
log_device_placement=True记录每个节点安排的设备
第二阶段:执行计算
TensorFlow程序运行的两个阶段:第一阶段:定义计算图中的所有运算第二阶段:运行计算
变量声明函数-tf.Variable
作用
保存和更新神经网络中的参数
声明定义变量的初始化方法
虽然在变量定义时给出了变量初始化的方法,但这个方法并没有被真正运行
随机值初始化
tf.random_normal()
正态分布,参数:平均值、标准差、取值范围;
tf.truncated_normal()
正态分布(如果随机初始出来的值的平均超过两个标准差,会重新分配),参数:平均值、标准差、取值范围;
tf.random_uniform()
均匀分布
参数:最大值、最小值、取值类型
tf.random_gamma()
伽马分布
常数初始化
tf.zeros
产生全0的数组
tf.ones
产生全1的数组
tf.fill
产生一个全部为给定数字的数组
tf.constant
产生一个给定值的常量
其他变量的初始值初始化
在TensorFlow中,一个变量的值在被使用前,这个变量的初始化过程必须被明确的声明
执行变量的初始化方法
执行单个变量的初始化方法
sess.run(var.initializer)
执行所有变量的初始化方法
init_op=tf.global_variables_initializer()sess.run(init_op)
变量使用的两个步骤
张量与变量
在TensorFlow 中,变量的声明函数tf.Variable()函数是一个运算。这个运算的输出结果就是一个张量。
集合Collection-变量管理
简介
所有的变量都会被自动地加入到GraphKeys.VARAIBLES这个集合中
获取变量
获取全部变量
tf.global_variables()函数
获取可训练,需要优化的变量
tf.trainable_variables()函数
通过声明变量的参数trainable=Ture,这个变量会被加入到GraphKeys.TRAINABLE_VARIABLES集合中
GraphKeys.TRAINABLE_VARIABLES集合中的变量为TensorFlow默认优化对象
优势
在网络结构比较复杂的情况,使用集合管理过多的变量会使代码的可读性更高
特别是计算带有正则化的损失函数的时候
神经网络解决分类问题的四个步骤
提取问题中实体的特征向量作为神经网络的输入
训练神经网络
定义神经网络的结构和前向传播的输出
前向传播算法
矩阵乘法tf.matmul()
weights
bias
激活函数activation Function
Sigmoid函数
ReLU函数
Tanh函数
定义损失函数、学习率、反向传播优化的算法(优化器)
反向传播算法
通过运行sess.run(train_strp)就可以对所有GraphKeys.TRAINABLE_VARIABLES集合中的变量进行优化,使得在当前batch下损失函数更小
构建batch数据
placeholder机制提供位置
feed_dict提供数据
Tensorflow提供了placeholder机制用于提供输入数据。placeholder相当于一个位置,这个位置的数据在程序运行时再指定。需要指定它的数据类型,不必给出维度信息feed_dict是一个字典,在字典中需要给出每个用到的placehloder的取值batch_structure = placeholder+feed_dict 搭配使用
定义损失函数
交叉熵cross entropy
求和函数
-tf.reduce_mean()
通过张量的维数计算元素的平均值. 相当于Numpy中的np.mean().
直接对整个矩阵求平均
api
def reduce_mean(input_tensor, axis=None, keep_dims=False, name=None, reduction_indices=None):
根据给出的axis在input_tensor上求平均值。除非keep_dims为真,axis中的每个的张量秩会减少1。如果keep_dims为真,求平均值的维度的长度都会保持为1.如果不设置axis,所有维度上的元素都会被求平均值,并且只会返回一个只有一个元素的张量。
限制范围函数
tf.clip_by_value()
api
tf.clip_by_value(v,a,b) 功能:可以将一个张量中的数值限制在一个范围之内。(可以避免一些运算错误,如log0) 参数:(1)v:input数据(2)a、b是对数据的限制。 当v小于a时,输出a; 当v大于a小于b时,输出原值; 当v大于b时,输出b;
P77
MSE
...
定义学习率learning_rate
定义优化器optimizer
tf.train.GradientDescentOptimizer
tf.train.AdamOptimizer
tf.train.MomentumOptimizer
生成会话并且在训练数据上反复运行反向传播优化算法
使用训练好的神经网络来预测未知数据
预测
深层神经网络
深度学习
一类通过多层非线性变换对高复杂性数据建模算法的合集
特点
非线性
多层
线性模型的缺点
任意线性模型的组合仍然还是线性模型,能解决的问题有限。
激活函数Activation
功能:去线性化
种类
Tanh函数
tf.tanh()
ReLU函数
tf.nn.relu()
a = tf.nn.relu( tf.matmul(x, w1)+b1 )
Sigmoid函数
tf.sigmoid()
自定义激活函数
选择操作
tf.greater()
tf.where()
多层变换
感知机模型perception model
解决异或问题
解决方式:加入隐藏层
隐藏层功能
可以认为是从输入特征中提取了更高维的特征。因此,深层神经网络实际上有组合特征提取的功能,有助于解决不易提取的特征向量问题
损失函数Loss Function
作用
刻画输出向量与期望向量(真实值)之间有多接近【具体】
刻画不同神经网络模型的效果,通过优化损失函数来优化神经网络模型。【宽泛】
种类
交叉熵 cross entropy
cross_entropy = -tf.reduce_mean( y_*tf.log(tf.clip_by_value(y, le-10 ,1.0)))
注意点:交叉熵中两个矩阵是用*相乘的
矩阵乘法
tf.matmul(A,B)
矩阵元素之间之间相乘
A*B
常用于分类问题的损失函数
均方误差MSE
常用于回归问题中
mse = tf.reduce_mean(tf.square(y_-y))
分类问题
二分类
输出节点k=1
多分类
输出节点k=类别数量n
Sotemax回归
作用:将神经网络前向传播得到的结果变成概率分布(0,1)之间。
交叉熵+Softmax回归搭配使用,效果更好
封装API
tf.nn.softmax_cross_entropy_with_logits(label=y_ , logits=y)
y_真实值 标签值
y 输出值,预测值
tf.nn.sparse_softmax_cross_entropy_with_logits(label=y_ , logits = y)
在只有一个正确答案的分类问题中,该api可以加快计算进程
y 输出值,预测值
y_真实值 标签值
神经网络的优化算法
神经网络优化的两个阶段
第一阶段:通过前向传播算法计算预测值,并讲预测值和真实值做对比得出两者之间的差距
第二阶段:用过反向传播算法计算损失函数对每一个参数的梯度,再根据梯度和学习率使用梯度下降算法更新每一个参数
反向传播算法 backpropagation
梯度下降算法 gradient decent
学习率 learning rate
梯度下降算法并不能保证得到的是全局最优解,而是局部最优解。多试几次
限制
训练神经网络时,参数的初始值会很大程度的影响最后得到的结果。同时,只有当损失函数为凸函数时,梯度下降算法才能保证达到全局最优解
计算时间太长;每一轮迭代都需要计算在全部训练数据上的损失函数
随机梯度下降Stochastic gradient descent
简介:在每一轮迭代中,随机选择一条训练数据来优化损失函数
目的:加快训练速度
问题:在某一条训练数据上的损失函数最小不能代表全部训练数据的损失函数最小,导致损失函数甚至不能达到局部最小值。
批量随机梯度下降 batch Stochastic gradient descent
简介:在每一轮迭代中,每次计算一小部分训练数据的损失函数进行优化神经网络
目的:前两种算法的折中
x = tf.placeholder(tf.float32, shape=(batch_size, 2), name= 'x-input')
神经网络的进一步优化
学习率的指数衰减
简介:学习率控制了参数更新的速度
学习率的设置问题
学习率过大,无法收敛
学习率过小,收敛速度太慢
因此,学习率既不能过大,也不能过小
解决方案:指数衰减法
Tensorflow提供了一种比较灵活的学习率设置函数来实现学习率的设置,通过该函数,可以先使用较大的学习率来快速得到一个比较优的解,然后随着迭代的继续逐渐减小学习率,使得模型在训练后期更加稳定
tf.train.exponential_decay(staircase=False,)函数
参数staircase:选择不同的递减方式
True
global_step / decay_steps会被转化成整数,这会使得学习率成为了一个阶梯函数(staircase Function)
此时,decay_step = 训练样本的数量/ batch_size, 即每完整地过完一遍训练数据,学习率就减小一次。这使得所有数据对模型训练有相等的作用。
False
学习率随迭代轮数变化的趋势为单调递减的曲线
decayed_learning_rate = learning_rate * decay_rate^(global_step / decay_steps)
初始学习率、衰减系数和衰减速度一般都是根据经验设置的
decayed_learning_rate
每一轮优化时使用的学习率
learning_rate
事先设定的初始学习率
decay_rate
衰减的速度
随着迭代数的增加,衰减的速度减小,学习率降低
global_step
全局迭代计数变量 = 计数器,作用:提醒到了多少步,该进行什么操作了
正则化解决过拟合问题
简介
在损失函数中加入刻画模型复杂程度的指标
此时,损失函数J(theta) + lambdaR(w)
lambda
表示模型复杂损失在总损失中的比例
R(w)
刻画的是模型的复杂度
方法
L1正则化
特点:1.会让参数变得稀疏。稀疏值神经网络中会有更多的权重变为0,类似于特征的选择功能。2. 带L1正则化的损失函数不可导
tf.contrib.layers.l1_regularizer()函数
tf.contrib.layers.l1_regularizer(lambda)(w)
L2正则化
特点: 1. 该方法不会让参数变得更加稀疏,因为平方会让本来就很小的参数忽略不计,所以模型不会进一步的将这个参数调整为0;2. 带L2正则化的损失函数可导
tf.contrib.layers.l2_regularizer()函数
返回一个函数,计算一个给定参数的L2正则化项的值
TensorFlow会将L2正则化损失值除以2使得求导得到的结果会更加简洁。
L1正则化+L2正则化
在实践中,也可以将L1正则化和L2正则化同时使用。
基本思想:限制权重的大小,使得模型不能任意拟合训练数据中的随机噪声
问题
1.在简单的神经网络中,可以比较容易的计算带有正则化的损失函数。但是当神经网络的参数增多后,带有正则化的损失函数的loss定义会很长,可读性差并且容易出错
2. 当结构复杂后,网络结构的定义 和计算损失函数的部分一般不在同一个函数中,通过这种方式计算(直接计算)不方便
解决方案:使用结合collection
滑动平均模型
简介
将每一轮迭代得到的模型综合起来,从而提高最终得到的模型在测试数据上的表现,使其更加健壮robust。
函数接口API
tf.train.ExponentialMovingAverage( decay,num_unpdate)
简介:将每一轮迭代得到的模型综合起来,从而提高最终得到的模型在测试数据上的表现,使其更加健壮robust。
参数decay
用于控制模型更新的速度
decay决定了模型更新的速度,decay越大模型越趋于稳定。
在实际应用中,deday一般会设置为非常接近于1的数(比如0.99或0.9999)
ExponentialMovingAverage:对每一个变量会维护一个影子变量(shadow variable) ,这个影子变量的初始值=对应变量的初始值,而每次运行变量更新时,影子变量的值会更新为:
shadow_variable = decay x shadow_variable +(1- decay) x variable
参数num_updates
自动设置decay参数
为了使得模型在训练前期可以更新的快
计算公式 min{decay , (1+num_updates)/(10+num_updates)}
计算过程
利用 num_updates自动设置decay参数
利用自动设置的decay参数和ExponentialMovinngAverage函数构建滑动平均模型类