CNN中的多通道卷积(RGB等)

本文详细解析了卷积神经网络中的卷积过程,包括一通道和多通道下的多个卷积核卷积过程,并通过实例说明了如何计算输出的特征图数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

卷积过程是对一个通道的图像进行卷积,比如10个卷积核,得到10个feature map, 那么输入图像为RGB三个通道呢,输出就为 30个feature map吗, 答案肯定不是的, 输出的个数依然是卷积核的个数10,只是输出时对RGB三个通道加和。

1、 一通道多个卷积核卷积过程:

一个卷积核得到的特征提取是不充分的,我们可以添加多个卷积核,比如32个卷积核,可以学习32种特征。在有多个卷积核时,如下图所示:输出就为32个feature map。

卷积神经网络


2.多通道的多个卷积核

下图展示了在四个通道上的卷积操作,有两个卷积核,生成两个通道。其中需要注意的是,四个通道上每个通道对应一个卷积核。

先将w2忽略,只看w1,那么在w1的某位置(i,j)处的值,是由四个通道上(i,j)处的卷积结果相加然后再取激活函数值得到的。  所以最后得到两个feature map, 即输出层的卷积核核个数为 feature map 的个数。

卷积神经网络

卷积神经网络

所以,在上图由4个通道卷积得到2个通道的过程中,参数的数目为4×2×2×2个,其中4表示4个通道,第一个2表示生成2个通道,最后的2×2表示卷积核大小。

3.实例

下图是一个3d的RGB效果,每个kernel(filter)可以扫描出一张feature map,多个filter可以叠加出很厚的feature maps,前一层filter做卷积可以形成后一层的一个像素点


如下图,可以代表i行j列k深度的一个输出像素值,k’代表第k个filter,w代表filter中的值,x代表输入,b是偏值。

4.计算实例

假设有两个卷积核为:,因此M=2,kernel_h=2,kernel_w=2,K= kernel_h * kernel_w=4。

输入图像矩阵为:,因此image_h=3,image_w=3,令边界扩展为0即pad_h=0,pad_w=0,滑动步长为1,即stride_h=1,stride_w=1,故N=[(3+2*0-2)/1+1]*[ (3+2*0-2)/1+1]=2*2=4。

A矩阵(M*K)为(一行为一个卷积核),B矩阵(K*N)为(B矩阵的每一列为一个卷积核要卷积的大小)

计算C矩阵:

C=A*B=*=

C中的分别为两个输出特征图像即feature map。验证了 有几个卷积核就有几个feature map。


说明:

在Caffe源码中,src/caffe/util/math_functions.cu(如果使用CPU则是src/util/math_functions.cpp)中的caffe_gpu_gemm()函数,其中有两个矩阵A(M*K)与矩阵 B(K*N),大家可以通过输出M、K、N的值即相应的矩阵内容来验证上述的原理,代码中的C矩阵与上述的C矩阵不一样,代码中的C矩阵存储的是偏置bias,×是A与B相乘后得到M*N大小的矩阵,然后再跟这个存储偏置的矩阵C相加完成卷积过程。如果是跑Mnist训练网络的话,可以看到第一个卷积层卷积过程中,M=20,K=25,N=24*24=576。

  (caffe中涉及卷积具体过程的文件主要有:src/caffe/layers/conv_layer.cu、src/caffe/layers/base_conv_layer.cpp、src/caffe/util/math_functions.cu、src/caffe/util/im2col.cu)


参考:

1.多通道(比如RGB三通道)卷积过程

https://blog.youkuaiyun.com/u014114990/article/details/51125776

2.【机器学习】彻底搞懂CNN

https://www.cnblogs.com/rucwxb/p/7975504.html




