Isaac Li

码农 + 测试


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

神经网络-VGG

发表于 2018-08-24 | 分类于 Deep Learning

VGG 网络结构图

upload successful

upload successful

VGG的特点:

小卷积核。作者将卷积核全部替换为3x3(极少用了1x1);

小池化核。相比AlexNet的3x3的池化核,VGG全部为2x2的池化核;

层数更深特征图更宽。基于前两点外,由于卷积核专注于扩大通道数、池化专注于缩小宽和高,使得模型架构上更深更宽的同时,计算量的增加放缓;

全连接转卷积。网络测试阶段将训练阶段的三个全连接替换为三个卷积,测试重用训练时的参数,使得测试得到的全卷积网络因为没有全连接的限制,因而可以接收任意宽或高为的输入。

特征图

网络在随层数递增的过程中,通过池化也逐渐忽略局部信息,特征图的宽度高度随着每个池化操作缩小50%,5个池化l操作使得宽或者高度变化过程为:224->112->56->28->14->7,但是深度depth(或说是channel数),随着5组卷积在每次增大一倍:3->64->128->256->512->512。特征信息从一开始输入的224x224x3被变换到7x7x512,从原本较为local的信息逐渐分摊到不同channel上,随着每次的conv和pool操作打散到channel层级上。

特征图的宽高从512后开始进入全连接层,因为全连接层相比卷积层更考虑全局信息,将原本有局部信息的特征图(既有width,height还有channel)全部映射到4096维度。也就是说全连接层前是7x7x512维度的特征图,估算大概是25000,这个全连接过程要将25000映射到4096,大概是5000,换句话说全连接要将信息压缩到原来的五分之一。VGGNet有三个全连接,我的理解是作者认为这个映射过程的学习要慢点来,太快不易于捕捉特征映射来去之间的细微变化,让backprop学的更慢更细一些(更逐渐)。

换句话说,维度在最后一个卷积后达到7x7x512,即大概25000,紧接着压缩到4096维,可能是作者认为这个过程太急,又接一个fc4096作为缓冲,同时两个fc4096后的relu又接dropout0.5去过渡这个过程,因为最后即将给1k-way softmax,所以又接了一个fc1000去降低softmax的学习压力。

feature map维度的整体变化过程是:先将local信息压缩,并分摊到channel层级,然后无视channel和local,通过fc这个变换再进一步压缩为稠密的feature map,这样对于分类器而言有好处也有坏处,好处是将local信息隐藏于/压缩到feature map中,坏处是信息压缩都是有损失的,相当于local信息被破坏了(分类器没有考虑到,其实对于图像任务而言,单张feature map上的local信息还是有用的)。

但其实不难发现,卷积只增加feature map的通道数,而池化只减少feature map的宽高。如今也有不少做法用大stride卷积去替代池化,未来可能没有池化。

卷积组

说到特征图的变化,我们可以进一步切分网络观察整体结构,再次拿出CS231n的博客里的描述网络结构的layer pattern:INPUT -> [[CONV -> RELU]N -> POOL?]M -> [FC -> RELU]*K -> FC,以pooling操作为切分点对整个网络分组的话,我们会得到五组卷积,五组卷积中有2种卷积组的形式,切分后的VGG网络可以描述成下面这样:

前两组卷积形式一样,每组都是:conv-relu-conv-relu-pool;

中间三组卷积形式一样,每组都是:conv-relu-conv-relu-conv-relu-pool;

最后三个组全连接fc层,前两组fc,每组都是:fc-relu-dropout;最后一个fc仅有fc。

虽然CS231n里将这种形式称为layer pattern,但我更喜欢把以卷积起始池化为止的最短结构称之为“卷积组”。

不难发现VGG有两种卷积组,第二种([conv-relu]-[conv-relu]-[conv-relu]-pool)比第一种([conv-relu]-[conv-relu]-pool) 多了一个[conv-relu]。我的理解是:

多出的relu对网络中层进一步压榨提炼特征。结合一开始单张feature map的local信息更多一些,还没来得及把信息分摊到channel级别上,那么往后就慢慢以增大conv filter的形式递增地扩大channel数,等到了网络的中层,channel数升得差不多了(信息分摊到channel上得差不多了),那么还想抽local的信息,就通过再加一个[conv-relu]的形式去压榨提炼特征。有点类似传统特征工程中,已有的特征在固定的模型下没有性能提升了,那就用更多的非线性变换对已有的特征去做变换,产生更多的特征的意味;

多出的conv对网络中层进一步进行学习指导和控制不要将特征信息漂移到channel级别上。

上一点更多的是relu的带来的理解,那么多出的[conv-relu]中conv的意味就是模型更强的对数据分布学习过程的约束力/控制力,做到信息backprop可以回传回来的学习指导。本身多了relu特征变换就加剧(权力释放),那么再用一个conv去控制(权力回收),也在指导网络中层的收敛;

