# 机器学习中的 NumPy 张量的温和介绍

> 原文： [https://machinelearningmastery.com/introduction-to-tensors-for-machine-learning/](https://machinelearningmastery.com/introduction-to-tensors-for-machine-learning/)

在深度学习中，通常会将围绕张量的大量讨论视为基础数据结构。

Tensor 甚至出现在谷歌旗舰机器学习库的名称中：“TensorFlow”。

张量是线性代数中使用的一种数据结构，与向量和矩阵一样，您可以使用张量计算算术运算。

在本教程中，您将了解哪些张量以及如何使用 NumPy 在 Python 中对它们进行操作

完成本教程后，您将了解：

*   这些张量是矩阵的推广，并使用 n 维数组表示。
*   如何使用张量实现元素操作。
*   如何执行张量产品。

让我们开始吧。

![A Gentle Introduction to Tensors for Machine Learning with NumPy](img/11c5b1d90e311f196e22db2365206864.jpg)

使用 NumPy 轻松介绍机器学习的张量
照片由[DanielTombrañaGonzález](https://www.flickr.com/photos/teleyinex/10074893905/)拍摄，保留一些权利。

## 教程概述

本教程分为 3 个部分;他们是：

1.  什么是张量？
2.  Python 中的张量
3.  元素智能张量操作
4.  张量产品

## 什么是张量？

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

> 在一般情况下，布置在具有可变轴数的规则网格上的数字数组被称为张量。

- 第 33 页，[深度学习](http://amzn.to/2B3MsuU)，2016 年。

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

张量表示法很像矩阵表示法，大写字母表示张量和小写字母，下标整数表示张量中的标量值。

```
     t111, t121, t131     t112, t122, t132     t113, t123, t133
T = (t211, t221, t231),  (t212, t222, t232),  (t213, t223, t233)
     t311, t321, t331     t312, t322, t332     t313, t323, t333
```

可以使用标量，向量和矩阵执行的许多操作可以重新表示为使用张量执行。

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

## Python 中的张量

与向量和矩阵一样，张量可以使用 N 维数组（ndarray）在 Python 中表示。

张量可以作为列表列表与 array（）的构造函数内联定义。

下面的示例将 3x3x3 张量定义为 NumPy ndarray。三个尺寸更容易包裹你的头。在这里，我们首先定义行，然后是作为列堆叠的行列表，然后是在多维数据集中作为级别堆叠的列的列表。

```
# create tensor
from numpy import array
T = 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(T.shape)
print(T)
```

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

您可以看到，至少在三维空间中，张量被打印为一系列矩阵，每层一个矩阵。对于此 3D 张量，轴 0 指定级别，轴 1 指定列，轴 2 指定行。

```
(3, 3, 3)
[[[ 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]]]
```

## 元素智能张量操作

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

在本节中，我们将完成四个主要的算术运算。

### Tensor Addition

具有相同尺寸的两个张量的元素相加得到具有相同尺寸的新张量，其中每个标量值是父张量中标量的元素加法。

```
     a111, a121, a131     a112, a122, a132
A = (a211, a221, a231),  (a112, a122, a132)

     b111, b121, t131     b112, b122, b132
B = (b211, t221, t231),  (b112, b122, b132)

C = A + B

     a111 + b111, a121 + b121, a131 + b131     a112 + b112, a122 + b122, a132 + b132
C = (a211 + b211, a221 + b221, a231 + b231),  (a112 + b112, a122 + b122, a132 + b132)
```

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

```
# tensor addition
from numpy import array
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]],
  ])
B = 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]],
  ])
C = A + B
print(C)
```

运行该示例将打印两个父张量的添加。

```
[[[ 2  4  6]
  [ 8 10 12]
  [14 16 18]]

 [[22 24 26]
  [28 30 32]
  [34 36 38]]

 [[42 44 46]
  [48 50 52]
  [54 56 58]]]
```

### 张量减法

从具有相同尺寸的另一张量的一个张量的逐元素减法导致具有相同维度的新张量，其中每个标量值是父张量中标量的逐元素减法。

```
     a111, a121, a131     a112, a122, a132
A = (a211, a221, a231),  (a112, a122, a132)

     b111, b121, t131     b112, b122, b132
B = (b211, t221, t231),  (b112, b122, b132)

C = A - B

     a111 - b111, a121 - b121, a131 - b131     a112 - b112, a122 - b122, a132 - b132
C = (a211 - b211, a221 - b221, a231 - b231),  (a112 - b112, a122 - b122, a132 - b132)
```

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

```
# tensor subtraction
from numpy import array
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]],
  ])
B = 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]],
  ])
C = A - B
print(C)
```

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

```
[[[0 0 0]
  [0 0 0]
  [0 0 0]]

 [[0 0 0]
  [0 0 0]
  [0 0 0]]

 [[0 0 0]
  [0 0 0]
  [0 0 0]]]
```

### Tensor Hadamard 产品

一个张量与具有相同维度的另一张量的元素乘法导致具有相同维度的新张量，其中每个标量值是父张量中标量的元素乘法。

与矩阵一样，该操作被称为 Hadamard 乘积，以区别于张量乘法。在这里，我们将使用“o”运算符来指示张量之间的 Hadamard 产品操作。

```
     a111, a121, a131     a112, a122, a132
A = (a211, a221, a231),  (a112, a122, a132)

     b111, b121, t131     b112, b122, b132
B = (b211, t221, t231),  (b112, b122, b132)

C = A o B

     a111 * b111, a121 * b121, a131 * b131     a112 * b112, a122 * b122, a132 * b132
C = (a211 * b211, a221 * b221, a231 * b231),  (a112 * b112, a122 * b122, a132 * b132)
```

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

```
# tensor Hadamard product
from numpy import array
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]],
  ])
B = 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]],
  ])
C = A * B
print(C)
```

运行该示例将打印倍增张量的结果。

```
[[[  1   4   9]
  [ 16  25  36]
  [ 49  64  81]]

 [[121 144 169]
  [196 225 256]
  [289 324 361]]

 [[441 484 529]
  [576 625 676]
  [729 784 841]]]
```

### Tensor Division

一个张量的元素划分与具有相同维度的另一个张量导致具有相同维度的新张量，其中每个标量值是父张量中标量的元素划分。

```
     a111, a121, a131     a112, a122, a132
A = (a211, a221, a231),  (a112, a122, a132)

     b111, b121, t131     b112, b122, b132
B = (b211, t221, t231),  (b112, b122, b132)

C = A / B

     a111 / b111, a121 / b121, a131 / b131     a112 / b112, a122 / b122, a132 / b132
C = (a211 / b211, a221 / b221, a231 / b231),  (a112 / b112, a122 / b122, a132 / b132)
```

在 NumPy 中，我们可以通过划分数组直接划分张量。

```
# tensor division
from numpy import array
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]],
  ])
B = 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]],
  ])
C = A / B
print(C)
```

运行该示例将打印分割张量的结果。

```
[[[ 1\.  1\.  1.]
  [ 1\.  1\.  1.]
  [ 1\.  1\.  1.]]

 [[ 1\.  1\.  1.]
  [ 1\.  1\.  1.]
  [ 1\.  1\.  1.]]

 [[ 1\.  1\.  1.]
  [ 1\.  1\.  1.]
  [ 1\.  1\.  1.]]]
```

## 张量产品

张量积算子通常表示为中间带有小 x 的圆。我们在这里将其表示为“（x）”。

给定具有 q 维度的张量 A 和具有 r 维度的张量 B，这些张量的乘积将是具有 q + r 的量级的新张量，或者换言之，q + r 维度。

张量积不限于张量，也可以在矩阵和向量上执行，这可以是练习的好地方，以便开发更高维度的直觉。

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

```
a = (a1, a2)

b = (b1, b2)

c = a (x) b

     a1 * [b1, b2]
c = (a2 * [b1, b2])
```

或者，展开：

```
     a1 * b1, a1 * b2
c = (a2 * b1, a2 * b2)
```

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

```
     a11, a12
A = (a21, a22)

     b11, b12
B = (b21, b22)

C = A (x) B

            b11, b12          b11, b12
     a11 * (b21, b22), a12 * (b21, b22)
C = [       b11, b12          b11, b12 ]
     a21 * (b21, b22), a22 * (b21, b22)
```

Or, unrolled:

```
     a11 * b11, a11 * b12, a12 * b11, a12 * b12
     a11 * b21, a11 * b22, a12 * b21, a12 * b22
C = (a21 * b11, a21 * b12, a22 * b11, a22 * b12)
     a21 * b21, a21 * b22, a22 * b21, a22 * b22
```

张量积可以使用 tensordot（）函数在 NumPy 中实现。

该函数将两个要乘以的张量作为参数，并将产品总和的轴作为参数，称为总和减少。要计算张量积，也称为 NumPy 中的张量点积，轴必须设置为 0。

在下面的示例中，我们定义了两个 ord​​er-1 张量（向量）并计算张量积。

```
# tensor product
from numpy import array
from numpy import tensordot
A = array([1,2])
B = array([3,4])
C = tensordot(A, B, axes=0)
print(C)
```

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

结果是 2 阶张量（矩阵），长度为 2×2。

```
[[3 4]
 [6 8]]
```

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

## 扩展

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

*   使用您自己的小设计张量数据更新每个示例。
*   使用小向量或矩阵数据实现本教程未涉及的其他三种张量乘法。
*   编写自己的函数来实现每个张量操作。

如果你探索任何这些扩展，我很想知道。

## 进一步阅读

如果您希望深入了解，本节将提供有关该主题的更多资源。

### 图书

*   [学生向量和张量指南](http://amzn.to/2kmUvvF)，2011。
*   第 12 章，专题，[矩阵计算](http://amzn.to/2B9xnLD)，2012。
*   [Tensor Algebra 和 Tensor Analysis for Engineers](http://amzn.to/2C6gzCu) ，2015。

### API

*   [N 维数组](https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.ndarray.html)
*   [numpy.tensordot（）API](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.tensordot.html)

### 用品

*   [维基百科上的张量代数](https://en.wikipedia.org/wiki/Tensor_algebra)
*   [维基百科上的张量](https://en.wikipedia.org/wiki/Tensor)
*   维基百科上的 [Tensor 产品](https://en.wikipedia.org/wiki/Tensor_product)
*   [维基百科上的外部产品](https://en.wikipedia.org/wiki/Outer_product)

### 其他

*   [Tensor 训练格式中大规模数据分析的基本张量操作](https://arxiv.org/abs/1405.7786)，2016。
*   张量积，直接和，[量子力学 I](http://hitoshi.berkeley.edu/221a/tensorproduct.pdf) ，2006。
*   [Tensorphobia 和外部产品](https://jeremykun.com/2016/03/28/tensorphobia-outer-product/)，2016 年。
*   [Tensor 产品](https://jmanton.wordpress.com/2011/10/12/the-tensor-product/)，2011

## 摘要

在本教程中，您了解了哪些张量以及如何使用 NumPy 在 Python 中操作它们。

具体来说，你学到了：

*   这些张量是矩阵的推广，并使用 n 维数组表示。
*   如何使用张量实现元素操作。
*   如何执行张量产品。

你有任何问题吗？
在下面的评论中提出您的问题，我会尽力回答。