1. 卷积的概念
局部感知、权值共享、多核卷积
2. 感受野的概念
在卷积神经网络中,感受野的定义是 卷积神经网络每一层输出的特征图(feature map)上的像素点在原始图像上映射的区域大小。
RCNN论文中有一段描述,Alexnet网络pool5输出的特征图上的像素在输入图像上有很大的感受野(have very large receptive fields (195 × 195 pixels))和步长(strides (32×32 pixels) ), 这两个变量的数值是如何得出的呢?
2.1 感受野大小的计算方法
感受野计算时有下面的几个情况需要说明:
- 第一层卷积层的输出特征图像素的感受野的大小等于滤波器的大小
- 深层卷积层的感受野大小和它之前所有层的滤波器大小和步长有关系
- 计算感受野大小时,忽略了图像边缘的影响,即不考虑padding的大小,关于这个疑惑大家可以阅读一下参考文章2的解答进行理解
这里的每一个卷积层还有一个strides的概念,这个strides是之前所有层stride的乘积,即strides(i) = stride(1) * stride(2) * ...* stride(i-1)。
关于感受野大小的计算采用top to down的方式, 即先计算最深层在前一层上的感受野,然后逐渐传递到第一层,使用的公式可以表示如下:
其中stride 表示卷积的步长; fsize表示卷积层滤波器的大小。
用python实现了计算Alexnet zf-5和VGG16网络每层输出feature map的感受野大小,实现代码:
#!/usr/bin/env python
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']}}
imsize = 224
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__':
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)
执行结果图:
参考资料
- http://stackoverflow.com/questions/35582521/how-to-calculate-receptive-field-size
- http://stackoverflow.com/questions/37136829/receptive-fields-on-convnets-receptive-field-size-confusion/37143998#37143998
- CNN感受野的计算
- Convolutional Feature Maps: Elements of Efficient (and Accurate) CNN-based Object Detection
- Spatial Pyramid Pooling in Deep ConvolutionalNetworks for Visual Recognition
6. http://blog.cvmarcher.com/posts/2015/05/17/cnn-trick/
3. Cross-Entropy Loss 定义与意义
在分类问题的应用中,模型输入数据并将其映射到指定类别上的概率分布,比如输入一张图片Img(假设图中是狗),模型最后输出一个分布y_pre=(0.5,0.3,0.2)分别表示这张图中的内容是(狗,猫,杯子)的可能性。通过逐步调整模型参数,模型的预测结果越来越接近理想值(1.0,0.,0.),这就是分类的基本方法。
问题在于,人可以通过肉眼判断预测值和真实值的相似性直接判定模型的优劣,这还只是在寡类预测中,超多类预测中类别细分到1000+个,肉眼将很难直接判断那个模型预测效果更好。那么怎么通过数学的方法来判断模型性能以便于模型分析和调参呢?相对熵 ,也称信息散度、KL散度,可表征两个分布之间的相似性,能用于上述需求。
3.1 什么是熵(Entropy)
在热力学中,熵是中表征物质状态的参量之一,用符号S表示,其物理意义是体系混乱程度的度量。
在信息论中,熵称为信息熵更加贴切,它代表随机变量不确定度的度量。举例来说,假设有某信源向外播报,一次发送一个字符,我们将下一次将播报的字符视为随机变量X且X取[a,b,c,d,e]中的一个,可想而知X取值的概率越确定(例如p=[1,0,0,0,0]
意为X=a,且永远只可能取X=a)X不确定性就越小,系统的熵值就越小。反之,X的取值概率为p=[1/5,1/5,1/5,1/5,1/5]
那么X的取[a,b,c,d,e]是等可能性的,X的不确定性最大,熵值也是最大。信息熵还在不等长编码中代表着传输信息所需要的平均最小【比特数/实体】。随机变量熵的计算公式如下:
p(x_i)
表示X为第i个候选实例x_i
的概率。
3.2 交叉熵(Cross Entropy)
交叉熵定义:对一随机事件X
,其真实概率分布为p(X)
,从数据中得到的概率分布为q(X)
,则我们定义,交叉熵为
交叉熵表征的是使用观察分布
q(X)
来编码真实分布p(X)
的数据所需要的比特数,也可以说是使用观察分布q(X)
来编码真实分布p(X)
的数据时为了消歧所需付出的代价或努力。交叉熵始终不小于信息熵,只有观察分布q(X)
和真实分布p(X)
相等时交叉熵才等于信息熵,即H(p,q)=H(p) 当且仅当p=q,意为使用观察分布q(X)
来编码真实分布p(X)
的数据我们需要付出更多的代价才行,证明可参见相对熵的非负性证明。
3.3 相对熵
相对熵又称信息散度、信息增益或KL散度(Kullback–Leibler divergence)。相对熵是两个概率分布p(X)
和q(X)
差别的非对称性的度量;从信息论的角度来看相对熵描述的是基于观察分布q(X)
来编码来自真实分布p(X)
的样本时平均所需的额外比特数/样本。相对熵的定义如下:
展开来看即:
相对熵不具有对称性,但有非负性,即:
相对熵非负性证明:
相对熵可以衡量两个随机分布之间的距离,当两个随机分布相同时,它们的相对熵为零,当两个随机分布的差别增大时,它们的相对熵也会增大。 因此,在机器学习中我们可以使用KL散度来衡量预测分类和真实类别的举例,作为模型预测能力的表征,对于所有样本平均KL散度越小则模型的性能越好;反之,模型性能越差。
相对熵公式3.3中,信息熵H(p)的确定性(可看作已知,对于有监督分类训练这是一定的),仅交叉熵H(p,q)受模型预测性能的影响有所波动,对于每个样本KL散度的增减以及增减大小全部由交叉熵贡献,而且KL散度作为模型误差估计在误差回传的时候信息熵不贡献回传信息,因此我们可以使用交叉熵代替KL散度作为模型误差计算方法,这样一来达到同等的模型优化目的且不影响模型优化能力(因为不改变回传误差量),同时可减少计算量。 这也是目前机器学习中广泛采用交叉熵而不是KL散度作为误差模型的原因。