1.1 了解模型的运行机制
TensorFlow的运行机制属于“定义”与“运行”相分离。从操作层面可以抽象成两种:模型构建和模型运行。在模型构建过程中,需要先了解几个概念,如表4-1所示。
表4-1中定义的内容都是在一个叫做“图”的容器中完成的。关于“图”,有以下几点需要理解。
● 一个“图”代表一个计算任务。
● 在模型运行的环节中,“图”会在会话(session)里被启动。
● session将图的OP分发到如CPU或GPU之类的设备上,同时提供执行OP的方法。这些方法执行后,将产生的tensor返回。在Python语言中,返回的tensor是numpy ndarray对象;在C和C++语言中,返回的tensor是TensorFlow::Tensor实例。
如图4-1所示为session与图的工作关系。
(1)训练场景:是实现模型从无到有的过程,通过对样本的学习训练,调整学习参数,形成最终的模型。其过程是将给定的样本和标签作为输入节点,通过大量的循环迭代,将图中的正向运算(从输入的样本通过OP运算得到输出的方向)得到的输出值,再进行反向运算(从输出到输入的方向),以更新模型中的学习参数,最终使模型产生的正向结果最大化地接近样本标签。这样就得到了一个可以拟合样本规律的模型。(2)测试场景和使用场景:测试场景是利用图的正向运算得到的结果与真实值进行比较的差别;使用场景也是利用图的正向运算得到结果,并直接使用。所以二者的运算过程是一样的。对于该场景下的模型与正常编程用到的函数特别相似。在函数中,可以分为实参、形参、函数体与返回值。同样在模型中,实参就是输入的样本,形参就是占位符,运算过程就相当于函数体,得到的结果相当于返回值。另外,session与图的交互过程中还定义了以下两种数据的流向机制。● 注入机制(feed):通过占位符向模式中传入数据。
● 取回机制(fetch):从模式中得到结果。
下面通过实例逐个演示session在各种情况下的用法。先从session的建立开始,接着演示session与图的交互机制,最后演示如何在session中指定GPU运算资源
2.2利用TensorFlow实现简单线性回归
2.2.1实现思路
(1)定义TensorFlow输入节点。
(2)定义“学习参数”的变量。
(3)定义“运算”。
(4)优化函数,优化目标。
(5)初始化所有变量。
(6)迭代更新参数到最优解。
(7)测试模型。
(8)使用模型。
2.2.2实现代码
- 1 准备好数据集:y = 0.8x + 0.7 100个样本
- 2 建立线性模型
- 随机初始化W1和b1
- y = W·X + b,目标:求出权重W和偏置b
- 3 确定损失函数(预测值与真实值之间的误差)-均方误差
- 4 梯度下降优化损失:需要指定学习率(超参数)
import tensorflow as tf
import os
def linear_regression():
"""
自实现线性回归
:return: None
"""
# 1)准备好数据集:y = 0.8x + 0.7 100个样本
# 特征值X, 目标值y_true
X = tf.random_normal(shape=(100, 1), mean=2, stddev=2)
# y_true [100, 1]
# 矩阵运算 X(100, 1)* (1, 1)= y_true(100, 1)
y_true = tf.matmul(X, [[0.8]]) + 0.7
# 2)建立线性模型:
# y = W·X + b,目标:求出权重W和偏置b
# 3)随机初始化W1和b1
weights = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)))
bias = tf.Variable(initial_value=tf.random_normal(shape=(1, 1)))
y_predict = tf.matmul(X, weights) + bias
# 4)确定损失函数(预测值与真实值之间的误差)-均方误差
error = tf.reduce_mean(tf.square(y_predict - y_true))
# 5)梯度下降优化损失:需要指定学习率(超参数)
# W2 = W1 - 学习率*(方向)
# b2 = b1 - 学习率*(方向)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)
# 初始化变量
init = tf.global_variables_initializer()
# 开启会话进行训练
with tf.Session() as sess:
# 运行初始化变量Op
sess.run(init)
print("随机初始化的权重为%f, 偏置为%f" % (weights.eval(), bias.eval()))
# 训练模型
for i in range(100):
sess.run(optimizer)
print("第%d步的误差为%f,权重为%f, 偏置为%f" % (i, error.eval(), weights.eval(), bias.eval()))
return None