关于卷积神经网络的几个问题的记录

 本文为学习卷积网络,以及搭建网络时出现的思路做一些总结:

  1. CNN的原理
  2. 1*1卷积核的用处
  3. Conv1d的作用

 

卷积神经网络(CNN)的原理

原理借用吴恩达老师上课的笔记

首先来看conv2d的一层计算的过程

关于卷积神经网络的几个问题的记录

原图像为6*6*3 首先和一个3*3*3的卷积核做卷积,最终得到的是一个4*4*1的,为什么呢?

首先我们来看他是怎么计算的,将这个3*3*3的方块整个贴在图片上

关于卷积神经网络的几个问题的记录

这时候蓝点所对应的值是整个黄色方块3*3*3 27个参数 与图片第一个3*3*3区域所乘起来的结果求和得到的,所以这里得到一个输出需要做27次乘法以及若干次求和.那么整个结果就是这个立方体在整张图片上滑动后得到的结果,如果现在以1的步长向右边移动,那么最终得到的是  6-3+1=4 所以其边长是4的一张图.

我们把图像记为W*H*C  卷积核记做K*K*C, 注意这里的C一定要相同,不然这个立方体不能覆盖一个区域内的图像的垂直范围,我们说的步长叫做stride记做S,padding记做P,具体原理百度一下.

padding大致的原理是我们从图上来看如果小方块向右移动,移动到一定程度我们发现部分溢出了图片,那么卷积就默认到头了,即这一行的卷积结束,换行继续进行卷积,但是这样边缘的部分信息可能就无法照顾到(因为边缘的信息只有在方块移动到最边上才会被计算一次),为了能在边缘也能多次做卷积提取特征,就在外面不上一条这就是padding.具体可参考

padding视频

得到图像的体积为  W=(W+2*P-K)/S +1   H=(H+2*P-K)/S + 1,假设我们的stride是1那么same padding的意思就是输入输出的图像大小,WH不变那么我们的padding此时应该P=(K-1)/2;

 

那我们知道刚才6*6*3 同3*3*3进行卷积得到的是一张4*4*1的图片

因此一个卷积核(kernel)同图片卷积得到的是一层特征,因此如果添加多个kernel进行卷积就能得到多通道的数据

比如想要out  channel 为10 那么需要10个这样的过滤器进行卷积,就能得到10通道的输出

然后,简单讲一下池化,池化主要是为了进一步缩小得到特征的尺寸,比如这个4*4*1的输出,我们设置池化的kernel为2,那么在每个2*2的区域内最大值(最大池化)被认为是这个2*2内最有特点的值被拿出来作为这个区域的值 或者把平均值(平均池化)拿出来作为这个区域的值,那么我们发现整个区域内的4个数通过一个数来代表,就极大的提取了特征的量.具体可参考

池化的详细解释

1*1的卷积核的作用

1*1的卷积核主要用来减少网络的学习参数

比如刚才的例子而言假设我们使用3*3*3的卷积核然后需要获得10通道的特征,利用same-padding那么我们知道最终获得的是6*6*10的输出每个输出需要训练卷积核的参数为3*3*3所以 最终获得这个输出层需要训练的参数是6*6*10*3*3*3=9720个参数,如果我们直接用1*1*10的进行卷积则需要训练的参数为6*6*10*1*1*3=1080,当然具体的操作一般是通过1*1的卷积核进行降维后再通过3*3*C的卷积核进行升维度,但是从上面的例子可以看到,1*1*C的卷积核能够有效的降维度.

Conv1d的用处

刚才解释了conv2d,conv1d其实和conv2d一样,只不过其数据长宽中有一个是一维度的即可能其数据是W*C,其他过程和CONv2d一样,就可以看成一个白条(kernel)在数据上滑动提取特征,然后不同的过滤器提取出不同的特征进行组合,这里我用pytorch做一个简单的测试

import torch
import torch.nn as nn

m1 = nn.Conv1d(1, 2, 1, stride=1)
m2 = nn.Conv1d(2, 10, 1, stride=1)
input = torch.randn(10, 1, 10)
output = m1(input)

print(input.shape)
print(output.shape)
output = m2(output)
print(output.shape)

最终输出的结果是

torch.Size([10, 1, 10])
torch.Size([10, 2, 10])
torch.Size([10, 10, 10])

可以用于一维数据的特征提取以及NLP中词向量的特征提取

这里的10 是mini-batch size