离散卷积与多通道互相关:参考答案

目录

\[ \begin{align}\begin{aligned}\newcommand{\ba}{\boldsymbol{a}} \newcommand{\bb}{\boldsymbol{b}} \newcommand{\be}{\boldsymbol{e}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bw}{\boldsymbol{w}} \newcommand{\bx}{\boldsymbol{x}} \newcommand{\by}{\boldsymbol{y}} \newcommand{\bz}{\boldsymbol{z}} \newcommand{\bd}{\boldsymbol{d}} \newcommand{\bv}{\boldsymbol{v}} \newcommand{\bs}{\boldsymbol{s}}\\\newcommand{\btheta}{\boldsymbol{\theta}} \newcommand{\bbeta}{\boldsymbol{\beta}} \newcommand{\bgamma}{\boldsymbol{\gamma}} \newcommand{\bsigma}{\boldsymbol{\sigma}} \newcommand{\md}{\mbox{d}} \newcommand{\bmu}{\boldsymbol{\mu}} \newcommand{\bone}{\boldsymbol{1}} \newcommand{\bzero}{\boldsymbol{0}} \newcommand{\bepsilon}{\boldsymbol{\epsilon}} \newcommand{\bphi}{\boldsymbol{\phi}} \newcommand{\bh}{\boldsymbol{h}} \newcommand{\bc}{\boldsymbol{c}} \newcommand{\br}{\boldsymbol{r}} \newcommand{\bQ}{\boldsymbol{Q}} \newcommand{\bK}{\boldsymbol{K}} \newcommand{\bV}{\boldsymbol{V}} \newcommand{\bSigma}{\boldsymbol{\Sigma}} \newcommand{\bg}{\boldsymbol{g}} \newcommand{\bxi}{\boldsymbol{\xi}} \newcommand{\bvarepsilon}{\boldsymbol{\varepsilon}} \newcommand{\bdelta}{\boldsymbol{\delta}} \newcommand{\bq}{\boldsymbol{q}} \newcommand{\bk}{\boldsymbol{k}} \newcommand{\bJ}{\boldsymbol{J}} \newcommand{\bp}{\boldsymbol{p}} \newcommand{\bi}{\boldsymbol{i}} \newcommand{\bo}{\boldsymbol{o}} \newcommand{\bE}{\boldsymbol{E}} \newcommand{\bH}{\boldsymbol{H}} \newcommand{\bL}{\boldsymbol{L}} \newcommand{\bu}{\boldsymbol{u}} \newcommand{\bLambda}{\boldsymbol{\Lambda}} \newcommand{\trans}{^{\rm\scriptsize T}} \newcommand{\var}{\mathrm{var}}\\\newcommand{\bA}{\boldsymbol{A}} \newcommand{\bB}{\boldsymbol{B}} \newcommand{\bC}{\boldsymbol{C}} \newcommand{\bD}{\boldsymbol{D}} \newcommand{\bG}{\boldsymbol{G}} \newcommand{\bI}{\boldsymbol{I}} \newcommand{\bM}{\boldsymbol{M}} \newcommand{\bP}{\boldsymbol{P}} \newcommand{\bS}{\boldsymbol{S}} \newcommand{\bU}{\boldsymbol{U}} \newcommand{\bW}{\boldsymbol{W}} \newcommand{\bX}{\boldsymbol{X}} \newcommand{\bY}{\boldsymbol{Y}} \newcommand{\bZ}{\boldsymbol{Z}} \newcommand{\cotp}{\textcolor[RGB]{48,209,88}{TP}} \newcommand{\cotn}{\textcolor[RGB]{100,210,255}{TN}} \newcommand{\cofp}{\textcolor[RGB]{94,92,230}{FP}} \newcommand{\cofn}{\textcolor[RGB]{191,90,242}{FN}}\\\newcommand{\numcotp}{\textcolor[RGB]{48,209,88}{50}} \newcommand{\numcotn}{\textcolor[RGB]{100,210,255}{30}} \newcommand{\numcofp}{\textcolor[RGB]{94,92,230}{10}} \newcommand{\numcofn}{\textcolor[RGB]{191,90,242}{10}} \DeclareMathOperator*{\argmin}{arg\,min}\end{aligned}\end{align} \]

离散卷积与多通道互相关:参考答案#

返回正文练习 · 返回答案索引

说明#

