图像卷积的常见误区与个人思考

这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战

有一次我复现一个经典网络,为了保证代码的优美性,想省一个if-else,因此想找一个特殊的模块,能将输入原封不动地输出。但是我也不知道什么样的模块具有这样的功能,就在一个计算机交流群里问了一下群友。

我:pytorch里想让输入原封不动输出应该用什么模块呀
群友A:1*1的卷积核
我:万一我输入是多通道的呢
群友A:1*1*N呗
群友B:conv2d(input_ch, input_ch, 1),输入输出通道保持一致。但1*1有点类似全连接。
复制代码

看到这里,我已经开始笑了——看来大家跟我一样,对这些基础知识的理解并不是特别透彻。而除此之外,跟其他同学聊到卷积时,我也能感觉到卷积尤其是1*1卷积是一个误解的重灾区。因此,今天打算把之前的思考整理下来,以便回顾。

卷积操作

卷积神经网络主要用于图像数据的处理,所以我们本次重点讨论的是图像卷积。作为一个选修过信号与系统课程的学生,我对卷积有着更原始、更初级,但也更准确的认识。对两个函数的卷积操作可以理解为是对其中一个函数翻转、移位,再测量它们之间的重叠。而在卷积神经网络中,卷积层严格来说是个错误的叫法,所谓卷积操作其实是互相关运算,而不是卷积,李沐老师在《动手学深度学习》中指出了这一点,本文暂且按下不表。

我们看下《动手学深度学习》中对二维卷积的定义:

在二维互相关运算中,卷积窗口从输入张量的左上角开始,从左到右、从上到下滑动。 当卷积窗口滑动到新一个位置时,包含在该窗口中的部分张量与卷积核张量进行按元素相乘,得到的张量再求和得到一个单一的标量值,由此我们得出了这一位置的输出张量值。

Untitled.png

先从上面这个对话说起。

群友A最初的回复1*1的卷积核,乍一看是正确答案,因为对于一个单通道的输入而言,1*1的卷积核确实能保证不改变输入。不过我很快反问多通道输入的场景,群友的回复是1*1*N,另一位群友给出了代码和更准确的解释,但这其实是不对的。

对于多通道的卷积,卷积核的层数要与输入的层数一致,才能进行互相关运算,但是如果只有一个卷积核,那么输出的通道数就只会是1,如果用1*1*N的卷积核(滤波器),就相当于把输入的N个通道全部对应相加,最后得到了一个求和之后的单通道矩阵,而且这种损坏是不可逆的,我们也无法从中还原出输入前的N个通道各自的本来面貌。

Untitled1.png

卷积层与通道数的关系

进一步,按照群友所说的,输入输出通道数保持一致,这样就需要多组卷积核。关于输入通道与输出通道,这其实是很多同学模糊不清的第一个地方。在卷积操作中,输入通道数等于每个滤波器中卷积核的个数,输出通道数等于滤波器的个数。

首先我们先看下卷积层的构成,如图:

Untitled2.png

我们把中间核函数所对应的这部分称为一个卷积层。在一个卷积层中包含单个或多个滤波器,而每个滤波器又有多层,所谓的卷积核个数,就是每个滤波器有多少层。在上图中,每个滤波器中卷积核的个数为3,滤波器的个数为232也分别对应输入通道数和输出通道数。

回到群消息,如果输入输出通道数保持一致,那么则需要一个1*1*N*N的滤波器,但问题在于,这N个卷积核各自的值应该如何设定?如果全部设置成一样的,那么最终会把N通道输入变成N个一模一样的输出,显然是不正确的。不过我承认,如果N个卷积核全部设置为不同值,只要滤波器中的值能构成一个N*N的可逆矩阵,那么是可以从输出中将输入反解出来的,但这样就南辕北辙了。总之,想利用卷积操作将多通道的输入原封不动地输出是不可行的。

1*1卷积和全连接层有什么关系

这又是一个容易误解的地方,我见过不止一个人觉得1*1卷积本质上就是全连接层。虽然是很基础的问题,没什么意义,但既然都写到这了,我还是顺便把我的思考也记录一下吧。

1*1卷积和全连接层虽然没什么关系,但也有互通之处。全连接层可以用一种特殊的卷积层代替,假设输入为7*7*512,全连接层为长为4096的向量,如果用卷积层来代替这个全连接层,则在该卷积层中:

  • 4096个滤波器
  • 每个滤波器有512层(512个卷积核)
  • 每层的大小为7*7

这样输出的维度也是1*1*4096,因此可以通过卷积层来实现该全连接运算。

猜你喜欢

转载自juejin.im/post/7055131484285304845