TensorFlow最重要的两个概念:Tensor和Flow
Tensor:张量,多维数组
Flow:流,表达了张量之间通过计算相互转化的过程
TensorFlow是通过计算图的形式表述计算的编程系统
TensorFlow中每一个计算都是计算图上的一个节点,节点之间的边描述了计算之间的依赖关系
图例:
计算图的使用:
TensorFlow程序一般分为两个阶段:
1、 需要定义计算图中所有的计算
2、 执行计算
TensorFlow中的计算图不仅仅可以用来隔离张量和计算,他还提供了管理张量和计算的机制。
TensorFlow中自动维护的集合列表:
TensorFlow的数据模型—Tensor张量
张量是TensorFlow管理数据的形式
TensorFlow程序中所有的数据通过张量的形式来表示。
张量可以被理解为多维数组,零阶张量表示标量(一个数),一阶张量为向量(一维数组),n阶张量表示n为数组。
张量在TensorFlow中实际并不是直接采用数组来表示,张量只是对TensorFlow中运算结果的引用。
张量不保存数字,张量保存的是如何得到这些数字的计算过程。
例如:
import tensorflow as tf
a = tf.constant([1.0,2.0],name="a")
b =tf.constant([2.0,3.0],name="b")
result = tf.add(a, b, name=”add”)
print(result) #输出:Tensor(“add:0”, shape=(2,),dtype=float32)
tf.constant是一个计算,计算结果为张量,保存在名字为a的变量中。
案例得出,张量主要保存了三个属性:名字、维度、类型
名字(name):不仅仅是一个张量的唯一标识,同时给出了该张量的计算过程
例如:张量的命名 = node:src_output
Node为节点名称,src_output为当前张量来自节点的第几个输出
维度(shape):描述了一个张量的维度信息
类型(type):每个张量会有一个唯一的类型
TensorFlow支持14种类型:
浮点数:float32/float64
整数:int8/int16/int32/int64/unit8
布尔型:bool
复数:complex64/complex128
张量的使用:
TensorFlow的数据类型相对简单
主要的使用为两大类:
1、对中间计算结果的引用,当计算的复杂度增加时通过张量的引用来计算中间结果可以使代码可读性强;通过张量来存储中间结果,这样方便获取中间结果。
2、计算图构造完成后,张量可以用来获得计算结果,使用会话得到具体的结果数字。
TensorFlow运行模型—Session会话
TensorFlow中使用会话来执行定义好的运算
会话拥有并管理TensorFlow程序运行时的所有资源。
所有的计算完成之后需要关闭会话来帮助系统回收资源,否则可能资源泄露。
使用会话的模式一般有两种:
1、 明确调用会话生成函数和关闭会话的函数
例如:
sess= tf.Session()
print(sess.run(result))
sess.close()
2、为了解决异常退出时的资源释放问题,TensorFlow可以他通过Python的上下文管理器管理会话。
通过tf.ConfigProto()配置需要生成的会话,可以配置并行线程数,CPU分配策略,运算超时时间等等参数。
TensorFlow实现神经网络
输入层和输出层之间的神经网络交隐藏层,隐藏层越多神经网络越深,
神经网络通过对参数的合理设置来解决分类问题或者回归问题。
神经网络解决分类问题的步骤:
1、 提取问题中实体的特征向量作为神经网络的输入
2、 定义神经网络的结构,并定义如何从神经网络输入得到输出,前向传播算法。
3、 通过训练数据来调整神经网络中的参数的取值,训练过程。
4、 使用训练好的神经网络预测位置数据
前向传播算法:
不同的神经网络结构前向传播算法都不一样
最简单的神经元结构的输出就是所有输入的加权和,不同的输入权重就是神经元的参数。
神经网络的优化过程就是优化神经元中参数取值的过程。
计算神经网络的前向传播结果需要三部分信息:
1、 神经网络的输入
2、 神经网络的连接结构
3、 每个神经元的参数
TensorFlow中matmul()实现了矩阵乘法的功能
TensorFlow变量:Variable的作用是保存和更新神经网络中的参数,需要初始值。
TensorFlow随机生成函数:
(1)tf.random_normal(shape,mean=0.0,stddev=1.0,dtype=tf.float32,seed=None,name=None)
random_normal: 正太分布随机数,均值mean,标准差stddev
(2)tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
truncated_normal:截断正态分布随机数,均值mean,标准差stddev,不过只保留[mean-2*stddev,mean+2*stddev]范围内的随机数
(3)tf.random_uniform(shape,minval=0,maxval=None,dtype=tf.float32,seed=None,name=None)
random_uniform:均匀分布随机数,范围为[minval,maxval]
TensorFlow常数生成函数:
zeros:生成全0数组
ones:生成全1数组
fill:生成全给定数字的数组
constant:生成一个给定的常数
在神经网络中偏置项(bias)通常会使用参数来设置初始值
案例:
import tensorflow as tf
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.constant([[0.7,0.9]])
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
sess = tf.Session()
# 计算是需要初始化变量
# sess.run(w1.initializer) #单个初始化太麻烦
# sess.run(w2.initializer)
init_op = tf.global_variables_initializer()#全局初始化
sess.run(init_op)
print(sess.run(y))
sess.close()
Variable是一个运算,输出结果为一个张量。,所以变量是一种特殊的张量。
监督学习的最重要的思想是:在已知答案的标注上,模型给出的预测结果要尽可能的接近真实答案。
通过调整神经网络中的参数对训练数据进行拟合,可使模型对未知的样本提供预测能力。
反向传播算法:
神经网络优化算法中,最常用的方法是反向传播算法。
反向传播算法实现一个迭代的过程,每次迭代的开始需要选取一小部分训练数据,这部分数据为一个batch。这个batch会通过前向传播算法得到神经网络模型的预测结果,算出预测值和真实值的差距(损失函数),反向传播算法会更新神经网络参数的取值,使得这个batch上神经网络的预测结果与真实值最为接近。
损失函数:刻画当前的预测值和真实值之间的差距,通过反向传播算法来调整神经网络参数的取值,使得差距可以最小化。
简单的损失函数:
定义了真实值与预测值之间的交叉熵,定义了学习率,定义了反向传播优化方法。
cross_entropy = -tf.reduce_mean(y_ *tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
learning_rate = 0.001
train_step = tf.train.AdadeltaOptimizer(learning_rate).minimize(cross_entropy)
常用的优化有三种:
GradientDescentOptimizer、AdamOptimizer、MomentumOptimizer
完整的神经网络样例程序:
实现步骤:
定义神经网络结构和前向传播的输出结果。
定义损失函数,选择反向传播优化算法。
生成会话,在训练集上反复运行反向传播优化算法。
代码:
import tensorflow as tf
from numpy.random import RandomState
# 训练数据大小
batch_size = 8
# 神经网络参数
w1 = tf.Variable (tf.random_normal ([2, 3],stddev=1, seed=1))
w2 = tf.Variable (tf.random_normal ([3, 1],stddev=1, seed=1))
# 方便使用不大的batch大小
x = tf.placeholder (tf.float32,shape=(None, 2), name="x-input")
y_ = tf.placeholder (tf.float32,shape=(None, 1), name="y-input")
#定义前向传播过程
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.AdadeltaOptimizer(0.001).minimize(cross_entropy)
# 随机模拟数据集
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size,2)
Y = [[int(x1+x2 < 1)] for (x1,x2) in X]
# 创建会话运行tf的程序
with tf.Session() as sess:
#初始化变量
init_op = tf.global_variables_initializer()
sess.run(init_op)
print("w1:",sess.run(w1))
print("w2:",sess.run(w2))
print("\n")
# 输出训练前参数的值
# 训练轮数
STEPS = 6000
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 training step(s),cross entropy on all data is%g"%
(i,total_cross_entropy))
# 交叉熵越小,预测数据和真实数据差距越小
print("w1:",sess.run(w1))
print("w2:",sess.run(w2))