einsum is all you needed

torch.einsum用法详解 是PyTorch中的一个函数,用于执行爱因斯坦求和约定(Einstein summation)运算。它提供了一种灵活而强大的方式来执行多维张量的操作和变换。其中,equation是一个字符串,用于指定爱因斯坦求和约定的运算方式,operands是一个或多个输入张量。在equation中,你可以使用大写字母表示张量的维度标识符,使用小写字母表示对应维度的长度。通过指定输入张量和输出张量之间的维度关系,你可以定义所需的运算操作。下面是一个简单的例子,展示了如何使用# 两个向量的点积。 阅读详情

如果问pytorch中最强大的一个数学函数是什么?

我会说是torch.einsum:爱因斯坦求和函数。

它几乎是一个"万能函数":能实现超过一万种功能的函数。

不仅如此,和其它pytorch中的函数一样,torch.einsum是支持求导和反向传播的,并且计算效率非常高。

einsum 提供了一套既简洁又优雅的规则,可实现包括但不限于:内积,外积,矩阵乘法,转置和张量收缩(tensor contraction)等张量操作,熟练掌握 einsum 可以很方便的实现复杂的张量操作,而且不容易出错。

尤其是在一些包括batch维度的高阶张量的相关计算中,若使用普通的矩阵乘法、求和、转置等算子来实现很容易出现维度匹配等问题,但换成einsum则会特别简单。

套用一句深度学习paper标题当中非常时髦的话术,torch.einsum is all you needed 😋!

公众号后台回复关键词:einsum,获取本文源代码链接。

一,einsum规则原理

顾名思义,einsum这个函数的思想起源于家喻户晓的小爱同学:爱因斯坦~。

很久很久以前,小爱同学在捣鼓广义相对论。广义相对论表述各种物理量用的都是张量。

比如描述时空有一个四维时空度规张量,描述电磁场有一个电磁张量,描述运动的有能量动量张量。

d4e8e9094e267977ac8aac438fa13165.jpeg

在理论物理学家中,小爱同学的数学基础不算特别好,在捣鼓这些张量的时候,他遇到了一个比较头疼的问题:公式太长太复杂了。

有没有什么办法让这些张量运算公式稍微显得对人类友好一些呢,能不能减少一些那种扭曲的求和符号呢?

小爱发现,求和导致维度收缩,因此求和符号操作的指标总是只出现在公式的一边。

例如在我们熟悉的矩阵乘法中

k这个下标被求和了,求和导致了这个维度的消失,所以它只出现在右边而不出现在左边。

这种只出现在张量公式的一边的下标被称之为哑指标,反之为自由指标。

小爱同学脑瓜子滴溜一转,反正这种只出现在一边的哑指标一定是被求和求掉的,干脆把对应的求和符号省略得了。

这就是爱因斯坦求和约定:

只出现在公式一边的指标叫做哑指标,针对哑指标的求和符号可以省略。

公式立刻清爽了很多。

这个公式表达的含义如下:

C这个张量的第i行第j列由这个张量的第i行第k列和这个张量的第k行第j列相乘,这样得到的是一个三维张量, 其元素为,然后对在维度k上求和得到。

公式展现形式中除了省去了求和符号,还省去了乘法符号(代数通识)。

借鉴爱因斯坦求和约定表达张量运算的清爽整洁,numpy、tensorflow和 torch等库中都引入了 einsum这个函数。

上述矩阵乘法可以被einsum这个函数表述成

C = torch.einsum("ik,kj->ij",A,B)

这个函数的规则原理非常简洁,3句话说明白。

  • 1,用元素计算公式来表达张量运算。

  • 2,只出现在元素计算公式箭头左边的指标叫做哑指标。

  • 3,省略元素计算公式中对哑指标的求和符号。

import torch 

A = torch.tensor([[1,2],[3,4.0]])
B = torch.tensor([[5,6],[7,8.0]])

C1 = A@B
print(C1)

C2 = torch.einsum("ik,kj->ij",[A,B])
print(C2)
tensor([[19., 22.],
        [43., 50.]])
tensor([[19., 22.],
        [43., 50.]])

二,einsum基础范例

einsum这个函数的精髓实际上是第一条:

用元素计算公式来表达张量运算。

而绝大部分张量运算都可以用元素计算公式很方便地来表达,这也是它为什么会那么神通广大。

例1,张量转置

#例1,张量转置
A = torch.randn(3,4,5)

