NumPy机器学习张量入门

在深度学习中,我们经常会看到关于张量作为基础数据结构的讨论。

张量(Tensor)这个词甚至出现在谷歌旗舰机器学习库的名称中:“TensorFlow”。

张量是线性代数中使用的一种数据结构,与向量和矩阵一样,你可以对张量进行算术运算。

在本教程中,你将了解什么是张量,以及如何使用 Python 和 NumPy 来操作它们。

完成本教程后,您将了解:

  • 张量是矩阵的推广,并使用n维数组来表示。
  • 如何用张量实现逐元素运算。
  • 如何执行张量积。

用我的新书《机器学习线性代数》开启你的项目,书中包含所有示例的分步教程Python 源代码文件

让我们开始吧。

  • 2019年10月更新:修正了数组索引名称中的拼写错误(感谢 Henry Chan)。
A Gentle Introduction to Tensors for Machine Learning with NumPy

NumPy机器学习张量入门
照片由 Daniel Lombraña González 拍摄,保留部分权利。

教程概述

本教程分为3个部分;它们是

  1. 什么是张量?
  2. Python中的张量
  3. 逐元素的张量运算
  4. 张量积

在机器学习线性代数方面需要帮助吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

什么是张量?

张量是向量和矩阵的推广,可以很容易地理解为多维数组。

在一般情况下,一个按常规网格排列、具有可变数量轴的数字数组被称为张量。

— 第33页, 《深度学习》, 2016.

向量是一维或一阶张量,矩阵是二维或二阶张量。

张量表示法与矩阵表示法非常相似,用一个大写字母表示一个张量,用带下标整数的小写字母表示张量内的标量值。

许多可以对标量、向量和矩阵执行的运算,都可以重新定义为对张量执行。

作为一个工具,张量和张量代数被广泛应用于物理和工程领域。在机器学习中,它是一个已知的术语和技术集,深度学习模型的训练和操作可以用张量来描述。

Python中的张量

与向量和矩阵一样,张量可以在Python中使用N维数组(ndarray)来表示。

张量可以在 array() 构造函数中以内联方式定义为列表的列表。

下面的示例将一个3x3x3的张量定义为NumPy ndarray。三维更容易理解。在这里,我们首先定义行,然后是将行堆叠成列的列表,最后是将列堆叠成立方体中的层的列表。

运行该示例首先打印张量的形状,然后打印张量本身的值。

你可以看到,至少在三维情况下,张量被打印为一系列矩阵,每一层一个。对于这个3D张量,轴0指定层,轴1指定行,轴2指定列。

逐元素的张量运算

与矩阵一样,我们可以在张量之间执行逐元素的算术运算。

在本节中,我们将介绍四种主要的算术运算。

张量加法

两个具有相同维度的张量进行逐元素相加,会得到一个具有相同维度的新张量,其中每个标量值是父张量中标量的逐元素相加结果。

在 NumPy 中,我们可以直接通过相加数组来添加张量。

运行该示例会打印两个父张量相加的结果。

张量减法

从一个张量中逐元素减去另一个具有相同维度的张量,会得到一个具有相同维度的新张量,其中每个标量值是父张量中标量的逐元素相减结果。

在 NumPy 中,我们可以直接通过相减数组来减去张量。

运行该示例会打印从第二个张量中减去第一个张量的结果。

张量哈达玛积

一个张量与另一个具有相同维度的张量进行逐元素相乘,会得到一个具有相同维度的新张量,其中每个标量值是父张量中标量的逐元素相乘结果。

与矩阵一样,该运算被称为哈达玛积(Hadamard Product),以区别于张量乘法。在这里,我们将使用“o”运算符来表示张量之间的哈达玛积运算。

在 NumPy 中,我们可以直接通过相乘数组来乘以张量。

运行该示例会打印张量相乘的结果。

张量除法

