数学小记之卷积

本文简述了1维卷积和2维卷积的实现

一维卷积

描述卷积的方式很多,譬如这个:

  • 一个函数在另一个函数上的加权叠加

虽然各个解释都有助于我们对卷积的理解,但是个人感觉还是直接通过公式来了解卷积更为直观(简单起见,这里我们仅讨论卷积的离散定义):

f ( x ) ∗ g ( x ) = ∑ n = − ∞ ∞ f ( n ) g ( x − n ) f(x)*g(x) = \sum_{n=-\infty}^{\infty}f(n)g(x - n) f(x)g(x)=n=f(n)g(xn)

注意一下这个公式,其所表达的意思是: fg 这两个函数在 x 处的卷积值,而这个在 x 处的卷积值是通过取遍自变量 n 的"所有值(从负无穷到正无穷)"而计算出来的

当然,对于实际给出的 f 函数(序列) 和 g 函数(序列) 都不会是无穷的,所以计算过程中自变量 n 的取值自然也不会是无穷的,举个简单的例子,假设我们有以下的函数(序列):

f ( 0 ) = 1 , f ( 1 ) = 2 , f ( 2 ) = 3 g ( 0 ) = 4 , g ( 1 ) = 5 , g ( 2 ) = 6 f(0) = 1, f(1) = 2, f(2) = 3\\ g(0) = 4, g(1) = 5, g(2) = 6 f(0)=1,f(1)=2,f(2)=3g(0)=4,g(1)=5,g(2)=6

并设 fg 的卷积结果为 h, 那么 h(1) 等于多少呢?

f ( 1 ) ∗ g ( 1 ) = h ( 1 ) = ? f(1)*g(1) = h(1) = ? f(1)g(1)=h(1)=?

我们来套用一下之前的公式:

f ( 1 ) ∗ g ( 1 ) = h ( 1 ) = ∑ n = − ∞ ∞ f ( n ) g ( 1 − n ) f(1)*g(1) = h(1) = \sum_{n=-\infty}^{\infty}f(n)g(1 - n) f(1)g(1)=h(1)=n=f(n)g(1n)

考虑到 n1 - n 的合法范围(n 需为 f 的合法索引,1 - n 需为 g 的合法索引),我们有:

0 = m i n _ i n d e x ( f ) &lt; = n &lt; = m a x _ i n d e x ( f ) = 2 0 = m i n _ i n d e x ( g ) &lt; = 1 − n &lt; = m a x _ i n d e x ( g ) = 2 &ThickSpace; ⟹ &ThickSpace; 0 &lt; = n &lt; = 1 0 = min\_index(f) &lt;= n &lt;= max\_index(f) = 2\\0 = min\_index(g) &lt;= 1 - n &lt;= max\_index(g) = 2\\\implies0 &lt;= n &lt;= 1 0=min_index(f)<=n<=max_index(f)=20=min_index(g)<=1n<=max_index(g)=20<=n<=1

所以对于 h(1) 来说 自变量 n 有两个合法取值: 01, 于是我们有:

f ( 1 ) ∗ g ( 1 ) = h ( 1 ) = f ( 0 ) g ( 1 − 0 ) + f ( 1 ) g ( 1 − 1 ) = f ( 0 ) g ( 1 ) + f ( 1 ) g ( 0 ) = 1 ∗ 5 + 2 ∗ 4 = 13 f(1)*g(1) = h(1) = f(0)g(1 - 0) + f(1)g(1 - 1) = f(0)g(1) + f(1)g(0) = 1 * 5 + 2 * 4 = 13 f(1)g(1)=h(1)=f(0)g(10)+f(1)g(11)=f(0)g(1)+f(1)g(0)=15+24=13

其余的卷积数值也可以依样进行计算,有兴趣的朋友可以自行试下~

下面是使用 Lua 实现的一维卷积示例:

local function dimension(f)
    if type(f) == "table" then
        local dim = #f
        if dim > 0 then
            return dim, dimension(f[1])
        else
            return 0
        end
    end
end

local function value(f, ...)
    if f then
        local dim_index = { ... }
        for i = 1, #dim_index do
            local index = dim_index[i]
            f = f[index]
            if not f then
                return 0
            end
        end
    end
    
    return f
end

-- 1d convolution, sample f(array with 3 elements) and g(array with 3 elements), h is convolution result(array index is from 0)
-- h(0) = f(0) * g(0)
-- h(1) = f(0) * g(1) + f(1) * g(0)
-- h(2) = f(0) * g(2) + f(1) * g(1) + f(2) * g(0)
-- h(3) = f(1) * g(2) + f(2) * g(1)
-- h(4) = f(2) * g(2)