#B = torch.permute(A,[0,2,1])
B = torch.einsum("ijk->ikj",A) 

print("before:",A.shape)
print("after:",B.shape)
before: torch.Size([3, 4, 5])
after: torch.Size([3, 5, 4])

例2,取对角元

#例2,取对角元
A = torch.randn(5,5)
#B = torch.diagonal(A)
B = torch.einsum("ii->i",A)
print("before:",A.shape)
print("after:",B.shape)
before: torch.Size([5, 5])
after: torch.Size([5])

例3,求和降维

#例3,求和降维
A = torch.randn(4,5)
#B = torch.sum(A,1)
B = torch.einsum("ij->i",A)
print("before:",A.shape)
print("after:",B.shape)
before: torch.Size([4, 5])
after: torch.Size([4])

例4,哈达玛积

#例4,哈达玛积
A = torch.randn(5,5)
B = torch.randn(5,5)
#C=A*B
C = torch.einsum("ij,ij->ij",A,B)
print("before:",A.shape, B.shape)
print("after:",C.shape)
before: torch.Size([5, 5]) torch.Size([5, 5])
after: torch.Size([5, 5])

例5,向量内积

#例5,向量内积
A = torch.randn(10)
B = torch.randn(10)
#C=torch.dot(A,B)
C = torch.einsum("i,i->",A,B)
print("before:",A.shape, B.shape)
print("after:",C.shape)
before: torch.Size([10]) torch.Size([10])
after: torch.Size([])

例6,向量外积

#例6,向量外积
A = torch.randn(10)
B = torch.randn(5)
#C = torch.outer(A,B)
C = torch.einsum("i,j->ij",A,B)
print("before:",A.shape, B.shape)
print("after:",C.shape)
before: torch.Size([10]) torch.Size([5])
after: torch.Size([10, 5])

例7,矩阵乘法

#例7,矩阵乘法
A = torch.randn(5,4)
B = torch.randn(4,6)
#C = torch.matmul(A,B)
C = torch.einsum("ik,kj->ij",A,B)
print("before:",A.shape, B.shape)
print("after:",C.shape)
before: torch.Size([5, 4]) torch.Size([4, 6])
after: torch.Size([5, 6])

例8,张量缩并

#例8,张量缩并
A = torch.randn(3,4,5)
B = torch.randn(4,3,6)
#C = torch.tensordot(A,B,dims=[(0,1),(1,0)])
C = torch.einsum("ijk,jih->kh",A,B)
print("before:",A.shape, B.shape)
print("after:",C.shape)
before: torch.Size([3, 4, 5]) torch.Size([4, 3, 6])
after: torch.Size([5, 6])

三,einsum高级范例

einsum可用于超过两个张量的计算。

例9,bilinear注意力机制

例如:双线性变换。这是向量内积的一种扩展,一种常用的注意力机制实现方式)

不考虑batch维度时,双线性变换的公式如下:

考虑batch维度时,无法用矩阵乘法表示,可以用元素计算公式表达如下:

#例9,bilinear注意力机制

#====不考虑batch维度====
q = torch.randn(10) #query_features
k = torch.randn(10) #key_features
W = torch.randn(5,10,10) #out_features,query_features,key_features
b = torch.randn(5) #out_features

#a = q@W@k.t()+b  
a = torch.bilinear(q,k,W,b)
print("a.shape:",a.shape)


#=====考虑batch维度====
Q = torch.randn(8,10)    #batch_size,query_features
K = torch.randn(8,10)    #batch_size,key_features
W = torch.randn(5,10,10) #out_features,query_features,key_features
b = torch.randn(5)       #out_features

#A = torch.bilinear(Q,K,W,b)
A = torch.einsum('bq,oqk,bk->bo',Q,W,K) + b
print("A.shape:",A.shape)
a.shape: torch.Size([5])
A.shape: torch.Size([8, 5])

例10,scaled-dot-product注意力机制

我们也可以用einsum来实现更常见的scaled-dot-product 形式的 Attention.

不考虑batch维度时,scaled-dot-product形式的Attention用矩阵乘法公式表示如下:

考虑batch维度时,无法用矩阵乘法表示,可以用元素计算公式表达如下:

#例10,scaled-dot-product注意力机制

#====不考虑batch维度====
q = torch.randn(10)  #query_features
k = torch.randn(6,10) #key_size, key_features

