文章

Tensorflow - 新的开始

关于

正好要在工作中使用tf做一些事情,之前都是零散的读过一些分析的文章,这次系统的从头开始学习和理解一边Tensorflow,在这里记录一下这个过程与大家分享。

我写文章会略过一些非常容易搜索到的内容(比如如何安装tf?),只提出一些我认为关键的问题和概念以及我的理解。

简介

简介省略,感兴趣移步:Tensorflow Get Started 以下是摘要和个人理解:

照搬原文,写的很好:

TensorFlow is a programming system in which you represent computations as graphs.Nodes in the graph are called ops (short for operations).An op takes zero or more Tensors, performs some computation, and produces zero or more Tensors. A Tensor is a typed multi-dimensional array. For example, you can represent a mini-batch of images as a 4-D array of floating point numbers with dimensions [batch, height, width, channels].

A TensorFlow graph is a description of computations. To compute anything, a graph must be launched in a Session.A Session places the graph ops onto Devices, such as CPUs or GPUs, and provides methods to execute them.These methods return tensors produced by ops as numpy ndarray objects in Python, and as tensorflow::Tensor instances in C and C++.

简单的说Tensorflow就是一个用图来抽象计算方法的架构,图中的节点就是一个操作,节点的输入可能是零个或多个Tensor,输出也可能是零个或多个Tensor,而Tensor可以理解为一个多维数组。

Session就是某个图的运行时,可以把图应用在不同的环境里运行,譬如CPU/GPU、混合CPU/GPU、分布式运算等等。

因此可以看到Tensorflow实际上定义了一种“声明式”的语言,其需要首先声明所有的操作然后一次运行(作为对比的例子,另外一种是“命令式”的所有操作都是立即执行的)。这两种方法各有利弊,声明式的方式可以使得框架更加容易对计算进行优化(比如相同子图消除等等),命令式的方式要更加灵活方便执行控制。

概念

以下将介绍Tensorflow里的一些基本概念。

  • Graph

    Graph是整个计算图的定义,其是由包含了所有计算操作的拓扑图组成的。需要注意的是很多非计算操作(譬如Saver)都需要在Graph上注册节点。因此Graph更一般的定义是一个操作的拓扑定义。

  • Node

    图上的节点,对应于一个具体的操作。操作可以是算术运算也可以是某种IO操作等等。一个Node可以输入零个或多个Tensor,也可以输出零个或多个Tensor。

  • Session

    Graph的运行时环境。Graph本身是操作的定义,因此并不包含运行的输入、过程和结果数据。如果要运行图中定义的操作,就需要生成一个Session,给定要计算的目标、输入的数据来运行Session。

  • Tensor

    一个多维数组,图上节点之间传递的数据。

  • Rank

    Rank本意是矩阵的秩,不过Tensor Rank和Matrix Rank的意义不太一样,这里就还叫Rank防止混淆了。Tensor Rank的意义是维度,比如Rank = 1就是向量,Rank = 2就是矩阵了。(Rank = 0就是一个值了)

  • Shape

    Shape就是Tensor在各个维度上的长度组成的数组,譬如Rank = 0的Tensor Shape = [](因为没有维度嘛),Rank = 1的Tensor Shape = [a],Rank = 2的Tensor Shape = [a, b]这样。

  • Type

    Type就是Tensor中每一个元素的数据类型了,基本上就是字符串、不同精度的整型、浮点型以及布尔型等。

  • Variable

    根据以上Tensor的定义可以看出Tensor是一个动态概念,当一次运行结束之后Tensor的内容就消失了。因此如果要在一个Session中保存数据的话就需要使用到Variable了。Variable中保存的内容不会因为运行结束而销毁,只要在Session的生存期内其值是一直存在的。

入门

参考自: Introduction

注:以下是Tensorflow早期版本的样例,修订文章的时候保留了这一部分,新版本的样例会在以后补充上。

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
import tensorflow as tf
import numpy as np

# Create 100 phony x, y data points in NumPy, y = x * 0.1 + 0.3
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data * 0.1 + 0.3

# Try to find values for W and b that compute y_data = W * x_data + b
# (We know that W should be 0.1 and b 0.3, but TensorFlow will
# figure that out for us.)
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b

# Minimize the mean squared errors.
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

# Before starting, initialize the variables.  We will 'run' this first.
init = tf.initialize_all_variables()

# Launch the graph.
sess = tf.Session()
sess.run(init)

# Fit the line.
for step in range(201):
    sess.run(train)
    if step % 20 == 0:
        print(step, sess.run(W), sess.run(b))

# Learns best fit is W: [0.1], b: [0.3]

首先创建了一个长度为100的向量,元素用随机数,然后转换为np.float32,而后进行向量计算,使用公式y = x * 0.1 + 0.3生成向量y。接下来的代码就是根据x和y进行线性拟合,推测w, b。

创建两个tf变量,然后用平方误差均值作为损失函数,optimizer的目标很明确就是尽可能的减小损失函数的输出,这里的optimizer是梯度下降的方法。关于梯度下降文章很多了。

这段代码很简单,我有一个不明确的疑惑就是tf怎么知道在对拟合函数进行优化的时候可以调整w和b的数值?是因为w和b是Variable吗?

测试输出:

1
2
3
4
5
6
7
8
9
10
11
array([-0.45210266], dtype=float32), array([ 0.82762206], dtype=float32))
(20, array([-0.07229783], dtype=float32), array([ 0.39228484], dtype=float32))
(40, array([ 0.05423164], dtype=float32), array([ 0.32451412], dtype=float32))
(60, array([ 0.08784232], dtype=float32), array([ 0.30651182], dtype=float32))
(80, array([ 0.09677048], dtype=float32), array([ 0.3017298], dtype=float32))
(100, array([ 0.0991421], dtype=float32), array([ 0.3004595], dtype=float32))
(120, array([ 0.09977212], dtype=float32), array([ 0.30012208], dtype=float32))
(140, array([ 0.09993947], dtype=float32), array([ 0.30003244], dtype=float32))
(160, array([ 0.09998392], dtype=float32), array([ 0.30000862], dtype=float32))
(180, array([ 0.09999574], dtype=float32), array([ 0.30000231], dtype=float32))
(200, array([ 0.09999888], dtype=float32), array([ 0.30000061], dtype=float32))`

可以看到w趋近于0.1,b趋近于0.3

OK,本文到此结束,介绍了一些Tensorflow的基本概念,下一章开始从Mnist tutorial for ml beginners开始。

本文由作者按照 CC BY 4.0 进行授权