卷积的目的在于提取特征,或者说卷积就是提取特征的一种方法
神经网络总体架构: 1. 提取特征 2. 分类 提取特征,层 在CV领域,提取特征的一种方法是 卷积 分类: 全连接 中间会穿插一系列增加模型拟合能力的方法: BN MAXPOOL RULE DROPOUT BN,RULE,DROPOUT在深度学习是通用的,不限于区域处理,这里先谈卷积与MAXPOOL
层 : 分步
是什么是层,AI中的层,CV中的层? 一层指 神经网络中的一次综合计算,比如一次卷积计算就是一层,通常占一行代码的位置 层更侧重分步,这样一个神经网络: 1. 一个卷积 提取特征 2. 一个全连接分类 那个这神经网络就是两层
特征:分类
特征侧重的是分类, 比如一个向量的元素个数是n,处于n个不同的维度上, 重在强调差异性上,所以才是 “特征” 卷积API必不可少的两个参数就是: 输入特征,输出特征 - 输入特征,重在告诉API数据有多少个维度 - 输出特征,要提取出多少维度的特征, 这里,每一个特征,都是所有输入特征综合的一个计算结果, 是全体数据集某种计算方式的一个输出 广义上讲,层也可以用来划分类别,从不同层面描述事物时,其实就是分类, 所以,特征有时也叫特征层 但若提到神经网络的层数时,则指是分步
卷积核
一个像素有[R,G,B]三色,也可以说数据有三层, 卷积核对应也有三层,即,每个数据特征层对应一个卷积核, 每一层上卷积核的参数是随机初始化,之后再学习训练 卷积API要求输入特征数,因为要用这个参数初始化卷积核的层数,
原事物A有m个维度/特征/层,每个维度都对应一个矩阵,也叫特征图M[m1,m2] 每个卷积的输入皆是m*M的数据,是输入原事物所有特征的信息, 通常是所有特征的特征图计算完后,将m个计算结果相加 事物A与一个卷积进行n次计算,每次计算的网络参数都随机初始化, A 与卷积1线性计算一次,得到一个新的特征图M1[m1,m2](卷积通常不改变特征图shape) ... A 与卷积n线性计算一次,得到一个新的特征图Mn[m1,m2](卷积通常不改变特征图shape) 如此,原事物A的m维就转换到了n维 ,其shape由[m,m1,m2] --> [n,m1,m2] 这就是卷积的大致计算过程,在API还不熟悉的情况下,理解到这一步足够用,下面从其他角度再反复描述一下 卷积提取特征 提取的特征越来越多,每个特征图包含的信息越来越纯/少(毕竟总体信息不变,用于表示的量多了,每个量上的信息就会少), 就像线性方程组变换消元一样,在消元的过程中,每一行的(特征)变量在减少,在纯化, 如果有解,最后每一行化为xi=bi的形式,不再是多个特征变量线性混合映射到一个数,比如: x1 = 2 x2 = 5 .... 特征提取,特征提取,如何提取? 就是从多个维度去过滤/计算,一个维度过滤出这个维度的信息,其他维度都不要,最后过滤出来的特征图,信息量小了,但相对较纯 举例 要复制一款药物,说明书上列出七种成份, 你有十个仪器, A仪器用于检测是否含有a成分药物及多少,是否含有其他成分检测不出来 十个仪器检测下来,你检测出了六种,其中五种在说明书上,一种未在说明书上列出 这就是特征提取,逆向提纯一个 复杂事物,得到其 组成结构 (数学理论对应线性回归,回归其基本组成,但要知道,并非所有事物的结构都是线性的,我们只是用线性结构去近似描述一切事物) 接下来是分析问题,找出哪里出了问题 还有一个组成你不知道是啥,说明你的检测能力有限,仪器种类不够, AI中就是模型不够好,有待提升
从一张灰色图片说起
img.shape = [1,1,H,W] 1. 初始化一个shape=[3,3]的参数矩阵w 2. 从[H,W]矩阵的左上角开始,取下[3,3]的一个子矩阵a 3. sum(a*w),按位相乘再相加,得到一个标量b1 4. 从[H,W]矩阵的左上角开始,向左走一步stride=1,取下[3,3]的一个子矩阵a2 5. sum(a*b),按位相乘再相加,得到一个标量b2 6. 重复以上过程,直到走完 (H-3 +1) 步, 此时得到一行数据 7. 向下移到一行,再重复以上过程,直到下移(W-3 +1)行
卷积公式
K 代表要取多少个索引上的元素作为核的一个维度/边长 2P P代表一边补0的个数,但两边都补相同的相数,所以是2P, 通常中左右相等,上下相等, 补完这个2P之后,(L+2P-K)/S 就会是一个整数 怎么就是整数了? 是因为要得到一个整数,然后去找了一个能得到整数结果的P值,输入进行, 然后才得了整数... 步长虽然是一步步走出来的,但逻辑上其实是多少等分的意思, 就是要分成多少份 每一份都是原来全体元素的一个局部,要与相同shape的参数矩阵按位相乘再相加,得到一个数, 这个数是某个视角上新的特征元素,它与原来的shape有位置上的对应关系
import torch from torch import nn from torch.nn import functional as F """以图像为例 2维卷积shape格式: [N,C,H,W] N: batch_size 批量大小,一次处理多少个图像 C:channel 通道,也就是多少层,多少个特征,一张图像最小元素向量,即像素向量的元素个数 H:height 高度 也就是图像有多少行,一行有多少个像素, W:width 宽度 也就是图像有多少列,一列有多少个像素 """ X = torch.randn(32, 3, 256, 256) conv2d = nn.Conv2d(in_channels=3, #输入数据层数/特征数是 3 out_channels=16, #每个卷积核3层,进行16次卷积核运算,得到16个特征 kernel_size=(3, 3), #一个卷积核是一个3*3的方阵 stride=(1, 1), #上下左右一次走一步 padding=(1,1), #上下左右各补1层 bias = True, #使用偏置,默认为true padding_mode='zeros')#补的位置填充0,默认为0
conv2d(X).shape torch.Size([32, 16, 256, 256]) 3 1 1 是一种经典计算,实际上可尝试不同的数值 图像上要表达的核心信息在 中央,这种核的补法/设计,最大程度地保留了中间的信息
2维卷积,卷积核在两个方向/维度上移动,pytorch的2维卷积数据的shape为[N,C,H,W] 1维卷积,卷积核在1个方向/维度上移动,pytorch的1维卷积数据的shape为[N,C,L] 推广到3维,就是,卷积核在3个方向/维度上移动,pytorch的3维卷积数据的shape为[N,C,D,H,W] 3维不常用,这里只说1维
import torch from torch import nn from torch.nn import functional as F
"""1维卷积计算,自然语言处理,信号处理等 数据shape:[N, C, L] N: batch_size 批量个数 C:channel 通道数 L:length 长度 序列的长度 举例:自然语言处理中: N:句子,有多少句话 C:单词,每个单词向量的特征数 L:一个句子的单词个数 """ # 32句话,每个单词128维,一句话10个单词 S = torch.randn(32, 128, 10) conv1d = nn.Conv1d(in_channels=128, out_channels=256, kernel_size=3, stride=1, padding=1)
conv1d(S).shape torch.Size([32, 256, 10])
全连接是一次计算所有参数与所有数据同时计算 卷积每次计算的时候,是一个卷积核的参数与对应的数据进行计算, 单次计算的量比全连接低一个档次,但总体的计算量要高于全连接
局部分块计算的顺序
相比全连接,卷积是一种流式计算,因为一次只计算整体数据的一个局部,
同时,卷积看似有顺序,即将数据分成一个个数据块-子矩阵,然后依然计算, 实则每个子矩阵计算完就是一个数值,最后是这些数值相加, 这意味着 实则无序,这些拆分后的子矩阵之间无顺序上的依赖关系, 先计算哪个分块,后计算哪个分块,结果一样, 比如来回跳着走,最后相加后结果一样, 所以卷积可以并行计算
新旧特征图位置对应关系
但卷积的确有位置对应关系,这种映射关系是指, 原数据shape的某个卷积核计算的位置与新特征图上元素位置一一对应, 比如2维图像上第1个卷积核计算结果必定是新的特征图上左上角的第1个点/数值, 是原特征图局部区域 与 新特征图元素位置的 一一对应关系
只要这种特征图位置对应关系不打乱, 每次按步长移动的计算,可以不按顺序计算,还可以并发计算