目录
老饼讲解:一步一步上手深度学习

【运算】细说一下CNN的卷积运算

作者 : 老饼 发表日期 : 2025-10-12 20:30:08 更新日期 : 2026-05-20 14:33:44
老饼讲解-简单易懂,干货满满,爽过嗦螺!


CNN卷积神经网络,固名思议,就是因为它加入了卷积的运算。

好了,这节我们先来细细唠一下CNN的基本卷积运算是什么。

一、CNN的卷积如何运算

好了,我们先来看一下CNN的卷积是如何运算的,再来讲一下它卷积运算背后的意义。

1.1. CNN的卷积运算

CNN的卷积运算呢,其实就是用一个矩阵窗口,逐步移动来计算目标图片的输出值。好了,不要蒙圈,直接看个例子。设目标图片的矩阵,卷积核的矩阵,如下:

那么,第一步来了,从X的左上角开始,将X和W的元素对应相乘再相加,就得到第一个输出11,如下:

卷积运算-Step-1

接下来将窗口向右移一下,就又得到第2个输出17,如下:

卷积运算-Step-2

就按着这样,从从左到右、从上到下的逐格移动进行计算,就得到最终的卷积结果了,如下:

 卷积运算过程

也就是,最终:

恭喜你,学会卷积的基础运算了!

1.2. 如何理解卷积

好了,卷积的意义是什么呢?它主要来源于"猫眼看世界",也就是借鉴眼睛看东西时,逐块逐块看的方式。

 如何理解卷积运算

卷积核呢,就相当于眼睛啦,眼睛每看一块,就得到一个信号(也就是卷积核与当前输入块的加权和)。所以呢,通过逐块逐块看,最后原始图片通过眼睛就映射到了一个新的信号图片上。

二、卷积的填充与步幅

2.1. 卷积的填充

好了,有的小伙伴会发现,卷积之后尺寸变小了,这个简单,只需要在原始输入上添加填充就行了。要填充多少才能让输入与输出的Size一致呢?这个算一下就可以了,但这个不用着急,事实上后来大家都喜欢用3x3的卷积核,然后四周填充都为1,那么就可以保持一致了。

卷积的常用方式

在CNN刚提出时大家总喜欢计算经过卷积之后的输出size,初学者在学习这些模型时也跟着算算算,其实不用算,因为搞到后面大家都统一用"3x3卷积核+1填充"了,它的是keep Size的,也就不用算了。勤奋的同学,如果要用其它Size的卷积核,那么可以在网上搜搜卷积输出size的计算公式,不过我更喜欢在pytorch中直接盲调到一致。

2.1. 卷积的步幅

好了,有的小伙伴又说,我的卷积窗口只能一步一步移吗?不能几步几步的移吗?

可以的,你爱怎么移就怎么移,例如,两步两步的移,那么就是如下的计算方式:

步幅为2的卷积

 有的同学会问,为啥不往下移了,因为下面已经不够2行了啦~如果下面还有两行,还得继续往下移。

好了,事实上,在pytorch里,只需设置一下stride(步幅)参数就行了,下面代码实现时可以玩玩。

三、卷积的多通道运算

3.1. 卷积的运算-多通道输入

好了,我们来说说多通道输入时的卷积运算。

例如,彩色图片,一般3个输入通道(R,G,B),此时输入就是三维的张量。

多输入通道卷积

如图所示,当输入为多通道时,对应地,卷积核也要在通道上进行扩展。与单通道时一样,当窗口移动时,卷积核元素与X的元素对应相乘再相加,就是当前的输出。需要注意的是,与卷积核运算时,是所有元素相乘再相加哦、不是一个通道一个输出哦,所以不管输入是多少通道,最终输出都是单通道。

1.3. 卷积的运算-多输出通道

好了,我们知道,不管多少个输入通道,最终经过卷积后都是单通道。

那么,我们如果想要多个输出通道怎么办?这个好办!要多少个输出通道就用多少个卷积核就行了!

多输出通道卷积

如图所示,既然一个卷积核一个输出通道,那来两个卷积核,就两个输出通道了~

四、玩一玩pytorch的CNN卷积层

好了,下面我们用pytorch来玩一玩CNN的卷积运算吧,就胡乱地玩一下。

4.1.CNN卷积运算代码-一个简单的例子

以1.1节中手算的卷积运算为例,在pytorch中用代码实现如下:

import torch
X =  torch.tensor([[[[1,3,1,2],[2,6,8,5],[4,2,1,0]]]], dtype=torch.float32)    # 输入数据
c = torch.nn.Conv2d(1, 1, kernel_size=(2,2),bias = False)                      # 初始化卷积类
c.weight.data =torch.tensor([[[[1,2],[2,0]]]], dtype=torch.float32)            # 设置卷积核W 
out = c(X)                                                                     # 对输入进行卷积计算
#-------------打印结果-----------------------
print('输入数据:',X)                 
print('卷积核:',c.weight.data)
print('卷积结果:',out)

运行结果如下:

卷积的计算结果

可以看到,这跟我们在1.1节手算的例子是一致的。

4.1.CNN卷积运算代码-详细例子

如果要设置卷积的步幅、填充等,则可以参考下面的代码例子:

import torch
X = torch.rand(1,2,4,4)
# 输入通道3、输出通道2、卷积核3*3,步幅1,上下填充1左右填充0,带阈值
c = torch.nn.Conv2d(2, 1, kernel_size=(3,3), stride=1,padding=(1, 0),bias = True)  # 初始化卷积
out = c(X)                                                                         # 对输入进行卷积计算
#-------------打印结果-----------------------
print('输入数据:',X)                 
print('卷积核权重:',c.weight.data)
print('卷积核阈值:',c.bias.data)
print('卷积结果:',out)

从代码中我们可以看到,初始化一个卷积核时,可以设置它的输入通道、输出通道,卷积核Size,步幅、填充等等参数,而在pytorch中,卷积核是默认带阈值的,即卷积完之后每个输出通道再加上一个阈值。

总结

好了,这节我们讲了卷积的基本运算、填充、步幅等等,以及多输入、输出的卷积是怎么样一回,并展示了pytorch提供的卷积运算方法,相信通过这一节,应该对卷积有了基本的了解。

事实上,CNN的卷积运算非常的多,用一本书来说CNN的卷积都说不完,入门先学一点基本卷积运算就可以了,以后遇到什么,再拓展什么就行了。



图标 评论
添加评论