百合海羽星 發表於 2025-12-5 23:48:00

一只菜鸟学深度学习的日记:入门卷积

<blockquote>
<p>本文以作者阅读《Dive into Deep Learning》为线索,融合串联了自身理解感悟、原始论文、优秀文章等。如有无意侵权,请联系本人删除。</p>
</blockquote>
<p>卷积神经网络,由图像处理而生,但在NLP等方面仍有较大作用。<br>
图像分辨率大时,对模型参数数量要求很多<br>
原理:</p>
<ul>
<li>物体是什么 与 物品所在的位置 无关 --- <strong>平移不变性</strong></li>
<li>最初只探索图像中的局部区域,忽略不同空间的关系 --- <strong>局部性</strong></li>
</ul>
<p>如果我们用MLP处理图像,用输入层图像<span class="math inline">\(\mathbf{X}(高H,宽W)\)</span>、其隐藏层表示<span class="math inline">\(\mathbf{H}\)</span>是矩阵或者说是二维张量,且二者形状相同。<br>
我们想要所有隐藏神经元都能接收到每一个像素的信息,就要使用四阶张量<span class="math inline">\(\mathbf W\)</span>。<br>
设 <span class="math inline">\(bias=\mathbf U\)</span>,可以把全连接层写为:</p>
<p></p><div class="math display">\[\begin{split}\begin{aligned} \left[\mathbf{H}\right]_{i, j} &amp;= [\mathbf{U}]_{i, j} + \sum_k \sum_l[\mathbf{ W}]_{i, j, k, l}[\mathbf{X}]_{k, l}\\ \\ &amp;令 k = i + a,l = j + b,则 [\mathbf W]_{i,j,i+a,j+b} = [\mathbf V]_{i,j,a,b}\\
\\&amp;=[\mathbf{U}]_{i, j} +
\sum_a \sum_b [\mathbf{V}]_{i, j, a, b}[\mathbf{X}]_{i+a, j+b}\end{aligned}\end{split}
\]</div><p></p><p>我们为什么做<span class="math inline">\(W\rightarrow V\)</span>这个公式的形式上的变换呢?<br>
为了便于理解、过渡</p>
<ul>
<li><span class="math inline">\(W\)</span> 是输出位置和输入位置的局部连接</li>
<li><span class="math inline">\(V\)</span> 是输出位置和相对偏移位置的连接,更符合直觉<br>
这就是局部连接:<br>
以输入输出<span class="math inline">\(3 \times 3\)</span>,局部窗口大小<span class="math inline">\(2\times 2\)</span>为例,<br>
*注:这里例子中窗口是从当前位置开始的2×2区域,并非以当前位置为中心的对称窗口,仅用于说明局部连接的概念。<br>
有</li>
</ul>
<p></p><div class="math display">\[\begin{split}
H&amp; = W\cdot X + W\cdot X \\ &amp;+
         W\cdot X + W\cdot X\\
         &amp;=V\cdot X+V\cdot X\\&amp;+
         V\cdot X+V\cdot X\\
\end{split}\]</div><p></p><p>如果<span class="math inline">\(a、b\)</span>遍历所有值,就能覆盖图像所有位置,即每个神经元都能看到整个输入图像。</p>
<p>然鹅,在这样的局部连接层中,权重<span class="math inline">\(V\)</span>是依赖于输出位置<span class="math inline">\((i,j)\)</span>的,即每个位置的神经元都有独立的滤波器。这意味着如果输入图像很大,参数量会非常庞大。<br>
所以我们可以假设,图像中不同位置的局部模式应该以相同的方式处理。即一个边缘检测器无论在图像的左上角还是右下角都应该有相同的权重,这就是平移不变性。<br>
现在,我们运用平移不变性,即<span class="math inline">\(V、U\)</span>实际与<span class="math inline">\((i,j)\)</span>的值无关,可以知道:</p>
<p></p><div class="math display">\[[\mathbf{V}]_{i, j, a, b} = [\mathbf{V}]_{a, b}
\]</div><p></p><p>同理,偏置<span class="math inline">\(U\)</span>也应当与位置无关。若我们假设每个输出通道共享一个偏置(单通道情况下就是一个常数<span class="math inline">\(b\)</span>),则</p>
<p></p><div class="math display">\[[\mathbf U]_{i,j}=b
\]</div><p></p><p>再带入原公式,我们就顺利得到了一个二维卷积的定义。<br>
我们称其中的<span class="math inline">\(\mathbf V\)</span>是<em>卷积核</em> 或 <em>滤波器</em>。</p>
<p><em>补充:</em><br>
传统图像处理中的滤波器,一般要求:</p>
<ul>
<li>滤波器的大小应该是奇数,这样它才有一个中心,才有了半径的称呼,例如5x5大小的核的半径就是2。</li>
<li>滤波器矩阵所有的元素之和等于1,以保证滤波前后图像的亮度保持不变。</li>
</ul>
<p><strong>但</strong>在卷积神经网络中,卷积核是通过数据自动学习得到的,没有这些约束:</p>
<ul>
<li>后续的批量归一化层会调整特征分布的均值和方差</li>
<li>偏置参数可以补偿均值偏移</li>
<li>激活函数(如ReLU)会引入非线性并改变数值范围</li>
</ul>
<p>CNN中的卷积核是一种特征检测器,而不是传统意义上的图像滤波器。它们被训练来检测对任务有用的模式筛选特征(如边缘、纹理、形状 · · ·),而不是保持图像属性不变。</p>
<p>我们再用局部性,即一个像素通常只与其邻近像素有较强的关联,而与遥远像素的关联很弱。将<span class="math inline">\(|a|、|b|\)</span>限制在局部的范围之内。 在推导中就可简单将外部区域的权重设为 <span class="math inline">\(0\)</span> 。<br>
有</p>
<p></p><div class="math display">\[[\mathbf{H}]_{i, j} = b + \sum_{a = -\Delta}^{\Delta} \sum_{b = -\Delta}^{\Delta} [\mathbf{V}]_{a, b}[\mathbf{X}]_{i+a, j+b}
\]</div><p></p><p>这就是一个二维离散卷积层(忽略填充、步幅)。</p>
<h4 id="现在理解一下卷积">现在理解一下“卷积”</h4>
<p>下面是连续函数的卷积公式:</p>
<p></p><div class="math display">\[(f * g)(t) = \int_{-\infty}^{\infty} f(\tau) g(t-\tau) d\tau
\]</div><p></p><p><span class="math inline">\(g(t-\tau)\)</span> 表示将 <span class="math inline">\(g(\tau)\)</span> 翻转得到 <span class="math inline">\(g(-\tau)\)</span>,再向右平移 <span class="math inline">\(t\)</span> 个单位</p>
<p>然而,在在上文中我们并没有对卷积核 <span class="math inline">\(V\)</span> 进行翻转,而是直接滑动,这其实是互相关。<br>
所以我们为什么依旧用“卷积”这个词呢?</p>
<ul>
<li>沿用信号处理领域词语。</li>
<li>严格数学卷积依旧存在翻转步骤,而且 <span class="math inline">\(V\)</span> 是可学习的参数,不是一成不变的,可以自适应是否翻转。</li>
<li>是否翻转,都是线性操作,不影响模型的表达能力。<br>
深度学习中实际使用的是互相关(无翻转)<br>
所以,一般情况下,把“卷积”理解为“用一个可学习的小窗口在输入上滑动并进行加权求和”即可。<br>
因为我们输入的其实是离散图像数据,是一个张量,所以我们将这个公式离散化,就可以得到</li>
</ul>
<p></p><div class="math display">\[(f * g)(i, j) = \sum_a\sum_b f(a, b) g(i-a, j-b)
\]</div><p></p><p>深度学习实际使用的互相关为:</p>
<p></p><div class="math display">\[(f * g)(i, j) = \sum_a\sum_b f(a, b) g(i+a, j+b)
\]</div><p></p><p>注意这里的 <span class="math inline">\(f\)</span> 对应卷积核,<span class="math inline">\(g\)</span>对应输入图像,与连续卷积公式中的 <span class="math inline">\(f,g\)</span> 角色可能相反,但这是常用的表示方式</p>
<h3 id="多维张量">多维张量</h3>
<p>显然,纯黑白格子画例外,所有输入的图像都不是简简单单的二维张量,每个像素点位置的基础上都储存着灰度或者RGB三通道,所以我们可以在这里暂且认为输入是一个三维张量(实际训练中我们更多使用四维<span class="math inline">\((height, weight, channel, batch\_size)\)</span> )。<br>
因此输入 <span class="math inline">\(\mathbf X\)</span> 是一个三维张量,形状为<span class="math inline">\((C_{in},H,W)\)</span>,其中 <span class="math inline">\(C_{in}\)</span> 是输入通道数,那么卷积也应调为<span class="math inline">\([\mathbf V]_{a,b,c}\)</span><br>
这时,对于每个空间位置的隐藏层 <span class="math inline">\(\mathbf H\)</span> ,我们各用一组堆叠着的二维张量的<em>通道</em> 表示,而每个通道都向后续层提供一组空间化的学习特征,我们称之为“特征映射”。</p>
<p>对于特征映射,每个映射(通道)都是一个<span class="math inline">\((高度×宽度)\)</span>的二维矩阵,其中每一个值都表示着某个特定特征在输入图像对应位置的激活强度。<br>
这里的特征保留了位置信息,即映射上的每个坐标点都对应输入图像的某个区域,是空间化、保留空间结构的。<br>
其中,浅层特征映射、中层特征映射、深层特征映射应用、意义不同:浅层特征映射检测简单模式(如边缘、纹理),中层特征映射检测组合模式,深层特征映射对应高级语义特征。</p>
<p>在这里,为了支持输入<span class="math inline">\(\mathbf X\)</span> 和隐藏层 <span class="math inline">\(\mathbf H\)</span> 能用多个通道,更有普适性,可以让 <span class="math inline">\(\mathbf V\)</span> 再添加一个坐标,使其表示 <span class="math inline">\((size\_h,size\_w,C_{in},C_{out})\)</span> 。<br>
这是一个含有多个通道的隐藏层表示:</p>
<p></p><div class="math display">\[[\mathbf{H}]_{i,j,d} =b_d + \sum_{a = -\Delta}^{\Delta} \sum_{b = -\Delta}^{\Delta} \sum_{c=0}^{C_{in}-1} [\mathbf{V}]_{a, b, c, d} [\mathbf{X}]_{i+a, j+b, c}
\]</div><p></p><p>其中 <span class="math inline">\(a,b\)</span> 是卷积核的空间维度(高度、宽度),<span class="math inline">\(c\)</span> 是输入通道索引,<span class="math inline">\(d\)</span> 是输出通道索引,<br>
<span class="math inline">\(b_d\)</span> 是第 <span class="math inline">\(d\)</span> 个输出通道的偏置</p><br><br>
来源:https://www.cnblogs.com/yldeveloper/p/19314046
頁: [1]
查看完整版本: 一只菜鸟学深度学习的日记:入门卷积