深度残差网络的个人理解

June 21st, 2017 by JasonLe's Tech 1,088 views

上篇对于三大RCNN算法进行了阐述,算法首要都必须提取整幅图的特征向量,目前性能比较好的神经网络是ResNet。ResNet使用了深度残差网络(Deep Residual Network),这种网络的发明的背景在于网络的层数在不断增加的情况下出现识别率降低的问题。

Deep Residual Network采用在层与层之间添加shortcut,即每层的输出不是传统神经网络当中输入的映射,而是映射和输入的叠加。

网上很多观点都倾向于梯度消失,即对网络做BP推导的话,

本来每个子项就特别小,再乘以更小的子项导致梯度趋近于0,而Deep Residual Network采用添加路径的方式将X1和XL连接起来,导致偏导置于一个比较大的数,在BP过程中,梯度不容易消失。

学术界对于出现这种问题的根源有不同的看法,我倾向这种增加路径的方式非常类似于Dropout,一个是增加路径,一个是随机减少路径,实际上效果来自于训练层数的减少,实际每次训练网络结构层数少于网络最大层数。

目前在我算法里,我使用的是ResNet50,50就是包含50层Conv卷积,ResNet50在网上有现成的model和weights,不过这里为了加深理解提供部分基于Keras的模型代码和模型结构图示。

    x = ZeroPadding2D((3, 3))(img_input)

    x = Convolution2D(64, (7, 7), strides=(2, 2), name='conv1', trainable = trainable)(x)
    x = FixedBatchNormalization(axis=bn_axis, name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2))(x)

    x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1), trainable = trainable)
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='b', trainable = trainable)
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='c', trainable = trainable)

    x = conv_block(x, 3, [128, 128, 512], stage=3, block='a', trainable = trainable)
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='b', trainable = trainable)
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='c', trainable = trainable)
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='d', trainable = trainable)

    x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e', trainable = trainable)
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f', trainable = trainable)

上图只是针对其中一个conv_block,conv_block分出两个分支,一个分支卷积一次,一个分支卷积3次,然后在res2a处将两个分支Add。identity_block则是直接将输入和三次卷积结果Add。

 

http://blog.csdn.net/superCally/article/details/55671064

https://my.oschina.net/yilian/blog/667900

https://arxiv.org/pdf/1605.06431.pdf

 

RCNN、Fast RCNN和Faster RCNN的个人理解

June 1st, 2017 by JasonLe's Tech 2,050 views

最近在使用Keras对我定义的目标进行训练和目标检测,目前最火的目标检测框架就是Faster RCNN了,Faster RCNN克服了他的前辈RCNN和Fast RCNN固有的一些问题,提升了检测速度,使得在视频领域的目标检测成为可能。

RCNN算法这里简单提一下:

  • 区域提名:通过Selective Search从原始图片提取2000个左右区域候选框;
  • 区域大小归一化:把所有侯选框缩放成固定大小(原文采用227×227)
  • 特征提取:通过CNN网络,提取特征;
  • 分类与回归:在特征层的基础上添加两个全连接层,再用SVM分类来做识别,用线性回归来微调边框位置与大小,其中每个类别单独训练一个边框回归器。

RCNN最大弊端就是拥有太多的候选框,这个导致每个候选框都要分别通过CNN提取特征,计算量依然很大,其中有不少其实是重复计算,最终这个也使得目标识别非常慢

Fast RCNN是RCNN的改进版,借鉴了SPP-Net中对于提取到的卷积层特征的处理,即提出去掉了原始图像上对于ROI区域的crop/warp等操作(也就是把所有的候选框都做归一化),换成了在提取到的卷积特征上的空间金字塔池化层(Spatial Pyramid Pooling,SPP)。因此无论图片大小如何,无论图像向量唯独如何,经过Spatial Pyramid Pooling操作,提取出来的提取出来的维度数据都是一致的,这样就可以统一送至全连接层了。

ROI操作(Spatial Pyramid Pooling,SPP):

通过上图可以看到feature map 经过SPP层被分割成了16个256d+4个256d+1个256d的ROI 特征向量。因此在Fast RCNN中输入的候选框可大可小,然后根据得到的候选框区域投影到整幅图片的特征向量层。

总的Fast RCNN步骤如下:

  • 特征提取:以整张图片为输入利用CNN得到图片的特征层;
  • 区域提名:通过Selective Search等方法从原始图片提取区域候选框,并把这些候选框一一投影到最后的特征层;
  • 区域归一化:针对特征层上的每个区域候选框进行RoI Pooling操作,得到固定大小的特征表示
  • 分类与回归:然后再通过两个全连接层,分别用softmax多分类做目标识别,用回归模型进行边框位置与大小微调。

Faster RCNN在Fast RCNN的基础上更进一部,不再使用Selective Search等方法获取候选框,而是利用RPN(Region Proposal Networks)网络来计算候选框。RPN以一张任意大小的图片为输入,输出一批矩形区域提名,每个区域对应一个目标分数和位置信息。当然RPN和Fast RCNN共用基础的图片特征。