d_k = k.shape[-1]
a = torch.softmax(q@k.t()/d_k,-1) 

print("a.shape=",a.shape )

#====考虑batch维度====
Q = torch.randn(8,10)  #batch_size,query_features
K = torch.randn(8,6,10) #batch_size,key_size,key_features

d_k = K.shape[-1]
A = torch.softmax(torch.einsum("in,ijn->ij",Q,K)/d_k,-1) 

print("A.shape=",A.shape )
a.shape= torch.Size([6])
A.shape= torch.Size([8, 6])

以上。

万水千山总是情,点个在看行不行?😋

公众号后台回复关键词:einsum,获取本文源代码链接。

731e439ae994ff5a6b133393ae50d6ab.png

einops和einsum:直接操作张量的利器 einops 和 einsum einops和einsum是Vision Transformer的代码实现里出现的两个操作tensor维度和指定tensor计算的神器,在卷积神经网络里不多见,本文将介绍简单介绍一下这两样工具,方便大家更好地理解Vision Transformer的代码。 einops:直接操作tensor维度的神器 github地址:https://github.com/arogozhnikov/einops einops:灵活和强大的张量操作,可读性强和可靠性好的代码。支持numpy、p 阅读详情

相关推荐

PyTorch中用einsum实现自注意力:告别维度地狱的张量运算实践

爱因斯坦求和约定(einsum)是深度学习中张量运算的声明式表达范式,其核心在于通过维度标签明确定义输入输出形状与求和轴,而非依赖易错的transpose/view/matmul组合。相比命令式操作,einsum将数学直觉直接映射为可验证的代码方程,显著提升multi-head attention等高维运算的可读性、可维护性与跨框架兼容性。在NLP与CV模型开发中,它被广泛用于QKV投影、scores计算与加权聚合等关键环节,尤其适合处理batch、head、token、dim等多语义维度的结构化张量。本文

xpmwgcwm的博客 429

einsum(爱因斯坦求和)

爱因斯坦求和约定是一种强大的工具,它允许你以一种非常紧凑和灵活的方式指定多维数组之间的操作。虽然Python本身不直接支持这种语法,但NumPy和PyTorch等库提供了对它的支持,使得你可以利用这种约定来编写更简洁、更高效的代码。

AI浩 1015

矩阵操作万能函数 einsum 详细解析(通法教你如何看懂并写出einsum表达式)

可能你在某个地方听说了einsum,然后不会写,或者看不懂。这篇文章将会一步一步教会你如何使用(通法哦,只要学会方法就全会了)。ein 就是爱因斯坦的ein,sum就是求和。einsum就是爱因斯坦求和约定,其实作用就是把求和符号省略,就这么简单。举个例子:我们现在有一个矩阵A2×2=(1234) A_{2\times 2} = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} A2×2​=(13​24​)我们想对A的“行”进行求和得到矩阵B(向量B),用

iioSnail的博客 1万+

TensorRT - 喜大普奔,TensorRT8.2 EA起开始支持Einsum爱因斯坦求和算子

1 TensorRT 8.2 EA版本支持爱因斯坦求和算子Einsum NVIDIA在2021年10月6日发布的TensorRT新版本 8.2 Early Access版本终于开始支持爱因斯坦求和算子Einsum,这个消息真是为模型工业化部署的同学省了不少的时间。 TensorRT中具体可支持的Onnx算子可参考:https://github.com/onnx/onnx-tensorrt/blob/master/docs/operators.md, 但是目前Einsum也是支持大部分等式,暂不支持省略号和

HW140701的博客 2127

从IMC层到应力点:手把手教你用SEM/EDS给BGA焊点做一次‘体检’

本文详细介绍了如何使用SEM/EDS技术对BGA焊点进行全面失效分析,从样品制备到SEM观察、EDS分析,再到综合诊断,手把手教你识别焊点的微观特征和成分异常。文章特别强调了IMC层分析在BGA焊接失效诊断中的关键作用,并提供了实用的实验室技巧和常见失效模式对照表,帮助工程师快速定位问题根源。

weixin_42685438的博客 385

Einsum Is All You Need

基础 一直弄不清楚这个einsum,今天花了些时间学习,以下是学习记录。 首先是找到了这个视频 https://www.youtube.com/watch?v=CLrTj7D2fLM&ab_channel=FacultyofKhan Why use Einsum Extremely Convenient and Compact 有4个规则 Any twice-repeated index in a single term is summed over ij,j->i i is t

