了解用于深度学习的 einsum:从头开始实现具有多头自注意力机制的 Transformer

通过编写自定义多头自注意力单元和转换器块来了解 einsum 符号和 einops

来源:AI夏令营

如果您现在是一名机器学习研究人员/工程师,那么您绝对应该了解 einsum 操作!

就我个人而言,我曾经因为 einsum 操作而放弃理解 git repos。原因是:尽管我对张量操作感到很满意,但 einsum 不在我的武器库中。

不是

长话短说,我决定要熟悉 einsum 符号。由于我对计算机视觉中的 transformer 和自注意力特别感兴趣,所以我有一个巨大的游乐场。

在本文中,我将广泛尝试熟悉 einsum(在 Pytorch 中),同时,我将实现著名的自注意力层,最后是原始的 Transformer。

代码非常具有教育意义!我还没有训练任何大型自注意力模型,但我计划这样做。说实话,我在这个过程中学到的东西比我最初预期的要多得多。

如果你想先深入研究理论,请随时查看我关于注意力和变压器的文章。

注意力 变压器

如果没有,让游戏开始吧!

本教程的代码可在 GitHub 上找到。用星号表示支持!

本教程的代码可在 GitHub 上找到。用星号表示支持!

GitHub

为什么是 einsum?

首先,einsum 符号是关于优雅和干净的代码。许多人工智能行业专家和研究人员一致使用它:

einsum 符号是关于优雅和干净的代码

为了让你更加信服,让我们看一个例子:

你想合并 4D 张量的 2 个维度,第一个和最后一个。

x = x.permute(0, 3, 1, 2)N, W, C, H = x.shapex = x.contiguous().view(N * W, C, -1)

x = x.permute(0, 3, 1, 2)

x = x 排列 ( 0 , 3 , 1 , 2 )

N, W, C, H = x.shape

N , W , C , H = x 形状

x = x.contiguous().view(N * W, C, -1)

x = x . contiguous ( ) . view ( N * W , C , - 1 )

这不是编码的最佳方式,但它符合我的观点!

就我个人而言,这段代码让我感到很害怕!

使用 einsum 来提高代码的可读性是一种很好的做法。在前面的例子中,代码如下:

x = einops.rearrange(x, 'b c h w -> (b w) c h')
x = einops . rearrange