Tensor 数据类型
在介绍 Tensor 数据之前,先介绍两种 Python 常用的数据结构,并解释,为什么做深度学习不用这些数据结构,而是要用 Tensor。
List : Python中最常用的数据结构,以 [ ] 括起来,如 [1, 1.1, ‘hello’, ‘(1,2)’, layers] ,缺点是储存图片占用内存非常大,读写图片数据效率低。
np.array : 存成一个静态数组,转置、加减乘除等运算方便灵活,但 numpy 不提供创建张量函数和自动梯度求导,也不提供 GPU 支持,不适合深度学习。
tf.tensor : tensorflow 中的数据载体,偏重神经网络的计算。为减少初学者的入门难度,tensorflow 和 numpy 的 API 刻意相近,而且参数的命名也是刻意相近,从而方便从 numpy 转化到 tensorfolw 中。tensorflow 中使用它来表示数据:标量是张量,向量是张量,矩阵是张量,矩阵的矩阵是张量。
tf.constant()
创建 Tensor 常量
# 导入需要的库
import tensorflow as tf
import numpy as np
tf.constant(1) # 常量1,其数据可以更改
tf.constant(1.) # 常量1.0,其数据可以更改,为float型
tf.constant(2.2, dtype=tf.int32) # 强制将f1oat型设置为int型,会报错
tf.constant(2., dtype=tf.double) # 将float可以强制设置为double型
tf.constant([True, False]) # bool型变量
tf.constant('Hello World!') # string类型变量
tf.constant(np.array(2.0))
tf.constant(np.array(2.0), dtype=tf.float32)
其中需要注意的是:
由 numpy 数组变换到 tensorflow 的张量时需要稍加注意。numpy 创建数组时默认的浮点型是 double,而 tf 在创建张量时默认是 float32。tf 在接收 numpy 数组时会同时接受其元素的数据类型。tf 的使用者可能很多都是需要在 GPU 上运行的程序,而 GPU 处理 float32 比处理 double 要快很多,所以如果对数据精度要求并没有太高的话,最好还是使用单精度的 float32,而不是双精度的 double。
tensorflow 中的 shape
np.shape():
这个函数是 numpy 中的一个函数,其功能是获取括号内数据的长度或维度信息,其使用对象既可以是一个数,也可以是数组或矩阵。
array.shape:
array.shape 是 np.ndarray 的方法,可以快速获取矩阵的形状,注意此处不加括号!!!
np.shape(0)
np.shape([0])
np.shape([1, 2, 3])
np.shape([[1], [2]])
a = np.zeros([2, 3])
a
np.shape(a)
np.shape(a)[1]
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b.shape
b.shape[0]
c = [1, 2, 3]
c.shape
TensorFlow 时用张量这种数据结构来表示所有的数据。同时可以把初级的 TensorFlow 理解为线性代数的计算工具。Shape 表示为张量的阶(但是此时又区分与线代中的阶),几何意义可以大致理解为张量(向量)的几何维度。而 [ ] 中的内容可以理解为向量中的维度界。而无[ ]这个界进行限制则可以理解为无法构成向量。这样就可以很好的理解 TensorFlow 中的 Shape 了。
获取变量维度是一个使用频繁的操作,在 TensorFlow 中获取变量维度主要用到的操作有以下三种:
Tensor.shape
Tensor.get_shape()
tf.shape(input,name=None,out_type=tf.int32)
方法1与方法2基本一样,只不过前者是 Tensor 的属性变量,后者是 Tensor 的函数。
方法1、2均返回 TensorShape 类型,而方法3返回一个 1D 的 out_type 类型的 Tensor。
方法1、2可以在任意位置使用。
方法1、2获取的是静态 shape,可以返回不完整的 shape;方法3获取的是动态的 shape,必须是完整的 shape。
看一下代码关于shape
isinstance(a,tf.Tensor) || tf.is_tensor(b) || a.dtype isinstance(a,tf.Tensor)
判断 a 是否为 Tensor。
isinstance() 会认为子类是一种父类类型,考虑继承关系。如果要判断两个类型是否相同推荐使用 isinstance()。语法 isinstance(object, classinfo) 参数 object ——实例对象;classinfo ——可以是直接或间接类名、基本类型。
tf.is_tensor(b) 判断 b 是否为 Tensor。
a.dtype
返回数据类型。
Convert
aa = tf.convert_to_tensor(a,dtype = tf.int32) # 将numpy转换为tensor并指定数据类型为int32
aaa = tf.cast(aa,dtype = tf.double) # 张量数据类型转换为double
tf.Variable
Variable 是特殊的张量,也是 tf 的使用者常见的一种复合数据类型,一般用于模型中需要在训练过程中进行调整的参数。
Variable在初始化之后还是可以修改其内容的,并且其包含了 “trainable” 属性,该属性在训练时可以用于判断这个 Variable 是否需要被调整。而一般的 Tensor 在初始化之后是不能修改内容的,如果需要修改,就只能生成一个新的 Tensor。并且一般的 Tensor 没有 “trainable” 属性,说明在训练时,是完全不需要在误差反传中进行调整。
To Numpy
创建 Tensor From Numpy, List
tf.zeros()
tf.zeros_like()
tf.ones()
tf.fill()
tf.random_normal() 函数用于从服从指定正太分布的数值中取出随机数
shape: 输出张量的形状,必选
mean: 正态分布的均值,默认为0
stddev: 正态分布的标准差,默认为1.0
dtype: 输出的类型,默认为tf.float32
seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样
name: 操作的名称
Random Permutation(随机排列)
小结:
张量的维度变换
改变张量的形状**tf.reshape(tensor,shape)**函数
tf.reshape(tf.reshape(tf.range(24),[2,3,4]),[4,-1])
表示把0-23这24个数转换成3行4列的二维数组,[4, -1] 表示把二维数组转换成第一维长度为4,-1表示第二维长度根据张量元素总个数和其他维度长度自动推导出来
<tf.Tensor: id=7, shape=(4, 6), dtype=int32, numpy=
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])>
此操作只改变张量数组的视图,在NumPy数组中的存储数据并没有改变。
多维张量的轴(维度)
张量中轴的用法和NumPy数组中的一样,如图所示:
轴也可以是负数,表示往后向前索引,例如上图中三维张量的axis的值为也可以是-3,-2,-1
增加维度
tf.expand_dlim(tensor,axis),axis表示增加的维度,axis可负
删除维度
tf.squeeze(tensor,axis),只能删除长度为1的维度,axis省略时删除所有长度为1的维度
交换维度
tf.transpose(a,perm),perm表示轴的顺序,值空时表示转置。
拼接张量
tf.concat(tensors,axis),axis表示在哪个轴上进行拼接。
分割张量
tf.split(value,x,axis),当x为数字时,表示切割成x个张量;当x为数组时,按数组值进行切割。
堆叠张量
tf.stack(values,axis),合并张量时创建一个新的维度。
分解张量
tf.unstack(values,axis),将张量分解为多个张量,分解后得到的张量和原张量维数都少了一维。
张量的部分采样
索引和切片:
索引:和Python中列表的使用方法类似,以MNIST为例(60000, 28, 28)表示有6万张图片,28 表示二维图片中每个像素的灰度值。mnist[0][1][2]表示取第1张图片中的第2行的第3列。
切片:对象名[起始位置:结束位置:步长],三个参数都可以省略,起始位置到结束位置前闭后开。
采用切片的方式,只能进行连续的、或者有规律的采样。
数据提取:根据索引,抽取出没有规律的、特定的数据
选择采样维度
张量运算
加减乘除运算
幂指对数运算
其他运算
三角函数和反三角函数运算
重载运算符
广播机制
两个不同维度的张量相加,两个张量最后一个维度的长度必须相等。一个数字和多维张量进行算法操作时,这个数字对张量中的每一个元素进行相应的算法操作;一维张量和多维张量进行运算时,一维张量和多维张量的每一行进行运算操作;以此类推。
张量和NumPy数组
NumPy数组转化为张量:tf.constant(); tf.convert_to_tensor
张量转换为NumPy数组:Tensor.numpy()
执行TensorFlow操作,TensorFlow将自动的把NumPy数组转换为张量;执行NumPy操作, NumPy将自动的张量转换为NumPy数组;只要操作数中有一个Tensor对象,就把所有 的操作数都转化为张量, 然后再进行运算。