大黄老鼠的小本本 479

脑机接口(BCI)从原理到开发实战 07|运动想象BCI实战:基于BCI Competition IV 2a数据集

本文基于BCI Competition IV 2a数据集,详细介绍运动想象脑机接口系统的全流程实现。首先概述了该数据集的实验范式、参数特点和优势,然后指导环境准备与数据下载。通过代码示例展示了数据加载、事件标记提取和信号可视化方法。重点构建了完整的预处理流水线,包括通道选择、重参考、带通滤波(8-30Hz)和ICA去伪迹等关键步骤。文章旨在帮助读者将零散的BCI知识整合为完整的实战项目,掌握从原始脑电数据到运动意图解码的核心技术。

小明的博客 852

einsum算子不支持问题处理

当torch.einsum算子在onnx转om找不到时,如何进行代码替换。torch.einsum里面为计算方式为bhwc乘以hkc得到bhwk。

funnyPython的博客 658

从内外参推导IPM变换方程及代码实现(生成AVM环视拼接图)

最近想实现AVM拼接,看了不少博客和论文,不过比较愚钝,一直没能很好理解原理,尤其是怎么在实现时把下文中Z1和Z2消除的,所以严谨的推导了一下对应的公式,如有不对,水平有限,烦请指出~IPM变换(逆透视变换),顾名思义,即将正常透视效应消除的变换,变换结果为鸟瞰图BEV(俯视图);AVM环视拼接一般是将车身前后左右的四个鱼眼相机拼接成环视图(也是俯视),其使用的单应矩阵将四个相机转到同一个俯视坐标系。

mxdsdo09的博客 4175

树莓派4B玩转ROS2 Humble:Ubuntu Desktop一键安装与配置教程

本文详细介绍了在树莓派4B上安装和配置ROS2 Humble的完整教程,包括硬件准备、Ubuntu Desktop系统安装、一键部署ROS2、网络配置优化以及常见问题解决方案。通过简化安装流程和性能调优技巧,帮助开发者快速搭建机器人开发环境,充分发挥树莓派4B在ROS2应用中的潜力。

w8x9y0z1的博客 969

einsum is all you need

最近发现一个超赞的函数:einsum!

m0_74982304的博客 163

雷赛控制卡全方位使用指南:从硬件连接到高级应用

雷赛控制卡以其接口简单、编程便捷、性价比高的特点,成为中小自动化设备的理想选择。使用时需注意:硬件连接需注重抗干扰设计(屏蔽线、接地);软件开发需合理配置运动参数(脉冲当量、加减速);调试阶段需充分利用 DMCStudio 工具验证性能。通过本文介绍的方法,可快速实现从硬件搭建到复杂运动控制的全流程开发,满足雕刻、切割、装配等多场景的自动化需求。

品质生活,极致编程。 3779

EINSUM IS ALL YOU NEED

Tim Rocktäschelhttps://medium.com/ibm-data-ai/einsum-an-easy-intuitive-way-to-write-tensor-operation-9e12b8a80570Understanding einsum for Deep learning: implement a transformer with multi-head self-attention from scratch | AI Summer

bbbeoy的专栏 196

5分钟搞定PettingZoo多智能体环境搭建:从安装到运行第一个Demo

本文详细介绍了如何在5分钟内完成PettingZoo多智能体环境的搭建,从安装到运行第一个Demo。通过精准的版本控制和常见问题解决方案,帮助开发者快速上手多智能体强化学习(MARL)环境配置,并提供了实战案例和性能优化技巧。

backprop5master的博客 223

AI处理器组合

编号0-3的处理器处于同一个链路中,编号4-7的处理器处于另外一个链路中,不通链路中的处理器不能通信,如下图所示。- 如果申请处理器个数为1,则选择同一链路,剩余可用的处理器数量为1个的最佳,其次是剩余3个的为次佳,然后是剩余2个,最后是剩余4个。输出为组合列表,当array=[0, 1, 4, 5, 6, 7] ,num=1时,输出为[[0], [1]]- 如果申请处理器个数为2,则选择同一链路剩余可用的处理器数量2个的为最佳,其次是剩余4个,最后是剩余3个。任务申请1个处理器。

面试高手的博客 1万+

opt_einsum 项目教程

