CNN详解——反向传播过程

CNN的反向传播过程,从原理上讲,与普通的反向传播相同(都使用了链式法则),从具体形式上讲,CNN的反向传播公式又比较特殊,这是因为CNN独有的4个特点:

  1. 局部感知:卷积核和图像卷积时,每次卷积核所覆盖的像素只是一小部分。这一小部分也叫做感受野。
  2. 权值共享:同一层的每个感受野被卷积时,卷积参数都是相同的。
  3. 多卷积核:同一层的每个感受野可能被多个不同的卷积核分别进行卷积,输出多个通道(每个卷积核的结果是一个通道)。
  4. 池化:下采样过程,图像经过池化后,大小会缩小一定倍数。

一般的反向传播

一般的反向传播(即全连接网络)的公式如下:

δ(l)iJ(θ)w(l)ijJ(θ)b(l)i=g(z(l)i)j=1Sl+1δ(l+1)jw(l)ji=δ(l+1)ia(l)j=δ(l+1)i δ i ( l ) = g ′ ( z i ( l ) ) ∑ j = 1 S l + 1 δ j ( l + 1 ) w j i ( l ) ∂ J ( θ ) ∂ w i j ( l ) = δ i ( l + 1 ) a j ( l ) ∂ J ( θ ) ∂ b i ( l ) = δ i ( l + 1 )

向量形式的表达如下:
δ(l)J(θ)W(l)J(θ)b(l)=(W(l))Tδ(l+1)g(z(l))=δ(l+1)(a(l))T=δ(l+1) δ ( l ) = ( W ( l ) ) T δ ( l + 1 ) ∘ g ′ ( z ( l ) ) ∂ J ( θ ) ∂ W ( l ) = δ ( l + 1 ) ( a ( l ) ) T ∂ J ( θ ) ∂ b ( l ) = δ ( l + 1 )

详细推导过程见 反向传播算法的公式推导

反向传播公式的分析

1、对于敏感度的传播: δ(l)i=g(z(l)i)Sl+1j=1δ(l+1)jw(l)ji δ i ( l ) = g ′ ( z i ( l ) ) ∑ j = 1 S l + 1 δ j ( l + 1 ) w j i ( l ) ,可以直接根据链式法则去解释它:
(1)根据前向传播规则, δ(l)i δ i ( l ) 的改变,先影响了此节点的输出值,然后影响了下一层所有的 δ(l+1)j δ j ( l + 1 )
(2)根据链式法则,此节点由输入到输出,其梯度需要乘以 g

