参考来源:博客链接
使用线性模型来对数据点进行建模。线性模型的数学表示是:
y = W.x + b
Where:
x: house size, in sqm
y: predicted house price, in $
(1) Tensors
TensorFlow中使用tensor数据结构(实际上就是一个多维数据)表示所有的数据,并在图计算中的节点之间传递数据一个tensor具有固定的类型、级别和大小,更加深入理解这些概念可参考Rank, Shape, and Type
(2) 在线性模型中,tensorflow 的基本组件是:
-
占位符(Placeholder)- 表示执行梯度下降时将实际数据值输入到模型中的一个入口点。例如房子面积 (x) 和房价 (y_),
x=tf.placeholder(tf.float32,[None,1]) y_=tf.placeholder(tf.float32,[None,1])
-
变量:表示我们试图寻找的能够使成本函数降到最小的 「good」值的变量,例如 W 和 b,
W=tf.Variable(tf.zeros([1,1])) b=tf.Variable(tf.zeros[1])) y=tf.matmul(x,W)+b
-
成本函数:
cost=tf.reduce_sum(tf.pow((y_ - y),2))
-
梯度下降:有了线性模型、成本函数和数据,我们就可以开始执行梯度下降从而最小化代价函数,以获得 W、b 的「good」值。
train_step = tf.train.GradientDescentOptimizer(0.00001).minimize(cost)
0.00001 是我们每次进行训练时在最陡的梯度方向上所采取的「步」长;它也被称作学习率(learning rate).
(3)训练模型
训练包含以预先确定好的次数执行梯度下降,或者是直到成本函数低于某个预先确定的临界值为止。TensorFlow的使用,所有变量都需要在训练开始时进行初始化,否则它们可能会带有之前执行过程中的残余值。
init = tf.initialize_all_variables()
虽然 TensorFlow 是一个 Python 库,Python 是一种解释性的语言,但是默认情况下不把 TensorFlow 运算用作解释性能的原因,因此不执行上面的 init 。相反 TensorFlow 是在一个会话中进行;创建一个会话 (sess) 然后使用 sess.run() 去执行.
sess = tf.Session()
sess.run(init)
完整代码
import numpy as np
import tensorflow as tf
# Model linear regression y = Wx + b
x = tf.placeholder(tf.float32, [None, 1])
W = tf.Variable(tf.zeros([1,1]))
b = tf.Variable(tf.zeros([1]))
product = tf.matmul(x,W)
y = product + b
y_ = tf.placeholder(tf.float32, [None, 1])
# Cost function sum((y_-y)**2)
cost = tf.reduce_mean(tf.square(y_-y))
# Training using Gradient Descent to minimize cost
train_step = tf.train.GradientDescentOptimizer(0.0000001).minimize(cost)
sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)
steps = 1000
for i in range(steps):
# Create fake data for y = W.x + b where W = 2, b = 0
xs = np.array([[i]])
ys = np.array([[2*i]])
# Train
feed = { x: xs, y_: ys }
sess.run(train_step, feed_dict=feed)
print("After %d iteration:" % i)
print("W: %f" % sess.run(W))
print("b: %f" % sess.run(b))
# Suggested by @jihobak
print("cost: %f" % sess.run(cost, feed_dict=feed))
# NOTE: W should be close to 2, and b should be close to 0
在上面的训练中,我们在每个 epoch 送入单个数据点,这被称为随机梯度下降(stochastic gradient descent)。我们也可以在每个 epoch 送入一堆数据点,这被称为 mini-batch 梯度下降,或者甚至在一个 epoch 一次性送入所有的数据点,这被称为 batch 梯度下降。
请看下图的比较,注意这 3 张图的 2 处不同:
- 每个 epoch 送入 TensorFlow 图(TF.Graph)的数据点的数量(图右上方)
-
梯度下降优化在调整 W 和 b 值时所考虑的数据点的数量(图右下方)
要在随机/mini-batch/batch 梯度下降之间切换,我们只需要在将数据点送入训练步骤[D]之前将这些数据点分成不同的 batch 大小,即为 [C] 使用如下的代码片段:
# * all_xs: 所有的特征值
# * all_ys: 所有的输出值
# datapoint_size: all_xs/all_ys 中点/项的数量
# batch_size: 配置如下:
# 1: 随机模型
# integer < datapoint_size: mini-batch模式
# datapoint_size: batch模式
# i: 当前epoch数量
if datapoint_size == batch_size:
Batch 模式,所以选择所有数据点从 index 0 开始
batch_start_idx = 0
elif datapoint_size < batch_size:
不可能
raise ValueError(“datapoint_size: %d, must be greater than
batch_size: %d” % (datapoint_size, batch_size))
else:
随机/mini-batch模式: 从所有可能的数据点中分批选择数据点
batch_start_idx = (i * batch_size) % (datapoint_size — batch_size)
batch_end_idx = batch_start_idx + batch_size
batch_xs = all_xs[batch_start_idx:batch_end_idx]
batch_ys = all_ys[batch_start_idx:batch_end_idx]
将分批的数据点定义为xs, ys, 它们会被送入 'train_step'训练步骤
xs = np.array(batch_xs)
ys = np.array(batch_ys)
- 学习率变化
学习率(learn rate)是指梯度下降调整 W 和 b 递增或递减的速度。学习率较小时,处理过程会更慢,但肯定能得到更小成本;而当学习率更大时,我们可以更快地得到最小成本,但有「冲过头」的风险,导致我们没法找到最小成本。为了克服这一问题,许多机器学习实践者选择开始时使用较大的学习率(假设开始时的成本离最小成本还很远),然后随每个 epoch 而逐渐降低学习率。
TensorFlow 带有多种支持学习率变化的梯度下降优化器,例如 tf.train.AdagradientOptimizer 和 tf.train.AdamOptimizer.
使用 tf.placeholder 调整学习率如同前面所看到的,如果我们在这个例子中声明了 tf.placeholder 来设置学习率,然后在 tf.train.GradientDescentOptimizer 中使用它,我们可以在每个训练 epoch 向其送入一个不同的值,这很像我们给x 和 y_ 送入不同的数据点,这也是每个 epoch 的 tf.placeholders.