PyTorch - 12 - 深度学习代码 - ArgMax和缩减Tensor Ops

Tensor Reduction Operations

`
让我们为还原操作定义一个开始。

张量的归约运算是减少张量中包含的元素数量的运算。
A reduction operation on a tensor is an operation that reduces the number of elements contained within the tensor.

到目前为止,在本系列文章中,我们已经了解到,张量是深度学习的数据结构。 我们的首要任务是将数据元素加载到张量中。

因此,张量非常重要,但最终,我们在本系列中学到的操作中正在做的事情是管理张量中包含的数据元素。

张量使我们能够管理数据。

整形操作使我们能够沿特定轴定位元素。 逐元素运算允许我们对两个张量之间的元素执行运算,归约运算允许我们对单个张量内的元素执行运算。

我们来看一个代码示例。

Reduction Operation Example

假设我们使用以下3 x 3 rank-2张量:

> t = torch.tensor([
    [0,1,0],
    [2,0,2],
    [0,3,0]
], dtype=torch.float32)

让我们看一下我们的第一个归约运算:

> t.sum()
tensor(8.)

利用事实

> t.numel()
9

> t.sum().numel()
1

我们可以看到

> t.sum().numel() < t.numel()
True

张量的标量分量之和是使用sum()张量方法计算的。 该调用的结果是标量值张量。

根据sum()调用的结果检查原始张量中的元素数量,我们可以看到,确实,对sum()的调用返回的张量包含的元素少于原始张量。

由于该操作已减少了元素数量,因此我们可以得出结论sum()方法是一种减少操作。

Common Tensor Reduction Operations

如您所料,这是一些其他常见的归约函数:

> t.sum()
tensor(8.)

> t.prod()
tensor(0.)

> t.mean()
tensor(.8889)

> t.std()
tensor(1.1667)

所有这些张量方法都通过对所有张量元素进行运算而将张量缩减为单个元素标量值张量。

归约运算通常使我们能够计算跨数据结构的合计(总)值。 在我们的情况下,我们的结构是张量。

不过,这是一个问题:

归约运算是否总是将一个张量归约为张量?
Do reduction operations always reduce to a tensor with a single element?

答案是不!

实际上,我们经常一次减少特定的轴。 这个过程很重要。 就像我们打算重新调整批次中的图像张量,同时仍保持批次轴时,看到的是重新整形。

Reducing Tensors By Axes

为了减少相对于特定轴的张量,我们使用相同的方法,我们只是传递了维参数的值。让我们来看看实际情况。

假设我们有以下张量:

> t = torch.tensor([
    [1,1,1,1],
    [2,2,2,2],
    [3,3,3,3]
], dtype=torch.float32)

这是一个3 x 4 rank-2张量。两个轴的长度不同将有助于我们理解这些归约操作。

让我们再次考虑sum()方法。仅这次,我们将指定要减小的尺寸。我们有两个轴,所以我们两个都做。看看这个。

> t.sum(dim=0)
tensor([6., 6., 6., 6.])

> t.sum(dim=1)
tensor([ 4.,  8., 12.])

当我在学习如何工作时第一次看到它时,我很困惑。如果您像我一样感到困惑,强烈建议您先尝试了解此处的情况,然后再继续。

请记住,我们正在沿着第一轴减小此张量,并且沿第一轴运行的元素是数组,而沿第二轴运行的元素是数字。

让我们回顾一下这里发生的事情。

Understanding Reductions By Axes

我们将首先处理第一个轴。当求和第一个轴时,我们求和第一个轴的元素。

就像这样:

> t[0]
tensor([1., 1., 1., 1.])

> t[1]
tensor([2., 2., 2., 2.])

> t[2]
tensor([3., 3., 3., 3.])

> t[0] + t[1] + t[2]
tensor([6., 6., 6., 6.])

惊喜!元素操作在这里起作用。

当我们沿第一条轴求和时,我们就是对第一条轴的所有元素求和。为此,我们必须利用逐元素加法。这就是为什么我们在系列中的归约运算之前介绍了逐元素运算的原因。

张量中的第二个轴包含以四个为一组的数字。由于我们有四个数字组成的三组,因此得到三个总和。

> t[0].sum()
tensor(4.)

> t[1].sum()
tensor(8.)

> t[2].sum()
tensor(12.)

> t.sum(dim=1)
tensor([ 4.,  8., 12.])

这可能需要花费一些时间。如果确实如此,请放心,您可以这样做。

现在,有了这繁重的工作。现在让我们看一下在神经网络编程中使用的一种非常常见的归约运算,称为Argmax。

Argmax Tensor Reduction Operation

Argmax是一个数学函数,它告诉我们将哪个参数作为输入提供给函数时会导致函数的最大输出值。

Argmax返回张量内最大值的索引位置。

当我们在张量上调用argmax()方法时,该张量将减少为一个新的张量,该张量包含一个指示最大值在张量内部的索引值。让我们在代码中看到这一点。

假设我们有以下张量:

t = torch.tensor([
    [1,0,0,2],
    [0,3,3,0],
    [4,0,0,5]
], dtype=torch.float32)

在这个张量中,我们可以看到最大值是最后一个数组的最后一个位置的5。

假设我们是张量步行者。要到达此元素,我们沿着第一个轴走直到到达最后一个数组元素,然后我们走到该数组的末尾并经过4和两个0。

让我们看一些代码。

> t.max()
tensor(5.)

> t.argmax()
tensor(11)

> t.flatten()
tensor([1., 0., 0., 2., 0., 3., 3., 0., 4., 0., 0., 5.])

第一段代码为我们确认了max确实为5,但是对argmax()方法的调用告诉我们5位于索引11。这是怎么回事?

我们将看看此张量的展平输出。如果我们没有为argmax()方法指定轴,则它会从展平的张量中返回最大值的索引位置,在这种情况下确实为11。

让我们看看现在如何使用特定轴。

> t.max(dim=0)
(tensor([4., 3., 3., 5.]), tensor([2, 1, 1, 2]))

> t.argmax(dim=0)
tensor([2, 1, 1, 2])

> t.max(dim=1)
(tensor([2., 3., 5.]), tensor([3, 1, 3]))

> t.argmax(dim=1)
tensor([3, 1, 3])

在此代码中,我们正在使用该张量的两个轴。请注意,对max()方法的调用如何返回两个张量。第一个张量包含最大值,第二个张量包含最大值的索引位置。这就是argmax给我们的。

对于第一个轴,最大值分别为4、3、3和5。这些值是通过跨第一个轴的每个数组取元素方向的最大值来确定的。

对于这些最大值中的每一个,argmax()方法告诉我们该值沿第一轴位于哪个元素。

  • 4位于第一轴的索引2。
  • 前3个位于第一个轴的索引1。
  • 第二个3位于第一个轴的索引1。
  • 5位于第一轴的索引2。

对于第二根轴,最大值为2、3和5。这些值是通过取第一根轴的每个数组内的最大值来确定的。我们有三组,每组四个,这给了我们3个最大值。

此处的argmax值告诉每个数组内最大值所在的索引。

实际上,我们经常在网络的输出预测张量上使用argmax()函数,以确定哪个类别的预测值最高。

Accessing Elements Inside Tensors

张量需要的最后一种常见操作是从张量内部访问数据的能力。 让我们来看看PyTorch的这些。

假设我们有以下张量:

> t = torch.tensor([
    [1,2,3],
    [4,5,6],
    [7,8,9]
], dtype=torch.float32)

> t.mean()
tensor(5.)

> t.mean().item()
5.0

在此检查这些操作。 当我们在这个3 x 3张量上调用均值时,减少的输出是标量值张量。 如果我们想实际获得一个数字值,可以使用item()张量方法。 这适用于标量值张量。

看看我们如何使用多个值:

> t.mean(dim=0).tolist()
[4.0, 5.0, 6.0]

> t.mean(dim=0).numpy()
array([4., 5., 6.], dtype=float32)

当我们计算第一个轴上的平均值时,将返回多个值,并且可以通过将输出张量转换为Python列表或NumPy数组来访问数值。

Advanced Indexing And Slicing

使用NumPy ndarray对象,我们有一组非常健壮的索引和切片操作,而PyTorch张量对象也支持其中的大多数操作。

使用此资源进行高级索引编制和切片。

Deep Learning Project

恭喜您在本系列中取得了如此出色的成绩。 所有这些张量主题都是很原始的且很底层的,但是对它们的深入了解使我们作为神经网络程序员的发展变得更加轻松。

现在,我们准备开始本系列的第二部分,我们将使用所有这些知识。 我们将探索我们将要训练的数据集,即Fashion-MNIST数据集。
在这里插入图片描述
该数据集包含来自十种不同服装类别的六万个示例训练集。 我们将使用PyTorch构建卷积神经网络,该神经网络可以准确预测给定输入件的正确服装,因此请继续关注!

下一个再见!

猜你喜欢

转载自blog.csdn.net/weixin_48367136/article/details/112490303