放牧代码和思想
专注自然语言处理、机器学习算法
    时间有限,只有GitHub上的issue能及时处理,大约每周末一次。另外,不要叫我楼主,谢谢。

CS224n笔记7 TensorFlow入门

目录

这节课由TA们介绍了TF里的几个基本概念(graph、variable、placeholder、session、fetch、feed),基本流程。然后现场敲代码演示如何在TF上跑线性回归和训练词向量。与优达学城的《深度学习公开课》不同之处在于,后者是一个浮躁的快餐培训课程,看完了只知道大象是柱状的。

TensorFlow.png

深度学习框架简介

为什么要用成熟的框架,而不是从头写一个:

  • 这些框架提供了大规模机器学习算法的成熟实现

  • 方便地计算梯度

  • 标准化机器学习应用,方便共享交流

  • 多种算法、理念、抽象、编程语言等的融合

  • 提供GPU并行运算的接口

TF是什么

不是口红。

tom-ford-lip-color-2015-swatch-review.png

  • TensorFlow是一个图计算的开源类库

  • 最初由Google Brain团队开发,用来进行机器学习研究

  • TensorFlow是一个描述机器学习算法和实现机器学习算法的接口

图计算编程模型

中心思想是将数值运算以图的形式描述。

  • 图的节点是某种运算,支持任意数量的输入和输出

  • 图的边是tensor(张量,n维数组),在节点之间流动

比如ReLU激活函数:

$$h=ReLU(Wx+b)$$

计算图如下:

hankcs.com 2017-06-21 上午10.15.56.png

其中$W$和$b$是变量,变量通常是模型的参数。这些数据也可看做运算节点,只不过是无输出产生输出的节点。变量可以储存下来,作为模型的一部分发布。

hankcs.com 2017-06-21 上午10.19.36.png

而$x$只是一个placeholder(占位符),只在执行的时候填充输入,编程的时候指定大小即可。

hankcs.com 2017-06-21 上午10.30.48.png

剩下的3个节点是运算单元:

hankcs.com 2017-06-21 上午10.33.10.png

要描述这样的图运算,只需编写代码:

hankcs.com 2017-06-21 上午10.34.20.png

这段代码只是构建了运算图,连输入都没有,自然无法马上获取$h$的值。

图在哪里

上述代码并没有显式地声明节点和边,TensorFlow根据数学表达式自动构造了运算图。

如何运行

到目前为止,我们只定义了一张图,如何执行它呢?我们可以通过session将这张图部署到某个执行环境(CPU、GPU、Google的TensorProcessingUnit……)上去。session就是到某个软硬件执行环境的绑定。

在代码中只需新增三行:

hankcs.com 2017-06-21 上午10.52.59.png

其中第一个run初始化了所有变量。第二个run中有两个概念:

sess.run(fetches, feeds)	

fetches是一系列图节点(其实就是某个节点,因为图是连通的,给我一个节点总可以找到所有节点)或说变量。feeds是一个从placeholder到其输入值的映射。

训练

前面的部分只是定义了一个图,知道如何执行它,接下来介绍如何训练模型。

定义损失

用变量定义损失,用placeholder定义label:

prediction = tf.nn.softmax(...)  #Output of neural network
label = tf.placeholder(tf.float32, [100, 10])
						
cross_entropy = -tf.reduce_sum(label * tf.log(prediction), axis=1)

如何计算梯度

先初始化一个optimizer,然后在图中损失函数节点后面添加一个优化操作(最小化,也是一种运算节点):

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

就像(大部分)函数都有自己的导数一样,TF中的运算节点都附带了梯度操作。在反向传播中,TF在计算图的逆向图上利用链式法则自动计算梯度。用户不需要编写梯度计算与参数更新的代码,而是交给optimizer自动完成。

在代码中是这样调用的:

hankcs.com 2017-06-21 上午11.23.08.png

变量共享

有时候我们想要生成一张图的多个实例,或者在多机多个GPU上训练同一个模型,就会带来同一个变量在不同位置出现。如何在不同位置共享同一个变量呢?

一种朴素的想法是弄个字典建立变量名到variable的映射:

variables_dict = {
    "weights": tf.Variable(tf.random_normal([782, 100]),
                           name="weights"
                           )
)
"biases": tf.Variable(tf.zeros([100]), name="biases"
}

但这样容易导致变量名冲突,TF支持命名空间:

with tf.variable_scope("foo"):
    v = tf.get_variable("v", shape=[
        1])  # v.name == "foo/v:0"
with tf.variable_scope("foo", reuse=True):
    v1 = tf.get_variable("v"
                         # Shared variable found!
                         ) )
with tf.variable_scope("foo", reuse=False):
    v1 = tf.get_variable("v"
# CRASH foo/v:0 already exists!

总结

TF的用法总结如下:

  1. 创建图
    a 前向传播/预测
    b 优化操作

  2. 初始化session

  3. 在session中执行

现场演示

印度小哥拿着MBP开始现场敲代码了,用的是Vim,经常少敲了括号,最后跑word2vec死活不知道哪里敲错了,干脆把写好的word2vec_complete.py调出来了事。这说明:

  • 至少在学习TF上,MBP还是有很多人在用的

  • 现场敲代码压力还是很大的

  • 一个有纠错提示的IDE还是很重要的

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » CS224n笔记7 TensorFlow入门

分享到:更多 ()

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的开源项目

HanLP自然语言处理包基于DoubleArrayTrie的Aho Corasick自动机