Tensorflow Source Codes Reading Notes

As there are very few Chinese tensorflow source codes annotaions on the Internet, I decided to write the article in Chinese such that more people can know more details about how TensorFlow works in source codes level.

这篇文章是我在2017年10月21日阅读tensorflow源码时做的笔记,并未是完全为了解释清楚tensorflow的源码实现而撰写,因此如有不准确或者不详尽之处还请谅解。参考的tensorflow的版本是1.3.0。

TensorFlow概览

  • TensorFlow其实有两个关键词,一个是Tensor,代表在整个Flow中主要的输入输出类型都是tensor; 还有一个是Flow其实就是意味着一个有向图。所以在TF中的整个计算模式就是围绕算子,数据进行的。算子可以理解成定义好的函数,数据可以理解成函数的输入和输出。一个函数执行完毕后的输出又作为下一步计算的输入,因此各个算子和数据(tensor)之间行程了数据流图。
  • 关于怎么构建的这幅图可以移步tensorflow官网解释
  • 下面是一副tensorFlow的计算数据流图(来自于TensorFlow官方教程):

TensorFlow 计算图

  • 上面这幅图中,计算了一个线性模型
    $$
    y = Wx + b
    $$
    并通过梯度下降来计算真实分类和实际计算的分类的差距来更新参数Wb

Tensor类

  • 根据实验,tensorflow的placeholder的type为 <class 'tensorflow.python.framework.ops.Tensor'>. 因此在 tensorflow.python.framework.ops 目录下找到了关于tensor的定义。
  • tensor可以理解成一个”多维的list”,该类提供了以下方法的重载:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# List of Python operators that we allow to override.
OVERLOADABLE_OPERATORS = {
# Binary.
"__add__",
"__radd__",
"__sub__",
"__rsub__",
"__mul__",
"__rmul__",
"__div__",
"__rdiv__",
"__truediv__",
"__rtruediv__",
"__floordiv__",
"__rfloordiv__",
"__mod__",
"__rmod__",
"__lt__",
"__le__",
"__gt__",
"__ge__",
"__and__",
"__rand__",
"__or__",
"__ror__",
"__xor__",
"__rxor__",
"__getitem__",
"__pow__",
"__rpow__",
# Unary.
"__invert__",
"__neg__",
"__abs__",
"__matmul__",
"__rmatmul__"
}
  • 其中tensor 类不支持__bool__(self)以及__nonzero__(self)的布尔表达式的判断。也不支持__iter__(self)的迭代方式。如有错误访问均报错。
  • Tensor对象提供了一个eval(self, feed_dict=None, session=None) 函数,该函数实则计算生成该tensor实例的算子(operation)所需的全部所需的输入(inputs)。该函数实际调用的session.run()。对于这里我的理解是,因为每一个tensor或者占位符(placeholder)在tensorflow中都作为实际的图节点来进行表示的,该图是一个类似于拓扑图的有向无环图,因此eval方法实际上是计算拓扑优先顺序在该tensor之前的所有节点。
  • Tensor还有一个很重要的属性: _consumers。该属性记录了后续的所有以当前这个tensor为输入的所有算子。有了这个属性,tensorflow可以比较有效地建立起一个有向图来计算。