### 多通道 CNN 卷积层计算公式及其数学推导 在卷积神经网络(CNN)中,多通道输入数据通常用于处理图像或其他具有多个特征维度的数据。例如,在RGB彩色图像中,每个像素有三个颜色通道:红色、绿色和蓝色。为了有效地提取这些多维数据中的空间特征,卷积操作被扩展到支持多通道输入。 #### 1. 基本概念 对于单通道输入,卷积核是一个二维矩阵,它与输入数据进行滑动窗口操作并执行逐元素相乘再求和的操作[^1]。然而,在多通道情况下,卷积核不仅需要覆盖输入的空间维度(高度和宽度),还需要覆盖所有的输入通道数。因此,一个多通道卷积核实际上是由多个二维卷积核组成的三维张量,其中每个二维卷积核对应于输入的一个特定通道。 #### 2. 多通道卷积的定义 假设输入数据 \( X \in \mathbb{R}^{H_{\text{in}} \times W_{\text{in}} \times C_{\text{in}}} \),表示输入的高度 (\( H_{\text{in}} \))、宽度 (\( W_{\text{in}} \))通道(\( C_{\text{in}} \))卷积核 \( K \in \mathbb{R}^{C_{\text{out}} \times k_h \times k_w \times C_{\text{in}}} \),其中 \( C_{\text{out}} \) 是输出通道的数量,\( k_h \) 和 \( k_w \) 分别是卷积核的高度和宽度。 对于每一个输出通道 \( c' \) (\( c' = 0, ..., C_{\text{out}}-1 \)),对应的卷积核为 \( K_{c'} \in \mathbb{R}^{k_h \times k_w \times C_{\text{in}}} \)。该卷积核会作用在整个输入上,并通过如下公式计算: \[ Z[h', w', c'] = b[c'] + \sum_{h=0}^{k_h-1}\sum_{w=0}^{k_w-1}\sum_{c=0}^{C_{\text{in}}-1} X[h+h', w+w', c] \cdot K_{c'}[h, w, c], \] 这里: - \( h' \), \( w' \) 表示输出位置, - \( b[c'] \) 是偏置项, - \( X[h+h', w+w', c] \) 是输入数据的一部分, - \( K_{c'}[h, w, c] \)卷积核的部分权重。 上述公式可以理解为:对于每一对输入通道卷积通道,先做标准的二维卷积运算;然后将所有通道的结果加总起来得到最终的响应值[^2]。 #### 3. 输出尺寸计算 如果给定步幅 (stride) \( s \) 和填充大小 (padding) \( p \),则输出的高度和宽度可以通过下面的公式得出: \[ H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} + 2p - k_h}{s} \right\rfloor + 1, \] \[ W_{\text{out}} = \left\lfloor \frac{W_{\text{in}} + 2p - k_w}{s} \right\rfloor + 1. \] 这一步骤考虑到了如何调整输入数据以适应不同的卷积参数设置。 #### 4. 实现代码示例 以下是基于 Python 的简单实现片段展示如何手动完成一次多通道卷积过程: ```python import numpy as np def convolve_multi_channel(input_data, kernel, bias=None, stride=1, padding=0): batch_size, input_height, input_width, num_input_channels = input_data.shape output_channels, filter_height, filter_width, _ = kernel.shape padded_input = np.pad( input_data, ((0, 0), (padding, padding), (padding, padding), (0, 0)), mode='constant' ) output_height = int((input_height + 2 * padding - filter_height) / stride + 1) output_width = int((input_width + 2 * padding - filter_width) / stride + 1) result = np.zeros((batch_size, output_height, output_width, output_channels)) for out_c in range(output_channels): current_kernel = kernel[out_c] for i in range(output_height): for j in range(output_width): patch_start_i = i * stride patch_end_i = patch_start_i + filter_height patch_start_j = j * stride patch_end_j = patch_start_j + filter_width patches = padded_input[:, patch_start_i:patch_end_i, patch_start_j:patch_end_j, :] result[:, i, j, out_c] += np.sum(patches * current_kernel, axis=(1, 2, 3)) if bias is not None: result[..., out_c] += bias[out_c] return result ``` 此函数接受四维数组作为输入 (`batch`, `height`, `width`, `channels`) 并返回经过卷积后的结果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值