其实conv本身关注单张feature map上的局部信息,也是在尝试去尽量平衡已经失衡的channel级别(depth)和local级别(width、height)之间的天平。这个conv控制着特征的信息量不要过于向着channel级别偏移。

输入层

大都是2的N次方,这和网络中卷积或者池化层出现的stride为2的次数有关,比方VGGNet中每个pattern的卷积不会对feature map的宽度和高度有改变,而每个pattern结束前总会做一个stride为2的下采样,因为有5组,那么做5次就是32,所以VGGNet网络input大小一般都是32的倍数,即,n是下采样的次数,a是最终卷积和池化得到的feature map大小,如224或者384。

卷积层

现在常用的是小卷积核如3x3或者1x1。卷积为了保留feature map不变,通常会采取pad为1的操作,其实具体来说应该是:为了保证卷积后的feature map的宽度和高度不变,那么有pad=(F-1)/2,但我觉得这个有点问题,可以改成更一般的形式,不过首先可以看看计算下一层feature map宽高的公式:

因为要保证和一样,有,那么可以导出:

当Stride=1时,那么pad=(F-1)/2。因为现在stride=1的3x3卷积用的多,所以大家会默认说是pad=1(关于这点上,也是由于实验发现这样保留feature map的宽高情况下,性能好的缘故,我认为填补主要是针对stride大于1的情况带来的边界问题,如果input尺寸不是事先设定的,那么就会有边界无法卷积到的问题带来信息丢失。不过这种填补我认为也有一定问题,就是说原本conv3x3去计算对应位置的3x3,而填补后为0,这样相当于少算了一些值,这肯定还是有影响的)。但若stride不是1,那么要保证前后feature map的宽高一样,就要根据上面的公式计算得出。

另一个点是通常与Input比较接近的conv会采用大卷积核。关于接近input层使用较大的卷积核这点,我认为先是考虑到后面的操作,先尽可能用大的卷积核cover更多的原始信息(虽然经过了卷积有一些变换),第二点在于大卷积核带来的大感受野,后面的卷积层能的一个神经元能看到更大的input,第三点是GPU的显存受限,经典的例子就是AlexNet使用stride=4的conv11x11,目的就是从一开始就减少显存占用,其实这里的大stride,我觉得起到了一些正则的作用。但缺点也很明显,因为卷积核变大,矩阵乘法实现卷积时,若没有大stride,那么第一个矩阵的列数,也就是第二个矩阵的行数,会变大,带来大的计算量。所以在AlexNet中,大卷积核也对应使用了大的stride值。

池化层

常见2x2的max-pooling,少见3x3或者更大的kernel。更大的kernel带来的问题是信息丢失带来的信息损失,此外,stride通常为2;
在当时也有average pooling,但是在图像任务上max-pooling的效果更胜一筹,所以图像大多使用max-pooling。在这里我认为max-pooling更容易捕捉图像上的变化,梯度的变化,带来更大的局部信息差异性,更好地描述边缘、纹理等构成语义的细节信息,这点尤其体现在网络可视化上。

其实按照以上的设定看来,也是有好处的。卷积专注于保留空间信息前提下的channel变换,而池化则专注于空间信息的变换(下采样)。

全连接转卷积

VGG比较神奇的一个特点就是“全连接转卷积”, 也就是说,作者在测试阶段把网络中原本的三个全连接层依次变为1个conv7x7,2个conv1x1,也就是三个卷积层。改变之后,整个网络由于没有了全连接层,网络中间的feature map不会固定,所以网络对任意大小的输入都可以处理.

upload successful

上图是VGG网络最后三层的替换过程,上半部分是训练阶段,此时最后三层都是全连接层(输出分别是4096、4096、1000),下半部分是测试阶段(输出分别是1x1x4096、1x1x4096、1x1x1000),最后三层都是卷积层。下面我们来看一下详细的转换过程(以下过程都没有考虑bias,略了):

先看训练阶段,有4096个输出的全连接层FC6的输入是一个7x7x512的feature map,因为全连接层的缘故,不需要考虑局部性, 可以把7x7x512看成一个整体,25508(=7x7x512)个输入的每个元素都会与输出的每个元素(或者说是神经元)产生连接,所以每个输入都会有4096个系数对应4096个输出,所以网络的参数(也就是两层之间连线的个数,也就是每个输入元素的系数个数)规模就是7x7x512x4096。对于FC7,输入是4096个,输出是4096个,因为每个输入都会和输出相连,即每个输出都有4096条连线(系数),那么4096个输入总共有4096x4096条连线(系数),最后一个FC8计算方式一样,略。

再看测试阶段,由于换成了卷积,第一个卷积后要得到4096(或者说是1x1x4096)的输出,那么就要对输入的7x7x512的feature map的宽高(即width、height维度)进行降维,同时对深度(即Channel/depth维度)进行升维。要把7x7降维到1x1,那么干脆直接一点,就用7x7的卷积核就行,另外深度层级的升维,因为7x7的卷积把宽高降到1x1,那么刚好就升高到4096就好了,最后得到了1x1x4096的feature map。这其中卷积的参数量上,把7x7x512看做一组卷积参数,因为该层的输出是4096,那么相当于要有4096组这样7x7x512的卷积参数,那么总共的卷积参数量就是:

