Tensorflow官方API文档,Python版本、Java版本、C++版本和Go版本,以下介绍Python版本
一般为了编程方便,在引入依赖时,使用tf代替tensorflow,如下,下文内容中用TF代替Tensorflow
import tensorflow as tf
在TF程序中,主要操作的对象是tf.Tensor,即在TF框架中,数据都以tf.Tensor类型进行组织和存储,熟悉面向对象编程的话应该很容易理解(下文“Tensor对象”和“Tensor变量”的含义相同),可以看到该类定义在
>>> tf.Tensor
每个Tensor对象包括数据类型(data type)和形状(shape)两个基本属性,每个对象的数据类型是唯一的,由于python本身是一种弱类型的语言,因此创建Tensor变量时可以不指定数据类型,而是通过运行时判别。Tensor在数学上的名称是张量,张量会有阶数,零阶张量是标量,一阶张量是向量,二阶张量是矩阵,阶数可以更多,例如三阶张量、四阶张量等,如下表(源自https://www.tensorflow.org/programmers_guide/tensors)
Rank | Math entity |
---|---|
0 | Scalar (magnitude only) |
1 | Vector (magnitude and direction) |
2 | Matrix (table of numbers) |
3 | 3-Tensor (cube of numbers) |
n | n-Tensor (you get the idea) |
TF提供了以下函数可以初始化Tensor对象。
1) placeholder函数
x = tf.placeholder(tf.float32, [None, 1024])
初始化Tensor变量并赋值给x,类型为tf.float32,[None, 1024]表示行数不确定,列数为1024。使用print输出,可看到如下结果
Tensor("Placeholder:0", shape=(?, 1024), dtype=float32)
*注意字母p小写,在r1.4版本中大写无效
占位变量的意义在于,定义模块时,例如线性模型 "y = x * W + b"(TF中定义如下),其中 W 和 b 是模型参数,可以直接进行随机初始化,而 x 是我们的训练样本,只在在训练时输入训练数据后才有实际的值,因此,只能先声明占位变量,使得模型可以用代码表示出来,笔者认为这其实也是为什么 tensor变量需要用 eval() 方法或者通过 session.run() 之后才能看到具体的值,否则只能看到类型定义(下文举例说明)
y = tf.matmul(x, W) + b
2)Variable函数(示例源自https://www.tensorflow.org/programmers_guide/tensors)
一阶张量初始化如下,
mystr = tf.Variable(["Hello"], tf.string)
cool_numbers = tf.Variable([3.14159, 2.71828], tf.float32)
first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32)
its_very_complicated = tf.Variable([(12.3, -4.85), (7.5, -6.23)], tf.complex64)
二阶张量初始化,结构为1024行、10列,如下
W = tf.Variable(tf.zeros([1024, 10]))
*注意字母V大写
零阶张量初始化如下
mammal = tf.Variable("Elephant", tf.string)
ignition = tf.Variable(451, tf.int16)
floating = tf.Variable(3.14159265359, tf.float64)
its_complicated = tf.Variable((12.3, -4.85), tf.complex64)
高阶张量初始化如下
mystr = tf.Variable(["Hello"], tf.string)
cool_numbers = tf.Variable([3.14159, 2.71828], tf.float32)
first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32)
its_very_complicated = tf.Variable([(12.3, -4.85), (7.5, -6.23)], tf.complex64)
对于张量来说,使用 eval() 方法可以查看张量的具体数值,该方法返回 一个numpy数组,例如
>>> x=tf.zeros(10)
>>> x.eval()
array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)
使用tf.rank()函数可以获取一个张量的阶数,例如
>>> rk=tf.rank(x)
>>> rk.eval()
1
但是,一般需要输出一个Tensor对象的值 时,要通过session来输出,例如
>>> sess=tf.InteractiveSession()
>>> norm = tf.random_normal([2, 3], mean=-1, stddev=4)
>>> print(sess.run(norm))
[[-6.23512602 0.08872831 -4.23519659]
[-0.37180948 0.1739198 -3.45424032]]
因为在TF框架中,对于Tensor对象所指定的运算是动态执行的,例如,初始化一个正态随机的一阶张量tn,和一个全1的一阶张量t,再将他们相加,每次的结果会不同,如下
>>> tn = tf.random_normal([1,10], mean=-1, stddev=4)
>>> t = tf.ones(10)
>>> tmp = tn + t
>>> tmp.eval()
array([[-9.58623028, 0.70157331, 7.56238651, 0.12382185, 1.78133655,
-2.60228705, 2.09345794, 0.78153497, 4.40496349, 0.13798881]], dtype=float32)
>>> tmp.eval()
array([[-7.71660995, 6.11020565, -0.91900563, 1.48415923, -2.51670742,
0.39632952, 1.62038779, -1.51520824, -1.37992334, 2.52663517]], dtype=float32)
>>> tmp.eval()
array([[-1.53174448, 4.66375542, 0.84976286, -0.25260258, -4.49670076,
-1.02720261, 2.21190119, -1.00379395, 4.77040529, 5.89726973]], dtype=float32)
所以使用eval()方法的前提是,当前运行时已经创建了默认的session,例如创建交互式session,sess = tf.InteractiveSession(),否则会出现 如下错误 ,找不到缺省sesson
raise ValueError("Cannot evaluate tensor using `eval()`: No default "
ValueError: Cannot evaluate tensor using `eval()`: No default session is registered. Use `with sess.as_default()` or pass an explicit session to `eval(session=sess)`
而且使用 sess = tf.Session() 时,同样会出现如上问题。因此顾名思义,TF的交互式session就是在使用python交互式命令时使用的。
文档中指出,创建Tensor变量的最佳实践是通过 get_variable() 函数来实现,最简单的方式只需要指定名称和形状,如下
my_variable = tf.get_variable("my_variable", [1, 2, 3])
my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3], dtype=tf.int32, initializer=tf.zeros_initializer)
other_variable = tf.get_variable("other_variable", dtype=tf.int32, initializer=tf.constant([23, 42]))
3)constant
*注意字母c小写
4)SparseTensor
*注意字母S大写