1 问题
在相同情况下,卷积层和激活函数之间的区别是什么?
2 方法
卷积层就是用来提取图像的特征。
图像在计算机看来就是像素点组成的矩阵,对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:
可以看做一个恒定的滤波器filter也叫作卷积核)做内积(逐个元素相乘再求和)的操作就是卷积。
卷积层就是利用卷积核(也叫滤波器)来提取图像的特征。
不同的卷积核可以得到不同的特征。
在神经网络中,激活函数的作用是能够给神经网络加入一些非线性因素,使得神经网络可以更好地解决较为复杂的问题。在神经网络中也类似,我们需要引入一些非线性的因素,来更好地解决复杂的问题。而激活函数恰好能够帮助我们引入非线性因素,它使得我们的神经网络能够更好地解决较为复杂的问题。
激活函数的主要作用是提供网络的非线性建模能力。在卷积层中,我们主要采用了卷积的方式来处理,也就是对每个像素点赋予一个权值,这个操作显然就是线性的。但是对于我们样本来说,不一定是线性可分的,为了解决这个问题,我们可以进行线性变化,或者我们引入非线性因素,解决线性模型所不能解决的问题。如果没有激活函数,那么该网络仅能够表达线性映射,此时即便有再多的隐藏层,其整个网络跟单层神经网络也是等价的。因此也可以认为,只有加入了激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。
激活函数还可以构建稀疏矩阵,也就是稀疏性,这个特性可以去除数据中的冗余,最大可能保留数据的特征,也就是大多数为0的稀疏矩阵来表示(这个特性主要是对于Relu)
import torch from torch import nn class Inception(nn.Module): #in_planes模块输入的通道数 def __init__(self,in_planes): super().__init__() self.b1 = nn.Conv2d( in_channels=in_planes, out_channels=32, kernel_size=1, ) self.b2 = nn.Sequential( nn.Conv2d( in_channels=in_planes, out_channels=16, kernel_size=1, ), nn.Conv2d( in_channels=16, out_channels=32, kernel_size=3, padding=1 ) ) self.b3 = nn.Sequential( nn.Conv2d( in_channels=in_planes, out_channels=16, kernel_size=1, ), nn.Conv2d( in_channels=16, out_channels=32, kernel_size=5, padding=2, ) ) self.b4 = nn.Sequential( nn.MaxPool2d( kernel_size=3, padding=1, stride=1, ), nn.Conv2d( in_channels=in_planes, #!前面池化不改变通道数 out_channels=32, kernel_size=1, ) ) def forward(self,x): x1 = self.b1(x) x2 = self.b2(x) x3 = self.b3(x) x4 = self.b4(x) #[B,C,H,W] out = torch.cat([x1,x2,x3,x4],dim=1) return out if __name__ == '__main__': x = torch.rand(size=(1,32,56,56)) block = Inception(in_planes=32) out = block(x) print(out.shape) #torch.Size([1,256,56,56]) |
3 结语
针对探究卷积层和激活函数之间的区别这个问题,通过网上资料的查询,得出卷积层就是利用卷积核(也叫滤波器)来提取图像的特征。不同的卷积核可以得到不同的特征。而激活函数的主要作用是提供网络的非线性建模能力和构建稀疏矩阵,在根据课上的讲解深入理解了他们的区别。