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)

创建 n 维张量

# 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 将创建一个图来执行该函数。该图如下所示:

TensorFlow Graph 示例

TensorFlow Graph 示例

您可以轻松看到张量到达最终目的地所采用的路径。

例如,你可以看到操作 add 不能在 和 之前完成。该图解释了它将:

  1. 计算和:
  2. 加在一起
  3. 加至 2)
  4. 将 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: