如何在PyTorch中合并二维卷积?

如何在PyTorch中合并二维卷积?,pytorch,linear-algebra,convolution,Pytorch,Linear Algebra,Convolution,从线性代数我们知道线性算子是结合的 在深度学习世界中,这个概念被用来证明在NN层之间引入非线性是合理的,这种现象通俗地称为,() 在信号处理中,这是一个众所周知的优化内存和/或运行时需求的技巧() 因此,从不同的角度来看,合并卷积是一个非常有用的工具。如何用PyTorch实现它?如果我们有y=x*a*b(其中*表示卷积,a,b是您的内核),我们可以定义c=a*b,这样y=x*c=x*a*b如下: 导入火炬 def合并转换内核(k1,k2): """ :输入k1:形状为``的张量(out1、in1

从线性代数我们知道线性算子是结合的

在深度学习世界中,这个概念被用来证明在NN层之间引入非线性是合理的,这种现象通俗地称为,()

在信号处理中,这是一个众所周知的优化内存和/或运行时需求的技巧()


因此,从不同的角度来看,合并卷积是一个非常有用的工具。如何用PyTorch实现它?

如果我们有
y=x*a*b
(其中
*
表示卷积,
a,b
是您的内核),我们可以定义
c=a*b
,这样
y=x*c=x*a*b
如下:

导入火炬
def合并转换内核(k1,k2):
"""
:输入k1:形状为``的张量(out1、in1、s1、s1)``
:输入k1:形状为``的张量(out2、in2、s2、s2)``
:返回:形状为``的张量(out2,in1,s1+s2-1,s1+s2-1)``
所以和它的卷积等于和k1的卷积
然后是k2。
"""
填充=k2.形状[-1]-1
#翻转,因为这实际上是相关性,并排列以适应BHCW
k3=火炬。conv2d(k1。排列(1,0,2,3),k2。翻转(-1,-2),
填充=填充)。排列(1,0,2,3)
返回k3
为了说明等效性,本例将两个分别具有900和5000个参数的内核组合成一个具有28个参数的等效内核:

#创建2个转换内核
out1,in1,s1=(100,1,3)
out2,in2,s2=(2100,5)
kernel1=torch.rand(out1、in1、s1、s1、dtype=torch.float64)
kernel2=torch.rand(out2,in2,s2,s2,dtype=torch.float64)
#通过它们传播一个随机张量。注意,填充
#对应于“完整”数学运算(s-1)
b、 c,h,w=1,1,6,6
x=火炬.rand(b,c,h,w,D类型=火炬.float64)*10
c1=torch.conv2d(x,kernel1,padding=s1-1)
c2=torch.conv2d(c1,内核2,填充=s2-1)
#检查折叠的conv2d是否与c2相同:
kernel3=合并转换内核(kernel1,kernel2)
c3=torch.conv2d(x,kernel3,padding=kernel3.shape[-1]-1)
打印(内核3.形状)
打印((c2-c3).abs().sum()<1e-5)

注意:等价性是假设我们有无限的数值分辨率。我认为有人研究了叠加许多低分辨率浮点线性运算,并表明网络从数值误差中获益,但我无法找到它。任何参考都将不胜感激

“从线性代数中我们知道线性算子是可交换的和结合的。”这不是真的,你只能假设结合性,除了特殊情况(同时对角化)之外,交换性是罕见的。哎呀!你是对的,我指的是线性系统,不是算子。我会更正和澄清。“线性”的概念不同,令人困惑,因此我也将澄清这一点。谢谢你的评论!事实上,我刚把它取下来。作为记录,这是我的参考:。在那里,交换性被列为“系统线性”的一个属性。但在这个问题上,这种术语只是混淆/误导,不需要。再次感谢你!