• 深度学习九 —— 手撕 一维离散序列 的线性卷积 和 互相关


    手撕 一维离散序列 的线性卷积 和 互相关

    线性卷积

    公式

    一维离散线性卷积的计算公式如下:

    ( a ∗ v ) [ n ] = ∑ m = − ∞ ∞ a [ m ] v [ n − m ] (a * v)[n] = \sum_{m=-\infty}^{\infty}a[m]v[n-m] (av)[n]=m=a[m]v[nm]

    其中:

    a , v a, v a,v——数字序列;

    n n n——移位的位数。

    numpy中的convolve函数

    numpy.convolve(a, v, mode="full")
    
    • 1

    假定序列 a a a长度为 N N N,序列 v v v长度为 M M M,则有

    • m o d e = ′ f u l l ′ mode='full' mode=full,则结果序列长度 = N + M − 1 =N + M -1 =N+M1,包括重合的端点处的卷积结果,有边界效应
    • m o d e = ′ s a m e ′ mode = 'same' mode=same,则结果序列长度 = max ⁡ ( N , M ) = \max(N , M) =max(N,M),有边界效应
    • m o d e = ′ v a l i d ′ mode = 'valid' mode=valid,则结果序列长度 = max ⁡ ( N , M ) − min ⁡ ( N , M ) + 1 = \max(N, M) - \min(N, M) + 1 =max(N,M)min(N,M)+1,只返回卷积核和输入序列完全重合时的结果,没有边界效应

    注意: 在实际计算时,需要序列 a a a大于 v v v,否则 n u m p y numpy numpy内部会自动交换顺序

    手撕 convolve

    def convolve(a, v):
        r = []
        a = dict(enumerate(a))
        v = dict(enumerate(v))
        for i in range(len(a) + len(v) - 1):
            s = 0
            for j in range(len(a)):
                s += a[j] * v.get(i - j, 0)
            r.append(s)
        return r
     
    if __name__ == "__main__":
        nums1 = [10, 13, 16, 19, 22, 25, 28]
        nums2 = [20, 22, 24]
     
        print(np.convolve(nums1, nums2, mode="full").tolist())
        print(convolve(nums1, nums2))
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    最终得到结果为:

    [200, 480, 846, 1044, 1242, 1440, 1638, 1216, 672]
    [200, 480, 846, 1044, 1242, 1440, 1638, 1216, 672]
    
    • 1
    • 2

    互相关

    公式

    ( a ∗ v ) [ n ] = ∑ m = − ∞ ∞ a ∗ [ m ] v [ n + m ] (a * v)[n] = \sum_{m=-\infty}^{\infty}a^{*}[m]v[n+m] (av)[n]=m=a[m]v[n+m]

    其中,

    a , v a, v a,v——数字序列;

    n n n——移位位数;

    a ∗ a^{*} a—— a a a序列值的复数共轭,即实部不变,虚部取反。

    根据互相关的公式,我们可以得到在实数范围内, a ∗ = a a^{*} = a a=a

    此时,通过比较两个公式可以得到:序列 a a a与序列 v v v反转后的序列 的 卷积 == 序列 a a a 与 序列 v v v的互相关

    numpy互相关计算

    numpy.correlate(a, v, mode)
    
    • 1
    • m o d e = ‘ v a l i d ’ mode = ‘valid’ mode=valid:只返回有效的那一部分相关数据,共 M − N + 1 M-N+1 MN+1个;

    • m o d e = ‘ s a m e ’ mode = ‘same’ mode=same:只返回与 等长的那一部分相关数据,共 N N N个;

    • m o d e = ‘ f u l l ’ mode = ‘full’ mode=full:返回全部相关数据,共 M + N − 1 M+N-1 M+N1个。

    手撕 correlate

    根据公式中的结论,在实数范围内,

    序列 a a a与序列 v v v反转后的序列 的 卷积 == 序列 a a a 与 序列 v v v的互相关

    import numpy as np
    def convolve(a, v):
        r = []
        a = dict(enumerate(a))
        v = dict(enumerate(v))
        for i in range(len(a) + len(v) - 1):
            s = 0
            for j in range(len(a)):
                s += a[j] * v.get(i - j, 0)
            r.append(s)
        return r
     
    if __name__ == "__main__":
        nums1 = [10, 13, 16, 19, 22, 25, 28]
        nums2 = [20, 22, 24]
        print(np.correlate(nums1, nums2, mode="full").tolist())
        print(convolve(nums1, nums2[::-1]))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    得到结果为:

    [240, 532, 870, 1068, 1266, 1464, 1662, 1116, 560]
    [240, 532, 870, 1068, 1266, 1464, 1662, 1116, 560]
    
    • 1
    • 2
  • 相关阅读:
    06-Scala面向对象
    Python深度学习实战:Keras与高级多层感知器——用序列化保存模型
    论文笔记--Enriching Word Vectors with Subword Information
    PMP是水证吗,它的含金量到底怎么样?
    Redis-带你深入学习数据类型list
    你还不会写API文档吗
    java毕业生设计菜谱宣传系统计算机源码+系统+mysql+调试部署+lw
    头条文章_signature
    【Python】特殊方法、属性和运算符重载(22)
    高精度NTP时钟服务器(时间同步服务器)技术方案探讨
  • 原文地址:https://blog.csdn.net/weixin_43662553/article/details/126860132