[7x7x512]x4096,这里将7x7x512用中括号括起来,目的是把这看成是一组,就不会懵。

第二个卷积依旧得到1x1x4096的输出,因为输入也是1x1x4096,三个维度(宽、高、深)都没变化,可以很快计算出这层的卷积的卷积核大小也是1x1,而且,通道数也是4096,因为对于输入来说,1x1x4096是一组卷积参数,即一个完整的filter,那么考虑所有4096个输出的情况下,卷积参数的规模就是[1x1x4096]x4096。第三个卷积的计算一样,略。

其实VGG的作者把训练阶段的全连接替换为卷积是参考了OverFeat的工作,如下图是OverFeat将全连接换成卷积后,带来可以处理任意分辨率(在整张图)上计算卷积,而无需对原图resize的优势。

upload successful

不过可以看到,训练阶段用的是crop或者resize到14x14的输入图像,而测试阶段可以接收任意维度,如果使用未经crop的原图作为输入(假设原图比crop或者resize到训练尺度的图像要大),这会带来一个问题:feature map变大了。比方VGG训练阶段用224x224x3的图作为模型输入,经过5组卷积和池化,最后到7x7x512维度,最后经过无论是三个卷积或者三个全连接,维度都会到1x1x4096->1x1x4096->1x1x1000,而使用384x384x3的图做模型输入,到五组卷积和池化做完(即),那么feature map变为12x12x512,经过三个由全连接变的三个卷积,即feature map经历了6x6x4096->6x6x4096->6x6x1000的变化过程后,再把这个6x6x1000的feature map进行average,最终交给SoftMax的是1x1x1000的feature map进行分类。

以上便是将全连接转换成卷积以及将转换后的全卷积网络应用到测试阶段的方式。其实进一步来看卷积与全连接,二者最明显的差异不外乎一个前者是局部连接,但其实二者都有用到全局信息,只是卷积是通过层层堆叠来利用的,而全连接就不用说了,全连接的方式直接将上一层的特征图全部用上,稀疏性比较大,而卷积从网络深度这一角度,基于输入到当前层这一过程逐级逐层榨取的方式利用全局信息

1x1卷积

VGG在最后的三个阶段都用到了1x1卷积核,选用1x1卷积核的最直接原因是在维度上继承全连接,然而作者首先认为1x1卷积可以增加决策函数(decision function,这里的决策函数我认为就是softmax)的非线性能力,非线性是由激活函数ReLU决定的,本身1x1卷积则是线性映射,即将输入的feature map映射到同样维度的feature map。

1x1卷积的特点:

专注于跨通道的特征组合:conv1x1根本不考虑单通道上像素的局部信息(不考虑局部信息),专注于那一个卷积核内部通道的信息整合。conv3x3既考虑跨通道,也考虑局部信息整合;

对feature map的channel级别降维或升维:例如224x224x100的图像(或feature map)经过20个conv1x1的卷积核,得到224x224x20的feature map。尤其当卷积核(即filter)数量达到上百个时,3x3或5x5卷积的计算会非常耗时,所以1x1卷积在3x3或5x5卷积计算前先降低feature map的维度。

upload successful

实验结论

因为作者自己在下面实验的缘故,当然没有测试集的ground truth类别,所以作者就用验证集当做测试集来观察模型性能。这里作者使用两种方式来评估模型在测试集(实际的验证集)的性能表现:single scale evaluation和multi-scale evaluation。实验结论:

LRN层无性能增益(A和A-LRN)。作者通过网络A和A-LRN发现AlexNet曾经用到的LRN层(local response normalization,LRN是一种跨通道去normalize像素值的方法)没有性能提升,因此在后面的4组网络中均没再出现LRN层。 当然我也感觉没啥用,想到max-pooling比average-pooling效果好,我就感觉这个LRN没啥用,不过如果把LRN改成跨通道的max-normal,我感觉说不定会有性能提升。特征得到retain更明显。

深度增加,分类性能提高(A、B、C、D、E)。从11层的A到19层的E,网络深度增加对top1和top5的error下降很明显,所以作者得出这个结论,但其实除了深度外,其他几个网络宽度等因素也在变化,depth matters的结论不够convincing。

conv1x1的非线性变化有作用(C和D)。C和D网络层数相同,但D将C的3个conv3x3换成了conv1x1,性能提升。这点我理解是,跨通道的信息交换/融合,可以产生丰富的特征易于分类器学习。conv1x1相比conv3x3不会去学习local的局部像素信息,专注于跨通道的信息交换/融合,同时为后面全连接层(全连接层相当于global卷积)做准备,使之学习过程更自然。