RPN会产生K个Anchor Box,而每个Anchor Box都包括2K个score和4K个坐标点,socre就是这个区域的评分,有多大概率是这个东西?4K就是矩形的是个坐标位置。然后将这些Anchor Box和整幅图的特征向量结合起来(就是Feature Map ——> ROI Feature的操作,就是上面Fast RCNN步骤三,最后产生固定大小的特征表示),得到的固定大小的特征表示可以进行对应区域的classification,分类这个区域是不是那个物体,然后用 k 个回归模型(各自对应不同的Anchor Box)微调候选框位置与大小,最后进行目标真正的分类,判断这个目标是什么东西。

总的步骤:

  • 特征提取:同Fast R-CNN,以整张图片为输入,利用CNN得到图片的特征层;
  • 区域提名:在最终的卷积特征层上利用 k 个不同的矩形框(Anchor Box)进行提名, k 一般取9;
  • 分类与回归:对每个Anchor Box对应的区域进行object/non-object二分类,并用 k 个回归模型(各自对应不同的Anchor Box)微调候选框位置与大小,最后进行目标分类。

Faster RCNN得到区域提名以后,后续操作和Fast RCNN一模一样!事实上只需关注RPN即可,如下图流程(忽略前后的不同….):

梳理了整个算法脉络大白话就是:目标检测分为两大部分:1)区域提名 2)特征回归分类。每个部分都是各大算法进化过来的。

参考文献

[1] R. Girshick, J. Donahue, T. Darrell, J. Malik. Rich feature hierarchies for accurate object detection and semantic segmentation. ImageNet Large-Scale Visual Recognition Challenge workshop, ICCV, 2013.

[2] R. Girshick, J. Donahue, T. Darrell, J. Malik. Rich feature hierarchies for accurate object detection and semantic segmentation. IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2014.

[3] R. Girshick, J. Donahue, T. Darrell, J. Malik. Region-Based Convolutional Networks for Accurate Object Detection and Segmentation. IEEE Transactions on Pattern Analysis and Machine Intelligence, May. 2015.

[4] K. He, X. Zhang, S. Ren, and J. Sun. Spatial pyramid pooling in deep convolutional networks for visual recognition. In ECCV. 2014.

[5] S. Ren, K. He, R. Girshick, J. Sun. Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks. Advances in Neural Information Processing Systems 28 (NIPS), 2015.

CNN参数小结

May 11th, 2017 by JasonLe's Tech 964 views

CNN(Convolutional Neural Networks)是当下最火的一种神经网络,主要用来识别图像。CNN由三部分组成:Convolutional Layer, Pooling Layer 和 Fully-Connected Layer,卷积层和池化都是CNN特有的,全连接层是传统的神经网络。

整个网络流程就是 [INPUT – CONV – RELU – POOL – FC],其中CONV-RELU-POOL可以添加很多层,如图所示

举个例子:

  • 输入的数据都是28x28x1的图像,意思就是长宽都是28的pixel,并且是单通道图像。
  • 卷积层中,神经元与输入层中的一个局部区域相连,每个神经元都计算自己与输入层相连的小块区域与自己权重的内积。卷积层会计算所有神经元的输出。如果我们使用25个filter[3x3x25],每个filter是得到的输出数据体的维度就是[26x26x25]。
  • ReLU层将会逐个元素地进行激活函数操作,比如使用以0为阈值的max(0,x)作为激活函数。该层对数据尺寸没有改变,还是[26x26x25]。
  • 汇聚层在在空间维度(宽度和高度)上进行降采样(downsampling)操作,其实也就是POOL层[2×2],数据尺寸变为[13x13x25]。
  • 然后可以再次进行卷积、ReLU和Pool。
  • 全连接层将会计算分类评分,数据尺寸变为[1x1x10],其中10个数字对应的就是CIFAR-10中10个类别的分类评分值,全连接层与常规神经网络一样,其中每个神经元都与前一层中所有神经元相连接。

最开始卷积的维度变化让我很头疼,看了好久才理解。总结下面公式:

  • 输入数据体的尺寸为W1 * H1 * D1
  • 4个参数:
    filter的数量K
    filter的空间尺寸F
    步长stride S
    零填充数量(the amount of zero padding)P
  • 输出数据体的尺寸为W2 * H2 * D2 ,其中:
    W2=(W1-F+2P)/S+1
    H2=(H1-F+2P)/S+1 (宽度和高度的计算方法相同)
    D2=K
    由于参数共享,每个滤波器包含F * F *D1个权重,卷积层一共有F * F * D1  K个权重和K个偏置。

每进行一次卷积,图像的深度就增加一倍,深度与filter的数量K紧密相关!

常见的设置是F=3,S=1,P=1,零填充数量就是为了让输入图像长宽变为偶数(其实就是在图像外围填充0),例如是32、64、128等,而使用S=1的步长,是因为使得空间维度的降采样全部由Pooling层负责,卷积层只负责对输入数据体的深度进行变换。

使用这些参数需要考虑到内存的占用率,比如使用64个尺寸为3×3的滤波器对【224x224x3】的图像进行卷积,零填充为1,步长为1,那么得到的激活数据体尺寸是[224x224x64]。这个数量就是一千万的数据特征,或者就是72MB的内存!