一个张量与另一个具有相同维度的张量进行逐元素相除,会得到一个具有相同维度的新张量,其中每个标量值是父张量中标量的逐元素相除结果。

在 NumPy 中,我们可以直接通过相除数组来除以张量。

运行该示例会打印张量相除的结果。

张量积

张量积运算符通常用一个中间有一个小x的圆圈来表示。我们在这里用“(x)”来表示它。

给定一个q维张量A和一个r维张量B,这些张量的积将是一个阶为q + r的新张量,或者换句话说,是q + r维的。

张量积不仅限于张量,也可以对矩阵和向量进行运算,这是一个很好的练习起点,以便于培养对更高维度的直觉。

我们来看看向量的张量积。

或者,展开来看

我们来看看矩阵的张量积。

或者,展开来看

在 NumPy 中,可以使用 tensordot() 函数来实现张量积。

该函数接受两个要相乘的张量以及对乘积求和的轴作为参数,这被称为求和缩并。为了计算张量积,在 NumPy 中也称为张量点积,必须将轴设置为 0。

在下面的示例中,我们定义了两个一阶张量(向量)并计算了张量积。

运行该示例会打印张量积的结果。

结果是一个阶为2的张量(矩阵),尺寸为2×2。

张量积是您可能遇到的最常见的张量乘法形式,但还存在许多其他类型的张量乘法,例如张量点积和张量缩并。

扩展

本节列出了一些您可能希望探索的扩展本教程的想法。

  • 使用您自己的人为构造的小张量数据更新每个示例。
  • 使用小的向量或矩阵数据实现本教程未涵盖的其他三种张量乘法。
  • 编写您自己的函数来实现每个张量运算。

如果您探索了这些扩展中的任何一个,我很想知道。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

书籍

API

文章

其他

总结

在本教程中,您了解了什么是张量,以及如何使用 Python 和 NumPy 对其进行操作。

具体来说,你学到了:

  • 张量是矩阵的推广,并使用n维数组来表示。
  • 如何用张量实现逐元素运算。
  • 如何执行张量积。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

掌握机器学习线性代数!

Linear Algebra for Machine Learning

建立对线性代数的工作理解

...通过在 python 中编写代码

在我的新电子书中探索如何实现
机器学习线性代数

它提供关于以下主题的自学教程
向量范数、矩阵乘法、张量、特征分解、SVD、PCA 等等...

最终理解数据的数学

跳过学术理论。只看结果。

查看内容

