【技术专题】TensorFlow2 Python深度学习 - 张量(Tensor)的定义与操作

18 阅读6分钟

大家好,我是锋哥。最近连载更新《TensorFlow2 Python深度学习》技术专题。

QQ截图20260306194834.jpg 本课程主要讲解基于TensorFlow2的Python深度学习知识,包括深度学习概述,TensorFlow2框架入门知识,以及卷积神经网络(CNN),循环神经网络(RNN),生成对抗网络(GAN),模型保存与加载等。同时也配套视频教程 《2026版 TensorFlow2 Python深度学习 视频教程》

在 TensorFlow 2.x 中,张量(Tensor)是数据的核心表示方式,几乎所有的操作都会通过张量来进行。张量可以看作是一个多维数组或矩阵,它是一个包含数据的容器,可以存储不同类型的数据,如整数、浮点数、字符串等。

1. 张量的基本概念

张量是一个带有数据的 n 维数组。你可以把它理解为以下几种不同的情况:

  • 0维张量:标量(数值),如 5
  • 1维张量:向量,形如 [1, 2, 3]
  • 2维张量:矩阵,形如 [[1, 2], [3, 4]]
  • 3维张量:可以是一个立体数组,形如 [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
  • n维张量:任何维度的张量,形状根据数据决定。

2. 创建张量

从Python列表和NumPy数组创建

import tensorflow as tf
import numpy as np

# 创建0维张量(标量)
scalar = tf.constant(5)
print("标量:", scalar)
print("标量形状:", scalar.shape)
print("标量值:", scalar.numpy())  # 获取Python数值

# 创建1维张量(向量)
vector = tf.constant([1, 2, 3, 4, 5])
print("\n向量:", vector)
print("向量形状:", vector.shape)

# 创建2维张量(矩阵)
matrix = tf.constant([[1, 2, 3],
                      [4, 5, 6]])
print("\n矩阵:", matrix)
print("矩阵形状:", matrix.shape)

# 创建3维张量
tensor_3d = tf.constant([[[1, 2], [3, 4]],
                         [[5, 6], [7, 8]]])
print("\n3维张量:", tensor_3d)
print("3维张量形状:", tensor_3d.shape)

# 从NumPy数组创建
numpy_array = np.array([[1, 2], [3, 4]])
tensor_from_numpy = tf.constant(numpy_array)
print("\n从NumPy创建:", tensor_from_numpy)

运行结果:

标量: tf.Tensor(5, shape=(), dtype=int32)
标量形状: ()
标量值: 5

向量: tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
向量形状: (5,)

矩阵: tf.Tensor(
[[1 2 3]
 [4 5 6]], shape=(2, 3), dtype=int32)
矩阵形状: (2, 3)

3维张量: tf.Tensor(
[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]], shape=(2, 2, 2), dtype=int32)
3维张量形状: (2, 2, 2)

从NumPy创建: tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int64)

创建特殊张量

import tensorflow as tf

# 创建全零张量
zeros = tf.zeros([2, 3])
print("全零矩阵:\n", zeros.numpy())

# 创建全一张量
ones = tf.ones([3, 2])
print("\n全一矩阵:\n", ones.numpy())

# 创建单位矩阵
eye = tf.eye(3)  # 3x3单位矩阵
print("\n单位矩阵:\n", eye.numpy())

# 创建填充张量
filled = tf.fill([2, 2], 7)  # 2x2矩阵,全部填充为7
print("\n填充矩阵:\n", filled.numpy())

# 创建随机张量
random_uniform = tf.random.uniform([2, 3], minval=0, maxval=1)  # 均匀分布
print("\n均匀随机矩阵:\n", random_uniform.numpy())

random_normal = tf.random.normal([2, 2], mean=0, stddev=1)  # 正态分布
print("\n正态随机矩阵:\n", random_normal.numpy())

运行结果:

全零矩阵:
 [[0. 0. 0.]
 [0. 0. 0.]]

