TensorFlow入门

1.TensorFlow入门

1.1 计算模型——计算图

计算图:每一个计算为计算图的一个节点,边描述计算之间的依赖关系
TensorFlow程序可以分为两个阶段。在第一阶段需要定义图中所有的计算,第二阶段为执行计算。
tensorFlow自动将定义的计算转化为计算图上的节点,系统会维护一个默认的计算图。
不同计算图上的张量和运算都不会共享。

1.2 数据模型——张量

Tensor:张量。在tensorFlow程序中,所有数据都通过张量的形式来表示。
从功能角度,张量可以被简单理解为多维数组。
TensorFlow中的张量没有保存数字,保存的是如何得到这些数字的计算过程。

# 张量主要保存了三个属性,name,shape,type
# add:0 表示计算节点“add”输出的第一个结果,shape=(2,)表面张量为一个一维数组,数组长度为2,type表示数组类型
'''
输出
Tensor("add:0",shape=(2,),dtype=float32)
'''

1.3 运行模型——会话

使用会话session执行定义好的运算。会话拥有并管理tensorFlow运行时的所有资源,计算完成之后需要关闭会话来帮助系统回收资源,否则可能会出现资源泄露的问题。

1.3.1 会话模式1

# 创建会话
sess = tf.Session()
# 使用创建的会话得到运算结果
sess.run(result)
#关闭会话。释放资源;当程序因为异常退出是,关闭会话的函数可能就不会被执行而导致资源泄露
sess.close()

1.3.2 会话模式2

# 通过python上下文管理器管理会话
with tf.Session() as sess:
	sess.run(result)
# 不需要在调用Session.close关闭会话,上下文退出是会话关闭和资源释放自动完成

1.3.3 默认会话

sess = tf.Session()
with sess.as_default():
	print(result.eval())

1.4 tensorflow实现神经网络

# 
"""
Created on Tue Oct 30 09:12:10 2018
@author: cc
"""
import tensorflow as tf
from numpy.random import RandomState
# 定义训练数据的batch
batch_size =8
# 定义神经网络的参数,方差为1的随机数矩阵,随机种子为1
w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))

x=tf.placeholder(tf.float32,shape=(None,2),name="x-inpt")
y_=tf.placeholder(tf.float32,shape=(None,1),name="Y-inpt")
# 定义神经网络前向传播的过程,a为隐藏层计算所得
a =tf.matmul(x,w1)
y =tf.matmul(a,w2)
# 定义损失函数
cross_entropy = -tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-10,1.0)))
train_step =tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
# 通过随机数生成一个模拟数据集
rdm =RandomState(1)
dataset_size =1024
X = rdm.rand(dataset_size,2)
# 定义规则给出样本的标签,用0表示负样本(x1+x2>1),用1表示正样本(x1+x2<1)
Y =[[int(x1+x2<1)] for (x1,x2) in X]
# 创建一个会话运行Tensorflow程序
with tf.Session() as sess:
	# 初始化所有的参数
    init_op = tf.initialize_all_variables()
    sess.run(init_op)
    print(sess.run(w1))
    print(sess.run(w2))
    # 定义训练的轮数
    STEPS = 8000
    for i in range(STEPS):
    	# 每次选择batch_size个样本进行训练
        start =(i*batch_size)%dataset_size
        end = min(start+batch_size,dataset_size)
  		# 通过选择的样本训练神经网络并更新参数
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
        if i%1000 ==0:
        	 # 计算所有数据的交叉熵并输出
            total_cross_entropy = sess.run(cross_entropy,feed_dict={x:X,y_:Y})
            print("After %d traning steps,cross entropy on all data is %g" %(i,total_cross_entropy)) 
    # 训练好的参数               
    print(sess.run(w1))
    print(sess.run(w2))

2.神经网络

2.1 激活函数

2.2 损失函数loss function

用于判断输出向量和期望的向量的接近程度

2.2.1 分类问题

