TensorFlow 基础知识:张量、形状、类型、会话和 Opera职权范围
什么是张量?
Tensorflow 的名称直接源自其核心框架:Tensor。在 Tensorflow 中,所有计算都涉及张量。张量是一个 n 维向量或矩阵,表示所有类型的数据。张量中的所有值都具有相同的数据类型,并且形状已知(或部分已知)。数据的形状是矩阵或数组的维数。
张量可以源自输入数据或计算结果。在 TensorFlow 中,所有操作都在图内进行。图是一组连续进行的计算。每个操作称为 op 节点,彼此连接。
该图概述了节点之间的操作和连接。但是,它不显示值。节点的边缘是张量,即一种用数据填充操作的方式。
在机器学习中,模型由一串称为特征向量的对象组成。特征向量可以是任何数据类型。特征向量通常是填充张量的主要输入。这些值将通过张量流入运算节点,此运算/计算的结果将创建一个新的张量,而该张量又将用于新的运算。所有这些运算都可以在图中查看。
张量的表示
在 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.变量
- tf.常数
- tf.占位符
- tf.稀疏张量
在本教程中,您将学习如何创建 tf.constant 和 tf.Variable。
在开始本教程之前,请确保您已使用 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)
# 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)
可以按如下方式创建 1 维张量:
## Rank 1r1_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 列组成。
要创建 2 个张量维度的数组,您需要在每行后面关闭括号。查看下面的 Keras 张量形状示例
## 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)
您可以使用给定矩阵的形状来创建一个由 3 组成的向量。矩阵 m_shape 是 2×3 维。您可以使用以下代码创建一个由 XNUMX 填充的 XNUMX 行张量:
# 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 传递到括号中,则可以构建一个等于矩阵 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)
最后,你可以创建一个 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 会猜测最可能的数据类型。例如,如果您传递文本,它会猜测它是一个字符串并将其转换为字符串。
创建操作员
一些有用的 TensorFlow 运算符
您已经了解如何使用 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.减法(a,b)
- tf.multiply(a,b)
- tf.div(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)
代码说明
创建两个张量:
- 一个张量,分别为 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 matrixtensor_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 的基础。所有数学运算 (op) 都在图表内执行。您可以将图表想象为一个项目,其中执行所有运算。节点代表这些 op,它们可以吸收或创建新的张量。 |
张量 | 张量表示操作之间进展的数据。您之前了解了如何初始化张量。常量和变量之间的区别在于变量的初始值会随时间而变化。 |
时间 | 会话将从图中执行操作。要将张量的值提供给图,您需要打开一个会话。在会话中,您必须运行一个运算符来创建输出。 |
图表和会话是独立的。您可以运行会话并获取稍后用于进一步计算的值。
在下面的示例中,您将:
- 创建两个张量
- 创建操作
- 打开一个会话
- 打印结果
步骤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]
代码说明
- 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.
代码说明
- 将 numpy 导入为 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 不能在 和 之前完成。该图解释了它将:
- 计算和:
- 加在一起
- 加至 2)
- 将 3) 添加到
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
代码说明
- x:用常数值 5 初始化名为 x 的变量
- z:初始化一个名为 z 的变量,其值为常数 6
- c:初始化一个名为 c 的常量张量,其值为 5
- square:用常数值 2 初始化一个名为 square 的常量张量
- f:构造运算符
在这个例子中,我们选择保持变量的值不变。我们还创建了一个名为 c 的常量张量,它是函数 f 中的常量参数。它采用固定值 5。在图中,您可以在名为 constant 的张量中看到这个参数。
我们还在运算符 tf.pow() 中为幂构建了一个常数张量。这不是必需的。我们这样做是为了让您可以在图中看到张量的名称。它是称为正方形的圆圈。
从图中,你可以了解张量会发生什么,以及它如何返回 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,初始化器=[[1,2],[3,4]]) |
打开一个会话
时间 | 对象 |
---|---|
创建会话 | tf.Session() |
运行会话 | tf.Session.run() |
评估张量 | 变量名.eval() |
关闭会话 | sess.close() |
按区块划分的会话 | 使用 tf.Session() 作为 sess: |