多小卷积核比单大卷积核性能好(B)。作者做了实验用B和自己一个不在实验组里的较浅网络比较,较浅网络用conv5x5来代替B的两个conv3x3。多个小卷积核比单大卷积核效果好,换句话说当考虑卷积核大小时:depths matters。


引用:

VGG网络模型详解

神经网络-AlexNet

发表于 2018-08-21 | 分类于 Deep Learning

AlexNet 网络结构

upload successful

第一个模块 conv_1:

输入的图片大小为224x224x3

有96个卷积核,尺寸为11x11,即11x11x96。步长(stride)为4.

第二个模块 conv_2:

输入的tensor为27x27x96

卷积核的大小为: 5x5x256,步长为1,因此,步长为1时,feature map为27x27x256.

同样紧跟ReLU,和LRN层.尺寸不变

最大池化层,核大小为3x3,步长为2

第三个模块 conv_3:

输入tensor为13x13x256

卷积核 3x3x384,步长为1,feature map为:13x13x384

加上ReLU,尺寸不变

无最大池化层

第四个模块 conv_4:

配置和conv_3一样,因此feature map为:13x13x384

第五个模块 conv_5:

输入tensor为13x13x384

卷积核 3x3x256,步长为1,feature map为:13x13x256
加上ReLU,尺寸不变
最大池化层,核大小3x3, 步长为2, 因此feature map:6x6x256

第六个模块 fc_1:

卷积核6x6x256x4096,输出为一维向量,4096个元素。
加上ReLU,尺寸不变

第七个模块 fc_2:

输出为一维向量,4096个元素。
加上ReLU,尺寸不变

第8个模块 fc_3:

输出为一维向量,1000个元素。最后一层用了softmax,输出为1000个种类的各类概率值.

神经网络-LeNet

发表于 2018-08-20 | 分类于 Deep Learning

LeNet-5 的结构

upload successful

一。输入层:

输入的图像大小是 32x32pixel的图像,其中而数据库中是20x20的信息在28x28pixel的中心。拓展图像是为了高层特征可以位于高层感受野中心。例如图中A的上方的拐点,如果没有拓展图像输入,则其对应在S2中的位置很有可能位于feature map的最上方,无法处于任何感受野的中心。

二。隐藏层

1. C1 卷积层:kernel size=5x5,步长为1,无填充,生成6个feature map

参数个数为(5x5+1)x6=156(其中5x5对应kernel size,+1为bias,6为feature map 数目)。
连接数为156x28x28=122304(156为参数个数,其中feature map上每个像素点对应156个链接)。

2. S2 下采样层(Pooling): kernel size=2x2,步长为2,无填充。

下采样的作用: 利用图像的局部相关性原理,对图像进行子抽样,可以减少数据处理量,同时又保留有用的信息。

参数个数为 6x(1+1)=12。(因为LeNet-5采用的sigmoid(a*average(x)+b)作为池化函数)

链接个数为6x14x14x(2x2+1)=5880。六个feature map,总共6x14x14个feature,每个feature由4个C2特征+1个bias。

3. C3 卷积层:kernel size=5x5,步长为1,无填充,生成16个feature map。

C3中的每一个Feature Map连接到S2的所有6个Feature Map或者是几个Feature Map。表示本层的Feature Map是上一层提取的Feature Map的不同组合。为什么不把S2的每一个Feature Map连接到C3的每一个Feature Map中?原因有2: 第一,不完全连接机制连接的数量保持在合理范围,第二,这样破坏了网络的对称性,由于不同的Feature Map有不同的输入,所以迫使他们抽取不同的特征(理想状态特征互补)。

C3与S2的连接关系
upload successful

C3的前6个Feature Map以S2中的3个相邻的Feature Map子集为输入,接下来的6个Feature Map以S2中相邻的4个Feature Map作为输入,接下来的3个以不相邻的4个Feature Map子集作为输入,最后一个将S2中所有的Feature Map作为输入的话,C3将会有1516个可训练参数和151600个连接。

参数个数为(5x5x3+1)x6+(5x5x4+1)x9+(5x5x6+1)=1516个。括号内部为kernel_size x kernel_size x feature_map_num + bias_num,表示从feature_map_size卷积得到的feature map所需要的参数个数;括号外为相应得到feature map的数目

4.S4下采样层 (Pooling):,kernel size=2x2,步长为2,无填充。

参数个数为16x2=32

