TensorFlow 中的张量是什么?形状、类型和特性 Opera职权范围
什么是张量?
拼音作为的姓名 TensorFlow TensorFlow 的核心对象是张量,它直接衍生自张量。在 TensorFlow 中,所有计算都涉及张量。张量是一个 n 维向量或矩阵,可以表示所有类型的数据。张量中的所有值都具有相同的数据类型,并且具有已知(或部分已知)的形状,而数据的形状就是矩阵或数组的维度。
张量可以来源于输入数据,也可以来源于计算结果。在TensorFlow中,所有操作都在一个图中执行。该图是一系列按顺序进行的计算。每个操作称为一个操作节点(op node),节点之间相互连接。
该图概述了运算及其节点间的连接,但并未显示具体值。节点间的边代表张量,即一种向运算中填充数据的方法。
在机器学习中,模型会接收一个称为特征向量的对象列表作为输入。特征向量可以是任何数据类型,它通常是填充张量的主要输入。这些值通过张量流入操作节点,该操作的结果会创建一个新的张量,而这个新张量又会用于下一个操作。所有这些操作都可以在图中查看。
张量的表示
在 TensorFlow 中,张量是 n 维特征向量(即数组)的集合。例如,如果我们有一个 2×3 的矩阵,其值从 1 到 6,我们可以将其写成如下所示的矩阵:
TensorFlow 将此矩阵表示为:
[[1, 2, 3], [4, 5, 6]]
如果我们创建一个取值范围为 1 到 8 的三维矩阵,那么相同的数据就可以用一个由两个堆叠面组成的方框来表示:
TensorFlow 将此矩阵表示为:
[ [[1, 2],
[[3, 4],
[[5, 6],
[[7,8] ]
注:张量可以用标量表示,也可以具有三维以上的维度。只是高维张量更难可视化。
张量的类型
在 TensorFlow 中,所有计算都通过一个或多个张量进行。tf.Tensor 是一个具有三个属性的对象:
- 唯一标签(名称)
- 尺寸(形状)
- 数据类型 (dtype)
使用 TensorFlow 执行的每个操作都涉及对张量的操作。您可以创建四种主要的张量类型:
tf.Variabletf.constanttf.placeholdertf.SparseTensor
在本教程中,您将学习如何创建一个 tf.constant 配备 tf.Variable.
在运行代码之前,请记住一点:本教程遵循 TensorFlow 1.x 的原始 API,其中先构建计算图,然后在会话中执行。TensorFlow 2 默认采用即时执行,因此下面的一些符号已被移动或删除。但它们仍然可以通过以下方式访问: tf.compat.v1 命名空间,该表将每个命名空间映射到其现代对应物。
| TensorFlow 1.x 符号 | TensorFlow 2 等效版本 |
|---|---|
tf.placeholder() |
无需。积极执行即可。 Python 或者直接使用 NumPy 值,以及 tf.function 该参数在图形模式下起着相同的作用。 |
tf.Session() 和 sess.run() |
直接调用该操作并读取结果,或者将计算过程封装起来。 tf.function. |
tf.get_variable() |
tf.Variable(),平铺 Python 对象 trac将变量而非集合视为国王。 |
tf.global_variables_initializer() |
不需要。 tf.Variable 在创建时立即初始化。 |
tf.div() |
tf.divide()另请注意子程序traction op 的拼写是 tf.subtract(),不 tf.substract(). |
在开始学习本教程之前,请确保已激活安装了 TensorFlow 的 conda 环境。该环境名为 hello-tf。
对于 macOS 用户:
source activate hello-tf
对于 Windows 用户:
activate hello-tf
完成上述步骤后,就可以导入 TensorFlow 了。
# Import tf import tensorflow as tf
创建 n 维张量
首先创建一个具有一维的张量,即标量。
要创建张量,您可以使用 tf.constant() 如下面的 TensorFlow 张量形状示例所示:
tf.constant(value, dtype, name = "") arguments - `value`: Value of n dimension to define the tensor. Optional - `dtype`: Define the type of data: - `tf.string`: String variable - `tf.float32`: Float variable - `tf.int16`: Integer variable - "name": Name of the tensor. Optional. By default, `Const_1:0`
要创建维度为 0 的张量,请运行以下代码。
## rank 0 # Default name r1 = tf.constant(1, tf.int16) print(r1)
输出
Tensor("Const:0", shape=(), dtype=int16)
如下带注释的版本所示,该输出的三个部分分别对应于三个张量属性。
您还可以使用以下方式为张量指定一个自定义名称: name 论据。
# Named my_scalar r2 = tf.constant(1, tf.int16, name = "my_scalar") print(r2)
输出
Tensor("my_scalar:0", shape=(), dtype=int16)
每个张量都以其张量名称显示。每个张量对象都由诸如唯一标签(名称)、维度(形状)和 TensorFlow 数据类型(dtype)等属性定义。
您可以通过更改数据类型来定义具有十进制值或字符串的张量。
# Decimal r1_decimal = tf.constant(1.12345, tf.float32) print(r1_decimal) # String r1_string = tf.constant("Guru99", tf.string) print(r1_string)
输出
Tensor("Const_1:0", shape=(), dtype=float32) Tensor("Const_2:0", shape=(), dtype=string)
可以按如下方式创建一维张量:
## Rank 1 r1_vector = tf.constant([1,3,5], tf.int16) print(r1_vector) r2_boolean = tf.constant([True, True, False], tf.bool) print(r2_boolean)
输出
Tensor("Const_3:0", shape=(3,), dtype=int16) Tensor("Const_4:0", shape=(3,), dtype=bool)
您可以注意到 TensorFlow 形状仅由 1 列组成。
要创建一个二维张量数组,需要在每一行之后加上右括号。请查看下面的张量形状示例。
## Rank 2 r2_matrix = tf.constant([ [1, 2], [3, 4] ],tf.int16) print(r2_matrix)
输出
Tensor("Const_5:0", shape=(2, 2), dtype=int16)
该矩阵有 2 行 2 列,分别填充了值 1、2、3 和 4。
通过添加另一层括号,可以构造一个三维矩阵。
## Rank 3 r3_matrix = tf.constant([ [[1, 2], [3, 4], [5, 6]] ], tf.int16) print(r3_matrix)
输出
Tensor("Const_6:0", shape=(1, 3, 2), dtype=int16)
结果与本教程前面所示的三维盒状图相符。
张量的形状
当你打印一个张量时,TensorFlow 会推断其形状。但是,你也可以直接使用 TensorFlow 读取其形状。 shape 属性。
下面,你需要构建一个包含 10 到 15 之间数字的矩阵,并检查其形状。 m_shape.
# Shape of tensor
m_shape = tf.constant([ [10, 11],
[12, 13],
[14, 15] ]
)
m_shape.shape
输出
TensorShape([Dimension(3), Dimension(2)])
该矩阵有 3 行、2 列。
TensorFlow 有一些有用的命令来创建一个用 0 或 1 填充的向量或矩阵。例如,如果你想创建一个特定形状为 1 、用 10 填充的一维张量,你可以运行以下代码:
# Create a vector of 0 print(tf.zeros(10))
输出
Tensor("zeros:0", shape=(10,), dtype=float32)
该属性也适用于矩阵。这里,您创建一个 10×10 的矩阵,其中所有元素均为 1。
# Create a vector of 1 print(tf.ones([10, 10]))
输出
Tensor("ones:0", shape=(10, 10), dtype=float32)
你可以利用给定矩阵的形状构造一个全为 1 的向量。该矩阵 m_shape 具有 3×2 维度,因此以下代码创建一个包含 3 行且全部填充为 1 的张量:
# Create a vector of ones with the same number of rows as m_shape print(tf.ones(m_shape.shape[0]))
输出
Tensor("ones_1:0", shape=(3,), dtype=float32)
如果将值 1 传递给括号,则会构造一个全为 1 的向量,其值等于矩阵的列数。 m_shape.
# Create a vector of ones with the same number of column as m_shape print(tf.ones(m_shape.shape[1]))
输出
Tensor("ones_2:0", shape=(2,), dtype=float32)
最后,你可以创建一个完全由 1 填充的 3×2 矩阵。
print(tf.ones(m_shape.shape))
输出
Tensor("ones_3:0", shape=(3, 2), dtype=float32)
资料类型
张量的第二个属性是数据类型。一个张量一次只能存储一种类型的数据,并且你可以用以下方式读取该类型的数据: dtype 属性。
print(m_shape.dtype)
输出
<dtype: 'int32'>
有时,您需要更改数据类型。在 TensorFlow 中,这可以通过以下方式实现: tf.cast 方法。
例如:
下面,浮点张量被转换为整数。 cast 方法。
# Change type of data type_float = tf.constant(3.123456789, tf.float32) type_int = tf.cast(type_float, dtype=tf.int32) print(type_float.dtype) print(type_int.dtype)
输出
<dtype: 'float32'> <dtype: 'int32'>
如果在创建张量时未指定数据类型参数,TensorFlow 会自动选择数据类型。TensorFlow 会猜测最可能的数据类型:例如,如果您传递文本,它会推断为字符串。
创造 Opera器
一些有用的 TensorFlow Opera职权范围
您已经了解如何使用 TensorFlow 创建张量。现在是时候学习如何执行数学运算了。
TensorFlow 包含了所有基本操作。你可以从一个简单的操作入手,使用 TensorFlow 方法计算一个数的平方根。这个操作很简单,因为构建张量只需要一个参数。
一个数的平方根是用以下方法构造的: tf.sqrt(x)其中 x 为浮点数。
x = tf.constant([2.0], dtype = tf.float32)
print(tf.sqrt(x))
输出
Tensor("Sqrt:0", shape=(1,), dtype=float32)
注意:输出结果是一个张量对象,而不是 2 的平方根。在本例中,您打印的是张量的定义,而不是运算的实际结果。在下面的“会话”部分,您将学习 TensorFlow 如何执行这些运算。
以下列出一些常用操作。其原理相同:每个操作都需要一个或多个参数。
tf.add(a, b)tf.subtract(a, b)tf.multiply(a, b)tf.divide(a, b)tf.pow(a, b)tf.exp(a)tf.sqrt(a)
例如:
# Add tensor_a = tf.constant([[1,2]], dtype = tf.int32) tensor_b = tf.constant([[3, 4]], dtype = tf.int32) tensor_add = tf.add(tensor_a, tensor_b) print(tensor_add)
输出
Tensor("Add:0", shape=(1, 2), dtype=int32)
Code 说明
创建两个张量:
- 一个张量,分别为 1 和 2
- 一个张量,分别为 3 和 4
将两个张量相加。
请注意,两个张量必须具有相同的形状。您还可以对这两个张量执行乘法运算。
# Multiply tensor_multiply = tf.multiply(tensor_a, tensor_b) print(tensor_multiply)
输出
Tensor("Mul:0", shape=(1, 2), dtype=int32)
变量
到目前为止,你只创建了常量张量,这本身用途有限。数据总是以不同的值到达,为了捕捉这种变化,你可以使用 Variable 类。变量表示一个节点,其值随时间变化。
要创建变量,您可以使用 tf.get_variable() 方法。
tf.get_variable(name = "", values, dtype, initializer) argument - `name = ""`: Name of the variable - `values`: Dimension of the tensor - `dtype`: Type of data. Optional - `initializer`: How to initialize the tensor. Optional If initializer is specified, there is no need to include the `values` as the shape of `initializer` is used.
例如,以下代码创建了一个包含两个随机值的二维变量。默认情况下,TensorFlow 返回一个随机值。您可以将变量命名为 var。
# Create a Variable ## Create 2 Randomized values var = tf.get_variable("var", [1, 2]) print(var.shape)
输出
(1, 2)
在这个例子中,你创建了一个包含一行两列的变量,因此你将 [1, 2] 作为变量的维度传递。
张量的初始值也可以为零。例如,在训练模型时,需要在计算特征权重之前设置初始值。下面,我们将这些初始值设置为零。
var_init_1 = tf.get_variable("var_init_1", [1, 2], dtype=tf.int32, initializer=tf.zeros_initializer) print(var_init_1.shape)
输出
(1, 2)
您还可以将常量张量的值传递给变量。您可以使用以下方法创建常量张量: tf.constant() 并使用该张量初始化变量。
该变量的前几个值为 10、20、30 和 40。新张量的形状为 2×2。
# Create a 2x2 matrix tensor_const = tf.constant([[10, 20], [30, 40]]) # Initialize the first value of the tensor equals to tensor_const var_init_2 = tf.get_variable("var_init_2", dtype=tf.int32, initializer=tensor_const) print(var_init_2.shape)
输出
(2, 2)
占位符
占位符的作用是为张量提供数据。占位符初始化将流入张量的数据。要提供占位符,您可以使用…… feed_dict 参数,占位符仅在会话内提供。
在下一个示例中,您将看到如何使用该方法创建占位符。 tf.placeholder在“会话”部分,您将学习如何向占位符提供实际的张量值。
语法是:
tf.placeholder(dtype,shape=None,name=None ) arguments: - `dtype`: Type of data - `shape`: dimension of the placeholder. Optional. By default, shape of the data - `name`: Name of the placeholder. Optional data_placeholder_a = tf.placeholder(tf.float32, name = "data_placeholder_a") print(data_placeholder_a)
输出
Tensor("data_placeholder_a:0", dtype=float32)
时间
TensorFlow 围绕 3 个主要组件运行:
- 图表
- 张量
- 时间
| 组件 | 描述 |
|---|---|
| 图表 | 图是 TensorFlow 的基础。所有数学运算(操作)都在图中执行。您可以将图想象成一个项目,所有操作都在其中进行。节点代表这些操作,它们可以吸收或创建新的张量。 |
| 张量 | 张量表示操作之间不断变化的数据。您之前已经了解了如何初始化张量。常量和变量的区别在于,变量的初始值会随时间变化。 |
| 时间 | 会话用于执行图中的操作。要将张量的值输入到图中,需要打开一个会话。在会话中,必须运行一个运算符才能生成输出。 |
图表和会话是相互独立的。您可以运行一个会话,并将值保存下来以供后续计算。
在下面的示例中,您将:
- 创建两个张量
- 创建操作
- 打开一个会话
- 打印结果
步骤 1)创建两个张量 x 和 y
## Create, run and evaluate a session
x = tf.constant([2])
y = tf.constant([4])
步骤 2)通过将 x 和 y 相乘来创建运算符。
## Create operator
multiply = tf.multiply(x, y)
步骤 3)打开一个会话。所有计算都在会话内进行,完成后需要关闭会话。
## Create a session to run the code sess = tf.Session() result_1 = sess.run(multiply) print(result_1) sess.close()
输出
[8]
Code 解释
tf.Session()打开一个会话。所有操作都在会话内进行。run(multiply)执行步骤 2 中创建的操作print(result_1)最后,您可以打印结果。close()关闭会话
结果显示8,即x与y的乘积。
另一种创建会话的方法是在一个代码块内。它的优点是会自动关闭会话。
with tf.Session() as sess: result_2 = multiply.eval() print(result_2)
输出
[8]
在会话的上下文中,您可以使用 eval() 执行操作的方法。它等价于 run() 并使代码更易读。
您可以创建一个会话并查看迄今为止创建的张量内的值。
## Check the tensors created before sess = tf.Session() print(sess.run(r1)) print(sess.run(r2_matrix)) print(sess.run(r3_matrix))
输出
1 [[1 2] [3 4]] [[[1 2] [3 4] [5 6]]]
变量默认为空,即使在创建张量之后也是如此。您需要先初始化变量才能使用它。 tf.global_variables_initializer() 调用此函数可以一次性初始化所有变量的值,这在训练模型之前很有帮助。
您可以查看之前创建的变量的值。请注意,您需要使用 run 函数来评估张量。
sess.run(tf.global_variables_initializer()) print(sess.run(var)) print(sess.run(var_init_1)) print(sess.run(var_init_2))
输出
[[-0.05356491 0.75867283]] [[0 0]] [[10 20] [30 40]]
您可以使用之前创建的占位符,并为其赋一个实际值。您需要将数据传递给 feed_dict 论据。
例如,您将取占位符 data_placeholder_a 的 2 的幂。
import numpy as np power_a = tf.pow(data_placeholder_a, 2) with tf.Session() as sess: data = np.random.rand(1, 10) print(sess.run(power_a, feed_dict={data_placeholder_a: data})) # Will succeed.
Code 说明
import numpy as np:导入 NumPy的 用于创建数据的库tf.pow(data_placeholder_a, 2)创建操作np.random.rand(1, 10)创建一个随机数据数组feed_dict={data_placeholder_a: data}:向占位符填充数据
输出
[[0.05478134 0.27213147 0.8803037 0.0398424 0.21172127 0.01444725 0.02584014 0.3763949 0.66022706 0.7565559 ]]
图表
TensorFlow 使用数据流图来呈现每个操作。数据流图旨在展现各个操作之间的数据依赖关系。数学公式或算法由一系列连续的操作组成,而图表则是一种便捷的方式来可视化这些计算是如何协调进行的。
该图展示了节点和边。节点代表一个操作,即计算单元。边代表张量:它可以生成新的张量,也可以消耗输入数据,具体取决于各个操作之间的依赖关系。
图的结构将各个操作(即节点)连接起来,并展示了每个操作的输入方式。请注意,该图并不显示操作的输出;它仅用于可视化操作之间的连接。
我们来看一个例子。假设你想计算以下函数的值:
TensorFlow 会构建一个用于执行函数的计算图。该计算图如下所示:
您可以轻松看到张量到达最终目的地所采用的路径。
例如,该 add 节点不能在两者之前运行 Mul 和 Pow 他们已经得出结果。图表显示 TensorFlow 将:
- 计算 x·z
Mul节点和 x² 在Pow节点 - 将这两个结果加在一起。
add节点 - 将 z 加到该总和中。
add_1节点 - 在公式中加入常数 5
add_2节点
x = tf.get_variable("x", dtype=tf.int32, initializer=tf.constant([5])) z = tf.get_variable("z", dtype=tf.int32, initializer=tf.constant([6])) c = tf.constant([5], name = "constant") square = tf.constant([2], name = "square") f = tf.multiply(x, z) + tf.pow(x, square) + z + c
Code 说明
- x:用常数值 5 初始化名为 x 的变量
- z:初始化一个名为 z 的变量,其值为常数 6
- c:初始化一个名为 c 的常量张量,其值为 5
- square:用常数值 2 初始化一个名为 square 的常量张量
- f:构造运算符
在这个例子中,变量的值保持不变。常数张量 c 是函数 f 中的常数参数,其值固定为 5;在图中,你可以看到这个参数位于名为“常数”的张量中。
此外,还为算符中的幂创建了一个常数张量。 tf.pow()这不是必须的,但这意味着指数在图中表现为称为正方形的圆圈。
从图中可以看出张量发生了什么变化,以及为什么函数返回 66:5 × 6 加 5² 加 6 加 5 等于 66。
以下代码在会话中执行函数。
init = tf.global_variables_initializer() # prepare to initialize all variables with tf.Session() as sess: init.run() # Initialize x and y function_result = f.eval() print(function_result)
输出
[66]
TensorFlow 基础知识快速参考
下面四个表格汇总了本教程中使用的所有命令,方便您查找所需命令,而无需返回示例进行浏览。
创建一个常量张量
| 常数 | 对象 |
|---|---|
| D0 | tf.constant(1, tf.int16) |
| D1 | tf.constant([1,3,5], tf.int16) |
| D2 | tf.constant([ [1, 2], [3, 4] ],tf.int16) |
| D3 | tf.constant([ [[1, 2],[3, 4], [5, 6]] ], tf.int16) |
创建运算符
| 创建运算符 | 摆件 |
|---|---|
| a + b | tf.add(a, b) |
| a*b | tf.multiply(a, b) |
创建变量张量
| 创建变量 | 对象 |
|---|---|
| 随机值 | tf.get_variable("var", [1, 2]) |
| 初始化第一个值 | tf.get_variable("var_init_2", dtype=tf.int32, initializer=[ [1, 2], [3, 4] ]) |
打开一个会话
| 时间 | 对象 |
|---|---|
| 创建会话 | tf.Session() |
| 运行会话 | tf.Session.run() |
| 评估张量 | variable_name.eval() |
| 关闭会话 | sess.close() |
| 按区块划分的会话 | with tf.Session() as sess: |




