复数卷积
本文是结合网上的资料和自己的理解所写,若有不对的地方,欢迎批评指正。
本文资料均来源于网络,若有侵权,请联系删除。
一、简介
如果你去网上搜”复数卷积“很难看到专门讲解复数卷积这一概念的,大概率会搜到复数神经网络。
复数神经网络是出自《Deep Complex Networks》这篇论文,论文地址在下面给出。复数卷积只是复数神经网络中的一部分,但是很少有文章单独讲。
通常的网络都是实数,但是复数神经网络在某些领域具有一些优势,比如复数包含着一些相位信息等,相位信息对于一些领域可能很重要。
如果你想将你的网络改复数网络,其实是有点困难的,因为很多地方需要更改,比如loss、dropout、relu等等,都要改为复数,这个时候你也不知道改复数网络,效果会不会有提升,你可以先尝试改复数卷积,看看有没有效果,在尝试更改复数网络。
论文地址:https://arxiv.org/abs/1705.09792
二、原理
如果想要搞清楚什么是复数卷积,那么先理解一下卷积的概念。
其实卷积很容易理解,我用一个例子来解释什么是卷积。
如果我们有一张5*5的图片,图片中的数字代表该位置的像素值,像素值越大颜色越亮。
用一个3*3的滤波器进行卷积,更通俗的意义上说,该卷积的卷积核为3。
![](/qrcode.jpg)
有了图片和滤波器,那么该怎么卷积呢,请看下面的图片。
如果不了解卷积的计算过程,就可能不太清楚,这些数怎么来的,不用担心,计算过程如下:
看到这,是不是就对卷积的整个流程很熟悉了呢。
下面介绍复数卷积。
复数的表现形式为: V r + j V i V_r+jV_i Vr+jVi,而实数和复数的不同之处在于,多了一个虚部。
实数卷积有输入和卷积核且均为实数,那复数卷积肯定也有输入和卷积核且也均为复数。
复数卷积的输入和卷积核可以写为:
- 输入: V = V r + j V i V=V_r+jV_i V=Vr+jVi
- 卷积核: K = K r + j K i K=K_r+jK_i K=Kr+jKi
它们的计算公式如下:
K ∗ V = ( K r + j K i ) ∗ ( V r + j V i ) = ( K r ∗ V r − K i ∗ V i ) + j ( K r ∗ V i + K i ∗ V r ) K*V=(K_{\mathfrak{r}}+jK_{\mathfrak{i}})*(V_{\mathfrak{r}}+jV_{\mathfrak{i}})=(K_{\mathfrak{r}}*V_{\mathfrak{r}}-K_{\mathfrak{i}}*V_{\mathfrak{i}})+j(K_{\mathfrak{r}}*V_{\mathfrak{i}}+K_{\mathfrak{i}}*V_{\mathfrak{r}}) K∗V=(Kr+jKi)∗(Vr+jVi)=(Kr∗Vr−Ki∗Vi)+j(Kr∗Vi+Ki∗Vr)
注:j*j=-1
如果用一个图来表示,那么可以这样表示
如果使用一个矩阵来表示,那么可以写成这样。
( K r + j K i ) ∗ ( V r + j V i ) = [ K r − K i K i K r ] ∗ [ V r V i ] (K_{\mathfrak{r}}+jK_{\mathfrak{i}})*(V_{\mathfrak{r}}+jV_{\mathfrak{i}})=\begin{bmatrix}\mathbf{K_r}&-\mathbf{K_i}\\\mathbf{K_i}&\mathbf{K_r}\end{bmatrix}*\begin{bmatrix}\mathbf{V_r}\\\mathbf{V_i}\end{bmatrix} (Kr+jKi)∗(Vr+jVi)=[KrKi−KiKr]∗[VrVi]
到这里,复数卷积已经讲完了,你看懂了吗?
如果想要本文的文件,请在公众号“冬天的李同学”回复“2023.9.3”获取。
希望本文对你有帮助。
三、代码实现
def apply_complex(fr, fi, input, dtype = torch.complex64):
return (fr(input.real)-fi(input.imag)).type(dtype) \
+ 1j*(fr(input.imag)+fi(input.real)).type(dtype)
class ComplexConv2d(Module):
def __init__(self,in_channels, out_channels, kernel_size=3, stride=1, padding = 0,
dilation=1, groups=1, bias=True):
super(ComplexConv2d, self).__init__()
self.conv_r = Conv2d(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias)
self.conv_i = Conv2d(in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias)
def forward(self,input):
return apply_complex(self.conv_r, self.conv_i, input)
四、参考资料
1.https://mp.weixin.qq.com/s/y0CN-Q-gjuB-op99SvUCJA
2.https://www.bilibili.com/video/BV1my4y1J715?t=628.5
3.https://blog.csdn.net/qq_38290475/article/details/104630767?
ili.com/video/BV1my4y1J715?t=628.5
3.https://blog.csdn.net/qq_38290475/article/details/104630767?
4.https://mp.weixin.qq.com/s/TsmIZuhLPIgLD7mXl2Ms_A