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 增加内容

results matching ""

    No results matching ""