以下答案与正文10道题逐题对应。推导题给出主要步骤;编程和实验题给出参考程序和检查方法,并说明结果适用于哪些条件。

  1. 空洞卷积核覆盖的有效长度为 \(f_{\mathrm{eff}}=r(f-1)+1\)⁠。填充后长度为 \(d_x+2p\)⁠,合法左端点为 \(0,s,2s,\ldots\)⁠,最大值不超过 \(d_x+2p-f_{\mathrm{eff}}\)⁠。因此起点个数为 \(\lfloor(d_x+2p-f_{\mathrm{eff}})/s\rfloor+1\)⁠,化简即得题中的 \(d'_x\)⁠。要求 \(s\geq1\)⁠、\(r\geq1\)⁠,且 \(d_x+2p\geq r(f-1)+1\)⁠;否则没有合法输出位置。

  2. 每个位置先求第一通道窗口和,再减去第二通道的窗口和 4。四个第一通道窗口和依次为 4、6、4、5,因此输出为 \(\begin{bmatrix}4-4&6-4\\4-4&5-4\end{bmatrix}=\begin{bmatrix}0&2\\0&1\end{bmatrix}\)⁠。该计算是互相关,核没有翻转;两个输入通道的结果在同一输出通道内求和。

  3. 每个输出通道有 \(3(3)(3)=27\) 个核参数和 1 个偏置,总参数量为 \(16(27+1)=448\)⁠。输出共有 \(32(32)(16)\) 个位置,每个位置进行 27 次乘加,故卷积部分为 \(32(32)(16)(27)=442368\) 次乘加。若把乘法和加法分别计数,应明确采用的换算约定。

  4. \(\delta=(\delta_1,\delta_2)\)⁠,并按正文定义 \((T_\delta\bX)_{cij}=X_{c,i-\delta_1,j-\delta_2}\)⁠。代入互相关定义后,\(\mathcal C(T_\delta\bX)_{qij}=\sum_{c,u,v}X_{c,i+u-\delta_1,j+v-\delta_2}W_{q,c,u,v}=\mathcal C(\bX)_{q,i-\delta_1,j-\delta_2}\)⁠,即 \(T_\delta\mathcal C(\bX)\)⁠。有限填充时,平移会改变哪些位置接触人工边界;步幅大于 1 时只保留一个采样子网格,任意 1 像素平移不一定对应输出网格上的整数平移。

  5. 直接实现应把输出尺寸与索引写清楚:

    import numpy as np
    
    def _pair(value, name):
        if np.isscalar(value):
            value = int(value)
            return value, value
        if len(value) != 2:
            raise ValueError(f"{name} 必须是一个整数或两个整数")
        return int(value[0]), int(value[1])
    
    def conv2d_nchw(x, w, b, padding=0, stride=1, dilation=1):
        m, c_in, h, width = x.shape
        c_out, c_w, kh, kw = w.shape
        if c_in != c_w:
            raise ValueError("输入通道数与卷积核不一致")
        p1, p2 = _pair(padding, "padding")
        s1, s2 = _pair(stride, "stride")
        d1, d2 = _pair(dilation, "dilation")
        if min(p1, p2) < 0 or min(s1, s2, d1, d2) < 1:
            raise ValueError("填充不能为负,步幅和空洞率必须为正整数")
        h_out = (h + 2*p1 - d1*(kh-1) - 1) // s1 + 1
        w_out = (width + 2*p2 - d2*(kw-1) - 1) // s2 + 1
        if min(h_out, w_out) <= 0:
            raise ValueError("卷积核大于填充后的输入")
        xp = np.pad(x, ((0,0), (0,0), (p1,p1), (p2,p2)))
        out = np.empty((m, c_out, h_out, w_out),
                       dtype=np.result_type(x, w, b))
        for i in range(m):
            for q in range(c_out):
                for r in range(h_out):
                    for s in range(w_out):
                        row = r * s1
                        col = s * s2
                        window = xp[i, :,
                                    row:row+d1*(kh-1)+1:d1,
                                    col:col+d2*(kw-1)+1:d2]
                        out[i, q, r, s] = np.sum(window * w[q]) + b[q]
        window_info = {
            "padded_shape": xp.shape,
            "window_shape": (c_in, kh, kw),
            "output_shape": out.shape,
            "padding": (p1, p2),
            "stride": (s1, s2),
            "dilation": (d1, d2),
        }
        return out, window_info
    

    window_info 给出核验窗口抽取所需的维度、填充、步幅和空洞率信息;调试时还可增加首末窗口的索引样例,但不应返回所有窗口而无谓占用内存。

  6. 循环版与向量化版必须使用相同的 NCHW、填充和互相关约定;PyTorch conv2d 也不翻转核。随机 float64 小张量上用 allclose 比较,同时记录最大绝对误差。再取只在左上角为 1 的非对称核;若程序错误翻核,输出会向相反方向偏移,测试应稳定失败。向量化版的窗口矩阵可能占用较多内存,因此速度比较必须同时报告峰值内存。

  7. 单位脉冲用于检查核方向与位置,全 1 输入用于检查窗口求和,非对称核用于区分卷积与互相关;多通道测试验证沿输入通道求和和输出通道相互独立;分别改变 \(p_1,p_2\)⁠、\(s_1,s_2\)\(r_1,r_2\) 后,断言理论尺寸等于实际维度。最小合法输入应产生 \(1\times1\) 空间输出,非法通道数、非正步幅和非正空洞率必须报错。整数输出尺寸应完全一致,浮点值再使用与数据类型相符的误差范围。

  8. 三种实现先在同一小张量上确认数值一致,再放入相同网络并复制相同权重。数据批次、种子、更新次数和硬件保持一致。框架内核通常最快,朴素循环最慢,im2col 以额外窗口内存换取矩阵运算效率;但具体结果以实测为准。表中应给出测试指标、最大数值误差、训练秒数、448 等实际参数量和峰值内存。

  9. 两个 \(3\times3\) 卷积在步幅为 1 时产生 \(5\times5\)感受野⁠,并在中间加入一次非线性变换;空洞率为 2 的 \(3\times3\) 空洞卷积 也覆盖 \(5\times5\) 的范围,但读取的输入位置更加分散。为了使比较结果可靠,各组应使用相同的数据划分、随机种子、训练轮数和优化器尝试次数,只改变卷积形式,并报告性能及其波动、训练时间、固定批量预测时间、参数量、乘加量和峰值内存。串联小卷积核通常更容易控制参数量,但网络层数更深;空洞卷积不增加核参数量,却可能遗漏相邻位置的连续变化。

  10. Valid 会逐层缩小特征图,保持空间尺寸的 Same 填充保留更多边界附近位置,但人工填充值也会产生边界效应。两组必须调整分类输出层并如实报告由此产生的参数差异,其他训练条件相同。结果表包括测试指标、训练秒数、参数量及峰值内存。若保持尺寸组更慢或占用更多内存,可由更大的中间特征图解释;不能只比较准确率。