tensorflow概念详解之张量tensor
一、张量的概念
也许你已经下载了TensorFlow,而且准备开始着手研究深度学习。但是你会疑惑:TensorFlow里面的Tensor,也就是“张量”,到底是个什么鬼?也许你查阅了维基百科,而且现在变得更加困惑。也许你在NASA教程中看到它,仍然不知道它在说些什么?问题在于大多数讲述张量的指南,都假设你已经掌握他们描述数学的所有术语。
我像小孩子一样讨厌数学,所以如果我能明白,你也可以!我们只需要用简单的措辞来解释这一切。所以,张量(Tensor)是什么,而且为什么会流动(Flow)?
0维张量/标量 标量是一个数字
1维张量/向量 1维张量称为“向量”。
2维张量 2维张量称为矩阵
3维张量 公用数据存储在张量 时间序列数据 股价 文本数据 彩色图片(RGB)
让我们先来看看tensor(张量)是什么?
张量=容器
张量是现代机器学习的基础。它的核心是一个数据容器,多数情况下,它包含数字,有时候它也包含字符串,但这种情况比较少。因此把它想象成一个数字的水桶。
张量有多种形式,首先让我们来看最基本的形式,你会在深度学习中偶然遇到,它们在0维到5维之间。我们可以把张量的各种类型看作这样(对被题目中的猫咪吸引进来小伙伴说一句,不要急!猫咪在后面会出现哦!):
0维张量/标量 ,装在张量/容器水桶中的每个数字称为“标量”。标量是一个数字。你会问为什么不干脆叫它们一个数字呢?我不知道,也许数学家只是喜欢听起来酷?标量听起来确实比数字酷。
实际上,你可以使用一个数字的张量,我们称为0维张量,也就是一个只有0维的张量。它仅仅只是带有一个数字的水桶。想象水桶里只有一滴水,那就是一个0维张量。
本文将使用Python,Keras,TensorFlow和Python库Numpy。在Python中,张量通常存储在Nunpy数组,Numpy是在大部分的AI框架中,一个使用频率非常高的用于科学计算的数据包。
你将在Kaggle(数据科学竞赛网站)上经常看到Jupyter Notebooks(安装见文末阅读链接,“数学烂也要学AI:带你造一个经济试用版AI终极必杀器”)关于把数据转变成Numpy数组。Jupyter notebooks本质上是由工作代码标记嵌入。可以认为它把解释和程序融为一体。
我们为什么想把数据转换为Numpy数组?
很简单。因为我们需要把所有的输入数据,如字符串文本,图像,股票价格,或者视频,转变为一个统一得标准,以便能够容易的处理。
这样我们把数据转变成数字的水桶,我们就能用TensorFlow处理。
它仅仅是组织数据成为可用的格式。在网页程序中,你也许通过XML表示,所以你可以定义它们的特征并快速操作。同样,在深度学习中,我们使用张量水桶作为基本的乐高积木。
1维张量/向量 如果你是名程序员,那么你已经了解,类似于1维张量:数组。
每个编程语言都有数组,它只是单列或者单行的一组数据块。在深度学习中称为1维张量。张量是根据一共具有多少坐标轴来定义。1维张量只有一个坐标轴。 1维张量称为“向量”。我们可以把向量视为一个单列或者单行的数字。
如果想在Numpy得出此结果,按照如下方法:我们可以通过NumPy’s ndim函数,查看张量具有多个坐标轴。我们可以尝试1维张量。
2维张量 你可能已经知道了另一种形式的张量,矩阵——2维张量称为矩阵,这不是基努·里维斯(Keanu Reeves)的电影《黑客帝国》,想象一个excel表格。我们可以把它看作为一个带有行和列的数字网格。这个行和列表示两个坐标轴,一个矩阵是二维张量,意思是有两维,也就是有两个坐标轴的张量。
在Numpy中,我们可以如下表示:
x = np.array([[5,10,15,30,25],
[20,30,65,70,90],
[7,80,95,20,30]])
张量是具有统一类型(称为 dtype)的多维数组。您可以在 tf.dtypes.DType 中查看所有支持的 dtypes。
如果您熟悉 NumPy,就会知道张量与 np.arrays 有一定的相似性。
就像 Python 数值和字符串一样,所有张量都是不可变的:永远无法更新张量的内容,只能创建新的张量。
基础知识
首先,创建一些基本张量。
下面是一个“标量”(或称“0 秩”张量)。标量包含单个值,但没有“轴”。
# This will be an int32 tensor by default; see "dtypes" below.
rank_0_tensor = tf.constant(4)
print(rank_0_tensor)
tf.Tensor(4, shape=(), dtype=int32)
“向量”(或称“1 秩”张量)就像一个值列表。向量有 1 个轴:
# Let's make this a float tensor.
rank_1_tensor = tf.constant([2.0, 3.0, 4.0])
print(rank_1_tensor)
tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)
“矩阵”(或称“2 秩”张量)有 2 个轴:
# If you want to be specific, you can set the dtype (see below) at creation time
rank_2_tensor = tf.constant([[1, 2],
[3, 4],
[5, 6]], dtype=tf.float16)
print(rank_2_tensor)
tf.Tensor( [[1. 2.] [3. 4.] [5. 6.]], shape=(3, 2), dtype=float16)
标量,形状:[] |
向量,形状:[3] |
矩阵,形状:[3, 2] |
|---|