`opt_einsum` 是一个用于优化 `einsum` 函数执行时间的 Python 库。`einsum` 是许多科学计算库(如 NumPy、TensorFlow、PyTorch 等)中用于张量收缩的函数。`opt_einsum` 通过优化张量收缩的顺序,显著减少了计算时间,特别是在处理大规模张量时。 `opt_einsum` 支持多种后端,包括 NumPy、Dask、PyTorch、Ten...

gitblog_00738的博客 1356

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

详解 einsum(Einstein Summation):高效实现张量运算的利器

用简洁的爱因斯坦求和约定(Einstein Summation Convention)高效地执行张量运算,而不需要显式地调用 matmul、dot 或 transpose 等函数。

阿正的梦工坊 2906

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

[代码学习]einsum详解

该函数用于对一组输入 Tensor 进行 Einstein 求和,该函数目前仅适用于paddle的动态图。Einstein 求和是一种采用 Einstein 标记法描述的 Tensor 求和,输入单个或多个 Tensor,输出单个 Tensor。参数返回。

orDream的博客 834

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Numpy库中einsum函数用法

【导读】 einsum全称Einstein summation convention(爱因斯坦求和约定),又称为爱因斯坦标记法。能够计算任何维度的张量收缩。einsum的写法省去了求和符号,显得更加简洁。

qq_40806950的博客 2151

Einsum: numpy,pytorch and Tensorflow

EINSUM IS ALL YOU NEED 如果你和我一样,你会发现很难记住 PyTorch/TensorFlow 中用于计算点积、外积、转置和矩阵向量或矩阵矩阵乘法的所有不同函数的名称和签名。 Einsum 表示法是表达所有这些以及对张量的复杂操作的一种优雅方式,本质上是使用特定于领域的语言。 除了不必记住或定期查找特定库函数之外,这还有其他好处。 一旦你理解并使用了 einsum,你将能够更快地编写更简洁高效的代码。 当不使用 einsum 时,很容易引入不必要的张量整形和转置,以及可以省略的中间张量

weixin_42890793的博客 496

einsum的基础使用

einsum全称为Einstein summation convention,是一种求和的范式,在很多基于多维张量的张量运算库,如numpy,tensorflow,pytorch中都有所应用。einsum可以用一种很简单的,统一的方式去表示很多多维张量的运算。让我们以numpy中的einsum为例子,理解这种运算表达方式。 这里贴出numpy中的einsum的API: numpy.eins...

机器学习杂货铺1号店 1万+

Einsum in PyTorch✍️

写在前面     Einsum是一种domain-specific language 域指定语言,可以高性能的实现诸如:dot products, outer product, 矩阵转置 transposes,矩阵向量乘法以及矩阵矩阵之间的乘法。其在numpy、tensorflow、pytorch等框架中可以大大提高编程效率以及矩阵运算的速度,代码也更加简洁。 EINSUM IN DEEP LEARNING once for all   &nb

CREATOR_XiaoLi 676

numpy.einsum() 使用方法

einsum函数是 Numpy 库非常出色的计算函数之一。einsum函数非常灵活,也非常高效,运行时占用的存储空间很小。不过einsum函数这么多优异的特点不是没有代价的——要想灵活的使用它,就需要花一些时间了解它。 网络上已经有不少内容介绍einsum函数的基本原理和实现,所以本文不对这些内容再做赘述,相反,这里只是做一些相对易懂的基本介绍,重点在于介绍如何使用它。.........

人无远虑,必有近忧 8166

einsum的原理与使用

爱因斯坦求和法是numy和pytorch中的有效矩阵运算工具,本文介绍其原理和使用方法

weixin_45101959的博客 1373

掌握numpy.einsum与torch.einsum:提升科学计算与深度学习中的运算效率和代码可读性

本文介绍了numpy.einsum和torch.einsum在科学计算和深度学习中的应用,包括Einstein求和记号的概念及其简化复杂运算的作用。详细阐述了两者的使用方法,如numpy.einsum的基础操作和torch.einsum在复杂运算如注意力机制以及自动微分中的优势。通过对比einsum与手动实现的嵌套循环运算,深入理解其机制。该博客旨在帮助读者熟练掌握这两种工具,提升计算效率和代码可读性,以应对各类科学计算和深度学习任务。

m0_51661400的博客 3127
上一篇: 120分钟吃掉DIEN深度兴趣演化网络
下一篇: 20分钟吃掉推荐算法业务知识
算法美食屋
博客等级 码龄9年 2万+粉丝 154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值