离散余弦变换(DCT)在深度学习的应用//fcanet与本人工作

更新 2022.11.02

按公式写的1D-dct不能复现与scipy中1d-dct一样的结果,而且scipy中的1d-idct不能对dct的结果可逆,通过调试torch-dct能够得到多维数据情况下的dct_result

[8,7,96]x[96,96] = [8,7,96]#1d-dct模块中的fc层矩阵运算

[8,7]x[7,7] = [8,7] #DINET模块中的fc层矩阵运算

更新 2022.11.08//DCT与IDCT数学理论推导

一维离散余弦变换(DCT)及其反变换(IDCT)公式的一种推导_蟹黄堡每天一份,蟹蟹的博客-CSDN博客_一维离散余弦变换

代码

import torch
import torch.nn as nn
import math

class ts_channel_block(nn.Module):
    def __init__(self, channel, ratio=1):
        super(ts_channel_block, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool1d(1) #innovation
        self.fc = nn.Sequential(
                nn.Linear(channel, channel // ratio, bias=False),
                nn.ReLU(inplace=True),
                nn.Linear(channel // ratio, channel, bias=False),
                nn.Sigmoid()
        )

    def forward(self, x):
        b, c, l = x.size() # (B,C,L)
        # y = self.avg_pool(x) # (B,C,L) 通过avg=》 (B,C,1)
        # print("y",y.shape)
        y = self.avg_pool(x).view(b, c) # (B,C,L) 通过avg=》 (B,C,1)
        print("y",y.shape)
        #为了丢给Linear学习,需要view把数据展平开
        # y = self.fc(y).view(b, c, 96)

        y = self.fc(y).view(b,c,1)
        print("y",y.shape)
        return x * y
class dct_channel_block(nn.Module):
    def __init__(self, channel=96,ratio=1):
        super(dct_channel_block, self).__init__()
        # self.avg_pool = nn.AdaptiveAvgPool1d(1) #innovation
        self.fc = nn.Sequential(
                nn.Linear(channel, 1, bias=False),
                nn.ReLU(inplace=True),
                nn.Linear(1, channel, bias=False),
                nn.Sigmoid()
        )

    def forward(self, x):
        b, c, l = x.size() # (B,C,L)
        # y = self.avg_pool(x) # (B,C,L) 通过avg=》 (B,C,1)
        
        # y = self.avg_pool(x).view(b, c) # (B,C,L) 通过avg=》 (B,C,1)
        # print("y",y.shape)
        #为了丢给Linear学习,需要view把数据展平开
        # y = self.fc(y).view(b, c, 96)
        list = []
        for i in range(c):#i represent channel ,分别对channel的数据做dct
            freq=dct.dct(x[:,i,:])     
            print("freq-shape:",freq.shape)
            list.append(freq)
            ##把dct结果进行拼接,再进行频率特征学习
        
        stack_dct=torch.stack((list[0],list[1],list[2],list[3],list[4],list[5],list[6]),dim=1)
        stack_dct = torch.tensor(stack_dct)
        lr_weight = self.fc(stack_dct)
        print("lr_weight",lr_weight.shape)
        return x *lr_weight #result

tensor = torch.rand(8,7,96)
dct_model = dct_channel_block()
result = dct_model.forward(tensor) 
print("result.shape:",result.shape)



freq-shape: torch.Size([8, 96]) freq-shape: torch.Size([8, 96]) freq-shape: torch.Size([8, 96]) freq-shape: torch.Size([8, 96]) freq-shape: torch.Size([8, 96]) freq-shape: torch.Size([8, 96]) freq-shape: torch.Size([8, 96]) lr_weight torch.Size([8, 7, 96]) result.shape: torch.Size([8, 7, 96]) 



原理详细请参考这些链接了,DCT与DFT的关系,详解离散余弦变换(DCT) - 知乎 (zhihu.com)

DCT是FFT的实数部分,肯定会有信息损失,但同时也降低了计算量。

(23 封私信 / 42 条消息) 为什么 DCT 比 FFT 变换具有更好的能量聚集度? - 知乎 (zhihu.com)

(224条消息) FcaNet解读_周先森爱吃素的博客-CSDN博客_fcanet //讲得不错


我主要讲讲DCT在深度学习的应用。

读者可能疑惑,推导了那么多,那么DCT变换到底哪好用了呢,首先,DCT变换较DFT变换具有更好的频域能量聚集度(说人话就是能够把图像更重要的信息聚集在一块),那么对于那些不重要的频域区域和系数就能够直接裁剪掉(有点像淘金,你把石头里重要的金子都弄到一块,剩下没啥用的石子不就可以扔了么),因此,DCT变换非常适合于图像压缩算法的处理,例如现在大名鼎鼎的jpeg就是使用了DCT作为图像压缩算法

当然,DCT同时也在音频信号处理,数字水印方面也发挥着各种作用,至于二维DCT变换和DCT矩阵的编码方式在了解DCT的原理后应该要做出来也就只是一些拓展问题了,在这就不再继续讨论了。

最后作为一只信号狗,也希望广大的科研同行也能够将自己的专长知识写成通俗易懂不装逼不忽悠的文章分享给广大生活在水深火热之中的其他同行中。

毕竟作为信号处理最底层的一群狗,整天看着一堆不知所云的资料真是本是同根生相煎何太急你说是不?


在下面是关于DCT的一维公式与二维公式,还有证明Fcanet论文里面的2d-GAP是2d-DCT的一个special case,然后再这个思想的基础上,证明1d-GAP是1d-DCT的一个special case.//属于自己的工作

(227条消息) DCT变换自学笔记_Allen---J的博客-CSDN博客_dct变换公式

论文里面省去了一些常数归一化因子,这是原来公式

这是论文里面的公式,可见少了一个2/N,不过这并不影响。

 这里为证明2d-GAP是2d-DCT的一个special case。

基于上面的思想,开始证明1d-GAP是1d-DCT的一个special case,

接下来的任务顺序

现在有个问题其他频率下的结果的shape是长什么样的呢,

还有要写出这个操作的pytorch代码

 接下来看看,这部分是关于2d-DCT如何与原始senet结合的

其实看到这里我才反应过来,这里的DCT机制是每个DCT-base对应一个c'(C/N)通道进行DCT变换,而我之前以为是不同DCT-base对所用的C做DCT变换,其实如果这样的话我就有个思考了,这种FCAnet的机制就是有点碰运气了,有点像xgboost那种感觉,求平均了,在不考虑算法时空复杂度的情况下对所有通道C做频率变换比如DWT然后再压缩也是一个不错的考虑。


Q:怎么理解DCT中的低频信号,是怎么定义的?为什么说低频信号蕴含更多的能量(信息量)

A:https://zhuanlan.zhihu.com/p/85299446

1. 首先这里夸奖一下作者,能够详尽地给出dft到dct的变换。
2. 你这里没有解释关键点,为何低频会有能量聚集,高频不会呢?而且还说dct比dft有更好的高频能量聚集?dft来源于一般的周期函数展开成fourier级数,所以对于聚集的问题可以使用一般的连续周期函数类似说明。连续周期函数展开成fourier级数,第一点fourier系数收敛到0,也就显示高频的影响逐渐消失;第二点对于(原函数 - fourier展开式前n项和)一致收敛到0,也就是说明低频占据函数主项,高频逐渐失去作用(高频决定细节,低频决定函数轮廓);第三点对于(原函数 - fourier展开式前n项和)做L2积分,也就是能量积分,是收敛到0,更加说明低频能量趋近于真实能量,而高频能量决定细微的震荡,是可以忽视的。就以上三个证据,足矣说明低频的地位远远高于高频。 然后说dct比dft有更好的能量聚集,这句话本身就是自相矛盾的,dct来源于偶函数下的dft,两者的数学性质完全一致,二者应该是有一样好的能量聚集性,只不过dct更适用于偶函数下的dft。 

(252条消息) 数字图像处理 --- 图像的傅里叶变换的频谱特征 一(周期性,能量分布,fftshift,交错性)_松下J27的博客-CSDN博客_图像的傅里叶频谱是如何反映图像的特征的?

//这个博客也告诉了怎么看图像的高频与低频,和里面的一张图片告诉傅里叶变换在一维信号分析的重要性 。


猜你喜欢

转载自blog.csdn.net/weixin_43332715/article/details/127446473