TensorFlow 2.x 基础总结
TensorFlow 是面向深度学习算法的科学计算库,内部数据保存在张量(Tensor)上,所有的运算操作(Operation,简称OP)都是基于张量对象进行的。
数据类型
基本数据类型,包括数值类型、字符串类型和布尔类型。
数值类型
x = tf.constant(1, dtype=tf.float64) # 标量,维度为0的张量
x = tf.constant([1,2,3]) # 向量,维度为1的张量
x = tf.constant([[1,2,3],[4,5,6]]) # 矩阵,维度为2的张量
x.shape # 返回张量的形状
x.numpy() # 将张量转换为NumPy数组
数值类型的精度,常用的有tf.int16、tf.int32、tf.int64、tf.float16、tf.float32、tf.float64等,一般默认为tf.int32和tf.float32。
字符串类型
x = tf.constant('Hello, World!')
y = tf.constant('Hi!')
tf.strings.lower(x) # 转换为小写
tf.strings.split(x, ',') # 用逗号分割x
tf.strings.lenth(x) # x的长度
tf.strings.join([x, y]) # 拼接x和y
布尔类型
为了方便表达比较运算操作的结果,TensorFlow还支持布尔类型的张量。
x = tf.constant(True)
x = tf.constant([1,2,3])
y = tf.constant([1])
tf.equal(x, y) # [True, False, False]
数据精度转换与类型转换
x = tf.constant(np.pi, dtype=tf.float16)
x = tf.cast(x, tf.float32) # 数据精度转换
x = tf.constant([-1, 0, 1, 2])
x = tf.cast(x, tf.bool) # 数据类型转换,0表示False, 非0表示True
待优化张量
为了区分需要计算梯度信息的张量和不需要计算梯度信息的张量,TensorFlow增加了一种专门的数据类型来支持梯度信息的记录:tf.Variable,并增加了name和trainable属性。
待优化张量可以视为普通张量的特殊类型,普通张量也可通过GradientTape.watch()方法来临时加入跟踪梯度信息的列表,从而支持自动求导功能。
创建张量
- 从列表、数组对象创建
tf.convert_to_tensor([1,2,3])
tf.convert_to_tensor(np.array([1,2,3]))
- 特殊张量
tf.zeros((1,2))
tf.ones((1,2))
tf.ones_like(x) # 创建形状同x、元素为1的张量
tf.zeros_like(x)
tf.fill((1,2,3), -1) # 创建形状为(1,2,3)、元素均为-1的张量
- 创建已知分布的张量
tf.random.normal(shape, mean, stddev) # 创建形状为shape、均值为mean、标准差为stddev的正态分布
tf.random.uniform(shape, minval, maxval, dtype) # 创建采样自[minval, maxval)区间的均匀分布的张量
- 序列、索引
tf.range(start, limit, delta) # 创建[start, limit)区间、步长为delta的序列
索引与切片
索引
x = tf.random.normal([4,32,32,3])
x[0]
x[2][3][4]
x[1][2][3][4]
切片
同数组中的start:stop:step方式。
维度变换
基本的维度变换操作函数包括改变视图reshape、插入新维度expand_dims、删除维度squeeze、交换维度transpose、复制数据tile等函数。
# 改变视图
tf.reshape(x, (3,3))
# 增加维度
tf.expand_dims(x, axis=2) # 在指定的axis轴前增加维度
# 删除维度,只能删除长度为1的维度
tf.squeeze(x, axis=2) # 删除索引号为axis的维度
# 交换维度
tf.transpose(x, perm)
# 复制数据
tf.tile(x, multiples)
数学运算
# 加、减、乘、除、整除、取余
+ - * / // %
tf.add tf.subtract tf.multiply tf.divide
# 乘方
tf.pow(x, a) # x的a次方
x**2 # x的a次方
tf.square(x) # x的平方
tf.sqrt(x) # x的平方根
# 指数
tf.pow(a, x) # 指数运算
tf.exp(x) # 自然指数
# 对数
tf.math.log(X) # 自然对数
# 矩阵相乘
x@y
tf.matmul(x,y)
合并与分割
# 拼接,不会产生新的维度
tf.concat([x,y], axis)
# 堆叠,产生新的维度
tf.stack([a,b], axis)
# 分割
tf.split(x, num_or_size_splits, axis)
tf.unstack(x, axis)
数据统计
# 范数
tf.norm(x, ord)
# 最值、均值、和, 当不指定axis时,会求全局
tf.reduce_max(x, axis)
tf.reduce_min(x, axis)
tf.reduce_mean(x, axis)
tf.reduce_sum(x, axis)
tf.argmax(x, axis) # 在axis轴上,x的最大值的索引号
tf.argmin(x, axis) # 在axis轴上,x的最小值的索引号
张量比较
tf.math.equal(x,y)
tf.math.greater(x,y)
tf.math.less(x,y)
tf.math.greater_equal(x,y)
tf.math.less_equal(x,y)
tf.math.not_equal(x,y)
tf.math.is_nan(x)
张量填充与限幅
# 填充
tf.pad(x, paddings)
# 限幅
tf.maximum(x, 5) # 张量x的最小值为5
tf.minimum(x, 5) # 张量x的最大值为5
高级操作
tf.gather(x, [1,3,4], axis)
tf.gather_nd(x, [[1,2],[2,2],[4,5]])
mask = [True, False, False, True]
tf.boolean_mask(x. mask, axis)
tf.where(conditions, x, y) # 返回形状同x、y的张量,条件为真时,取x对应的值,否则取y对应的值
tf.scatter_nd(indices, updates, shape)
tf.meshgrid(x, y)
经典数据集使用
在TensorFlow中,keras.datasets模块提供了常用经典数据集的自动下载、管理、加载与转换功能,并且提供了tf.data.Dataset数据集对象,方便实现多线程(Multi-Threading)、预处理(Preproceing)、随机打散(Shuffle)和批训练(Training on Batch)等常用数据集的功能。
常用数据集如:
-
Boston Housing,波士顿房价趋势数据集,用于回归模型训练与测试
-
CIFAR10/100,真实图片数据集,用于图片分类任务
-
MNIST/Fashion_MNIST,手写数字图片数据集,用于图片分类任务
-
IMDB,情感分类任务数据集,用于文本分类任务
# 数据集加载
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() # 加载数据集,返回格式为Numpy数组,需转为tensor
# 构建Dataset对象
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) # 创建Dataset对象,方便使用TensorFlow自带的数据集操作函数
# 随机打散
train_dataset = train_dataset.shuffle(buffer_size) # 随机打散样本,不会打乱样本与标签之间的映射关系。buffer_size指定缓冲池的大小
# 批处理
train_dataset = train_dataset.batch(512) # 一次从数据集中产生512个数据样本
# 预处理
train_dataset = train_dataset.map(preporcess) # preprocess为自定义的函数
# 循环训练
for epoch in range(epochs):
for step, (x, y) in enumerate(train_dataset):
# 每次训练一个batch size的数据