TensorFlow是Google开源的第二代用于数字计算(numerical computation)的软件库。它是基于数据流图的处理框架,图中的节点表示数学运算(mathematical operations),边表示运算节点之间的数据交互。TensorFlow从字面意义上来讲有两层含义,一个是Tensor,它代表的是节点之间传递的数据,通常这个数据是一个多维度矩阵(multidimensional data arrays)或者一维向量;第二层意思Flow,指的是数据流,形象理解就是数据按照流的形式进入数据运算图的各个节点。
TensorFlow是一个非常灵活的框架,它能够运行在个人电脑或者服务器的单个或多个CPU和GPU上,甚至是移动设备上。TensorFlow最早是Google大脑团队为了研究机器学习和深度神经网络而开发的,但后来发现这个系统足够通用,能够支持更加广泛的应用。至于为什么谷歌要开源这个框架,它是这样回应的:
“IfTensorFlow is so great, why open source it rather than keep it proprietary? Theanswer is simpler than you might think: We believe that machine learning is akey ingredient to the innovative products and technologies of the future.Research in this area is global and growing fast, but lacks standard tools. Bysharing what we believe to be one of the best machine learning toolboxes in theworld, we hope to create an open standard for exchanging research ideas andputting machine learning in products. Google engineers really do use TensorFlowin user-facing products and services, and our research group intends to shareTensorFlow implementations along side many of our research publications.”
TensorFlow特点
# Ubuntu/Linux 64-bit
$ sudo apt-get install python-pip python-dev
# Mac OS X
$ sudo easy_install pip
Install TensorFlow:
# Ubuntu/Linux 64-bit, CPU only:
$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
# Ubuntu/Linux 64-bit, GPU enabled:
$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.6.0-cp27-none-linux_x86_64.whl
# Mac OS X, CPU only:
$ sudo easy_install --upgrade six
$ sudo pip install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.6.0-py2-none-any.whl
安装完成后,输入如下命令,检测是否安装成功。
$ python
...
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
Hello, TensorFlow!
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42
>>>
如果报无法获取
CPU
信息错误,可以在上述代码中,修改添加如下几行:
NUM_CORES = 4 # Choose how many cores to use.
sess = tf.Session(
config=tf.ConfigProto(inter_op_parallelism_threads=NUM_CORES,
intra_op_parallelism_threads=NUM_CORES))
在使用TensorFlow之前,有必要了解如下几个概念:
1. 计算是用图的形式表示的。
2. Sessions是执行的入口,类似于SparkContext。
3. 数据是用tensor表示的。
4. Variables用来表示可变状态,比如模型参数。
5. 使用feeds和fetches从运算节点输入和输出数据。
TensorFlow计算框架要求所有的计算都表示成图,节点在图中被称为运算op(operation简称)。一个运算可以获得零个或者多个Tensors,经过计算,可以产生零个或者多个Tensors。一个Tensor是一个多维数组,举个例子,可以把一批图像数据表示成一个4维浮点数组[batch, height, width, channels]
计算图是通过Session提交,一个Session决定图中的运算该到那个设备上去计算,比如是选CPU还是CPU。运算op产生的结果在python中是一个numpy.ndarray数组对象,在C和C++中是tensorflow::Tensor实例。
构建图首先有构建运算op,op不一定要有输入,可以用Constant商量来构建一个运算节点,然后把它的结果输出到另外的运算中。如下是利用Constant生成一个简单的运算,并且以此构建了一个计算图。
import tensorflow as tf
# 创建一个1X2的矩阵matrix1
matrix1 = tf.constant([[3., 3.]])
# 创建一个2X1的矩阵matrix2
matrix2 = tf.constant([[2.],[2.]])
# 创建matrix1和matrix2的乘积运算,返回矩阵product
product = tf.matmul(matrix1, matrix2)
上面这个图中包含三个运算,两个constant()运算,一个矩阵乘法运算matmul()。要获得最终矩阵乘积的结果,需要用session提交这个图。
# 创建session对象
sess = tf.Session()
# 通过Session中run()方法提交计算图
result = sess.run(product)
print(result)
# ==> [[ 12.]]
# 运行完关闭这个Session
sess.close()
当Session运行完成后,需要手动关闭,当然你也可以利用“with”关键字,运行完自动关闭。
with tf.Session() as sess:
result= sess.run([product])
print(result)
在分布式运行环境下,一般不需要手动指出哪些运算该放到哪些机器上,比如CPU,GPU,但是框架提供了手动设置的功能。
with tf.Session() as sess:
withtf.device("/gpu:1"):
matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
product = tf.matmul(matrix1, matrix2)
...
目前支持这几种设备:
· "/cpu:0": The CPU of your machine.
· "/gpu:0": The GPU of your machine, if you have one.
· "/gpu:1": The second GPU of your machine, etc.
TensorFlow提供了一个类似iPython的机制,通过创建InteractiveSeesion对象来实现。
# Enter an interactive TensorFlow Session.
import tensorflow as tf
sess = tf.InteractiveSession()
x = tf.Variable([1.0, 2.0])
a = tf.constant([3.0, 3.0])
# Initialize 'x' using the run() method of itsinitializer op.
x.initializer.run()
# Add an op to subtract 'a' from 'x'. Run it and print the result
sub = tf.sub(x, a)
print(sub.eval())
# ==> [-2. -1.]
# Close the Session when we're done.
sess.close()
变量维护整个执行图过程中间的状态,比如Hadoop中的计数器就是一个变量。具体在机器学习任务中,当我们训练一个深度神经网络的时候,每一层的节点权重就是用Variable来表示的,在训练过程中,权重会不断地更新。看如下示例:
# Create a Variable, that will be initializedto the scalar value 0.
state = tf.Variable(0,name="counter")
# Create an Op to add one to `state`.
one = tf.constant(1)
new_value = tf.add(state, one)
update = tf.assign(state, new_value)
# Variables must be initialized by running an`init` Op after having
# launched the graph. We first have to add the `init` Op to thegraph.
init_op = tf.initialize_all_variables()
# Launch the graph and run the ops.
with tf.Session() as sess:
# Runthe 'init' op
sess.run(init_op)
# Printthe initial value of 'state'
print(sess.run(state))
# Runthe op that updates 'state' and print 'state'.
for _in range(3):
sess.run(update)
print(sess.run(state))
# output:
# 0
# 1
# 2
# 3
assign()是赋值运算,实际的执行是在 run() 被执行的时候开始。
获取一个op的运算结果,可以通过调用Session中的run()方法,同时可以获得多个结果,所有结果获取只需要执行一次run请求。
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
intermed = tf.add(input2, input3)
mul = tf.mul(input1, intermed)
with tf.Session() as sess:
result= sess.run([mul, intermed])
print(result)
# output:
# [array([ 21.], dtype=float32), array([ 7.],dtype=float32)]
之前介绍的数据输入使用Constant,直接输入一个明确的常量数据,TensorFlow同时提供了一种“占位符(placeholder)”方式,用来表示一个数据,然后在调用run,通过参数传入批量输入数据进去后,具体获取数据,具体可以如下示例:
# 创建两个输入input1和input2,这时这两个数据里面什么都没有
# 可以理解为申明了两个输入变量。
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.mul(input1, input2)
with tf.Session() as sess:
print(sess.run([output], feed_dict={input1:[7.], input2:[2.]}))
# output:
# [array([ 14.], dtype=float32)]
具体输入是feed_dict。
参考文献
1. https://github.com/tensorflow/tensorflow
2. http://www.tensorflow.org/
3. http://download.tensorflow.org/paper/whitepaper2015.pdf
廖博森 @DataSpark