function convolution_1d(f, g)
    local row_1 = dimension(f)
    local row_2 = dimension(g)
    if row_1 > 0 and row_2 > 0 then
        local h = {}
        
        local n = row_1 + row_2 - 2
        for i = 0, n do
            local sum = 0
            for j = 0, i do
                sum = sum + value(f, j + 1) * value(g, i - j + 1)
            end
            table.insert(h, sum)
        end
        
        return h
    end
end

示例中的 dimension函数 和 value函数 对于不熟悉 Lua 的朋友可能会造成些阅读障碍(对于示例来说确实有些过度技巧化了),在此我们可以简单理解:

  • dimension(f) 获取 f 的数组个数(支持多维数组)
  • value(f, …) 获取 f 在 …(不定参数) 所给定的索引处的数值,数值不存在则返回 0 (支持多维数组)
二维卷积

二维卷积可以使用一维卷积来进行类比,在此仅给出(离散定义)公式和相关示例实现(使用 Lua):

f ( x , y ) ∗ g ( x , y ) = ∑ m = − ∞ ∞ ∑ n = − ∞ ∞ f ( m , n ) g ( x − m , y − n ) f(x, y)*g(x, y) = \sum_{m=-\infty}^{\infty}\sum_{n=-\infty}^{\infty}f(m, n)g(x - m, y - n) f(x,y)g(x,y)=m=n=f(m,n)g(xm,yn)

示例代码如下,其中的 dimension函数 和 value函数 即来自于之前的示例代码,在此不再重复列出:

-- 2d convolution, sample f(matrix 3 * 3) and g(matrix 2 * 2), h is convolution result(matrix index is from (0, 0))
-- h(0, 0) = f(0, 0) * g(0, 0)
-- h(0, 1) = f(0, 0) * g(0, 1) + f(0, 1) * g(0, 0)
-- h(0, 2) = f(0, 1) * g(0, 1) + f(0, 2) * g(0, 0)
-- h(0, 3) = f(0, 2) * g(0, 1)
-- h(1, 0) = f(0, 0) * g(1, 0) + f(1, 0) * g(0, 0)
-- h(1, 1) = f(0, 0) * g(1, 1) + f(0, 1) * g(1, 0) + f(1, 0) * g(0, 1) + f(1, 1) * g(0, 0)
-- h(1, 2) = f(0, 1) * g(1, 1) + f(0, 2) * g(1, 0) + f(1, 1) * g(0, 1) + f(1, 2) * g(0, 0)
-- h(1, 3) = f(0, 2) * g(1, 1) + f(1, 2) * g(0, 1)
-- h(2, 0) = f(1, 0) * g(1, 0) + f(2, 0) * g(0, 0)
-- h(2, 1) = f(1, 0) * g(1, 1) + f(1, 1) * g(1, 0) + f(2, 0) * g(0, 1) + f(2, 1) * g(0, 0)
-- h(2, 2) = f(1, 1) * g(1, 1) + f(1, 2) * g(1, 0) + f(2, 1) * g(0, 1) + f(2, 2) * g(0, 0)
-- h(2, 3) = f(1, 2) * g(1, 1) + f(2, 2) * g(0, 1)
-- h(3, 0) = f(2, 0) * g(1, 0)
-- h(3, 1) = f(2, 0) * g(1, 1) + f(2, 1) * g(1, 0)
-- h(3, 2) = f(2, 1) * g(1, 1) + f(2, 2) * g(1, 0)
-- h(3, 3) = f(2, 2) * g(1, 1)

function convolution_2d(f, g)
    local row_1, col_1 = dimension(f)
    local row_2, col_2 = dimension(g)
    if row_1 > 0 and col_1 > 0 and row_2 > 0 and col_2 > 0 then
        local h = {}
        
        local m = row_1 + row_2 - 2
        local n = col_1 + col_2 - 2
        for i = 0, m do
            for j = 0, n do
                local sum = 0
                for k1 = 0, i do
                    for k2 = 0, j do
                        sum = sum + value(f, k1 + 1, k2 + 1) * value(g, i - k1 + 1, j - k2 + 1)
                    end
                end
                h[i + 1] = h[i + 1] or {}
                h[i + 1][j + 1] = sum
            end
        end
        
        return h
    end
end
参考
  1. 如何通俗地理解卷积?(很好的介绍文章,推荐首先阅读)
  2. 我对卷积的理解
  3. 最容易理解的对卷积(convolution)的解释
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值