CNN中术语解释
CNN网络的主要参数有下面这么几个:
卷积输出大小计算
1、图片经卷积 Conv2D 后输出大小计算公式如下: N = (W − F + 2P )/S+1
输出通道数 = 卷积核/池化核数量
2、反卷积 Conv2DTranspose 得到的图片大小计算方式: 反卷积的大小是由卷积核大小与滑动步长决定, in是输入大小, k是卷积核大小, s是滑动步长, padding的像素数 P, out是输出大小。 得到 out = (in - 1) s -2p + k,还有另外一个写法:W = (N - 1)S - 2P + F。
例如 输入:2x2, 卷积核:4x4, 滑动步长:3,填充像素为0, 输出:7x7 ,其计算过程就是, (2 - 1) * 3 + 4 = 7
3、池化得到的特征图大小计算方式: N=(W-F)/S+1,池化层一般不填充像素(VALID)
卷积向下取整,池化向上取整。卷积层一般填充像素(SAME),池化层一般不填充像素(VALID)?注意:stride为1的时候,当kernel为 3 padding为1或者kernel为5 padding为2,这种情况可直接得出卷积前后尺寸不变。
参考资料
分类问题中,直接使用输出层的输出有两个问题:
softmax回归解决了以上两个问题,它将输出值变换为值为正且和为1的概率分布,公式如下:
softmax(y)i=yi′=eyi∑nj=1eyjsoftmax(y)i=yi′=eyi∑j=1neyj
交叉熵刻画了两个概率分布之间的距离,它是分类问题中使用比较广泛的一种损失函数,交叉熵一般会与softmax回归一起使用,公式如下:
$$L = -\sum{c=1}^{M}y{c}log(p_{c})或者H(p,q)=-\sum p(x)logq(x)$$(p代表正确答案,q代表预测值)
从数学上来理解就是,为了让学到的模型分布更接近真实数据的分布,我们需要最小化模型数据分布与训练数据之间的 KL 散度,而因为训练数据的分布是固定的,因此最小化 KL 散度等价于最小化交叉熵,而且交叉熵计算更简单,所以机器/深度学习中常用交叉熵 cross-entroy 作为分类问题的损失函数。
Adam、AdaGrad、RMSProp优化算法具有自适应性
后一层神经元在前一层神经元的感受空间,也可以定义为卷积神经网络中每层的特征图(Feature Map)上的像素点在原始图像中映射的区域大小,即如下图所示: 感受野大小
注意:感受野在 CNN 中是呈指数级增加的。小卷积核(如33)通过多层叠加可取得与大卷积核(如77)同等规模的感受野,此外采用小卷积核有两个优势:
1、小卷积核需多层叠加,加深了网络深度进而增强了网络容量(model capacity)和复杂度(model complexity)
2、增强了网络容量的同时减少了参数个数。
感受野大小计算
计算感受野时,我们需要知道:
参考感受野(receptive file)计算
感受野大小的计算采用 top to down 的方式, 即先计算最深层在前一层上的感受野,然后逐渐传递到第一层,使用的公式可以表示如下: $$RF = ((RF-1)*stride + fsize
for layer in (top layer To down layer):
RF = ((RF - 1)* stride) + fsize
以下 Python 代码可以实现计算 Alexnet zf-5 和 VGG16 网络每层输出 feature map 的感受野大小,卷积核大小和输入图像尺寸默认定义好了,代码如下:
#!/usr/bin/env python
# [filter size, stride, padding]
net_struct = {'alexnet': {'net':[[11,4,0],[3,2,0],[5,1,2],[3,2,0],[3,1,1],[3,1,1],[3,1,1],[3,2,0]],
'name':['conv1','pool1','conv2','pool2','conv3','conv4','conv5','pool5']},
'vgg16': {'net':[[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1],
[2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0],[3,1,1],[3,1,1],[3,1,1],[2,2,0]],
'name':['conv1_1','conv1_2','pool1','conv2_1','conv2_2','pool2','conv3_1','conv3_2',
'conv3_3', 'pool3','conv4_1','conv4_2','conv4_3','pool4','conv5_1','conv5_2','conv5_3','pool5']},
'zf-5':{'net': [[7,2,3],[3,2,1],[5,2,2],[3,2,1],[3,1,1],[3,1,1],[3,1,1]],
'name': ['conv1','pool1','conv2','pool2','conv3','conv4','conv5']}}
def outFromIn(isz, net, layernum):
totstride = 1
insize = isz
for layer in range(layernum):
fsize, stride, pad = net[layer]
outsize = (insize - fsize + 2*pad) / stride + 1
insize = outsize
totstride = totstride * stride
return outsize, totstride
def inFromOut(net, layernum):
RF = 1
for layer in reversed(range(layernum)):
fsize, stride, pad = net[layer]
RF = ((RF -1)* stride) + fsize
return RF
if __name__ == '__main__':
imsize = 224
print "layer output sizes given image = %dx%d" % (imsize, imsize)
for net in net_struct.keys():
print '************net structrue name is %s**************'% net
for i in range(len(net_struct[net]['net'])):
p = outFromIn(imsize,net_struct[net]['net'], i+1)
rf = inFromOut(net_struct[net]['net'], i+1)
print "Layer Name = %s, Output size = %3d, Stride = % 3d, RF size = %3d" % (net_struct[net]['name'][i], p[0], p[1], rf)
输出结果如下:
layer output sizes given image = 224x224
************net structrue name is vgg16**************
Layer Name = conv1_1, Output size = 224, Stride = 1, RF size = 3
Layer Name = conv1_2, Output size = 224, Stride = 1, RF size = 5
Layer Name = pool1, Output size = 112, Stride = 2, RF size = 6
Layer Name = conv2_1, Output size = 112, Stride = 2, RF size = 10
Layer Name = conv2_2, Output size = 112, Stride = 2, RF size = 14
Layer Name = pool2, Output size = 56, Stride = 4, RF size = 16
Layer Name = conv3_1, Output size = 56, Stride = 4, RF size = 24
Layer Name = conv3_2, Output size = 56, Stride = 4, RF size = 32
Layer Name = conv3_3, Output size = 56, Stride = 4, RF size = 40
Layer Name = pool3, Output size = 28, Stride = 8, RF size = 44
Layer Name = conv4_1, Output size = 28, Stride = 8, RF size = 60
Layer Name = conv4_2, Output size = 28, Stride = 8, RF size = 76
Layer Name = conv4_3, Output size = 28, Stride = 8, RF size = 92
Layer Name = pool4, Output size = 14, Stride = 16, RF size = 100
Layer Name = conv5_1, Output size = 14, Stride = 16, RF size = 132
Layer Name = conv5_2, Output size = 14, Stride = 16, RF size = 164
Layer Name = conv5_3, Output size = 14, Stride = 16, RF size = 196
Layer Name = pool5, Output size = 7, Stride = 32, RF size = 212
************net structrue name is zf-5**************
Layer Name = conv1, Output size = 112, Stride = 2, RF size = 7
Layer Name = pool1, Output size = 56, Stride = 4, RF size = 11
Layer Name = conv2, Output size = 28, Stride = 8, RF size = 27
Layer Name = pool2, Output size = 14, Stride = 16, RF size = 43
Layer Name = conv3, Output size = 14, Stride = 16, RF size = 75
Layer Name = conv4, Output size = 14, Stride = 16, RF size = 107
Layer Name = conv5, Output size = 14, Stride = 16, RF size = 139
************net structrue name is alexnet**************
Layer Name = conv1, Output size = 54, Stride = 4, RF size = 11
Layer Name = pool1, Output size = 26, Stride = 8, RF size = 19
Layer Name = conv2, Output size = 26, Stride = 8, RF size = 51
Layer Name = pool2, Output size = 12, Stride = 16, RF size = 67
Layer Name = conv3, Output size = 12, Stride = 16, RF size = 99
Layer Name = conv4, Output size = 12, Stride = 16, RF size = 131
Layer Name = conv5, Output size = 12, Stride = 16, RF size = 163
Layer Name = pool5, Output size = 5, Stride = 32, RF size = 195
首先权值共享就是滤波器共享,滤波器的参数是固定的,即是用相同的滤波器去扫一遍图像,提取一次特征特征,得到feature map。在卷积网络中,学好了一个滤波器,就相当于掌握了一种特征,这个滤波器在图像中滑动,进行特征提取,然后所有进行这样操作的区域都会被采集到这种特征,就好比上面的水平线。
局部连接,权值共享,池化操作,多层次结构。
1、增加特征平移不变性。汇合可以提高网络对微小位移的容忍能力。
2、减小特征图大小。汇合层对空间局部区域进行下采样,使下一层需要的参数量和计算量减少,并降低过拟合风险。
3、最大汇合可以带来非线性。这是目前最大汇合更常用的原因之一。
Reference
(二)计算机视觉四大基本任务(分类、定位、检测、分割
卷积操作可获取图像区域不同类型特征,而汇合等操作可对这些特征进行融合和抽象,随着若干卷积、汇合等操作的堆叠,各层得到的深度特征逐渐从泛化特征(如边缘、纹理等)过渡到高层语义表示(躯干、头部等模式)。
首先所谓过拟合,指的是一个模型过于复杂之后,它可以很好地“记忆”每一个训练数据中随机噪音的部分而忘记了去“训练”数据中的通用趋势。 过拟合具体表现在:模型在训练数据上损失函数较小,预测准确率较高;但是在测试数据上损失函数比较大,预测准确率较低。解决办法如下:
L1 范数(L1 norm)是指向量中各个元素绝对值之和,也有个美称叫“稀疏规则算子”(Lasso regularization)。 比如 向量 A=[1,-1,3], 那么 A 的 L1 范数为 |1|+|-1|+|3|。简单总结一下就是:
在支持向量机学习过程中,L1 范数实际是一种对于成本函数求解最优的过程,因此,L1 范数正则化通过向成本函数中添加 L1 范数,使得学习得到的结果满足稀疏化,从而方便人类提取特征。
L1 范数可以使权值参数稀疏,方便特征提取。 L2 范数可以防止过拟合,提升模型的泛化能力。
Tensorflow 是一个通过计算图的形式来表述计算的编程系统,计算图也叫数据流图,可以把计算图看做是一种有向图,Tensorflow 中的每一个计算都是计算图上的一个节点,而节点之间的边描述了计算之间的依赖关系。
1、 可以使用更高的学习率。如果每层的scale不一致,实际上每层需要的学习率是不一样的,同一层不同维度的scale往往也需要不同大小的学习率,通常需要使用最小的那个学习率才能保证损失函数有效下降,Batch Normalization将每层、每维的scale保持一致,那么我们就可以直接使用较高的学习率进行优化。
2、 移除或使用较低的dropout。 dropout是常用的防止overfitting的方法,而导致overfit的位置往往在数据边界处,如果初始化权重就已经落在数据内部,overfit现象就可以得到一定的缓解。论文中最后的模型分别使用10%、5%和0%的dropout训练模型,与之前的40%-50%相比,可以大大提高训练速度。
3、 降低L2权重衰减系数。 还是一样的问题,边界处的局部最优往往有几维的权重(斜率)较大,使用L2衰减可以缓解这一问题,现在用了Batch Normalization,就可以把这个值降低了,论文中降低为原来的5倍。
4、取消Local Response Normalization层。 由于使用了一种Normalization,再使用LRN就显得没那么必要了。而且LRN实际上也没那么work。
5、Batch Normalization调整了数据的分布,不考虑激活函数,它让每一层的输出归一化到了均值为0方差为1的分布,这保证了梯度的有效性,可以解决反向传播过程中的梯度问题。目前大部分资料都这样解释,比如BN的原始论文认为的缓解了Internal Covariate Shift(ICS)问题。
在反向传播过程中需要对激活han函数进行求导,如果导数大于1,那么随着网络层数的增加,梯度更新将会朝着指数爆炸的方式增加这就是梯度爆炸。同样如果导数小于1,那么随着网络层数的增加梯度更新信息会朝着指数衰减的方式减少这就是梯度消失。
出现梯度消失和梯度爆炸的问题主要是因为参数初始化不当以及激活函数选择不当造成的。其根本原因在于反向传播训练法则,属于先天不足。当训练较多层数的模型时,一般会出现梯度消失问题(gradient vanishing problem)和梯度爆炸问题(gradient exploding problem)。注意在反向传播中,当网络模型层数较多时,梯度消失和梯度爆炸是不可避免的。
深度神经网络中的梯度不稳定性,根本原因在于前面层上的梯度是来自于后面层上梯度的乘积。当存在过多的层次时,就出现了内在本质上的不稳定场景。前面的层比后面的层梯度变化更小,故变化更慢,故引起了梯度消失问题。前面层比后面层梯度变化更快,故引起梯度爆炸问题。
解决梯度消失和梯度爆炸问题,常用的有以下几个方案:
循环神经网络(recurrent neural network, RNN), 主要应用在语音识别、语言模型、机器翻译以及时序分析等问题上。 在经典应用中,卷积神经网络在不同的空间位置共享参数,循环神经网络是在不同的时间位置共享参数,从而能够使用有限的参数处理任意长度的序列。 RNN可以看做作是同一神经网络结构在时间序列上被复制多次的结果,这个被复制多次的结构称为循环体,如何设计循环体的网络结构是RNN解决实际问题的关键。 RNN的输入有两个部分,一部分为上一时刻的状态,另一部分为当前时刻的输入样本。
不一定。导致模型不收敛的原因有很多种可能,常见的有以下几种:
1、减少网络层参数。用两个33卷积比用1个55卷积拥有更少的参数量,只有后者的2∗3∗3/5∗5=0.72。但是起到的效果是一样的,两个33的卷积层串联相当于一个55的卷积层,感受野的大小都是5×5,即1个像素会跟周围5*5的像素产生关联。把下图当成动态图看,很容易看到两个3×3卷积层堆叠(没有空间池化)有5×5的有效感受野。
2、更多的非线性变换。2个33卷积层拥有比1个55卷积层更多的非线性变换(前者可以使用两次ReLU激活函数,而后者只有一次),使得卷积神经网络对特征的学习能力更强。
paper中给出的相关解释:三个这样的层具有7×7的有效感受野。那么我们获得了什么?例如通过使用三个3×3卷积层的堆叠来替换单个7×7层。首先,我们结合了三个非线性修正层,而不是单一的,这使得决策函数更具判别性。其次,我们减少参数的数量:假设三层3×3卷积堆叠的输入和输出有C个通道,堆叠卷积层的参数为3×(3×3C) = 27C 个权重;同时,单个7×7卷积层将需要7×7×C = 49C 个参数,即参数多81%。这可以看作是对7×7卷积滤波器进行正则化,迫使它们通过3×3滤波器(在它们之间注入非线性)进行分解。
此回答可以参考TensorFlow实战p110,网上很多回答都说的不全。
Sigmoid函数公式如下: σ(x)=11+exp(−x)σ(x)=11+exp(−x)
relu函数方程 ReLU 的输出要么是 0, 要么是输入本身。虽然方程简单,但实际上效果更好。在网上看了很多版本的解释,有从程序实例分析也有从数学上分析,我找了个相对比较直白的回答,如下:
1、ReLU函数计算简单,可以减少很多计算量。反向传播求误差梯度时,涉及除法,计算量相对较大,采用ReLU激活函数,可以节省很多计算量;
2、避免梯度消失问题。对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失问题(在sigmoid接近饱和区时,变换太缓慢,导数趋于0,这种情况会造成信息丢失),从而无法完成深层网络的训练。
3、可以缓解过拟合问题的发生。Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。
4、相比sigmoid型函数,ReLU函数有助于随机梯度下降方法收敛。
参考链接
ReLU为什么比Sigmoid效果好
权值(权重)共享这个词是由LeNet5模型提出来的。以CNN为例,在对一张图偏进行卷积的过程中,使用的是同一个卷积核的参数。 比如一个3×3×1的卷积核,这个卷积核内9个的参数被整张图共享,而不会因为图像内位置的不同而改变卷积核内的权系数。说的再直白一些,就是用一个卷积核不改变其内权系数的情况下卷积处理整张图片(当然CNN中每一层不会只有一个卷积核的,这样说只是为了方便解释而已)。
参考资料
如何理解CNN中的权值共享
使用预训练模型的好处,在于利用训练好的SOTA模型权重去做特征提取,可以节省我们训练模型和调参的时间。
至于为什么只微调最后几层神经网络权重,是因为:
1、CNN中更靠近底部的层(定义模型时先添加到模型中的层)编码的是更加通用的可复用特征,而更靠近顶部的层(最后添加到模型中的层)编码的是更专业业化的特征。微调这些更专业化的特征更加有用,它更代表了新数据集上的有用特征。 (2). 2、训练的参数越多,过拟合的风险越大。很多SOTA模型拥有超过千万的参数,在一个不大的数据集上训练这么多参数是有过拟合风险的,除非你的数据集像Imagenet那样大。
参考资料
Python深度学习p127.
dropout具体工作流程
以标准神经网络为例,正常的流程是:我们首先把输入数据x通过网络前向传播,然后把误差反向传播一决定如何更新参数让网络进行学习。使用dropout之后,过程变成如下:
1、首先随机(临时)删掉网络中一半的隐藏神经元,输入输出神经元保持不变(图3中虚线为部分临时被删除的神经元); 2、然后把输入x通过修改后的网络进行前向传播计算,然后把得到的损失结果通过修改的网络反向传播。一小批训练样本执行完这个过程后,在没有被删除的神经元上按照随机梯度下降法更新对应的参数(w,b);3、然后重复这一过程:
dropout在神经网络中的应用
1、在训练模型阶段
不可避免的,在训练网络中的每个单元都要添加一道概率流程,标准网络和带有dropout网络的比较图如下所示:
2、在测试模型阶段
预测模型的时候,输入是当前输入,每个神经单元的权重参数要乘以概率p。
如何选择dropout 的概率
input 的dropout概率推荐是0.8, hidden layer 推荐是0.5, 但是也可以在一定的区间上取值。(All dropout nets use p = 0.5 for hidden units and p = 0.8 for input units.)
参考资料
1、[Dropout:A Simple Way to Prevent Neural Networks from Overfitting]
2、深度学习中Dropout原理解析
方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。它通过计算和统计图像局部区域的梯度方向直方图来构成特征。在深度学习取得成功之前,Hog特征结合SVM分类器被广泛应用于图像识别中,在行人检测中获得了较大的成功。
HOG特征原理
HOG的核心思想是所检测的局部物体外形能够被光强梯度或边缘方向的分布所描述。通过将整幅图像分割成小的连接区域(称为cells),每个cell生成一个方向梯度直方图或者cell中pixel的边缘方向,这些直方图的组合可表示出(所检测目标的目标)描述子。为改善准确率,局部直方图可以通过计算图像中一个较大区域(称为block)的光强作为measure被对比标准化,然后用这个值(measure)归一化这个block中的所有cells。这个归一化过程完成了更好的照射/阴影不变性。 与其他描述子相比,HOG得到的描述子保持了几何和光学转化不变性(除非物体方向改变)。因此HOG描述子尤其适合人的检测。
HOG特征提取方法就是将一个image:
1、灰度化(将图像看做一个x,y,z(灰度)的三维图像)
2、划分成小cells(2*2)
3、计算每个cell中每个pixel的gradient(即orientation)
4、统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的descriptor。
HOG特征检测步骤
颜色空间归一化——–>梯度计算————->梯度方向直方图———->重叠块直方图归一化———–>HOG特征
参考资料
HOG特征检测-简述
知名的有TensorFlow Lite、小米MACE、腾讯的ncnn等,目前都没有用过。
和防止模型过拟合的方法类似,另外还有模型融合方法。
最后的“scale and shift”操作则是为了让因训练所需而“刻意”加入的BN能够有可能还原最初的输入。不加也可以。
激活函数实现去线性化。神经元的结构的输出为所有输入的加权和,这导致神经网络是一个线性模型。如果将每一个神经元(也就是神经网络的节点)的输出通过一个非线性函数,那么整个神经网络的模型也就不再是线性的了,这个非线性函数就是激活函数。 常见的激活函数有:ReLU函数、sigmoid函数、tanh函数。
1、卷积层有参数,池化层没有参数
2、经过卷积层节点矩阵深度会改变,池化层不会改变节点矩阵的深度,但是它可以缩小节点矩阵的大小
假设输入层矩阵维度是96963,第一层卷积层使用尺寸为55、深度为16的过滤器(卷积核尺寸为55、卷积核数量为16),那么这层卷积层的参数个数为553*16+16=1216个,公式总结如下:卷积层参数量=(filter size 前一层特征图的通道数 ) 当前层filter数量 + 当前层filter数量
卷积中的特征图大小计算方式有两种,分别是‘VALID’和‘SAME’,卷积和池化都适用,除不尽的结果都向下取整。公式:O = (W-F+2P)/S+1,输入图片(Input)大小为I=WW,卷积核(Filter)大小为FF,步长(stride)为S,填充(Padding)的像素数为P。
判断一个输出向量和期望的向量有多接近,交叉熵(cross entroy)是常用的评判方法之一。交叉熵刻画了两个概率分布之间的距离,是分类问题中使用比较广泛的一种损失函数。 给定两个概率分布p和q,通过q来表示p的交叉熵公式为: H(p,q)=−∑p(x)logq(x)
softmax公式写一下:
softmax(y){i} = \frac{e^{yi}}{\sum{j=1}^{n}e^{yj}} softmax公式
准确率、召回率、F1
混淆矩阵:
查准率(准确率)P = TP/(TP+FP) 查全率(召回率)R = TP/(TP+FN) 准确率描述了模型有多准,即在预测为正例的结果中,有多少是真正例;召回率则描述了模型有多全,即在为真的样本中,有多少被我们的模型预测为正例。 以查准率P为纵轴、查全率R为横轴作图,就得到了查准率-查全率曲线,简称”P-R“曲线,显示改该曲线的图称为”P-R“图。 查准率、查全率性能的性能度量,除了”平衡点“(BEP),更为常用的是F1度量: *$$F1 = \frac{2PR}{P+R} = \frac{2TP}{样例总数+TP-TN}$$**
F1度量的一般形式:$F{\beta},能让我们表达出对查准率/查全率的偏见,公式如下:,能让我们表达出对查准率/查全率的偏见,公式如下:$F{\beta} = \frac{1+\beta ^{2}PR}{(\beta ^{2}*P)+R}$$ β>1β>1对查全率有更大影响,β<1β<1对查准率有更大影响。
不同的计算机视觉问题,对两类错误有不同的偏好,常常在某一类错误不多于一定阈值的情况下,努力减少另一类错误。在目标检测中,mAP(mean Average Precision)作为一个统一的指标将这两种错误兼顾考虑。
map指标解释
具体来说就是,在目标检测中,对于每张图片检测模型会输出多个预测框(远超真实框的个数),我们使用IoU(Intersection Over Union,交并比)来标记预测框是否预测准确。标记完成后,随着预测框的增多,查全率R总会上升,在不同查全率R水平下对准确率P做平均,即得到AP,最后再对所有类别按其所占比例做平均,即得到mAP指标。
交并比IOU
交并比(Intersection-over-Union,IoU),目标检测中使用的一个概念,是产生的候选框(candidate bound)与原标记框(ground truth bound)的交叠率,即它们的交集与并集的比值。最理想情况是完全重叠,即比值为1。 计算公式如下:
代码实现如下:
# candidateBound = [x1, y1, x2, y2]
def calculateIoU(candidateBound, groundTruthBound):
cx1 = candidateBound[0]
cy1 = candidateBound[1]
cx2 = candidateBound[2]
cy2 = candidateBound[3]
gx1 = groundTruthBound[0]
gy1 = groundTruthBound[1]
gx2 = groundTruthBound[2]
gy2 = groundTruthBound[3]
carea = (cx2 - cx1) * (cy2 - cy1) #C的面积
garea = (gx2 - gx1) * (gy2 - gy1) #G的面积
x1 = max(cx1, gx1)
y1 = min(cy1, gy1) # 原点为(0, 0),所以这里是min不是max
x2 = min(cx2, gx2)
y2 = max(cy2, gy2)
w = max(0, (x2 - x1))
h = max(0, (y2 - y1))
area = w * h #C∩G的面积
iou = area / (carea + garea - area)
return iou
常用数据增强方法:
数据增强分两类,一类是离线增强,一类是在线增强:
1、离线增强 : 直接对数据集进行处理,数据的数目会变成增强因子 x 原数据集的数目 ,这种方法常常用于数据集很小的时候
2、在线增强 : 这种增强的方法用于,获得 batch 数据之后,然后对这个batch的数据进行增强,如旋转、平移、翻折等相应的变化,由于有些数据集不能接受线性级别的增长,这种方法长用于大的数据集,很多机器学习框架已经支持了这种数据增强方式,并且可以使用GPU优化计算。
为了使得最后面的两个全连接层能够共享 conv layers(VGG) 权重。在所有的 RoIs 都被 pooling 成(512×7×7)的feature map后,将它 reshape 成一个一维的向量,就可以利用 VGG16 的预训练的权重来初始化前两层全连接。
faster rcnn将roi pooling替换为roi align效果有所提升
ROI Pooling原理
RPN 生成的 ROI 区域大小是对应与输入图像大小(每个roi区域大小各不相同),为了能够共享权重,所以需要将这些 ROI 映射回特征图上,并固定大小。ROI Pooling 具体操作如下:
RoIPooling、RoIAlign笔记
1、Conv layers 使用的是 VGG16,feat_stride=32(即表示,经过网络层后图片缩小为原图的1/32),原图800800,最后一层特征图feature map大小:2525
2、假定原图中有一 region proposal,大小为665665,这样,映射到特征图中的大小:665/32=20.78,即20.7820.78,源码中,在计算的时候会进行取整操作,于是,进行所谓的第一次量化,即映射的特征图大小为2020
3、假定pooled_w=7,pooled_h=7,即 pooling 后固定成77大小的特征图,所以,将上面在 feature map上映射的2020的 region proposal划分成 49个同等大小的小区域,每个小区域的大小20/7=2.86,即2.862.86
4、假定采样点数为4,即表示,对于每个 2.97*2.97 的小区域,平分四份,每一份取其中心点位置,而中心点位置的像素,采用双线性插值法进行计算,这样,就会得到四个点的像素值,如下图:
上图中,四个红色叉叉‘×’的像素值是通过双线性插值算法计算得到的.最后,取四个像素值中最大值作为这个小区域(即:2.972.97大小的区域)的像素值,如此类推,同样是49个小区域得到49个像素值,组成77大小的feature map
总结:知道了 RoiPooling 和 RoiAlign 实现原理,在以后的项目中可以根据实际情况进行方案的选择;对于检测图片中大目标物体时,两种方案的差别不大,而如果是图片中有较多小目标物体需要检测,则优先选择RoiAlign,更精准些
参考你真的学会RoI Pooling了吗?,自己的理解稍后补充。
参考机器学习必刷题-手撕推导篇(2):BP算法推导
参考卷积神经网络(CNN)反向传播算法
1.深度学习中的数据增强
《Batch Normalization Accelerating Deep Network Training by Reducing Internal Covariate Shift》阅读笔记与实现
深度学习中 Batch Normalization为什么效果好
详解机器学习中的梯度消失、爆炸原因及其解决方法