TensorFlow2基础
TensorFlow 是一个面向深度学习算法的科学计算库,内部数据保存在张量(Tensor)对象
上,所有的运算操作(Operation,简称 OP)也都是基于张量对象进行的。
-
1、数据类型:
数值类型、字符串类型、布尔类型
-
2、数值类型:
数值类型的张量是 TensorFlow 的主要数据载体,根据维度数来区分,可分为:
标量Scalar:单个实数,维度为0,shape=[]
向量Vector:n个实数有序集合,维度数为1,长度不定,shape=[n];如[1.2],[1.2,3.4]
矩阵Matrix:n行m列实数的有序集合,如[[1,2],[1,4]] 维数为2,每个维度长度不定,shape为[n,m]
张量Tensor:维度数>2的数组,张量的每个维度也作轴(Axis)
(补充:一般维度代表了具体的物理含义,比如 Shape 为[2,32,32,3]的张量共有 4 维,如果表示图片数据的话,每个维度轴代表的含义分别是图片数量、图片高度、图片宽度、图片通道数,其中 2 代表了 2 张图片,32 代表了高、宽均为 32,3 代表了 RGB 共 3 个通道。张量的维度数以及每个维度所代表的具体物理含义需要由用户自行定义。在TensorFlow中间,为了表达方便,一般把标量、向量、矩阵也统称为张量,不作区分,需要根据张量的维度数或形状自行判断。)
创建标量:
a = 1.2 #python
aa = tf.constant(1.2)
type(a), type(aa), tf.is_tensor(aa)
——>(float, tensorflow.python.framework.ops.EagerTensor, True)
打印张量:
x = tf.constant([1,2.,3.3])
print(x)
——><tf.Tensor: id=165, shape=(3,), dtype=float32, numpy=array([1. , 2. , 3.3],dtype=float32)>
(各部分表示:
id: TensorFlow 中内部索引对象的编号
shape: 张量的形状
dtype: 张量的数值精度
numpy()方法:返回 Numpy.array 类型的数据
如:x.numpy()
——>array([1.,2.,3.3], dtype=float32)
创建向量:
a = tf.constant([1.2]) # 创建一个元素的向量
a, a.shape
-->(<tf.Tensor: id=8, shape=(1,), dtype=float32, numpy=array([1.2],dtype=float32)>,TensorShape([1]))
a = tf.constant([1,2, 3.]) # 创建 3 个元素的向量
a, a.shape
-->(<tf.Tensor: id=11, shape=(3,), dtype=float32, numpy=array([1., 2., 3.],dtype=float32)>,TensorShape([3]))
创建矩阵:
a = tf.constant([[1,2],[3,4]]) # 创建 2 行 2 列的矩阵a,
a.shape
-
3、字符串类型
通过传入字符串对象即可创建字符串类型的张量
a=tf.constant(hello,deep learning)
在 tf.strings 模块中,提供了常见的字符串类型的工具函数
如: 小写化 lower()、
拼接join()、
长度 length()、
切分 split()等。
例如,将字符串全部小写化实现为:
tf.strings.lower(a)#小写化字符串
-
4、布尔类型
a = tf.constant(True) # 创建布尔类型标量
创建布尔类型的向量:a = tf.constant([True, False]) # 创建布尔类型向量
TensorFlow 的布尔类型和 Python 语言的布尔类型并不等价,不能通用,例如
a = tf.constant(True) # 创建 TF 布尔张量
a is True # TF 布尔类型张量与 python 布尔类型比较
a == True # 仅数值比较
Out:False # 对象不等价
<tf.Tensor: id=8, shape=(), dtype=bool, numpy=True> # 数值比较结果
-
5、数值精度
常用的精度类型有
tf.int16、tf.int32、tf.int64、tf.float16、tf.float32、tf.float64 等
(其中 tf.float64 即为 tf.double)
指定张量保存精度:
tf.constant(123456789, dtype=tf.int16)
tf.constant(123456789, dtype=tf.int32)
Out[12]:
<tf.Tensor: id=33, shape=(), dtype=int16,numpy=-13035> (发生了溢出,得到了错误的结果)
<tf.Tensor: id=35, shape=(), dtype=int32, numpy=123456789>
import numpy as np
np.pi # 从 numpy 中导入 pi 常量,实际保存的数据为 3.1415927。如果采用 tf.float64 精度保存π,则能获得更高的精度
tf.constant(np.pi, dtype=tf.float32) # 32 位
Out[13]:
<tf.Tensor: id=29, shape=(), dtype=float32, numpy=3.1415927>
-
6、读取精度
print('before:',a.dtype) # 读取原有张量的数值精度
if a.dtype != tf.float32: # 如果精度不符合要求,则进行转换
a = tf.cast(a,tf.float32) # tf.cast 函数可以完成精度转换
print('after :',a.dtype) # 打印转换后的精度
Out[15]:
before: <dtype: 'float16'>
after : <dtype: 'float32'>
-
7、类型转换
a = tf.cast(a,tf.float32) # tf.cast 函数可以完成精度转换
布尔类型与整型之间相互转换也是合法的,一般默认 0 表示 False,1 表示 True,在 TensorFlow 中,将非 0 数字都视为 True
a = tf.constant([-1, 0, 1, 2])
tf.cast(a, tf.bool) # 整型转布尔类型
a = tf.constant([True, False])
tf.cast(a, tf.int32) # 布尔类型转整型
-
8、待优化张量
普通的张量类型:不需要计算梯度信息的张量
待优化张量:需要计算梯度信息的张量
变化:
增加了一种专门的数据类型来支持梯度信息的记录:tf.Variable,
tf.Variable 类型添加了 name,trainable 等属性来支持计算图的构建,
(由于梯度运算会消耗大量的计算资源,而且会自动更新相关参数,对于不需要的优化的张量,如神经网络的输入𝑿,不需要通过 tf.Variable 封装;相反,对于需要计算梯度并优化的张量,如神经网络层的𝑾和𝒃,需要通过 tf.Variable 包裹以便 TensorFlow 跟踪相关梯度信息。)
通过 tf.Variable()函数可以将普通张量转换为待优化张量,例如:
a = tf.constant([-1, 0, 1, 2]) # 创建 TF 张量
aa = tf.Variable(a)
aa.name, aa.trainable # Variable 类型张量的属性
Out[20]:
('Variable:0', True)
其中张量的 name 和 trainable 属性是 Variable 特有的属性,name 属性用于命名计算图中的
变量,这套命名体系是 TensorFlow 内部维护的,一般不需要用户关注 name 属性;trainable
属性表征当前张量是否需要被优化,创建 Variable 对象时是默认启用优化标志,可以设置
trainable=False 来设置张量不需要优化。
除了通过普通张量方式创建 Variable,也可以直接创建,例如:
a = tf.Variable([[1,2],[3,4]]) # 直接创建 Variable 张量
Out[21]:
<tf.Variable 'Variable:0' shape=(2, 2) dtype=int32, numpy=array([[1, 2],[3, 4]])>
待优化张量可视为普通张量的特殊类型,普通张量其实也可以通过 GradientTape.watch()方
法临时加入跟踪梯度信息的列表,从而支持自动求导功能。
参考资料: https://github.com/dragen1860/Deep-Learning-with-TensorFlow-book
https://www.bilibili.com/video/av50600192