交叉熵:用来评估分类效果的意义,刻画的两个概率分布之间的聚类
H ( p , q ) = − ∑ p ( x ) log ⁡ q ( x ) H(p,q)=-\sum p(x)\log q(x) H(p,q)=p(x)logq(x)
Softmax回归,将神经网络前向传播得到的结果也变成概率分布
通过Softmax层将神经网络变成一个概率分布
假设原始神经网络输出为 y1,y2,……,yn ,经过Softmax回归处理之后的输出为:
s o f t m a x ( y ) i = y i ′ = e i y ∑ j = 1 n e y j softmax(y)_i =y_i&#x27; =\frac {e^y_i}{\sum_{j=1}^{n}e^{y_j}} softmax(y)i=yi=j=1neyjeiy
在1.1.4的例子中已经通过tensorflow实现交叉熵:

# 其中y——表示正确结果,y表示预测结果
cross_entropy = tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-10,10)))
  • tf.clip_by_value函数可以将张量中的数值控制在一个范围内,避免一些运算错误
  • tf.log用于对张量中的所有元素依次进行对数运算
  • * 表示矩阵中的元素直接相乘,矩阵乘法用tf.matmul
  • 计算结果为n*m二维矩阵,n为一轮中样例数量,m为分类的类别数量。根据交叉熵的公式,应该将每行的m个结果相加,得到所有样例的交叉熵,然后对n行取平均得到一个batch的平均交叉熵。 tf.reduce_mean 就是这个作用,相当于 ∑ i = 1 n n \frac{\sum_{i=1}^{n}}{n} ni=1n 运算
  • tf.nn.softmax_cross_entropy_with_logits(y,y_)可以计算softmax回归之后的交叉熵

2.2.2 回归问题

