Tensorflow 导论
课程中使用的tensorflow可以对公式自动求导,很大的方便了机器学习算法的实现和运算,而不需要对每种新的算法、公式或者损失函数自己来定义如何求导,如何更新。
tensorflow的设计受到之前的theanopackage很大影响。
引入Graph的概念,图上有node
Graph, Tensor, Operation, constant, Variable, Session
Tensorflow 实现线性回归
import tensorflow as tf
tf.reset_default_graph()
Constant
- Constant是一种tensor
- tensor类似numpy中的array, 我们常用的是一维(向量)、二维(矩阵)结构
为什么 print 看不到 c 的值
- 在这里只是『声明』了这个 Tensor
Tensorflow 中会有一个默认的 "Graph",所有『声明』的操作都记录在这个 Graph 上;声明的每一个值,都是在Graph上节点
Session
- Gapraph 要通过 Session 来执行
sess = tf.Session()
sess.run(c)
# with session
with tf.Session() as sess:
r = sess.run(c)
print(type(r))
print(r)
- c 在 Graph 里是一个 Tensor,Session 执行之后返回的是 numpy array
- Graph: 执行蓝图(有向无环图)
- Session: 具体执行 好处是什么:
- 可并行
- Graph 的不同部分可以放到不同的设备上(GPU/CPU)
Tensorflow上有两种Node
- Tensor
- Operation
随机数
r = tf.random_uniform([1], -1.0, 1.0)
返回的也是tensor; 参数:维度、产生范围
Variable的概念
- Tensorflow 中的 Variable 对机器学习应用至关重要
- 用 Tensor 赋值,能做 Tensor 相同的操作
- 和编程中『变量』的概念类似,用于维护一个可变的状态
- 不同 run 之间能保存状态
- 适合做什么?
变量需要一个专门的初始化过程
- 可以使用 tf.global_variables_initializer() 增加一个 operation,初始化所有变量
init = tf.global_variables_initializer()
sess.run(init)
sess.run(w)
初始化之后无论怎么运行,随机变量的值都不会变;除非重新初始化sess.run(init)
有了变量,我们知道还要有数据才能计算 Cost
实现梯度下降
train_step = tf.train.GradientDescentOptimizer(0.0001).minimize(cost)
costs = []
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(100):
sess.run(train_step)
cost_value = sess.run(cost)
costs.append(cost_value)
print(cost_value)
print(sess.run([w, b]))
Placeholder
x,y 作为常量传到Graph里面。如果数据量很大的话,工业界数据经常以T论,用这种方法每次要将数据全部读到内存来计算cost。这种数据量是没办法承受的。
回到梯度下降算法,梯度下降是在当前梯度走一小步,走完后重新计算梯度。在样本量N很大的时候,每次计算梯度时计算量都很大;而计算梯度其实只需考虑当前局部数据,全部计算是很浪费的。
随机梯度下降 Stochastic GD
- 随机选择1个样本计算梯度;
- 评价模型还是看所有样本上损失函数表现;
- 更新次数频繁(每次梯度计算更快)
- 数据不用一次读到内存,可以预先将文件随机Shuffle,把记录逐条读入,不需要每次重新采样
小批量梯度下降 Mini-Batch GD
- 在N很大时,去比较小的K作为样本大小
- 比随机梯度更准确,比Batch GD更新更频繁、内存上占优势
回到Tensorflow, 之前将x和y作为常量输入,因此无法更改。可以把Graph看成一个“虚”的东西,一个执行计划的蓝图;用一个"虚"的Node来替代"实"的数据,在运行的过程中,不断往Node中填充数据。在tensorflow中通过Placeholder来实现。
x_placeholder = tf.placeholder('float')
y_placeholder = tf.placeholder('float')
w = tf.Variable(tf.random_uniform([1], -1.0, 1.0), name='W')
b = tf.Variable(tf.zeros([1]), name='b')
y_bar = w * x_placeholder + b
cost = tf.reduce_mean(tf.square(y_bar - y_placeholder))
# GD
train_step = tf.train.GradientDescentOptimizer(0.0001).minimize(cost)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(100):
feed_dict = {x_placeholder:x.astype(float), y_placeholder:y}
sess.run(train_step, feed_dict=feed_dict)
print(sess.run(cost, feed_dict=feed_dict))
print(sess.run([w, b]))
Change log
2017.10.29 创建 2017.11.4 增加内容