TensorFlow 中的张量操作有哪些,如何高效处理张量
张量(Tensor)是 TensorFlow 的核心数据结构,理解张量操作对于高效使用 TensorFlow 至关重要。张量基础1. 创建张量import 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 npnumpy_array = np.array([1, 2, 3])tensor_from_numpy = tf.constant(numpy_array)2. 张量属性# 获取张量形状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. 基本索引# 创建示例张量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. 切片操作# 切片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. 高级索引# 使用 tf.gathertensor = 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_ndindices = tf.constant([[0, 1], [2, 0]])gathered_nd = tf.gather_nd(tensor, indices) # [2, 7]# 使用 tf.wherecondition = 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_maskmask = tf.constant([True, False, True])masked = tf.boolean_mask(tensor, mask) # [[1, 2, 3], [7, 8, 9]]张量运算1. 算术运算# 基本算术运算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. 数学函数# 三角函数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. 统计运算# 创建示例张量tensor = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 求和sum_all = tf.reduce_sum(tensor) # 45sum_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.0mean_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) # 9max_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) # 1min_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. 形状变换# Reshapetensor = tf.constant([[1, 2, 3], [4, 5, 6]])reshaped = tf.reshape(tensor, [3, 2]) # [[1, 2], [3, 4], [5, 6]]# Flattenflattened = tf.reshape(tensor, [-1]) # [1, 2, 3, 4, 5, 6]# Transposetransposed = 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. 维度操作# Stacka = tf.constant([1, 2, 3])b = tf.constant([4, 5, 6])stacked = tf.stack([a, b], axis=0) # [[1, 2, 3], [4, 5, 6]]# Unstackunstacked = tf.unstack(stacked, axis=0) # [tf.Tensor([1 2 3]), tf.Tensor([4 5 6])]# Concatconcat_axis0 = tf.concat([a, b], axis=0) # [1, 2, 3, 4, 5, 6]# Splittensor = 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. 填充和裁剪# Padtensor = 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]]# Cropcropped = 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]张量广播# 广播机制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 + bexcept tf.errors.InvalidArgumentError as e: print("Broadcasting not possible:", e)张量数据类型转换# 类型转换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)张量比较# 相等比较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]张量排序# 排序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]]张量拼接和分割# 拼接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]])]张量掩码和条件操作# 布尔掩码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 > 3result = tf.boolean_mask(tensor, mask) # [4, 5]张量归约操作# 归约操作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) # 362880all_true = tf.reduce_all(tensor > 0) # Trueany_true = tf.reduce_any(tensor > 5) # True高效张量操作技巧1. 使用向量化操作# 低效方式result = []for i in range(1000): result.append(i * 2)# 高效方式tensor = tf.range(1000)result = tensor * 22. 批量处理# 批量矩阵乘法batch_size = 32matrices_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 加速@tf.functiondef fast_operation(x): return tf.reduce_sum(x * 2)# 第一次调用会编译,后续调用会更快result = fast_operation(tf.random.normal([1000, 1000]))4. 避免不必要的复制# 使用 tf.identity 避免复制a = tf.constant([1, 2, 3])b = tf.identity(a) # 不创建新张量,只是引用5. 使用合适的设备# 使用 GPUwith tf.device('/GPU:0'): a = tf.random.normal([1000, 1000]) b = tf.random.normal([1000, 1000]) c = tf.matmul(a, b)# 使用 CPUwith tf.device('/CPU:0'): a = tf.constant([1, 2, 3]) b = tf.constant([4, 5, 6]) c = a + b6. 内存优化# 使用 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 编译# 使用 XLA 编译加速@tf.function(experimental_compile=True)def xla_compatible_function(x): return tf.reduce_sum(x ** 2)2. 混合精度from 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. 并行化# 使用并行映射dataset = tf.data.Dataset.range(1000)dataset = dataset.map(lambda x: x * 2, num_parallel_calls=tf.data.AUTOTUNE)总结TensorFlow 的张量操作提供了强大的数据处理能力:张量创建:多种创建张量的方法索引切片:灵活的索引和切片操作张量运算:丰富的算术和数学运算形状操作:灵活的形状变换广播机制:自动处理不同形状的张量高效操作:向量化、批量处理、设备选择等优化技巧掌握这些张量操作将帮助你更高效地使用 TensorFlow 进行深度学习开发。