回归问题是解决对具体数值的预测。常用的损失函数式均方误差MSE
M S E ( y , y ′ ) = ∑ i = 1 n ( y i − y i ′ ) 2 n MSE(y,y&#x27;)=\frac{\sum_{i=1}^{n}(y_i-y_i&#x27;)^2}{n} MSE(y,y)=ni=1n(yiyi)2
其中y_i表示一个batch中第i个数据的正确答案, y i ′ y_i&#x27; yi为神经网络的预测值

# tensorflow实现均方误差损失函数
mse = tf.reduce_mean(tf.square(y_-y))

除了上面的两种常见的还可以自定义损失函数

2.3 神经网络优化算法

梯度下降算法

用θ表示深度学习中的参数,J(θ)表示损失函数的取值,其梯度为 α α θ J ( θ ) \frac{\alpha}{\alpha \theta}J(\theta) αθαJ(θ)
学习率η:定义每次参数更新的幅度
θ n + 1 = θ n − θ α α θ n J ( θ n ) \theta_{n+1} =\theta_n - \theta \frac {\alpha}{\alpha\theta_n}J(\theta_n) θn+1=θnθαθnαJ(θn)
梯度下降算法通过梯度和学习率更新参数x的取值,使用梯度下降算法对参数的更新公示为 X n + 1 = X n − η Δ n X_{n+1}=X_n - \eta\Delta n Xn+1=XnηΔn
缺点:
1.不能保证达到全局最优解
2.计算时间太长。因为J(θ)是在所有训练数据上的损失和。
为了加速训练过程,可以采用 随机梯度下降的算法。每一次训练的过程中,随机优化某一天训练数据上的损失函数。但是这样得到的神经网络甚至无法达到局部最优。实际中一般采用这两个算法的折中——每次计算一小部分训练数据的损失函数。这部分数据被称为一个batch,通过矩阵运算。每次在batch上优化神经网络的参数并不会比单个数据慢太多。另一方面可以大大减小收敛所需的迭代次数。

反向传播算法back pagation

学习率设置

设置学习率 η \eta η 控制参数更新的速度。学习率过大,可能导致参数在极优值两侧来回移动;学习率过小,会降低优化速度,需要迭代更多轮才能达到理想的优化效果。
tensorFlow提供一种灵活的学习率设置方法——指数衰减法tf.train.exponential_decay函数实现指数衰减学习率。

global_step = tf.Variable(0)
# exponential_decay函数的作用:decay_learning_rate = learing_rate*decay_raye^(global_step/decay_steps)
# learing_rate:初始学习率,decay_rate:衰减系数,decay_steps:衰减速度
learning_rate=tf.train.exponential_decay(0.1,global_step,100,0.96,staircase=True)
# 更新学习率
learning_step = tf,train.GradientDescentOptimize(learning_rate).minimize(...my loss...,global_step = global_step)

过拟合问题

过度拟合了训练数据中的噪声而忽视了问题的整体规律。
为了避免过拟合问题,常用的方法是正则化。正则化的思想是在损失函数中加入刻画模型复杂程序的指标。
优化时不直接优化 J ( θ ) J(\theta) J(θ),而是优化 J ( θ ) + λ R ( ω ) J(\theta)+\lambda R(\omega) J(θ)+λR(ω),其中 R ( ω ) R(\omega) R(ω)刻画的是模型的复杂程度,而 λ \lambda λ表示的模型复杂损失在总损失中的比例。一般来说模型的复杂度只由权重 ω \omega ω决定
常见的刻画模型复杂度的函数 R ( ω ) R(\omega) R(ω)有两种,一种是L1正则化,一种是L2正则化。
L 1 正 则 化 : R ( ω ) = ∥ ω ∥ 1 = ∑ i ∣ ω i ∣ L1正则化:R(\omega)=\parallel\omega\parallel_1=\sum_i|\omega_i| L1R(ω)=ω1=iωi

L 2 正 则 化 : R ( ω ) = ∥ ω ∥ 2 2 = ∑ i ∣ ω i 2 ∣ L2正则化:R(\omega)=\parallel\omega\parallel_2^2=\sum_i|\omega_i^2| L2R(ω)=ω22=iωi2
正则化的思想是希望通过限制权重的大小,使模型不能任意拟合训练数据的随机噪声。L1正则化会让参数变得更稀疏;L1正则化不可导,L2正则化可导。在实践中,可以将L1正则化和L2正则化同时使用:
R ( ω ) = α ∥ ω ∥ 1 + ( 1 − α ) ∥ ω ∥ 2 2 = ∑ i α ∣ ω i ∣ + i ( 1 − α ) ∣ ω i 2 ∣ R(\omega)=\alpha\|\omega\|_1+(1-\alpha)\parallel\omega\parallel_2^2=\sum_i{\alpha|\omega_i|+_i(1-\alpha)|\omega_i^2|} R(ω)=αω1+(1α)ω22=iαωi+i(1α)ωi2

w=tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))
y=tf.matmual(x,w)
loss=tf.reduce_mean(tf.square(y_-y))+tf.contrib.layers.l2.regularize(lambda)(w)

滑动平均模型

每个变量维护一个影子变量shadow_variable,每次运行变量更新时,影子变量的值会更新,公式如下,其中decay为衰减率,variable为待更新的变量。
s h a d o w _ v a r i a b l e = d e c a y ∗ s h a d o w _ v a r i a b l e + ( 1 − d e c a y ) ∗ v a r i a b l e shadow\_variable=decay*shadow\_variable+(1-decay)*variable shadow_variable=decayshadow_variable+(1decay)variable

"""
Created on Wed Oct 31 11:00:25 2018
@author: cc
"""
import tensorflow as tf

v1= tf.Variable(0,dtype=tf.float32)
# step变量模拟神经网络的迭代轮数,可以用于动态控制衰减率
step = tf.Variable(0,trainable=False)
# 定义一个滑动平均的二类,初始为衰减率为0.99和控制衰减率的变量step
ema= tf.train.ExponentialMovingAverage(0.99,step)
# 定义一个更新变量滑动平均的操作,每次执行这个操作时,列表中变量都会被更新。
maintain_averages_op = ema.apply([v1])
with tf.Session() as sess:
    # 初始化所有变量
    init_op = tf.initialize_all_variables()
    sess.run(init_op)
    print(sess.run([v1,ema.average(v1)]))
    # 更新v1到5
    sess.run(tf.assign(v1,5))
    # 更新v1的滑动平均值
    sess.run(maintain_averages_op)
    print(sess.run([v1,ema.average(v1)]))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值