TensorFlow低阶API(二)—— 张量
简介
正如名字所示,TensorFlow这一框架定义和运行涉及张量的计算。张量是对矢量和矩阵向潜在的更高维度的泛化。TensorFlow在内部将张量表示为基本数据类型的n维数组。
在编写TensorFlow程序时,您操作和传递的主要对象是 tf.Tensor。tf.Tensor对象表示一个部分定义的计算,最终会生成一个值。TensorFlow程序首先会构建一个tf.Tensor对象图,详细说明如何基于其它可用张量计算每个张量,然后运行运行改图的某些部分以获得期望的结果。
tf.Tensor具有以下属性:
- 数据类型(例如float32、int32或string)
- 形状
张量中的每个元素都具有相同的数据类型,且该数据类型一定是已知的。形状,即张量的维数和每个维度的大小,可能只有部分已知。如果其输入的形状也完全已知,则大多数操作会生成形状完全已知的张量,但在某些情况下,只能在执行图时获得张量的形状。
有些类型的张量有点特殊,TensorFlow指南的其它部分有所介绍。以下是主要特殊张量:
除了tf.Variable以外,张量的值是不变的,这意味着对于单个执行任务,张量只是一个值。然而,两次评估同一张量可能会返回不同的值。例如,该张量是从磁盘读取数据的结果,或是生成随机数的结果。
阶
tf.Tensor对象的阶是它本身的维数。阶的同义词包括:秩、等级或n维。请注意,TensorFlow中的阶与数学中矩阵的阶并不是同一个概念。如下表所示,TensorFlow中的每个阶都对应一个不同的数学实例:
| 阶 | 数学实例 |
|---|---|
| 0 | 标量(只有大小) |
| 1 | 矢量(大小和方向) |
| 2 | 矩阵(数据表) |
| 3 | 3 阶张量(数据立体) |
| n | n 阶张量(自行想象) |
0阶
以下摘要演示了创建0阶变量的过程:
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.85j, tf.complex64)
注意:字符串在 TensorFlow 中被视为单一项,而不是一连串字符。TensorFlow 可以有标量字符串,字符串矢量,等等。
1阶
要创建1阶tf.Tensor对象,您可以传递一个项目列表作为初始值。例如:
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.85j, 7.5 - 6.23j], tf.complex64)
更高阶
2阶tf.Tensor对象至少包含一行和一列:
mymat = tf.Variable([[7],[11]], tf.int16)
myxor = tf.Variable([[False, True],[True, False]], tf.bool)
linear_squares = tf.Variable([[4], [9], [16], [25]], tf.int32)
squarish_squares = tf.Variable([ [4, 9], [16, 25] ], tf.int32)
rank_of_squares = tf.rank(squarish_squares)
mymatC = tf.Variable([[7],[11]], tf.int32)
同样,更高阶的张量由一个n维数组组成。例如,在图像处理过程中,会使用许多4阶张量,维度对应批次大小、图像宽度、图像高度和颜色通道。
my_image = tf.zeros([10, 299, 299, 3]) # batch x height x width x color
获取tf.Tensor对象的阶
要确定tf.Tensor对象的阶,需要调用 tf.rank 方法。例如,以下方法会程序化的确定上一节中所定义的tf.Tensor的阶:
r = tf.rank(my_image)
# After the graph runs, r will hold the value 4.
引用tf.Tensor切片
由于tf.Tensor是n维单元数组,因此要访问tf.Tensor中的某一单元,需要指定n个索引。
0阶张量(标量)不需要索引,因为其本身就是单一数字。
对于1阶张量(矢量),可以通过传递一个索引访问某个数字:
my_scalar = my_vector[2]
请注意,如果想从矢量中动态的选择元素,那么在 [ ] 内传递的索引本身可以是一个标量tf.Tensor。
对于2阶及以上的张量,情况更为有趣。对于2阶tf.Tensor,传递两个数字会如预期般返回一个标量:
my_scalar = my_matrix[1, 2]
而传递一个数字则会返回矩阵子矢量,如下所示:
my_row_vector = my_matrix[2]
my_column_vector = my_matrix[:, 3]
符号 : 是python切片语法,意味“不要触碰该维度”。这对更高阶的张量来说很有用,可以帮助访问其子矢量,子矩阵,甚至其它子张量。
形状
张量的形状是每个维度中元素的数量。TensorFlow在图的构建中自动推理形状。这些推理的形状可能具有已知阶或未知阶。如果阶已知,则每个维度的大小可能已知或未知。
TensorFlow文件编制中通过三种符号约定来描述张量维度:阶、形状和维数。下表阐述了 三者如何相互关联:
| 阶 | 形状 | 维数 | 示例 |
|---|---|---|---|
| 0 | [] | 0-D | 0 维张量。标量。 |
| 1 | [D0] | 1-D | 形状为 [5] 的 1 维张量。 |
| 2 | [D0, D1] | 2-D | 形状为 [3, 4] 的 2 维张量。 |
| 3 | [D0, D1, D2] | 3-D | 形状为 [1, 4, 3] 的 3 维张量。 |
| n | [D0, D1, ... Dn-1] | n 维 | 形状为 [D0, D1, ... Dn-1] 的张量。 |
形状可以通过整形Python列表/元组或者 tf.TensorShape 表示。
获取tf.Tensor对象的形状
可以通过两种方法获取tf.Tensor的形状。在构建图的时候,询问有关张量形状的已知信息通常很有帮助。可以通过查看shape属性(属于tf.Tensor对象)获取这些信息。该方法会返回一个 TensorShape 对象,这样可以方便地表示部分指定的形状(因为在构建图的时候,并不是所有形状都完全已知)。
也可以获取一个将在运行时表示另一个tf.Tensor的完全指定形状的tf.Tensor。为此,可以调动 tf.shape 操作。如此以来,您可以构建一个图,通过构建其它取决于输入tf.Tensor的动态形状的张量来控制张量的形状。
例如,以下代码展示了如何创建大小与给定矩阵中的列数相同的零矢量
zeros = tf.zeros(my_matrix.shape[1])
改变tf.Tensor对象的形状
张量的元素数量是其所有形状大小的乘积。标量的元素数量永远是1。由于通常有许多不同的形状具有相同数量的元素,因此如果能改变tf.Tensor的形状并使其元素固定不变通常会很方便。为此,可以使用 tf.reshape。
以下示例演示了如何重构张量:
rank_three_tensor = tf.ones([3, 4, 5])
matrix = tf.reshape(rank_three_tensor, [6, 10]) # Reshape existing content into
# a 6x10 matrix
matrixB = tf.reshape(matrix, [3, -1]) # Reshape existing content into a 3x20
# matrix. -1 tells reshape to calculate
# the size of this dimension.
matrixAlt = tf.reshape(matrixB, [4, 3, -1]) # Reshape existing content into a
#4x3x5 tensor # Note that the number of elements of the reshaped Tensors has to match the
# original number of elements. Therefore, the following example generates an
# error because no possible value for the last dimension will match the number
# of elements.
yet_another = tf.reshape(matrixAlt, [13, 2, -1]) # ERROR!
数据类型
除维度外,张量还具有数据类型。如需数据类型的完整列表,请参阅 tf.Dtype 页面。
一个tf.Tensor只能有一种数据类型。但是,可以将任意数据结构序列化为 string 并将其存储在tf.Tensor中。
可以将tf.Tensor从一种数据类型转型到另一种(通过 tf.cast ):
# Cast a constant integer tensor into floating point.
float_tensor = tf.cast(tf.constant([1, 2, 3]), dtype=tf.float32)
要检查tf.Tensor的数据类型,请使用 Tensor.dtype 属性。
用Python对象创建一个tf.Tensor时,可以选择指定数据类型。如果不指定数据类型,TensorFlow会选择一个可以表示您的数据的数据类型。TensorFlow会将Python整数转型为 tf.int32,并将Python浮点型转型为 tf.float32。此外,TensorFlow使用Numpy在转换至数组时使用的相同规则。
评估张量
计算图构建完毕后,您可以运行生成特定tf.Tensor的计算并获取分配给它们的值。这对于程序调试通过非常有帮助,也是TensorFlow的大部分功能正常运行所必需的。
评估张量最简单的方法是使用 Tensor.eval 方法。例如:
constant = tf.constant([1, 2, 3])
tensor = constant * constant
print(tensor.eval())
eval 方法仅在默认tf.Session处于活跃状态时才起作用。例如:
sess = tf.Session() constant = tf.constant([1, 2, 3])
tensor = constant * constant
print(tensor.eval(session = sess))
Tensor.eval 会返回一个与张量相同的Numpy数组。
有时没法在没有背景信息的情况下评估tf.Tensor,因为它的值可能取决于无法获取的动态信息。例如,在没有为placehloder提供之的情况下,无法评估依赖于placeholder的张量:
p = tf.placeholder(tf.float32)
t = p + 1.0
t.eval() # This will fail, since the placeholder did not get a value.
t.eval(feed_dict={p:2.0}) # This will succeed because we're feeding a value
# to the placeholder.
请注意,可以提供任何tf.Tensor,而不仅仅是占位符。
其它模型构造可能会使评估tf.Tensor变得较为复杂。TensorFlow无法直接评估在函数内部或控制流结构内部定义的tf.Tensor。如果tf.Tensor取决于队列中的值,那么只有在某个项加入队列后才能评估tf.Tensor;否则。评估将被搁置。在处理队列时,请先调用 tf.train.start_queue_runners,在评估任何tf.Tensor。
输出张量
出于调试目的,您可能需要输出tf.Tensor的值。虽然 tfdbg 提供高级调试支持,但TensorFlow也有一个操作可以直接输出tf.Tensor的值。
请注意,输出tf.Tensor时很少使用以下模式:
t = <<some tensorflow operation>>
print(t) # This will print the symbolic tensor when the graph is being built.
# This tensor does not have a value in this context.
上述代码会输出tf.Tensor对象(表示延迟计算),而不是其值。TensorFlow提供了 tf.Print 操作,该操作会返回其第一个张量参数(保持不变),同时输出第二个参数传递的tf.Tensor集合。
要正确使用tf.Print,必须使用其返回值。例如:
t = <<some tensorflow operation>>
tf.Print(t, [t]) # This does nothing
t = tf.Print(t, [t]) # Here we are using the value returned by tf.Print
result = t + 1 # Now when result is evaluated the value of `t` will be printed.
在评估result时,会评估所有影响result的元素。由于result依靠t,而评估t会导致输出其输入(t的旧值),所以系统会输出t。
参考链接:https://tensorflow.google.cn/guide/tensors#rank
TensorFlow低阶API(二)—— 张量的更多相关文章
- TensorFlow低阶API(四)—— 图和会话
简介 TensorFlow使用数据流图将计算表示为独立的指令之间的依赖关系.这可生成低级别的编程模型,在该模型中,您首先定义数据流图,然后创建TensorFlow会话,以便在一组本地和远程设备上运行图 ...
- TensorFlow低阶API(一)—— 简介
简介 本文旨在知道您使用低级别TensorFlow API(TensorFlow Core)开始编程.您可以学习执行以下操作: 管理自己的TensorFlow程序(tf.Graph)和TensorFl ...
- TensorFlow低阶API(三)—— 变量
简介 TensorFlow变量是表示程序处理的共享持久状态的最佳方法. 我们使用tf.Variable类操作变量.tf.Variable表示可通过其运行操作来改变其值的张量.与tf.Tensor对象不 ...
- spark streaming kafka1.4.1中的低阶api createDirectStream使用总结
转载:http://blog.csdn.net/ligt0610/article/details/47311771 由于目前每天需要从kafka中消费20亿条左右的消息,集群压力有点大,会导致job不 ...
- TebsorFlow低阶API(五)—— 保存和恢复
简介 tf.train.Saver 类提供了保存和恢复模型的方法.通过 tf.saved_model.simple_save 函数可以轻松地保存适合投入使用的模型.Estimator会自动保存和恢复 ...
- Tensorflow object detection API 搭建物体识别模型(二)
二.数据准备 1)下载图片 图片来源于ImageNet中的鲤鱼分类,下载地址:https://pan.baidu.com/s/1Ry0ywIXVInGxeHi3uu608g 提取码: wib3 在桌面 ...
- 基于TensorFlow Object Detection API进行迁移学习训练自己的人脸检测模型(二)
前言 已完成数据预处理工作,具体参照: 基于TensorFlow Object Detection API进行迁移学习训练自己的人脸检测模型(一) 设置配置文件 新建目录face_faster_rcn ...
- 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现(二)[超详细教程] ubuntu16.04版本
本节对应谷歌开源Tensorflow Object Detection API物体识别系统 Quick Start步骤(一): Quick Start: Jupyter notebook for of ...
- TensorFlow.org教程笔记(二) DataSets 快速入门
本文翻译自www.tensorflow.org的英文教程. tf.data 模块包含一组类,可以让你轻松加载数据,操作数据并将其输入到模型中.本文通过两个简单的例子来介绍这个API 从内存中的nump ...
随机推荐
- 【旧文章搬运】Windbg+Vmware驱动调试入门(四)---VirtualKD内核调试加速工具
原文发表于百度空间,2009-01-09========================================================================== 今天又想起 ...
- 把文件类型转化为byte[]
转自:https://blog.csdn.net/xinxiqi/article/details/78899159 package com.sanqing.util; import java.io.B ...
- List集合与Array数组之间的互相转换
1.数组转换成List集合 采用java中集合自带的asList()方法就可以完成转换了 String[] array = new String[] {"zhu", "w ...
- (二十四)权限控制(粗粒度)-通过filter
扩展:权限控制(粗粒度)-通过filter 过滤器编写步骤: 1.编写一个类 实现filter接口 重写方法 2.编写配置文件 <filter> <filter-mapping> ...
- ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 14. ASP.NET Core Identity 入门
默认的身份认证好授权系统 UserManager用来操作用户的类, Singi用来身份认证的 添加AccountController 先声明SignInManager和UserManager这两个服务 ...
- Eclipse中,Open Type(Ctrl+Shift+T)失效后做法。
好几天ctrl shift T都不好用了,一直认为是工程的问题,没太在意,反正ctrl shift R也可也,今天看同事的好用,于是到网上查了一下解决的方法,刚才试了一下,应该是这个问题,明天就去公司 ...
- bzoj 3230: 相似子串【SA+st表+二分】
总是犯低级错误,st表都能写错-- 正反分别做一遍SA,预处理st表方便查询lcp,然后处理a[i]表示前i个后缀一共有多少个本质不同的子串,这里的子串是按字典序的,所以询问的时候直接在a上二分排名就 ...
- Qt文本读写之二:目录操作
一.简介 QDir类用来访问目录结构及其内容,可以操作路径名.访问路径和文件相关信息以及操作底层的文件系统,还可以访问Qt的资源系统.Qt使用"/"作为通用的目录分隔符和URLs的 ...
- Codeforces Round #302 (Div. 1) 训练
链接: http://codeforces.com/contest/543 过程: 惨淡的只做出了A和C 题解: A 题解: 简单的一道题 我们用$dp[i][j]$表示当前考虑到前num个人(这个另 ...
- scau 17967 大师姐唱K的固有结界 分类暴力 + RMQ
由于能放两次,那么分类, 1.连续使用,(这个直接O(n^2)暴力) 2.分开使用. 分开使用的话,首先暴力枚举,用T时间,能从第1个位置,唱到第几首歌,然后剩下的就是从pos + 1, n这个位置, ...