第二次池化后,使用Flatten,压扁这个数据集合,建立二层全连接网络,第一层神经元数100,第二层为10。

 

 

参考:

http://cs231n.github.io/convolutional-networks/

http://cs231n.stanford.edu/syllabus.html

http://cs.stanford.edu/people/karpathy/convnetjs/demo/cifar10.html

主成分分析(Principal components analysis)的计算过程

April 28th, 2017 by JasonLe's Tech 879 views

今天使用Octave练习计算PCA,发现自己对于这个计算还不是特别了解,特此记录。

首先从txt中获取数据,然后将矩阵都入到X中。

octave:7> data = load('ex2data.txt')
data =

   2.50000   2.40000
   0.50000   0.70000
   2.20000   2.90000
   1.90000   2.20000
   3.10000   3.00000
   2.30000   2.70000
   2.00000   1.60000
   1.00000   1.10000
   1.50000   1.60000
   1.10000   0.90000
octave:8> X = data(:, [1, 2]);
octave:15> mu=mean(X)
mu =

   1.8100   1.9100

求x平均值,然后对于所有的样例,都减去对应的均值。这里x的均值是1.81和1.91,那么一个样例减去均值后即为(0.69,0.49),得到

octave:16> X_norm = bsxfun(@minus, X, mu);
octave:17> X_norm 
X_norm =

   0.690000   0.490000
  -1.310000  -1.210000
   0.390000   0.990000
   0.090000   0.290000
   1.290000   1.090000
   0.490000   0.790000
   0.190000  -0.310000
  -0.810000  -0.810000
  -0.310000  -0.310000
  -0.710000  -1.010000

我们使用这个矩阵去构造协方差矩阵sigma = (X_norm’ * X_norm)/size(X_norm(:,1))

octave:34> sigma = X_norm' * X_norm
sigma =

   5.5490   5.5390
   5.5390   6.4490

octave:35> sigma = sigma/10
sigma =

   0.55490   0.55390
   0.55390   0.64490

使用octave中的svd函数直接计算出协方差的特征值和特征向量

octave:36> [U,S,V] = svd(sigma)
U =

  -0.67787  -0.73518
  -0.73518   0.67787

S =

Diagonal Matrix

   1.155625          0
          0   0.044175

V =

  -0.67787  -0.73518
  -0.73518   0.67787

U为特征向量,S为sigma的特征值,通过特征值可以求变量的retained(保留程度)。
比如此时我们想把2维数据转换到1维数据上,那么可以使用U的第一列或者第二列,通过公式z=U’ * X_norm或者X_norm * U得到降维后的数据。

octave:39> z = X_norm*U(:,1)
z =

  -0.827970
   1.777580
  -0.992197
  -0.274210
  -1.675801
  -0.912949
   0.099109
   1.144572
   0.438046
   1.223821

研究其数理意义,就是求源数据到向量基z的投影误差最小,找到合适的基向量代表这个平面。
http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html

http://www.cnblogs.com/LeftNotEasy/archive/2011/01/19/svd-and-applications.html

修正Neural Network参数小结

April 14th, 2017 by JasonLe's Tech 934 views

在实际构建神经网络的过程中,经常碰到一些选择的问题,现在进行总结:

  • Getting more training examples: Fixes high variance
  • Trying smaller sets of features: Fixes high variance
  • Adding features: Fixes high bias
  • Adding polynomial features: Fixes high bias
  • Decreasing λ: Fixes high bias
  • Increasing λ: Fixes high variance.

当遇到高差异性时(high variance),可以试图增加训练样本或者减少特征数量来解决,但是如果遇到高偏见性(high bias),那么就表明这个训练集可能特征数太少,需要增加特征。λ作为惩罚系数存在,λ越大,惩罚系数越大,越可以修正高差异性,反之修正高偏见性。对于λ的取值,一般遵循在cross-validation set中取最优来决定。

Diagnosing Neural Networks

  • A neural network with fewer parameters is prone to underfitting. It is also computationally cheaper.
  • A large neural network with more parameters is prone to overfitting. It is also computationally expensive. In this case you can use regularization (increase λ) to address the overfitting.

Using a single hidden layer is a good starting default. You can train your neural network on a number of hidden layers using your cross validation set. You can then select the one that performs best.只有一层的神经网络最简单,但是同时可能会造成性能损失,所以我们要增加隐藏层数和特征数,但是复杂的神经网络又会导致过拟合和计算复杂度太高的问题,所以要权衡这种平衡。

Model Complexity Effects:

  • Lower-order polynomials (low model complexity) have high bias and low variance. In this case, the model fits poorly consistently.
  • Higher-order polynomials (high model complexity) fit the training data extremely well and the test data extremely poorly. These have low bias on the training data, but very high variance.
  • In reality, we would want to choose a model somewhere in between, that can generalize well but also fits the data reasonably well.

默认将数据集分为3部分,60%的训练集,20%的cross-validation set和20%的测试集。

参考:

https://www.coursera.org/learn/machine-learning/supplement/llc5g/deciding-what-to-do-next-revisited

http://www.cnblogs.com/sddai/p/5696834.html