链接个数为5x5x16x(2x2+1)=2000。(5为新生成feature map的size,16为feature map的数目,2为kernel size,1为bias。

5. C5 卷积层: kernel size=5x5,步长为1,无填充,全连接生成120个feature map。

参数个数为120x(5x5x16+1)=48120

链接个数等于参数个数,因为新生成feature map的size为1。

6.F6 全连接层:输入120个,输出84个

链接个数=参数个数=(120+1)x84,其中+1为bias。

全连接层的激活函数为Atanh(Sx),其中A和S为超参数。

输出表述是将给定的label转换为一个向量,作为神经网络的真值。

文章中是把图片对应的字符在7x12的bitmap上画出,白值为-1,黑值为1,其中84个像素平铺之后的向量对应为相应字符的表述,作为真值与F6连接。这样做的优点有:

  1. 对于识别全打印的ASCII字符有用(单独数字无用)
  2. 外表相近的字符如”i”和”1”等在这种表述中也相近,这样在神经网络之后加入个依靠语义更正的系统,可以提高准确率。
  3. 1 of N的表述在N大于几十的时候就会表现不好。
  4. 这样的表示可以用于拒绝非字符,而不是所有的都识别为字符。
    设置“白值为-1,黑值为1”的原因是为了把函数限定在sigmoid函数斜率较大的区域,否则收敛较慢

    三。输出层

    全连接层,共有10个节点,分别代表数字0到9,且如果节点i的值为0,则网络识别的结果是数字i。采用的是径向基函数(RBF)的网络连接方式。

    LeNet-5识别数字3的过程
    upload successful

Java 虚拟机

发表于 2018-08-15 | 分类于 Java

深入拆解Java虚拟机-极客时间 笔记

01 Java 代码是怎么运行的:

从虚拟机视角看,执行Java代码首先要将它编译而成的class文件加载到Java虚拟机中。加载后的Java类会被存放于方法区中。实际运行时,虚拟机会执行方法区的代码。

Java虚拟机会在内存中划分出堆和栈来存储运行时数据。会将栈细分为面向Java方法的Java方法栈,面向本地方法的本地方法栈,以及存放各个线程执行位置的PC寄存器。每当调用进入一个Java方法,Java虚拟机会在当前线程的Java方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。当退出当前执行的方法时,不管是正常返回还是异常返回,Java虚拟机均会弹出当前线程的当前栈帧,并将之舍弃。

为了满足不同用户场景需要,HotSpot内置了多个即时编译器:C1 C2 Graal。C1又叫Client编译器,面向的是对启动性能有要求的客户端GUI程序。采用的优化手段相对简单,因此编译时间较短。C2 又叫Server编译器,面向的是对峰值性能有要求的服务器端程序。从Java7开始,HotSpot默认采用分层编译的方式:热点方法首先会被C1编译,而后热点方法中的热点会进一步被C2编译。

RCNN, Fast RCNN, Faster RCNN

发表于 2018-07-26 | 分类于 Deep Learning

概览R-CNN

upload successful

一. RCNN

算法概要:首先输入一张图片,我们先定位出2000个物体候选框,然后采用CNN提取每个候选框中图片的特征向量,特征向量的维度为4096维,接着采用svm算法对各个候选框中的物体进行分类识别。也就是总个过程分为三个程序:

a、找出候选框;
b、利用CNN提取特征向量;
c、利用SVM进行特征向量分类。具体的流程如下图片所示:

upload successful

在CNN阶段,如果用selective search挑选出来的候选框与物体的人工标注矩形框的重叠区域IoU大于0.5,那么我们就把这个候选框标注成物体类别,否则我们就把它当做背景类别。

二. Fast RCNN

引入原因:FRCNN针对RCNN在训练时是multi-stage pipeline和训练的过程中很耗费时间空间的问题进行改进。它主要是将深度网络和后面的SVM分类两个阶段整合到一起,使用一个新的网络直接做分类和回归。

改进:最后一个卷积层后加了一个ROI pooling layer。ROI pooling layer首先可以将image中的ROI定位到feature map,然后是用一个单层的SPP layer将这个feature map patch池化为固定大小的feature之后再传入全连接层。

损失函数使用了多任务损失函数(multi-task loss),将边框回归直接加入到CNN网络中训练。

upload successful
图中省略了通过ss获得proposal的过程,第一张图中红框里的内容即为通过ss提取到的proposal,中间的一块是经过深度卷积之后得到的conv feature map,图中灰色的部分就是我们红框中的proposal对应于conv feature map中的位置,之后对这个特征经过ROI pooling layer处理,之后进行全连接。在这里得到的ROI feature vector最终被分享,一个进行全连接之后用来做softmax回归,用来进行分类,另一个经过全连接之后用来做bbox回归。

注意: 对中间的Conv feature map进行特征提取。每一个区域经过RoI pooling layer和FC layers得到一个 固定长度 的feature vector(这里需要注意的是,输入到后面RoI pooling layer的feature map是在Conv feature map上提取的,故整个特征提取过程,只计算了一次卷积。虽然在最开始也提取出了大量的RoI,但他们还是作为整体输入进卷积网络的,最开始提取出的RoI区域只是为了最后的Bounding box 回归时使用,用来输出原图中的位置)。

SPP网络

何恺明研究员于14年撰写的论文,主要是把经典的Spatial Pyramid Pooling结构引入CNN中,从而使CNN可以处理任意size和scale的图片;这中方法不仅提升了分类的准确率,而且还非常适合Detection,比经典的RNN快速准确。

SPP layer

根据pooling规则,每个pooling bin(window)对应一个输出,所以最终pooling后特征输出由bin的个数来决定。本文就是分级固定bin的个数,调整bin的尺寸来实现多级pooling固定输出。

upload successful

通过融合各级bin的输出,最终每一个unpooled FM经过SPP处理后,得到了1+4+16维的SPPed FM输出特征,经过融合后输入分类器。

这样就可以在任意输入size和scale下获得固定的输出;不同scale下网络可以提取不同尺度的特征,有利于分类。

RoI pooling layer

每一个RoI都有一个四元组(r,c,h,w)表示,其中(r,c)表示左上角,而(h,w)则代表高度和宽度。这一层使用最大池化(max pooling)来将RoI区域转化成固定大小的HW的特征图。假设一个RoI的窗口大小为hw,则转换成HW之后,每一个网格都是一个h/H * w/W大小的子网,利用最大池化将这个子网中的值映射到HW窗口即可。Pooling对每一个特征图通道都是独立的,这是SPP layer的特例,即只有一层的空间金字塔。

从预训练的网络中初始化数据

有三种预训练的网络:CaffeNet,VGG_CNN_M_1024,VGG-16,他们都有5个最大池化层和5到13个不等的卷积层。用他们来初始化Fast R-CNN时,需要修改三处:

①最后一个池化层被RoI pooling layer取代

②最后一个全连接层和softmax被替换成之前介绍过的两个兄弟并列层

③网络输入两组数据:一组图片和那些图片的一组RoIs

算法特点

1 通过Spatial Pyramid Pooling解决了深度网络固定输入层尺寸的这个限制,使得网络可以享受不限制输入尺寸带来的好处。

2 解决了RCNN速度慢的问题,不需要对每个Proposal(2000个左右)进行Wrap或Crop输入CNN提取Feature Map,只需要对整图提一次Feature Map,然后将Proposal区域映射到卷积特征层得到全链接层的输入特征。

upload successful

三. Faster RCNN

在Fast R-CNN还存在着瓶颈问题:Selective Search(选择性搜索)。要找出所有的候选框,这个也非常耗时。那我们有没有一个更加高效的方法来求出这些候选框呢?
在Faster R-CNN中加入一个提取边缘的神经网络,也就说找候选框的工作也交给神经网络来做了。这样,目标检测的四个基本步骤(候选区域生成,特征提取,分类,位置精修)终于被统一到一个深度网络框架之内。如下图所示:

upload successful

Faster R-CNN统一的网络结构如下图所示,可以简单看作RPN (Region Proposal Network)网络+Fast R-CNN网络。

upload successful
原理步骤如下:

首先向CNN网络【ZF或VGG-16】输入任意大小图片;

经过CNN网络前向传播至最后共享的卷积层,一方面得到供RPN网络输入的特征图,另一方面继续前向传播至特有卷积层,产生更高维特征图;

供RPN网络输入的特征图经过RPN网络得到区域建议和区域得分,并对区域得分采用非极大值抑制【阈值为0.7】,输出其Top-N【文中为300】得分的区域建议给RoI池化层;

第2步得到的高维特征图和第3步输出的区域建议同时输入RoI池化层,提取对应区域建议的特征;

第4步得到的区域建议特征通过全连接层后,输出该区域的分类得分以及回归后的bounding-box。

Region Proposal Network(RPN)的核心思想是使用卷积神经网络直接产生Region Proposal,使用的方法本质上就是滑动窗口。RPN的设计比较巧妙,RPN只需在最后的卷积层上滑动一遍,借助Anchor机制和边框回归可以得到多尺度多长宽比的Region Proposal。

单个RPN网络结构如下:

upload successful

在ZF网络模型下,给定输入图像(假设分辨率为600x1000),经过卷积操作得到最后一层的卷积特征图(大小约为40x60)。在这个特征图上使用3x3的卷积核(滑动窗口)与特征图进行卷积,最后一层卷积层共有256个Feature Map,那么这个3x3的区域卷积后可以获得一个256维的特征向量,后边接Cls Layer和Reg Layer分别用于分类和边框回归(跟Fast RCNN类似,只不过这里的类别只有目标和背景两个类别)。3x3滑窗对应的每个特征区域同时预测输入图像3种尺度(128,256,512),3种长宽比(1:1,1:2,2:1)的Region Proposal,这种映射的机制称为Anchor。所以对于这个40x60的Feature Map,总共有约20000(40x60x9)个Anchor,也就是预测20000个Region Proposal。下图是51x39个Anchor中心,以及9种Anchor示例。

upload successful

这样设计的好处是什么?虽然现在也是用的滑动窗口策略,但是,滑动窗口操作是在卷积层特征图上进行的,维度较原始图像降低了16x16倍(16如何得到的可参见前文);多尺度采用了9种Anchor,对应了三种尺度和三种长宽比,加上后边接了边框回归,所以即便是这9种Anchor外的窗口也能得到一个跟目标比较接近的Region Proposal

RPN层的具体流程

首先套用ImageNet上常用的图像分类网络,本文中试验了两种网络:ZF或VGG-16,利用这两种网络的部分卷积层产生原始图像的特征图;

对于1中特征图,用n×n【论文中设计为3×3,n=3看起来很小,但是要考虑到这是非常高层的feature map,其size本身也没有多大,因此9个矩形中,每个矩形窗框都是可以感知到很大范围的】的滑动窗口在特征图上滑动扫描【代替了从原始图滑窗获取特征】,每个滑窗位置通过卷积层1映射到一个低维的特征向量【ZF网络:256维;VGG-16网络:512维,低维是相对于特征图大小W×H,typically~60×40=2400】后采用ReLU,并为每个滑窗位置考虑k种【论文中k=9】可能的参考窗口【论文中称为anchors,见下解释】,这就意味着每个滑窗位置会同时预测最多9个区域建议【超出边界的不考虑】,对于一个W×H的特征图,就会产生W×H×k个区域建议;

步骤2中的低维特征向量输入两个并行连接的卷积层2:reg窗口回归层【位置精修】和cls窗口分类层,分别用于回归区域建议产生bounding-box【超出图像边界的裁剪到图像边缘位置】和对区域建议是否为前景或背景打分,这里由于每个滑窗位置产生k个区域建议,所以reg层有4k个输出来编码【平移缩放参数】k个区域建议的坐标,cls层有2k个得分估计k个区域建议为前景或者背景的概率。

算法特点

1 提出了Region Proposal Network(RPN),将Proposal阶段和CNN分类融到了一起,实现了一个完全的End-To-End的CNN目标检测模型。RPN可以快速提取高质量的Proposal,不仅加快了目标检测速度,还提高了目标检测性能。

2 将Fast-RCNN和RPN放在同一个网络结构中训练,共享网络参数。

upload successful


引用

RCNN,Fast RCNN,Faster RCNN 总结

目标检测之RCNN,SPP-NET,Fast-RCNN,Faster-RCNN

Ubuntu环境下SSH的安装及使用

发表于 2018-07-25 | 分类于 Linux

SSH分客户端openssh-client和openssh-server

Ubuntu默认是安装 SSH 客户端的,但是没有安装 server 端

  1. 安装server端

    sudo apt-get install openssh-server
    
  2. 然后确认sshserver是否启动

    ps -e|grep ssh
    

SSH常用的服务命令

停止服务:sudo /etc/init.d/ssh stop

启动服务:sudo /etc/init.d/ssh start

重启服务:sudo /etc/init.d/sshresart

断开连接:exit

《深入理解Java虚拟机》之读书笔记

发表于 2018-07-18 | 分类于 Java

引言

upload successful

理解Java虚拟机是学习并发编程的基础,本博以笔记的形式记录学习《深入理解Java虚拟机》知识要点。


第2章 Java内存区域与内存溢出异常

程序计数器: 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式实现的,在任何一个确定时刻,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

Java虚拟机栈:与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程相同。

本地方法栈:本地方法栈与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。

Java堆:Java堆是垃圾收集器管理的主要区域。

方法区:方法区域Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

Hadoop 3.x 版本导入Eclipse后的错误处理

发表于 2018-07-12 | 分类于 Big Data

在Eclipse里导入 hadoop源码时会遇到很多编译错误,下面是我遇到的一些问题及解决办法


错误一:hadoop-streaming 项目buildpath里的项目引用丢失

解决办法:删除 missing 的项目,重新添加


错误二:缺少 AvroRecord 文件

解决办法:下载 AvroRecord.java 文件,copy到需要引用这个文件的目录


错误三:找不到 Sun.net.spi.nameservice.NameService

解决办法:sun.net.spi.nameservice.NameService错误,这是一个需要import的包,存在于openjdk中,在OracleJdk中没找到,需要下载一个。NameService是一个接口,在网上找一个NameService放到该包中就好。
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/net/spi/nameservice/NameService.java#NameService

周老师西瓜书之读书笔记

发表于 2018-07-12 | 分类于 Machine Learning

引言

upload successful
内容简介

机器学习是计算机科学与人工智能的重要分支领域.本书作为该领域的入
门教材,在内容上尽可能涵盖机器学习基础知识的各方面.全书共16章,
大致分为3个部分:第1部分(第1~3章)介绍机器学习的基础知识;第2 
部分(第4~10章)讨论一些经典而常用的机器学习方法(决策树、神经
网络、支持向量机、贝叶斯分类器、集成学习、聚类、降维与度量学
习);第3部分(第11~16章)为进阶知识,内容涉及特征选择与稀疏学
习、计算学习理论、半监督学习、概率图模型、规则学习以及强化学习
等.每章都附有习题并介绍了相关阅读材料,以便有兴趣的读者进一步钻
研探索。
    本书可作为高等院校计算机、自动化及相关专业的本科生或研究生
 教材,也可供对机器学习感兴趣的研究人员和工程技术人员阅读参考。

作者简介

周志华,南京大学计算机系教授,ACM杰出科学家,IEEE Fellow, 
IAPR Fellow, IET/IEE Fellow, 中国计算机学会会士。国家杰出青年
科学基金获得者、长江学者特聘教授。先后担任多种SCI(E)期刊执行主
编、副主编、副编辑、编委等。中国计算机学会人工智能与模式识别专
业委员会主任,中国人工智能学会机器学习专业委员会主任,IEEE计算
智能学会数据挖掘技术委员会副主席。

====================================

以下为个人学习笔记

第5章:神经网络

采样层亦称为“汇合”(Pooling)层,其作用是基于局部相关性原理进
行亚采样,从而在减少数据量的同时保留有用信息----国内很多材料都
把 Pooling 层翻译成“池化”层,从汉字字面上是完全没法池化跟亚采
样有什么关系的,个人觉得还是周老师翻译的采样层或汇合层更好理解
一些。

第6章:支持向量机

如果原始空间是有限维,即属性数有限,那么一定存在一个高维特征空
间使样本可分。
我们希望样本在特征空间内线性可分,因此特征空间的好坏对支持向量
机的性能至关重要,需要注意的是,在不知道特征映射的形式时,我们
并不知道什么样的核函数是合适的,而核函数也仅是隐式地定义了这个
特征空间。于是,“核函数选择”成为支持向量机的最大变数,若核函数
选择不合适,则意味着将样本映射到了一个不合适的特征空间,很可能
导致性能不佳。

第7章: 贝叶斯分类

欲使用贝叶斯判定准则来最小化决策风险,首先要获得后验概率
P(c|x),然而,在现实任务中这通常难以直接获得,从这个角度来
看,机器学习所要实现的是基于有限的训练样本集尽可能准确地估计出
后验概率 P(c|x)。大体来说,主要有两种策略:给定x,可通过直接
建模 P(c|x)来预测c,这样得到是“判别式模型”;也可以先对联合概
率分布P(x,c)建模,然后再由此获得P(c|x)这样得到的是“生成式
模型”。显然,前面介绍的决策树、BP神经网络、支持向量机等,都可归
入判别式模型的范畴。

因此估计P(c|x)的问题就转化为如何基于训练数据D来估计先验P(c)
和似然P(x|c)。

类先验概率P(c)表达了样本空间中各类样本所占的比例,根据大数定
律,当训练集包含充足的独立同分布样本时,P(c)可通过各类样本出
现的频率来进行估计。

对类条件概率P(x|c)来说,由于它涉及关于x所有属性的联合概率,直
接根据样本出现的频率来估计将会遇到严重的困难。在现实应用中,这
个值往往远大于训练样本数m,也就是说,很多样本取值在训练集中根本
没有出现,直接使用频率来估计P(x|c)显然不可行,因为“未被观测
到”与“出现概率为零”通常是不同的。

为了避免其他属性携带的信息被训练集中未出现的属性值“抹去”,
在估计概率值时通常要进行“平滑(smoothing)”,常用“拉普拉斯
修正”。显然,拉普拉斯修正避免了因训练集样本不充分而导致概率估
值为零的问题,并且在训练集变大时,修正过程所引入的先验的影响
也会逐渐变得可忽略,使得估值逐渐趋向于实际概率值

拉普拉斯修正实质上假设了属性值与类别均匀分布,这是在朴素贝叶
斯学习过程中额外引入的关于数据的先验。

为了降低贝叶斯公式中估计后验概率P(c|x)的困难,朴素贝叶斯分
类器采用了属性条件独立性假设,但在现实任务中这个假设往往很难
成立,于是,人们尝试了对属性条件独立性假设进行一定程度的放松,
由此产生了一类称为“半朴素贝叶斯分类器”的学习方法。半朴素贝叶
斯分类器的基本想法是适当考虑一部分属性间的相互依赖信息,从而
既不需要进行完全联合概率计算,又不至于彻底忽略了比较强的属性
依赖关系。

nginx 启动问题

发表于 2018-07-09

一、现象描述

运行 nginx -t 启动 nginx 服务,启动后打开浏览器查看首页,找不到页面

二、问题定位

进入 nginx 的 logs 目录

cd  /usr/local/nginx/logs

查看目录文件

ls -l

发现只有 error.log 文件不为空,查看文件内容显示如下

invalid PID number "" in "/usr/local/nginx/nginx.pid"

三、解决方法

执行

nginx -c /etc/nginx/nginx.conf

重启 nginx 服务

nginx -s reload
1…345
Isaac Li

Isaac Li

44 日志
9 分类
36 标签
Links
  • deeplearning.ai
  • AI初学者
  • fast.ai
  • IBM Developer
  • Java Anti-Patterns
  • Tim Dettmers's blog
  • colash's blog
  • 阮一峰的网络日志
  • Dylan's blog
  • shartoo's blog
  • DATAQUEST
  • Java技术驿站
  • w3schools
  • 在线正则表达式测试
© 2018 Isaac Li
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4