NumPy机器学习张量入门的43条回应

  1. Laique Merlin Djeutchouang 2018年2月14日 晚上7:29 #

    嗨,Jason!

    非常棒、简单且详细地介绍了深度学习的关键数学工具之一。我认为任何张量领域的业余爱好者都可以轻松地从这里开始。

  2. Dhananjay 2018年5月31日 下午12:37 #

    你好,Jason

    这是一个非常棒的张量入门介绍。对于像我这样的初学者来说,阅读起来很快。非常有帮助。

  3. Xiwang Li 2018年11月3日 上午9:38 #

    感谢您的博客,非常有帮助。但我有一个普遍性的问题。为什么我们在深度学习中需要张量?为什么不直接使用Numpy数组呢?

    • Jason Brownlee 2018年11月4日 上午6:23 #

      你可以用numpy数组开发自己的库。

      张量只是矩阵的一种推广。

  4. justin 2019年1月15日 上午9:37 #

    “给定一个q维张量A和一个r维张量B,这些张量的积将是一个阶为q + r的新张量,或者换句话说,是q + r维的。”

    或许……应该是 q*r?

    • Victor 2019年7月7日 上午8:45 #

      很好的教程,定义非常清晰。我认为张量点积可能是最棘手的运算符,因为你只提供了低维度的几个例子,但没有提供n阶乘m阶的通用公式。我认为如果能将张量与表示深度学习概念的用途联系起来,也会很有帮助。

  5. Sebastian 2019年2月25日 晚上8:07 #

    谢谢你,总结得很好!

  6. Ahmad 2019年6月13日 凌晨1:49 #

    内容不错,但希望你也能讲讲分解和其他内容。谢谢,写得很好。

  7. Mahalingam 2019年6月29日 晚上9:11 #

    这与矩阵乘法完全不同。在矩阵中,维度被定义为 A mxn,其中矩阵 A 有 m 行和 n 列。

  8. Abraham 2019年7月16日 凌晨5:01 #

    嗨,Jason!
    我有一个关于张量转换的问题。我正在使用注意力机制,我必须在 for 循环中执行我的操作,所以我将结果存储在一个列表中。最后,我无法将列表转换为张量,以便将结果与全连接层连接起来。您能给我一些建议来解决这个问题吗?

    • Jason Brownlee 2019年7月16日 上午8:24 #

      列表或numpy数组都可以表示一个张量。

      我想你可能指的是某个特定库的张量数据类型?或许可以查看该库的API,了解如何将列表和数组转换为该类型?

  9. sunny1304 2019年7月25日 凌晨2:22 #

    非常好的教程。
    我不是数学专家,但是向量难道不是张量的一种特殊类型,而不是反过来吗?

    谢谢。

  10. Vladimir 2019年9月4日 凌晨12:39 #

    解释得很好。而且很容易理解!

  11. Henry Chan 2019年10月22日 上午11:06 #

    嗨,Jason,

    您说“对于这个3D张量,轴0指定层,轴1指定列,轴2指定行。”

    但我认为应该是
    对于这个3D张量,轴0指定层,轴1指定行,轴2指定列。

    A = array([
    [[1,2,3], [4,5,6], [7,8,9]],
    [[11,12,13], [14,15,16], [17,18,19]],
    [[21,22,23], [24,25,26], [27,28,29]]
    ])

    使用零索引,我们会有

    print(A[0,0,0]) –> 1: 层 0, 行 0, 列 0
    print(A[0,0,1]) –> 2: 层 0, 行 0, 列 1
    print(A[0,1,0]) –> 4: 层 0, 行 1, 列 0

    如果我错了请纠正我。
    谢谢

    • Jason Brownlee 2019年10月22日 下午1:48 #

      谢谢。

      也试试这个

      打印结果

      [1 2 3]
      [1 4 7]

  12. Yansen Xiao 2019年12月6日 凌晨2:42 #

    在所有的加法、减法、乘法和除法示例中,我看到这个
    b111, b121, t131
    B = (b211, t221, t231)

    “t”应该是“b”吗?我完全是张量的新手,这是我第一次学习它。

  13. Max 2020年1月28日 晚上11:46 #

    谢谢。我仍然很困惑,因为其他解释提到张量具有额外的属性,而“它只是矩阵的推广”这个想法没有捕捉到这些属性。

    “但是[广义矩阵]这种描述忽略了张量最重要的属性!

    张量是一个存在于某个结构中的数学实体,并与其他数学实体相互作用。如果以一种规则的方式变换结构中的其他实体,那么张量必须遵循一个相关的变换规则。”

    https://medium.com/@quantumsteinke/whats-the-difference-between-a-matrix-and-a-tensor-4505fbdc576c

    • Jason Brownlee 2020年1月29日 上午6:37 #

      对此不太确定…

      或许可以和作者谈谈他的想法?

    • matt 2020年5月27日 凌晨1:03 #

      看来计算机科学家们从物理学家/数学家那里借用了这个术语,并将其重新定义为“多维数组”。Jason Brownlee 甚至引用了《深度学习》这本书来指出这一点。但你的困惑是合理的,因为这并不是物理学家使用的定义。

      物理学家使用“张量”这个术语来指代一个几何对象,当坐标系改变时,它保持不变(即,它保留像长度、方向等属性)。

      了解什么不是张量可能会有帮助。假设我们关注向量中的一个分量。当底层坐标系改变时,这个分量(一个0阶张量)会改变。所以单个分量不能是张量,即使它满足多维数组的定义。

      要理解张量,我建议查看eigenchris的视频:https://www.youtube.com/watch?v=8ptMTLzV4-I&t=321s

  14. manikanta kotte 2020年4月1日 晚上10:22 #

    先生,如何用 for 循环来做那个求和?请解释一下?

  15. Stephen Hobbs 2020年6月18日 下午12:24 #

    谢谢Jason!非常有趣。这篇教程帮助我理解了这些概念。非常直接,代码和图表用得很好。做得好!

  16. Phil 2020年6月28日 上午6:04 #

    有用的文章,但它没有描述张量在机器学习领域代表什么。它们代表训练数据、模型本身、两者,还是其他?

    • Jason Brownlee 2020年6月29日 上午6:17 #

      谢谢。

      它们可以用来表示数据或模型系数,例如神经网络中的权重。

  17. dong zhan 2020年8月10日 下午3:58 #

    张量积,用这个 ⊗

  18. Abhi Bhagat 2020年8月29日 下午4:47 #

    在下面的例子中,我们定义了两个order-1张量(向量)并计算了张量积。

    您能解释一下这里的“-1”是怎么来的吗?

    • Jason Brownlee 2020年8月30日 上午6:31 #

      应读作“order-one”(一阶),而不是负一。例如,一维的。

  19. Abdul 2021年11月5日 上午7:48 #

    为什么要用张量?

    • Adrian Tam
      Adrian Tam 2021年11月7日 上午8:00 #

      因为这是我们可以将一组数字放在一起的方式。

  20. Roz 2021年12月21日 晚上9:02 #

    非常感谢这篇教程。
    最近我在处理一个问题,每个样本都是一个矩阵,例如10*10(所以数据集是一个维度为10*10*1000的张量)。
    我想对这个数据集进行分类,但分类不是离散的。
    所以这可能是一个回归问题。我不确定,而且我想预测一个矩阵(分类器的输出必须是一个矩阵)。
    有什么资源、书籍等可以帮助我解决这个问题吗?

    如果您能就此事提供指导,我将不胜感激。
    非常感谢。

  21. Elmar 2025年8月20日 上午9:48 #

    机器学习中的这些“数据张量”实际上令人困惑,因为数学中的张量有更强的含义。在数学中,张量可以从1个或多个向量参数(理论上也可以是0个参数)以一种特定的方式(每个参数都是线性的)映射到一个向量空间。在实践中,我们可能使用表格通过乘法和加法来计算任何参数下张量的输出,但这并不意味着表格就是张量。张量本身实际上“包含”了所有输入和输出之间的所有映射。

    当然,向量也可以是一个ndarray。Numpy中的Ndarrays在数学上是以元组为索引的向量。是矩阵积或张量积将某物变成了非平凡的张量(标量和列向量是平凡的张量)。我看到的ANN公式要么是一组矩阵(每层一个),要么是使用多维数字网格表示的矩阵,而不是像传统矩阵那样。我们也可以称之为线性代数和多维矩阵。(表格维度或Numpy轴的数量在数学张量中称为“阶”,或“模态数”。)超越经典矩阵乘法的情况是,当我们将滤波器由多个较小维度的滤波器组成时,在“数据张量”的多个维度上乘以一个滤波器。张量数学的主要好处是能高效地将多个线性运算一起计算。显然,这就是卷积神经网络所使用的。

    Numpy中的tensordot积就像是即时将ndarrays类型转换为数学张量。因为tensordot实际上有第三个参数,它指定了左因子和右因子的哪些轴将被视为参数(在左侧)和参数(在右侧)。张量的函数应用在参数轴和相关参数轴之间使用标量积(逐元素乘积并求和)。矩阵是一种特殊情况,行轴为参数,列轴为参数。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。