全一矩阵:
 [[1. 1.]
 [1. 1.]
 [1. 1.]]

单位矩阵:
 [[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

填充矩阵:
 [[7 7]
 [7 7]]

均匀随机矩阵:
 [[0.09006691 0.11618412 0.7688674 ]
 [0.7187872  0.85705507 0.41901422]]

正态随机矩阵:
 [[-0.45069897  0.07884365]
 [-0.29055706  0.04050421]]

3. 张量的关键属性

import tensorflow as tf

# 创建一个示例张量
tensor = tf.constant([[1, 2, 3],
                      [4, 5, 6]], dtype=tf.float32)

print("张量:", tensor)
print("形状(shape):", tensor.shape)  # 维度信息
print("秩(rank):", tensor.ndim)  # 维度数量
print("数据类型(dtype):", tensor.dtype)  # 数据类型
print("元素数量:", tf.size(tensor).numpy())  # 总元素个数
print("设备:", tensor.device)  # 所在设备(CPU/GPU)

运行结果:

张量: tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float32)
形状(shape): (2, 3)
秩(rank): 2
数据类型(dtype): <dtype: 'float32'>
元素数量: 6
设备: /job:localhost/replica:0/task:0/device:CPU:0

4. 张量的数据类型

import tensorflow as tf

# 指定数据类型创建张量
tensor_float32 = tf.constant([1, 2, 3], dtype=tf.float32)
tensor_int64 = tf.constant([1, 2, 3], dtype=tf.int64)
tensor_bool = tf.constant([True, False, True])

print("float32张量:", tensor_float32, tensor_float32.dtype)
print("int64张量:", tensor_int64, tensor_int64.dtype)
print("bool张量:", tensor_bool, tensor_bool.dtype)

# 数据类型转换
tensor_float = tf.constant([1.5, 2.7, 3.1])
tensor_int = tf.cast(tensor_float, dtype=tf.int32)  # 浮点数转整数
print("\n原始浮点张量:", tensor_float.numpy())
print("转换为整数:", tensor_int.numpy())

5. 张量操作

数学运算
import tensorflow as tf

a = tf.constant([[1, 2],
                 [3, 4]], dtype=tf.float32)
b = tf.constant([[5, 6],
                 [7, 8]], dtype=tf.float32)

# 基本算术运算
print("加法:\n", (a + b).numpy())  # 或 tf.add(a, b)
print("\n减法:\n", (a - b).numpy())  # 或 tf.subtract(a, b)
print("\n逐元素乘法:\n", (a * b).numpy())  # 或 tf.multiply(a, b)
print("\n逐元素除法:\n", (a / b).numpy())  # 或 tf.divide(a, b)

# 矩阵乘法
matrix_mult = tf.matmul(a, b)
print("\n矩阵乘法:\n", matrix_mult.numpy())

# 其他数学运算
print("\n平方:\n", tf.square(a).numpy())
print("\n平方根:\n", tf.sqrt(a).numpy())
print("\n指数:\n", tf.exp(a).numpy())
print("\n对数:\n", tf.math.log(a).numpy())

运行结果:

加法:
 [[ 6.  8.]
 [10. 12.]]

减法:
 [[-4. -4.]
 [-4. -4.]]

逐元素乘法:
 [[ 5. 12.]
 [21. 32.]]

逐元素除法:
 [[0.2        0.33333334]
 [0.42857143 0.5       ]]

矩阵乘法:
 [[19. 22.]
 [43. 50.]]

平方:
 [[ 1.  4.]
 [ 9. 16.]]

平方根:
 [[1.        1.4142135]
 [1.7320508 2.       ]]

指数:
 [[ 2.7182817  7.389056 ]
 [20.085537  54.59815  ]]

对数:
 [[0.        0.6931472]
 [1.0986123 1.3862944]]
形状操作
import tensorflow as tf

tensor = tf.constant([[1, 2, 3],
                      [4, 5, 6]])
print("原始张量:\n", tensor.numpy())
print("原始形状:", tensor.shape)

# 改变形状
reshaped = tf.reshape(tensor, [3, 2])  # 重塑为3x2
print("重塑为3x2:\n", reshaped.numpy())

# 展平
flattened = tf.reshape(tensor, [-1])  # -1 表示自动计算该维度大小
print("展平:", flattened.numpy())

# 转置
transposed = tf.transpose(tensor)
print("转置:\n", transposed.numpy())

# 增加/减少维度
expanded = tf.expand_dims(tensor, axis=0)  # 在第0维增加维度
print("增加维度:\n", expanded.numpy())
print("增加维度后形状:", expanded.shape)

squeezed = tf.squeeze(expanded, axis=0)  # 压缩维度
print("压缩维度:\n", squeezed.numpy())
print("压缩维度后形状:", squeezed.shape)

运行结果:

原始张量:
 [[1 2 3]
 [4 5 6]]
原始形状: (2, 3)
重塑为3x2:
 [[1 2]
 [3 4]
 [5 6]]
展平: [1 2 3 4 5 6]
转置:
 [[1 4]
 [2 5]
 [3 6]]
增加维度:
 [[[1 2 3]
  [4 5 6]]]
增加维度后形状: (1, 2, 3)
压缩维度:
 [[1 2 3]
 [4 5 6]]
压缩维度后形状: (2, 3)
索引和切片
import tensorflow as tf

tensor = tf.constant([[1, 2, 3, 4],
                      [5, 6, 7, 8],
                      [9, 10, 11, 12]])

print("原始张量:\n", tensor.numpy())

# 索引
print("第一行:", tensor[0].numpy())  # 第一行
print("最后一个元素:", tensor[-1, -1].numpy())  # 最后一行最后一列
print("元素(1,2):", tensor[1, 2].numpy())  # 第2行第3列

# 切片
print("前两行:\n", tensor[0:2].numpy())  # 行切片
print("所有行的第2-4列:\n", tensor[:, 1:3].numpy())  # 列切片
print("间隔取样:\n", tensor[::2, ::2].numpy())  # 每隔一个取一个

# 布尔索引
mask = tensor > 5
print("大于5的掩码:\n", mask.numpy())
print("大于5的值:", tensor[mask].numpy())

运行结果:

原始张量:
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
第一行: [1 2 3 4]
最后一个元素: 12
元素(1,2): 7
前两行:
 [[1 2 3 4]
 [5 6 7 8]]
所有行的第2-4列:
 [[ 2  3]
 [ 6  7]
 [10 11]]
间隔取样:
 [[ 1  3]
 [ 9 11]]
大于5的掩码:
 [[False False False False]
 [False  True  True  True]
 [ True  True  True  True]]
大于5的值: [ 6  7  8  9 10 11 12]

6. 张量广播

张量广播(Broadcasting)是一种使不同形状的张量能够进行元素级运算的技术,通过逻辑扩展小张量的维度使其与大张量形状兼容。 ‌

import tensorflow as tf

# 广播示例
a = tf.constant([[1, 2, 3]])  # 形状: (1, 3)
b = tf.constant([[4], [5], [6]])  # 形状: (3, 1)
print("a张量:\n", a.numpy())
print("b张量:\n", b.numpy())
# 广播机制会自动扩展维度以进行运算
result = a + b  # 相当于 [[1,2,3]] + [[4],[5],[6]]
print("a的形状:", a.shape)
print("b的形状:", b.shape)
print("广播相加结果:\n", result.numpy())
print("结果形状:", result.shape)

运行结果:

a张量:
 [[1 2 3]]
b张量:
 [[4]
 [5]
 [6]]
a的形状: (1, 3)
b的形状: (3, 1)
广播相加结果:
 [[5 6 7]
 [6 7 8]
 [7 8 9]]
结果形状: (3, 3)