### 卷积神经网络 (CNN) 中反向传播算法详解 #### 背景介绍 卷积神经网络(Convolutional Neural Network, CNN)是一种专门用于处理数据具有网格状拓扑结构的深度学习模型,广泛应用于图像识别等领域。其核心组成部分包括卷积层、池化层和全连接层。为了优化这些层中的权重参数,通常采用基于梯度下降的方法,其中反向传播算法起着至关重要的作用。 --- #### 反向传播的核心概念 反向传播的目标是通过链式法则计算损失函数相对于各层权重的梯度,并据此更新权重以最小化误差。对于 CNN 来说,由于存在特殊的层结构(如卷积层和池化层),传统的 DNN 反向传播算法无法直接应用[^2]。 以下是针对不同类型的层的具体实现: --- #### 1. **全连接层** 在 CNN 中,全连接层的功能与传统多层感知机(DNN)相同,因此可以直接沿用标准的反向传播公式。假设第 \( l \)- 层是一个全连接层,则其输出可表示为: \[ z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)} \] \[ a^{(l)} = f(z^{(l)}) \] 其中: - \( z^{(l)} \): 第 \( l \)- 层线性组合的结果; - \( W^{(l)}, b^{(l)} \): 当前层的权重矩阵和偏置项; - \( a^{(l)} \): 当前层经过激活函数后的输出; - \( f(\cdot) \): 激活函数; 反向传播过程中,需计算损失函数关于权重和偏置的导数: \[ \frac{\partial L}{\partial W^{(l)}} = \delta^{(l)} {a^{(l-1)}}^\top \] \[ \frac{\partial L}{\partial b^{(l)}} = \delta^{(l)} \] \[ \delta^{(l-1)} = {\left(W^{(l)}\right)}^\top \delta^{(l)} \odot f'(z^{(l-1)}) \] 这里,\( \delta^{(l)} \) 表示当前层的误差信号[^1]。 --- #### 2. **池化层** 池化操作的主要目的是降低特征维度并增强对局部变化的鲁棒性。常见的池化方式包括最大池化和平均池化。然而,在反向传播阶段,需要将后续层传递回来的误差重新分配到原始输入空间。 ##### (1)最大池化 如果某位置的最大值被选作输出,则仅允许该位置接收来自下一层的误差信号,其余位置保持零贡献。具体来说,设池化窗口大小为 \( k \times k \),则误差重分布规则为: \[ \delta_{i,j}^{(l-1)} = \begin{cases} \delta_k^{(l)}, & \text{if } i,j \text{ is the max position within window } k \\ 0, & \text{otherwise}. \end{cases} \] ##### (2)平均池化 对于平均池化,误差均匀分摊至整个池化窗口内的所有像素点: \[ \delta_{i,j}^{(l-1)} = \frac{1}{k^2} \sum_{m,n} \delta_m^{(l)}, \] 其中 \( m, n \) 是池化窗口的位置索引。 --- #### 3. **卷积层** 卷积层是最具特色的部分之一,它通过对输入特征图施加滑动滤波器提取局部模式。正向传播时,卷积运算可以形式化描述为: \[ y[i, j] = \sum_{u=0}^{F_h-1}\sum_{v=0}^{F_w-1} w[u,v] x[i+u, j+v], \] 其中 \( F_h, F_w \) 分别表示滤波器的高度和宽度。 在反向传播中,目标是从下游层传回的误差 \( \delta^{(l)} \) 推导出上游层的误差 \( \delta^{(l-1)} \) 和本层权重的梯度 \( \nabla_W \)。主要涉及三个步骤: ##### (1)计算权重梯度 \[ \nabla_W[f,g,h,w] = \sum_{p,q} \delta[p,q,f] \cdot X[p+s_f-g, q+s_g-h, w], \] 此处 \( s_f, s_g \) 是步幅参数。 ##### (2)计算偏差梯度 \[ \nabla_b[f] = \sum_p \sum_q \delta[p,q,f]. \] ##### (3)计算输入误差 利用转置卷积(也称为反卷积)完成这一任务: \[ \Delta_X[m,n,c] = \sum_r \sum_s \sum_t K[r,s,t,c] \cdot \delta[m+r-s_x, n+c-s_y, t], \] 其中 \( s_x, s_y \) 控制填充策略[^3]。 --- #### 实现代码示例 以下提供了一个简单的 Python 实现片段展示如何执行上述逻辑: ```python import numpy as np def conv_backward(dZ, cache): """ Implement backward propagation through convolution layer. Parameters: dZ: Gradient of cost with respect to output A of the conv layer cache: Tuple containing values needed for backpropagation Returns: dA_prev: Gradient of loss function wrt previous layer activations dW: Gradient of loss function wrt weights db: Gradient of loss function wrt biases """ # Extract cached data from forward pass (X, W, b, hparameters) = cache stride = hparameters['stride'] pad = hparameters['pad'] (_, _, H_prev, W_prev) = X.shape (f, f, channels, filters) = W.shape m, height_new, width_new, _ = dZ.shape # Initialize gradients dA_prev = np.zeros_like(X) dW = np.zeros_like(W) db = np.zeros((1, 1, 1, filters)) # Pad input if necessary X_pad = np.pad(X, ((0,), (0,), (pad,), (pad,)), 'constant') # Compute gradient updates via sliding windows over padded inputs for i in range(m): x_i = X_pad[i] da_prev_slice = np.zeros_like(x_i) for h in range(height_new): vert_start = h * stride vert_end = vert_start + f for w in range(width_new): horiz_start = w * stride horiz_end = horiz_start + f for c in range(filters): dz_patch = dZ[i, h, w, c] dw_update = x_i[:, vert_start:vert_end, horiz_start:horiz_end] * dz_patch dW[:, :, :, c] += dw_update db[:, :, :, c] += dz_patch da_prev_slice[:, vert_start:vert_end, horiz_start:horiz_end] += \ W[:, :, :, c] * dz_patch dA_prev[i, :, :, :] = da_prev_slice[:, pad:-pad, pad:-pad] return dA_prev, dW, db ``` --- #### 总结 综上所述,CNN反向传播机制依赖于逐层递归地计算梯度信息,并将其反馈至上一层次。尽管每种特定类型的操作有所不同,但它们都遵循统一的原则——即运用链式法则分解复杂的复合函数关系。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值