小工具知识网

当前位置: 首页 > 行业知识 > 神经网络系列---卷积

行业知识

神经网络系列---卷积

2026-11-06 03:39:43 来源:互联网转载

文章目录

    • 卷积神经网络
      • 卷积
      • 转置卷积
      • 卷积核和反卷积的三种实现方式
      • 卷���的次数计算

        卷积神经网络

        在神经网络的卷积层中,向下取整(Floor)是一种常用的策略,特别是在处理输出尺寸不是整数的情况时。当你计算出卷积层输出的尺寸(通常是宽度和高度)不是整数时,你可以简单地去掉小数部分,即对该数进行向下取整。

        向下取整通常意味着在卷积操作中你可能会忽略输入矩阵(也就是图像或者上一层的输出)的一小部分。这可能导致一些空间信息的丢失,但在实践中通常不会产生重大影响。

        举一个简单的例子,假设你有一个7x7的输入和一个3x3的卷积核,步长为2。通常,输出的尺寸会用以下公式来计算:

        输出尺寸 = ⌊ 输入尺寸 − 核尺寸 步长 ⌋ + 1 \text{输出尺寸} = \left\lfloor \frac{{\text{输入尺寸} - \text{核尺寸}}}{\text{步长}} \right\rfloor + 1 输出尺寸=⌊步长输入尺寸−核尺寸​⌋+1

        如果用这个公式计算,输出尺寸会是:

        ⌊ 7 − 3 2 ⌋ + 1 = 3 \left\lfloor \frac{{7 - 3}}{2} \right\rfloor + 1 = 3 ⌊27−3​⌋+1=3

        这里,向下取整实际上没有影响,因为计算结果刚好是一个整数。但如果输入尺寸是8x8,那么输出尺寸会是:

        ⌊ 8 − 3 2 ⌋ + 1 = ⌊ 5 2 ⌋ + 1 = 2 + 1 = 3 \left\lfloor \frac{{8 - 3}}{2} \right\rfloor + 1 = \left\lfloor \frac{5}{2} \right\rfloor + 1 = 2 + 1 = 3 ⌊28−3​⌋+1=⌊25​⌋+1=2+1=3

        在这个例子中,尽管精确的计算结果是3.5,但通过向下取整,输出尺寸变成了3。

        使用向下取整的一个优点是它简化了实现,因为你不需要特别处理边界条件。缺点是可能会丢失一些空间信息,尤其是当步长比较大的时候。然而,在许多应用场景中,这种信息丢失通常是可以接受的。

        神经网络中关于卷积池化的计算(不为整数时,卷积向下取整,池化向上取整)

        对于正向传播,我们使用原始的卷积核进行卷积操作。在反向传播时,为了计算输入或权重的梯度,通常需要进行“翻转”操作。

        需要注意的是,正向卷积和反向传播中的卷积(通常称为转置卷积或反卷积)在数学和实现上有一些不同。在正向传播中,卷积核与输入数据进行卷积以生成输出。而在反向传播中,我们关心的是如何改变输入或卷积核以最小化某个损失函数。

        为了具体说明为什么需要翻转卷积核,考虑一维情况(二维情况是类似的):

        假设正向卷积表示为 y = x ∗ w y = x * w y=x∗w,其中 x x x 是输入, w w w 是卷积核, y y y 是输出,‘*’ 是卷积操作。

        在反向传播过程中,我们通常需要计算损失函数 L L L 关于输入 x x x 的梯度( ∂ L ∂ x \frac{\partial L}{\partial x} ∂x∂L​)。为了找到这个梯度,我们需要用到链式法则:

        ∂ L ∂ x = ∂ L ∂ y ∗ rot180 ( w ) \frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} * \text{rot180}(w) ∂x∂L​=∂y∂L​∗rot180(w)

        其中, rot180 ( w ) \text{rot180}(w) rot180(w) 表示将 w w w 进行180度翻转。

        这样做的主要原因是数学上的一致性和计算的方便性。这样,前向和反向传播可以用相似的卷积操作来实现,大大简化了算法的实现。

        简而言之,在正向传播中我们使用原始的卷积核,而在反向传播时,为了计算梯度,我们通常需要用到翻转的卷积核。这主要是为了数学和计算的方便。

        在反向传播(backpropagation)过程中,通常会使用原始卷积核(kernel)的翻转版本。这里的“翻转”通常意味着沿两个空间维度(即不是批量维度或通道维度)旋转180度。

        例如,如果你有一个3x3的卷积核:

        K = ( a b c d e f g h i ) K = \begin{pmatrix}a & b & c \\d & e & f \\g & h & i\end{pmatrix} K= ​adg​beh​cfi​ ​

        翻转这个卷积核会得到:

        K rot = ( i h g f e d c b a ) K^{\text{rot}} = \begin{pmatrix}i & h & g\\f & e & d \\c & b & a\end{pmatrix} Krot= ​ifc​heb​gda​ ​

        在Eigen中,使用reverse()函数并指定需要翻转的维度可以实现这一点。例如,对于一个Eigen::MatrixXf对象kernel,你可以这样翻转它:

        Eigen::MatrixXf rotated_kernel = kernel.reverse();

        这里简单假设reverse()默认沿两个维度翻转矩阵。实际使用中,请确保你正确地翻转了维度。

        这个翻转的卷积核(或旋转180度的卷积核)通常用于反向传播过程中,以计算相对于输入的梯度。这与前向传播中使用的卷积核是同一个卷积核,只是翻转了。

        【卷积神经网络中的反向传播动画演示】

        通过将输入和卷积核展开(unroll)为矩阵,可以使用矩阵乘法来实现卷积和转置卷积操作。下面简要介绍如何使用这种技术。

        卷积

        假设我们有一个输入矩阵 X X X 和一个卷积核 K K K。我们首先将 X X X 展开为一个大矩阵 X unroll X_{\text{unroll}} Xunroll​,其中每一列都包含一个 K K K 能应用于 X X X 的局部区域。然后,我们将 K K K 展开为一个行向量 K unroll K_{\text{unroll}} Kunroll​。

        接下来,卷积操作可以通过以下矩阵乘法进行:

        O = K unroll × X unroll O = K_{\text{unroll}} \times X_{\text{unroll}} O=Kunroll​×Xunroll​

        其中 O O O 是输出矩阵。

        转置卷积

        对于转置卷积,方法基本相同,但展开和乘法的方向会有所不同。

        假设我们有一个输入矩阵 Y Y Y 和相同的卷积核 K K K。为了进行转置卷积,我们将 Y Y Y 展开为 Y unroll Y_{\text{unroll}} Yunroll​,然后执行以下矩阵乘法:

        O = X unroll × K T O = X_{\text{unroll}} \times K^T O=Xunroll​×KT

        这里, K T K^T KT 是 K K K 的转置。

        请注意,在这两种情况下,我们都需要格外注意矩阵的维度和展开的顺序。

        卷积核和反卷积的三种实现方式

        #include #include //卷积Eigen::MatrixXf conv2D(const Eigen::MatrixXf& input, const Eigen::MatrixXf& kernel, int stride) {    // 计算输出矩阵的尺寸    int rows = (input.rows() - kernel.rows()) / stride + 1;    int cols = (input.cols() - kernel.cols()) / stride + 1;    // 创建输出矩阵    Eigen::MatrixXf output(rows, cols);    for (int i = 0; i 

上一篇:宝塔面板脚本操作秘籍,一键挂起,轻松搞定!

下一篇:VM壳剥离秘籍,轻松解锁核心功能!