量化百科

Tensorflow学习笔记(1): 张量及其属性

由ypyu创建,最终由ypyu 被浏览 9 用户

本文主要介绍tf.Tensor的各种常用属性,张量是对矢量和矩阵向潜在的更高维度的泛化。对内,TensorFlow 将张量表现为基本数据类型的 n 维数组。

在编写 TensorFlow 程序时,操控和传递的主要目标是 tf.Tensortf.Tensor 目标表示一个部分定义的计算,最终会产生一个值。TensorFlow 程序首先建立 tf.Tensor 目标图,详细说明如何基于其他可用张量来计算每个张量,然后运行该图的部分内容以获得所期望的结果。

tf.Tensor 有以下属性:

  • 数据类型(例如 float32int32string
  • 形状

张量中的每个元素都具有相同的数据类型,且该数据类型一定是已知的。形状,即张量的维数和每个维度的大小,可能只有部分已知。如果其输入的形状也完全已知,则大多数指令会生成形状完全已知的张量,但在某些情况下,只能在图的执行时间找到张量的形状。

主要的张量包括:

  1. tf.Variable 变量张量,一般表示机器学习参数
  2. tf.constant 常量张量,一般用来表示常量,不可改变
  3. tf.placeholder 占位符张量,一般用来表示机器学习中输入的数据 left{ x,y right}

rank 阶 shape 形状

tf.Tensor就是它本身的维数,TensorFlow 中的阶与数学中矩阵的阶并不是同一个概念,TensorFlow 中的每个阶都对应一个不同的数学实例。

tf.Tensor的shape就是每个维度中元素的数量, 例如一个 2times2 的矩阵的rank是2,表示这个矩阵有两个维度,而其shape为 (2,2) 表示第一个维度上有两个元素,而第二个维度上也有两个元素。

查看tf.Tensor的rank需调用tf.rank方法。

查看tf.Tensor的shape需要调用读取shape属性 ,该方法会返回一个TensorShape目标。

tf.rank(myvariable)
myvariable.shape

我们用代码进行说明不同rank和shape的变量。

0阶变量 (scalar)

0阶变量用来表示标量(scalar),只有大小,可以认为是一个值,直接传递一个值作为初始值

shape = ()由于没有维度,因此返回为()

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)

print mammal.shape

************************************输出**************************************

()

1阶变量 (vector)

1阶变量用来表示矢量/向量(vector),具有大小和方向,

shape = (m, ) , 表示只有一个维度,该维度上有m个元素

要创建 1 阶tf.Tensor目标,可以传递一个list作为初始值

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)
print mystr.shape

************************************输出**************************************
(1,)

2阶变量

2阶变量,表示矩阵

shape = (m, n),表示有两个维度,第一个维度上m个元素,表示m个向量,每个向量具有n个元素

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)
print linear_squares.shape

************************************输出**************************************
(4,1)

更高阶的张量

同样由一个 n 维数组组成。例如,在图像处理过程中,会使用许多 4 阶张量,维度对应批量示例,图像宽度,图像高度和颜色通道

my_image = tf.zeros([10, 299, 299, 3])  # batch x height x width x color

reshape

张量的元素数量是其所有形状大小的乘积,通常我们需要对张量的形状进行变换,例如我们在训练模型时输入是一个1阶张量,但我们需要采用mini-batch gradient descent来进行模型训练,那么就需要把1阶张量reshape成一个2阶张量,由多个batch组成。这一点可以通过tf.reshape来完成。

下面代码演示如何reshape张量,下面我们首先得到一个3阶变量, shape = (3, 4, 5)

rank_three_tensor = tf.ones([3, 4, 5])  # 一个3阶变量,共3*4*5=60个元素
print rank_three_tensor.shape
************************************输出**************************************

(3, 4, 5)

我们将变换为一个2阶变量,shape = (6,10)

matrix = tf.reshape(rank_three_tensor, [6, 10]) # 
print matrix.shape

************************************输出**************************************
(6, 10) 

将其变换为一个2阶变量,-1表示需要根据其他维的数量来计算这一维的数量,这里我们得到 shape=(3,20)

matrixB = tf.reshape(matrix, [3, -1]) # 
print matrixB.shape
************************************输出**************************************

(3, 20)

必须注意reshape之后的张量元素与原本的张量元素个数相同,且排列相同,如果某一维维-1,那么必须可以成功reshape,元素个数能够满足变换后的元素个数,例如下面的例子就会失败,无法构造成一个正确的张量, 60 \div (13 * 2) \n e 0

tf.reshape(matrixAlt, [13, 2, -1]) 

切片

n阶的tf.Tensor对内表示为n维单元数组,要访问tf.Tensor中的某一单元,则需要指定 ,与python 访问list的切片相似。

0阶张量

(标量)不需要指数,因为其本身便是单一数字。

1阶张量

对于 1 阶张量(矢量)来说,传递单一指数则可以访问一个数字,如下所示

cool_numbers  = tf.Variable([3.14159, 2.71828], tf.float32)
slice_0 = cool_numbers[0]
print slice_0.shape

************************************输出**************************************
()

请注意,如果想从矢量中动态地选择元素,那么 [] 内传递的指数本身可以是一个标量 tf.Tensor。只需要能够解析即可

cool_numbers  = tf.Variable([3.14159, 2.71828], tf.float32)
idx = tf.Variable(1,tf.int16)
slice_0 = cool_numbers[idx]
print slice_0.shape

************************************输出**************************************
()

2阶张量及以上张量

对于 2 阶及以上的张量来说,情况更为有趣。对于 2 阶张量的 tf.Tensor 来说,传递两个数字会如预期般返回一个标量:

squarish_squares = tf.Variable([ [4, 9], [16, 25] ], tf.int32)
slice_2 = squarish_squares[0,0]
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(slice_2)

************************************输出**************************************
4

而传递一个数字,则会返回一个矩阵的子矢量,如下所示:

squarish_squares = tf.Variable([ [4, 9], [16, 25] ], tf.int32)
slice_3 = squarish_squares[0]
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(slice_3)

************************************输出**************************************
[4, 9]

符号 : 是 Python 切片语法,意味“不要触碰该维度”。这对更高阶的张量来说很有用,可以帮助访问其子矢量,子矩阵,甚至其他子张量。

squarish_squares = tf.Variable([ [1, 4, 9], [16, 25, 36] ], tf.int32)
slice_2 = squarish_squares[0,0]
slice_3 = squarish_squares[0,:1]
slice_4 = squarish_squares[:,1:]

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print sess.run(slice_2)
    print sess.run(slice_3)
    print sess.run(slice_4)
************************************输出**************************************

1
[1]
[[ 4  9]
 [25 36]]

我们来分析slice_4 = squarish_squares[:,1:],其中第一个维度为":",这个切片表示所有保留,而第二个维度"1:",表示这个切片为从第二个元素开始到最后一个元素,这个python切片用法大家应该很熟悉,因此结果为:

[[ 4  9]
 [25 36]]

\

标签

深度学习神经网络模型训练损失函数TensorFlow