张量的轴可能更多,下面是一个包含 3 个轴的张量:
# There can be an arbitrary number of
# axes (sometimes called "dimensions")
rank_3_tensor = tf.constant([
[[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]],
[[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]],
[[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]],])
print(rank_3_tensor)
tf.Tensor( [[[ 0 1 2 3 4] [ 5 6 7 8 9]] [[10 11 12 13 14] [15 16 17 18 19]] [[20 21 22 23 24] [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)
对于包含 2 个以上的轴的张量,您可以通过多种方式加以呈现。3 轴张量,形状:[3, 2, 5]

通过使用 np.array 或 tensor.numpy 方法,您可以将张量转换为 NumPy 数组。
np.array(rank_2_tensor)
在机器学习工作中,我们经常要处理不止一张图片或一篇文档——我们要处理一个集合。我们可能有10,000张郁金香的图片,这意味着,我们将用到4D张量,就像这样:
(sample_size, width, height, color_depth) = 4D
我们来看看一些多维张量存储模型的例子:
时间序列数据
用3D张量来模拟时间序列会非常有效!
医学扫描——我们可以将脑电波(EEG)信号编码成3D张量,因为它可以由这三个参数来描述:
(time, frequency, channel)
这种转化看起来就像这样:
如果我们有多个病人的脑电波扫描图,那就形成了一个4D张量:
(sample_size, time, frequency, channel)
Stock Prices
在交易中,股票每分钟有最高、最低和最终价格。如下图的蜡烛图所示:
纽交所开市时间从早上9:30到下午4:00,即6.5个小时,总共有6.5 x 60 = 390分钟。如此,我们可以将每分钟内最高、最低和最终的股价存入一个2D张量(390,3)。如果我们追踪一周(五天)的交易,我们将得到这么一个3D张量:
(week_of_data, minutes, high_low_price)
即:(5,390,3)
同理,如果我们观测10只不同的股票,观测一周,我们将得到一个4D张量
(10,5,390,3)
假设我们在观测一个由25只股票组成的共同基金,其中的每只股票由我们的4D张量来表示。那么,这个共同基金可以有一个5D张量来表示:
(25,10,5,390,3)
张量通常包含浮点型和整型数据,但是还有许多其他数据类型,包括:
- 复杂的数值
- 字符串
tf.Tensor 基类要求张量是“矩形”,也就是说,每个轴上的每一个元素大小相同。但是,有可以处理不同形状的特殊类型张量:
- 不规则张量(请参阅下文中的 RaggedTensor)
- 稀疏张量(请参阅下文中的 SparseTensor)
您可以对张量执行基本数学运算,包括加法、逐元素乘法和矩阵乘法。
a = tf.constant([[1, 2],
[3, 4]])
b = tf.constant([[1, 1],
[1, 1]]) # Could have also said `tf.ones([2,2])`
print(tf.add(a, b), "\n")
print(tf.multiply(a, b), "\n")
print(tf.matmul(a, b), "\n")
tf.Tensor( [[2 3] [4 5]], shape=(2, 2), dtype=int32) tf.Tensor( [[1 2] [3 4]], shape=(2, 2), dtype=int32) tf.Tensor( [[3 3] [7 7]], shape=(2, 2), dtype=int32)
print(a + b, "\n") # element-wise addition
print(a * b, "\n") # element-wise multiplication
print(a @ b, "\n") # matrix multiplication
tf.Tensor( [[2 3] [4 5]], shape=(2, 2), dtype=int32) tf.Tensor( [[1 2] [3 4]], shape=(2, 2), dtype=int32) tf.Tensor( [[3 3] [7 7]], shape=(2, 2), dtype=int32)
各种运算都可以使用张量。
c = tf.constant([[4.0, 5.0], [10.0, 1.0]])
# Find the largest value
print(tf.reduce_max(c))
# Find the index of the largest value
print(tf.math.argmax(c))
# Compute the softmax
print(tf.nn.softmax(c))
tf.Tensor(10.0, shape=(), dtype=float32) tf.Tensor([1 0], shape=(2,), dtype=int64) tf.Tensor( [[2.6894143e-01 7.3105854e-01] [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)
注:通常,在 TensorFlow 函数需要 Tensor 作为输入的任何地方,该函数也将接受可使用 tf.convert_to_tensor 转换为 Tensor 的任何内容。请参见下面的示例。
张量的广播机制
广播(Broadcasting)是TensorFlow中处理不同形状张量运算的重要机制,它自动扩展较小的张量以匹配较大张量的形状。
广播规则
从最后一个维度开始向前比较
两个维度要么相等,要么其中一个为1,要么其中一个不存在
在缺失或为1的维度上进行复制扩展
# 向量(3,)与标量()相加
a = tf.constant([1, 2, 3])
b = tf.constant(2)
c = a + b # 结果为[3,4,5],b被广播为[2,2,2]
# 矩阵(3,1)与向量(3,)相加
d = tf.constant([[1], [2], [3]])
e = tf.constant([10, 20, 30])
f = d + e # d被广播为[[1,1,1],[2,2,2],[3,3,3]]
# 结果为[[11,21,31],[12,22,32],[13,23,33]]
广播(Broadcasting)是 TensorFlow(以及 NumPy 等科学计算框架)中一种自动处理不同形状张量(或数组)之间运算的机制,核心作用是在不实际复制数据的情况下,让形状不匹配的张量能够进行元素级运算,从而简化代码并提高计算效率。
为什么需要广播?
当两个张量形状不同时,直接进行元素级运算(如加减乘除)会报错。例如,一个形状为 (3, 3) 的张量和一个形状为 (3, 1) 的张量,无法直接按元素相乘 —— 因为它们的列维度不匹配(3 vs 1)。广播机制通过虚拟扩展较小张量的维度(仅在计算时逻辑上扩展,不实际占用内存),让两者形状一致,从而完成运算。
广播的核心规则(从维度匹配角度理解)
TensorFlow 会从最后一个维度开始向前逐维度比较两个张量的形状,只有满足以下条件时才能广播:
两个维度相等;
其中一个维度为 1;
其中一个张量在该维度上 “不存在”(即维度长度为 0)。
若所有维度都满足上述条件,则可以广播;否则会报错。
广播的扩展逻辑
对于不满足 “维度相等” 的情况,会对维度为 1 或缺失的维度进行 “复制扩展”,使其与另一个张量的对应维度长度一致。
张量的聚合操作
#重新开始赋值;
tensor=tf.constant([[1,2,3],[4,5,6]])
#求和
sum_all=tf.reduce_sum(tensor)
sum_axis0=tf.reduce_sum(tensor,0) #延第0维【行】求和:
sum_axis1=tf.reduce_sum(tensor,1) #延第1维度【列】来 求和
print(sum_all)
print(sum_axis0)
print(sum_axis1)
#求平均值
tensor=tf.constant([[1,2,3],[4,5,6]],dtype=tf.float32)
mean_avg=tf.reduce_mean(tensor) #所有元素的均值
print("平均值",mean_avg)
#求最大值和最小值;
max_val=tf.reduce_max(tensor)
min_val=tf.reduce_min(tensor)
print(max_val,min_val)
#逻辑运算;
any_true=tf.reduce_any(tensor>4) #是否有元素>4 -->True
all_true=tf.reduce_all(tensor>4)
print(any_true,all_true)
总结
- 维度与属性:分 0 维(标量)、1 维(向量)、2 维(矩阵)及更高维(如 3 维存时间序列、4 维存图像);有固定
shape(维度大小)和dtype(数据类型),且不可变。 - 基础操作:可与 NumPy 数组互转;支持元素级 / 矩阵运算、聚合操作(求和 / 均值等),及索引查找、概率计算、逻辑判断等功能。
- 广播机制:不同形状张量运算时,逻辑扩展较小张量(从最后一维比较,维度需满足相等、其一为 1 或缺失),无需实际复制数据。
- 特殊类型与应用:含不规则(RaggedTensor)、稀疏(SparseTensor)张量;不同业务场景(如股票、图像)用对应维度张量存储。
- 点赞
- 收藏
- 关注作者
评论(0)