在 TensorFlow 的 Python API 中, a , b , and c 都是Tensor 对象. 一个Tensor 对象是一个操作(operation)结果的字符别名,它实际上并不储存操作(operation)输出结果的值。 TensorFlow 鼓励用户去建立复杂的表达式(如整个神经网络及其梯度)来形成 data flow graph 。 然后你可以将整个 data flow graph 的计算过程交给一个 TensorFlow 的Session , 此Session 可以运行整个计算过程,比起操作(operations)一条一条的执行效率高的多。
对CPU设备而言,支持的设备名是"/device:CPU:0" (或"/cup:0" ),对第i 个 GPU 设备是"/device:GPU:i"(或"/gpu:i" )
在with tf.device(name): context 中创建操作(operation),这样可以在指定的设备上运行操作(operation)。关于 TensorFlow 怎样将操作(operations)分配给设备的细节,参看TensorFlow使用 GPU ; 使用多 GPU 的示范
实例参看CIFAR-10 教程。
TensorFlow 支持许多种不同的数据类型和 tensor shape 。
Feeding 是 TensorFlow Session API 的一种机制,它允许在运行时用不同的值替换一个或多个 tensor 的值。Session.run() 的参数feed_dict 是一个字典, 它将Tensor 对象映射为 numpy 的数组(和一些其他类型)。 在执行 step 时,这些数组就是 tensor 的值。常会碰到某些 tensor 总是有值的,比如 inputs。tf.placeholder() 操作(operation)允许定义一种必须提供值的 tensor ,也可以随意限定它们的 shape。
如果t 是一个Tensor 对象, t.eval() 就是sess.run(t) ( sess 是当前默认 session)的简写。 以下两段小程序是等效的:
# 使用 `Session.run()`.
sess = tf.Session()
c = tf.constant(5.0)
print sess.run(c)
# 使用 `Tensor.eval()`.
c = tf.constant(5.0)
with tf.Session():
print c.eval()
在第二个例子中, session 的作用就象context manager , context manager 在with 块的生存期,将 session 作为默认的 session。对简单应用的情形(如单元测试),context manager 的方法可以得到更简洁的代码; 如果你的代码要处理多个 graph 和 session ,更直白的方式可能是显式调用Session.run() 。
Session 能够占有资源,例如variables,queues, 和readers; 这些资源会使用相当大量的内存。 当调用Session.close() 关闭 session 后,这些资源(和相关的内存)就被释放了。作为调用Session.run() 过程的一部分所创建的 tensors, 会在调用时或调用结束前释放。
最初的 TensorFlow 开源版本支持单一计算机内的多设备(CPUs 和 GPUs)。
TensorFlow 运行时会在许多不同的层面(dimensions)并行图的执行(graph execution):
TensorFlow 被设计成为支持多种客户端语言。当前支持最好的客户端语言是Python。C++ 客户端 API 提供了启动 graph 和运行 steps 的接口;
TensorFlow 支持多 GPU 和 CPU。请注意, TensorFlow 只使用计算能力(compute capability)大于 3.5 的 GPU 设备。
reader 类和queue 类提供特殊的操作(operations),这些操作(operations)在有可用的输入(对有界队列则是空闲空间)前会阻塞。使用这些操作(operations)可以创建复杂的输入流水线(input pipelines) ,不过,这会使 TensorFlow 的计算过程更复杂。
在某一 session 中,当一开始运行tf.Variable.initializer 操作(operation)时,变量就会被创建。此session 关闭后它就被摧毁(destroyed)了。
变量可以进行并发的读和写操作(operation)。由于变量是并发(concurrently)更新的, 所以从一个变量中读出的值可能会改变。在不互斥的条件下,对一个变量的并发的许多赋值操作(operation)是默认允许运行的。在对一个变量赋值时,如果想要加锁,可以将use_locking=True 传递给Variable.assign() 。
在 TensorFlow 中,一个 tensor 具备静态和动态两种 shape 。静态的 shape 可以用tf.Tensor.get_shape()方法读出:这种 shape 是由此 tensor 在创建时使用的操作(operations)推导得出的,可能是partially complete 的。如果静态 shape 没有完整定义的话,则一个 tensor 的动态 shape 可通过求tf.shape(t) 的值得到。
tf.Tensor.set_shape() 方法会更新一个Tensor 对象的静态 shape ,当静态 shape 信息不能够直接推导得出的时候,此方法常用来提供额外的 shape 信息。它不改变此 tensor 动态 shape 的信息。tf.reshape() 操作(operation)会以不同的动态 shape 创建一个新的 tensor。
如果能够创建一个 graph ,在批次大小可变(variable batch sizes)的情形下也可以正常运作将会是十分有用的,例如可以使用相同的代码完成(小)批量训练((mini-)batch training)和单例推导(single-instance inference)。这样生成的 graph 可以保存起来当作协议缓存(protocol buffer),也可以导入至其他的程序。创建一个可变大小的 graph 时,要记住最重要的事情是不要将批次大小(batch size)编码成为 Python 常数,而是用一个字符性(symbolic)的Tensor 来表示。下面的提示可能会有用:
• 用batch_size = tf.shape(input)[0] 从一个叫input 的Tensor 提取批次的维度(batch dimention),再将其存入一个名为batch_size 的Tensor 。
• 用tf.reduce_mean() 而不是tf.reduce_sum(...) / batch_size 。
• 如果你使用placeholders for feeding input,你就可以用tf.placeholder(..., shape=[None, ...]) 通过创建 placeholder 来具体指定一个可变的批次维度(variable batch dimention)。shape 的None 元素与可变大小的维度(a variable-sized dimension)相对应。
给你的 TensorFlow graph 增加 summary 操作(ops),接着用SummaryWriter 将这些 summaries 写入一个 logdirectory。然后用以下命令启动 TensorBoard 。
`python tensorflow/tensorboard/tensorboard.py --logdir=path/to/log-directory`
有两种主要的操作(operation)来处理自定义格式的数据。
1、较简单的方法:用 Python 编写一段分词的代码(parsing code),将数据转换成为 numpy array,然后用此数据把一个 [ tf.placeholder() ] (../api_docs/python/io_ops.md#placeholder) 传送给一个 tensor 。
2、更高效的方法是添加一个用 C++ 编写的操作(op),用这个操作(operation)来对你的数据格式进行分词(parse)。
TensorFlow 的操作注册机制允许你定义几种输入:单独的 tensor,一列相同类型的 tensors (例如把一个可变长列表中的 tensors 相加), 一列不同类型的 tensors (例如将一个 tuple 中的 tensors 入队(enqueue))。
只用 Python 2.7 进行了测试。了解对 Python 3 的兼容性来说,还需要有一些修改。
TensorFlow Python API 遵循PEP8 惯例。* 特别的,这里使用CamelCase 格式作为类名, snake_case 格式作为方程名, 方法名, 和属性名。我们也遵循Google Python style guide。
TensorFlow C++ 代码遵循Google C++ style guide。
(*注: 有一条例外: 使用 2 空格缩进而不是 4 空格缩进)
1、tf.boolean_mask()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf
x = tf.constant(2)
y = tf.constant(20)
z = tf.Variable([[6,1,2],[3,4,5],[0,0,0],[8,2,4]])
mask=z[:,0]>0
res = tf.boolean_mask(z,mask)
init_assign = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_assign)
print sess.run(res)
运行结果:
[[6 1 2]
[3 4 5]
[8 2 4]]
2、tf.concat
tf.concat(concat_dim, values, name=”concat”)
Concatenates tensors along one dimension.
将张量沿着指定维数拼接起来。个人感觉跟前面的pack用法类似
t1 = [[1, 2, 3], [4, 5, 6]]
t2 = [[7, 8, 9], [10, 11, 12]]
tf.concat(0, [t1, t2])
#==> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
tf.concat(1, [t1, t2])
#==> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]
3、tf.ones_like(tensor, dtype=None, name=None)
该方法用于创建一个所有参数均为1的tensor对象
给定一个tensor(tensor对象),该方法会返回一个类似当前参数类型以及维度的对象,但是所有参数的值均为1.当参数dtype选定了后,所有返回参数的类型也会变成选定的类型
该方法实际上为一个拷贝函数:默认情况下,它会拷贝参数tensor的类型,维度等数据,并将其中的值设置为1.当参数dtype设置后,那么拷贝后的tensor对象
参数:
name: 该操作别名 (可选).
返回:
所有参数为1的tensor对象
4、tf.gather(params, indices, validate_indices=None, name=None)
合并索引indices所指示params中的切片
5、tf.reshape(tensor, shape, name=None)
改变tensor的形状
# tensor ‘t’ is [1, 2, 3, 4, 5, 6, 7, 8, 9]
# tensor ‘t’ has shape [9]
reshape(t, [3, 3]) ==>
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
#如果shape有元素[-1],表示在该维度打平至一维
# -1 将自动推导得为 9:
reshape(t, [2, -1]) ==>
[[1, 1, 1, 2, 2, 2, 3, 3, 3],
[4, 4, 4, 5, 5, 5, 6, 6, 6]]
6、tf.tile(input, multiples, name=None)
矩阵合并
import tensorflow as tf
temp = tf.tile([1,2,3],[2])
temp2 = tf.tile([[1,2],[3,4],[5,6]],[2,3]) #2:行元素;3:列元素重复次数
with tf.Session() as sess:
print(sess.run(temp))
print(sess.run(temp2))
[1 2 3 1 2 3]
[[1 2 1 2 1 2]
[3 4 3 4 3 4]
[5 6 5 6 5 6]
[1 2 1 2 1 2]
[3 4 3 4 3 4]
[5 6 5 6 5 6]]
tf.gather(params, indices, validate_indices=None, name=None) |