众所周知,cnn的原理是
cnn的流程,摘自B站 av161751351、卷积核:
在第一步卷积计算的过程中,有一个非常重要的东西叫卷积核,
1.1、名字:
卷积核也叫滤波器,有些文章叫kernel,有些文章叫Filter,甚至有人叫感受野(receptive filed)其实都是一样东西
1.2、是什么:
一个卷积核包含图像的一种特征,做卷积运算实际上说白了就是在计算卷积核上面的特征和图像上面特征的相似度,相似度越高,越认为这图就是拥有此特征。
1.3、卷积核的特点:
卷积核的长度和宽度由超参数(也就是一开始手动设定的)决定,(从VGG有启发,一般来说设置为3*3这种比较小的),深度就必须一定要和数据集的输入深度一致!卷积核能够自学习,因此只要一开始给定kernel size就可以了
这些超参数是怎么确定的呢?可以参考一下
https://yq.aliyun.com/articles/610509
卷积核、滤波器、感受野这里还是要多说一下深度,对于图片来说,深度就是通道,对于输入深度来说,常见的有单通道灰度,三通道RGB,四通道ARGB,而对于输出深度来说,就是一个超参数了,这里有一个规定,输出深度=卷积核的个数,而一个卷积核(也就是一种卷积核)负责提取一个特征,(数量通常为2^n),就目前来看,超参数通过trial-and-error(试错)来确认,没有捷径。
2、初始化卷积层:
对于图像的二维卷积,pytorch有这个函数:
torch.nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True,padding_mode='zeros')
--in_channels => 输入图像的通道数(矩阵深度)
--out_channels => 输出卷积后的深度(Feature Map的个数,也就是在卷积计算过程中卷积核的个数,也就是希望提取特征的个数)
--kernel_size => 卷积核的大小(如果只有一个数字,则认为是正方形的,也可以用一个tuple来设定形状,形状一般为奇数*奇数,偶数*偶数会导致feature map大小不一致)
--stride => 卷积步长(每一次卷积计算完成之后,平移多少个像素)
--padding => padding的层数(当padding_mode='zero'的时候,padding操作就是补零操作,要使feature map的大小与原图大小一致,则padding=1)
--dilation => 卷积核元素之间的间距
dilation=1的时候--groups => 从输入通道到输出通道的阻塞连接数(即输入和输出之间的连接)
group=1,输出是所有的输入的卷积;
group=2,此时相当于有并排的两个卷积层,每个卷积层计算输入通道的一半,并且产生的输出是输出通道的一半,随后将这两个输出连接起来
groups = in_channels,每个输入通道都具有自己的一组过滤器,大小为
--bias => 偏置 (是否在结果中加入一个能自学习的偏置量)
3、开始卷积运算
3.1、卷积运算的过程(其实不用理会也可以,这里列出来只是好理解一点)
①、卷积核翻转180°
②、把卷积核中心对准像素x
③、对应元素相乘
④、相乘之后的值求均值(也就是每个值相加,并除以卷积核的元素个数),没有元素的地方补零(padding)
⑤、把加起来的值放到一边
⑥、平移卷积核,继续计算其他卷积
⑦、把所有计算之后的值放到一个矩阵里面,这个矩阵就叫做Feature Map
3.2、输入张量
Conv2d的输入是(,,,)
=> batch_size
=> 输入图像通道数量
=> 输入图像的高度
=> 输入图像的宽度
Conv2d的输出是(,, , )
输出的公式为: 其中为感受野()
4、激活(CV中通常使用ReLU)
ReLU:这个没啥好说的,把上面卷积之后的结果是负数的全部抹零(不激活),>=0的不变
如果ReLU失效的情况下,考虑使用Leaky ReLU或者Maxout,此时一般情况都可以解决。
Tanh函数在文本和音频处理有比较好的效果。
torch.nn.ReLU(inplace=False)
--inplace 是否覆盖原变量 (要是不覆盖,就要多一个内存空间来储存计算后的变量,覆盖了就不用,可以节省一点内存)
5、池化(Pooling)(也叫下采样,向下采样,让图片变模糊)
5.1、池化是什么
在不损失图像该有的信息的情况下,缩小图像,从而达到减少参数、加快收敛速度的目的
5.2、为什么池化
单通道图像中,一个像素点有一个权重(weight),三通道图像一个像素点就有3个权重。比如说一张128*128*1的图像中,一共有128*128=29184个权重,当经过2*2的池化层处理之后,图像变成64*64,此时的权重个数变成4096,参数量大大减少。
5.3、怎么样池化
池化有两种池化方式:
最大值池化(MaxPooling)(常用) (常用的原因:因为卷积的结果是与原图的相似度,那几个相似度中取最大那个,到最后判断的时候就容易很多了)
均值池化(AveragePooling)
池化原理:
最大值池化原理对于二维最大值池化,pytorch中有:
torch.nn.MaxPool2d(kernel_size,stride=None,padding=0,dilation=1,return_indices=False,ceil_mode=False)
--kernel_size => 池化核的大小, 和卷积核大小的设定一样,int为正方形,tuple为自定义大小(池化核越大,损失的信息越多)
--stride => 步长,(默认值为kernel_size,也就是相邻)
--padding => padding层数 (基本上很少用)
--dilation => 池化核元素直接的间距
--return_indices => 如果为True,则将返回最大索引以及输出。以后对torch.nn.MaxUnpool2d有用
--ceil_mode => 为True时,将使用ceil(向上取整)而不是floor(向下取整)来计算输出形状
5.4、对于输出大小的计算:
与卷积核的计算一样,边长基本上变成 ,比如(2,2),图像长度就边长原理的
6、最后阶段
6.1、全连接层(现在都9102年了!早就不用全连接了!这里是为了尊敬一下前辈们,介绍一下)
全连接就是逻辑回归,也就是分类器!不分类怎么知道这个是什么类别?
torch.nn.Linear(in_features,out_features,bias=True)
--in_features => 输入的网络神经元个数(也就是features的个数,也就是滤波器的个数)
--out_features => 输出的网络神经元个数,就是通过线性模型之后,剩下多少个freature
--bias => 偏置量
6.2、全卷积网络(FCN)
顾名思义,就是在最后阶段用卷积进行输出
全连接使用的是图像的全局信息,卷积使用的是局部信息,可是最大的局部就是全局呀!
全卷积网络由论文 Fully Convolutional Networks for Semantic Segmentation 提出
网友评论