张量(Tensor)是 TensorFlow 的核心数据结构,理解张量操作对于高效使用 TensorFlow 至关重要。
张量基础
1. 创建张量
pythonimport tensorflow as tf # 从 Python 列表创建张量 tensor1 = tf.constant([1, 2, 3, 4]) print(tensor1) # tf.Tensor([1 2 3 4], shape=(4,), dtype=int32) # 指定数据类型 tensor2 = tf.constant([1, 2, 3], dtype=tf.float32) print(tensor2) # tf.Tensor([1. 2. 3.], shape=(3,), dtype=float32) # 创建全零张量 zeros = tf.zeros([3, 4]) print(zeros.shape) # (3, 4) # 创建全一张量 ones = tf.ones([2, 3]) print(ones.shape) # (2, 3) # 创建指定值的张量 filled = tf.fill([2, 3], 5) print(filled) # [[5 5 5] [5 5 5]] # 创建随机张量 random_normal = tf.random.normal([3, 4], mean=0.0, stddev=1.0) random_uniform = tf.random.uniform([3, 4], minval=0, maxval=1) # 创建序列张量 range_tensor = tf.range(0, 10, 2) print(range_tensor) # [0 2 4 6 8] # 从 NumPy 数组创建 import numpy as np numpy_array = np.array([1, 2, 3]) tensor_from_numpy = tf.constant(numpy_array)
2. 张量属性
python# 获取张量形状 tensor = tf.constant([[1, 2, 3], [4, 5, 6]]) print(tensor.shape) # (2, 3) print(tf.shape(tensor)) # tf.Tensor([2 3], shape=(2,), dtype=int32) # 获取张量数据类型 print(tensor.dtype) # <dtype: 'int32'> # 获取张量维度 print(tf.rank(tensor)) # tf.Tensor(2, shape=(), dtype=int32) # 获取张量大小 print(tf.size(tensor)) # tf.Tensor(6, shape=(), dtype=int32) # 获取张量元素数量 print(tensor.numpy().size) # 6
张量索引和切片
1. 基本索引
python# 创建示例张量 tensor = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 获取单个元素 element = tensor[0, 1] # 2 # 获取一行 row = tensor[1, :] # [4, 5, 6] # 获取一列 col = tensor[:, 1] # [2, 5, 8] # 使用负索引 last_row = tensor[-1, :] # [7, 8, 9]
2. 切片操作
python# 切片 tensor = tf.constant([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) # 基本切片 sliced = tensor[0:2, 1:3] # [[2, 3], [6, 7]] # 步长切片 stepped = tensor[::2, ::2] # [[1, 3], [9, 11]] # 省略维度 simplified = tensor[1, :] # [5, 6, 7, 8]
3. 高级索引
python# 使用 tf.gather tensor = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) indices = tf.constant([0, 2]) gathered = tf.gather(tensor, indices) # [[1, 2, 3], [7, 8, 9]] # 使用 tf.gather_nd indices = tf.constant([[0, 1], [2, 0]]) gathered_nd = tf.gather_nd(tensor, indices) # [2, 7] # 使用 tf.where condition = tf.constant([[True, False], [False, True]]) values = tf.constant([[1, 2], [3, 4]]) result = tf.where(condition, values, tf.zeros_like(values)) # [[1, 0], [0, 4]] # 使用 tf.boolean_mask mask = tf.constant([True, False, True]) masked = tf.boolean_mask(tensor, mask) # [[1, 2, 3], [7, 8, 9]]
张量运算
1. 算术运算
python# 基本算术运算 a = tf.constant([1, 2, 3]) b = tf.constant([4, 5, 6]) # 加法 add = tf.add(a, b) # [5, 7, 9] add = a + b # [5, 7, 9] # 减法 subtract = tf.subtract(a, b) # [-3, -3, -3] subtract = a - b # [-3, -3, -3] # 乘法 multiply = tf.multiply(a, b) # [4, 10, 18] multiply = a * b # [4, 10, 18] # 除法 divide = tf.divide(a, b) # [0.25, 0.4, 0.5] divide = a / b # [0.25, 0.4, 0.5] # 幂运算 power = tf.pow(a, 2) # [1, 4, 9] power = a ** 2 # [1, 4, 9] # 矩阵乘法 matrix_a = tf.constant([[1, 2], [3, 4]]) matrix_b = tf.constant([[5, 6], [7, 8]]) matmul = tf.matmul(matrix_a, matrix_b) # [[19, 22], [43, 50]] matmul = matrix_a @ matrix_b # [[19, 22], [43, 50]]
2. 数学函数
python# 三角函数 x = tf.constant([0, np.pi/2, np.pi]) sin = tf.sin(x) # [0, 1, 0] cos = tf.cos(x) # [1, 0, -1] tan = tf.tan(x) # [0, inf, 0] # 指数和对数 exp = tf.exp(tf.constant([0, 1, 2])) # [1, 2.718, 7.389] log = tf.log(tf.constant([1, 2, 3])) # [0, 0.693, 1.099] log10 = tf.log(tf.constant([10, 100, 1000])) / tf.log(10.0) # [1, 2, 3] # 其他数学函数 abs = tf.abs(tf.constant([-1, -2, 3])) # [1, 2, 3] sqrt = tf.sqrt(tf.constant([1, 4, 9])) # [1, 2, 3] square = tf.square(tf.constant([1, 2, 3])) # [1, 4, 9] round = tf.round(tf.constant([1.2, 2.7, 3.5])) # [1, 3, 4] ceil = tf.ceil(tf.constant([1.2, 2.7, 3.5])) # [2, 3, 4] floor = tf.floor(tf.constant([1.2, 2.7, 3.5])) # [1, 2, 3]
3. 统计运算
python# 创建示例张量 tensor = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 求和 sum_all = tf.reduce_sum(tensor) # 45 sum_axis0 = tf.reduce_sum(tensor, axis=0) # [12, 15, 18] sum_axis1 = tf.reduce_sum(tensor, axis=1) # [6, 15, 24] # 平均值 mean_all = tf.reduce_mean(tensor) # 5.0 mean_axis0 = tf.reduce_mean(tensor, axis=0) # [4, 5, 6] mean_axis1 = tf.reduce_mean(tensor, axis=1) # [2, 5, 8] # 最大值 max_all = tf.reduce_max(tensor) # 9 max_axis0 = tf.reduce_max(tensor, axis=0) # [7, 8, 9] max_axis1 = tf.reduce_max(tensor, axis=1) # [3, 6, 9] # 最小值 min_all = tf.reduce_min(tensor) # 1 min_axis0 = tf.reduce_min(tensor, axis=0) # [1, 2, 3] min_axis1 = tf.reduce_min(tensor, axis=1) # [1, 4, 7] # 标准差 std = tf.math.reduce_std(tf.cast(tensor, tf.float32)) # 2.582 # 方差 var = tf.math.reduce_variance(tf.cast(tensor, tf.float32)) # 6.667
张量形状操作
1. 形状变换
python# Reshape tensor = tf.constant([[1, 2, 3], [4, 5, 6]]) reshaped = tf.reshape(tensor, [3, 2]) # [[1, 2], [3, 4], [5, 6]] # Flatten flattened = tf.reshape(tensor, [-1]) # [1, 2, 3, 4, 5, 6] # Transpose transposed = tf.transpose(tensor) # [[1, 4], [2, 5], [3, 6]] # Squeeze(移除维度为1的维度) tensor = tf.constant([[[1], [2], [3]]]) squeezed = tf.squeeze(tensor) # [1, 2, 3] # Expand dims(增加维度) expanded = tf.expand_dims(tensor, axis=0) # [[[[1], [2], [3]]]]
2. 维度操作
python# Stack a = tf.constant([1, 2, 3]) b = tf.constant([4, 5, 6]) stacked = tf.stack([a, b], axis=0) # [[1, 2, 3], [4, 5, 6]] # Unstack unstacked = tf.unstack(stacked, axis=0) # [tf.Tensor([1 2 3]), tf.Tensor([4 5 6])] # Concat concat_axis0 = tf.concat([a, b], axis=0) # [1, 2, 3, 4, 5, 6] # Split tensor = tf.constant([[1, 2, 3], [4, 5, 6]]) split = tf.split(tensor, 2, axis=0) # [tf.Tensor([[1 2 3]]), tf.Tensor([[4 5 6]])] # Tile(重复张量) tensor = tf.constant([[1, 2], [3, 4]]) tiled = tf.tile(tensor, [2, 3]) # [[1, 2, 1, 2, 1, 2], [3, 4, 3, 4, 3, 4], [1, 2, 1, 2, 1, 2], [3, 4, 3, 4, 3, 4]] # Repeat(重复元素) tensor = tf.constant([[1, 2], [3, 4]]) repeated = tf.repeat(tensor, repeats=2, axis=0) # [[1, 2], [1, 2], [3, 4], [3, 4]]
3. 填充和裁剪
python# Pad tensor = tf.constant([[1, 2], [3, 4]]) padded = tf.pad(tensor, [[1, 1], [1, 1]], mode='CONSTANT') # [[0, 0, 0, 0], [0, 1, 2, 0], [0, 3, 4, 0], [0, 0, 0, 0]] # Crop cropped = tf.image.crop_to_bounding_box(tensor, 0, 0, 1, 1) # [[1]] # Resize(主要用于图像) image = tf.random.uniform([100, 100, 3]) resized = tf.image.resize(image, [50, 50]) # [50, 50, 3]
张量广播
python# 广播机制 a = tf.constant([[1, 2, 3], [4, 5, 6]]) # shape (2, 3) b = tf.constant([1, 2, 3]) # shape (3,) # 自动广播 result = a + b # shape (2, 3) # [[2, 4, 6], [5, 7, 9]] # 显式广播 a = tf.constant([[1], [2], [3]]) # shape (3, 1) b = tf.constant([1, 2, 3]) # shape (3,) result = tf.broadcast_to(a, [3, 3]) + tf.broadcast_to(b, [3, 3]) # [[2, 3, 4], [3, 4, 5], [4, 5, 6]] # 检查广播是否可能 a = tf.constant([1, 2, 3]) b = tf.constant([1, 2]) try: result = a + b except tf.errors.InvalidArgumentError as e: print("Broadcasting not possible:", e)
张量数据类型转换
python# 类型转换 int_tensor = tf.constant([1, 2, 3]) float_tensor = tf.cast(int_tensor, tf.float32) # [1.0, 2.0, 3.0] # 检查类型 print(int_tensor.dtype) # <dtype: 'int32'> print(float_tensor.dtype) # <dtype: 'float32'> # 转换为 NumPy 数组 numpy_array = int_tensor.numpy() print(type(numpy_array)) # <class 'numpy.ndarray'> # 从 NumPy 数组创建张量 new_tensor = tf.constant(numpy_array)
张量比较
python# 相等比较 a = tf.constant([1, 2, 3]) b = tf.constant([1, 2, 4]) equal = tf.equal(a, b) # [True, True, False] not_equal = tf.not_equal(a, b) # [False, False, True] # 大小比较 greater = tf.greater(a, b) # [False, False, False] less = tf.less(a, b) # [False, False, True] greater_equal = tf.greater_equal(a, b) # [True, True, False] less_equal = tf.less_equal(a, b) # [True, True, True] # 元素级最大最小值 maximum = tf.maximum(a, b) # [1, 2, 4] minimum = tf.minimum(a, b) # [1, 2, 3]
张量排序
python# 排序 tensor = tf.constant([3, 1, 4, 1, 5, 9, 2, 6]) sorted = tf.sort(tensor) # [1, 1, 2, 3, 4, 5, 6, 9] # 获取排序索引 indices = tf.argsort(tensor) # [1, 3, 6, 0, 2, 4, 7, 5] # 按值排序 values, indices = tf.nn.top_k(tensor, k=3) # values: [9, 6, 5] # indices: [5, 7, 4] # 二维张量排序 tensor_2d = tf.constant([[3, 1, 4], [1, 5, 9], [2, 6, 5]]) sorted_2d = tf.sort(tensor_2d, axis=1) # [[1, 3, 4], [1, 5, 9], [2, 5, 6]]
张量拼接和分割
python# 拼接 a = tf.constant([[1, 2], [3, 4]]) b = tf.constant([[5, 6], [7, 8]]) # 沿 axis 0 拼接 concat_0 = tf.concat([a, b], axis=0) # [[1, 2], [3, 4], [5, 6], [7, 8]] # 沿 axis 1 拼接 concat_1 = tf.concat([a, b], axis=1) # [[1, 2, 5, 6], [3, 4, 7, 8]] # 分割 tensor = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 均匀分割 split_0 = tf.split(tensor, 3, axis=0) # [tf.Tensor([[1 2 3]]), tf.Tensor([[4 5 6]]), tf.Tensor([[7 8 9]])] # 不均匀分割 split_1 = tf.split(tensor, [1, 2], axis=0) # [tf.Tensor([[1 2 3]]), tf.Tensor([[4 5 6] [7 8 9]])]
张量掩码和条件操作
python# 布尔掩码 tensor = tf.constant([1, 2, 3, 4, 5]) mask = tf.constant([True, False, True, False, True]) masked = tf.boolean_mask(tensor, mask) # [1, 3, 5] # 条件选择 condition = tf.constant([True, False, True]) x = tf.constant([1, 2, 3]) y = tf.constant([4, 5, 6]) result = tf.where(condition, x, y) # [1, 5, 3] # 条件掩码 tensor = tf.constant([1, 2, 3, 4, 5]) mask = tensor > 3 result = tf.boolean_mask(tensor, mask) # [4, 5]
张量归约操作
python# 归约操作 tensor = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 沿轴归约 sum_axis0 = tf.reduce_sum(tensor, axis=0) # [12, 15, 18] sum_axis1 = tf.reduce_sum(tensor, axis=1) # [6, 15, 24] # 保持维度 sum_keepdims = tf.reduce_sum(tensor, axis=0, keepdims=True) # [[12, 15, 18]] # 多轴归约 sum_multi = tf.reduce_sum(tensor, axis=[0, 1]) # 45 # 特定归约 prod = tf.reduce_prod(tensor) # 362880 all_true = tf.reduce_all(tensor > 0) # True any_true = tf.reduce_any(tensor > 5) # True
高效张量操作技巧
1. 使用向量化操作
python# 低效方式 result = [] for i in range(1000): result.append(i * 2) # 高效方式 tensor = tf.range(1000) result = tensor * 2
2. 批量处理
python# 批量矩阵乘法 batch_size = 32 matrices_a = tf.random.normal([batch_size, 100, 100]) matrices_b = tf.random.normal([batch_size, 100, 100]) result = tf.matmul(matrices_a, matrices_b) # [32, 100, 100]
3. 使用 tf.function 加速
python@tf.function def fast_operation(x): return tf.reduce_sum(x * 2) # 第一次调用会编译,后续调用会更快 result = fast_operation(tf.random.normal([1000, 1000]))
4. 避免不必要的复制
python# 使用 tf.identity 避免复制 a = tf.constant([1, 2, 3]) b = tf.identity(a) # 不创建新张量,只是引用
5. 使用合适的设备
python# 使用 GPU with tf.device('/GPU:0'): a = tf.random.normal([1000, 1000]) b = tf.random.normal([1000, 1000]) c = tf.matmul(a, b) # 使用 CPU with tf.device('/CPU:0'): a = tf.constant([1, 2, 3]) b = tf.constant([4, 5, 6]) c = a + b
6. 内存优化
python# 使用 tf.data.Dataset 进行高效数据加载 dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) dataset = dataset.batch(32).prefetch(tf.data.AUTOTUNE) # 使用 tf.Variable 避免重复创建 var = tf.Variable(tf.zeros([1000, 1000])) var.assign(tf.random.normal([1000, 1000]))
张量操作性能优化
1. XLA 编译
python# 使用 XLA 编译加速 @tf.function(experimental_compile=True) def xla_compatible_function(x): return tf.reduce_sum(x ** 2)
2. 混合精度
pythonfrom tensorflow.keras import mixed_precision # 启用混合精度 policy = mixed_precision.Policy('mixed_float16') mixed_precision.set_global_policy(policy) # 张量会自动使用 float16 进行计算 a = tf.random.normal([1000, 1000]) b = tf.random.normal([1000, 1000]) c = tf.matmul(a, b) # 使用 float16 计算
3. 并行化
python# 使用并行映射 dataset = tf.data.Dataset.range(1000) dataset = dataset.map(lambda x: x * 2, num_parallel_calls=tf.data.AUTOTUNE)
总结
TensorFlow 的张量操作提供了强大的数据处理能力:
- 张量创建:多种创建张量的方法
- 索引切片:灵活的索引和切片操作
- 张量运算:丰富的算术和数学运算
- 形状操作:灵活的形状变换
- 广播机制:自动处理不同形状的张量
- 高效操作:向量化、批量处理、设备选择等优化技巧
掌握这些张量操作将帮助你更高效地使用 TensorFlow 进行深度学习开发。