【论文笔记】DeepLab系列

【深度学习】总目录

DeepLab系列是谷歌团队提出的一系列语义分割算法。DeepLab v1于2014年推出,随后2017到2018年又相继推出了DeepLab v2,DeepLab v3以及DeepLab v3+。

  • DeepLab v1《Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs》两个创新点是空洞卷积(Atros Convolution)和基于全连接条件随机场(Fully Connected CRF),通过两个模块级联,在PASCAL语义分割挑战中获得了第一,准确率超过第二名7.2%
  • DeepLab v2《DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs》,提出了空洞空间金字塔池化(Atros Spatial Pyramid Pooling,ASPP)。
  • DeepLab v3《Rethinking Atrous Convolution for Semantic Image Segmentation》,重新讨论了空洞卷积的使用,改进了ASPP结构,并把CRFs后处理给移除掉了
  • DeepLab v3+《Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation》,仿照U-Net的结构添加了一个向上采样的解码器模块,用来优化边缘的精度。

语义分割面临的挑战

  • 信号下采样连续的池化或下采样操作会导致图像的分辨率大幅度下降,从而损失了原始信息,且在上采样过程中难以恢复。
  • 空间不变性以获取图像中物体为核心的决策,必然需要空间不变性/不敏感,固有地限制了模型的空间精度。换句话说,对于同一张图片进行空间变换(如平移、旋转),其图片分类结果是不变的。但对于图像分割,对一张图片进行空间变换后,其结果是改变的。
  • 多尺度特征将不同尺度的特征图送入网络做融合,对于整个网络性能的提升很大,但是由于图像金字塔的多尺度输入,造成计算时保存了大量的梯度,从而导致对硬件的要求很高。

DeepLab V1

亮点:空洞卷积

空洞卷积也叫扩张卷积或者膨胀卷积,简单来说就是在卷积核元素之间加入一些空格(零)来扩大卷积核的过程。相同kernel size的空洞卷积和标准卷积的权重shape是一样的,二者的差异在于空洞卷积改变了输入的采样方法, 标准卷积是连续地、不间隔地采样,而空洞卷积是跳跃式地采样,跳跃的步长就是dilation(r)。当r=1时,空洞卷积和普通卷积一样。当r=2时,如下图所示,空洞卷积的感受野大小为7x7,r=3时,感受野大小为15x15。

亮点:CRF(Conditional Random Field)

输入图像经过多层卷积下采样后会导致分辨率大幅下降,这使得像素的位置信息丢失,导致还原图像尺寸的过程pixel的定位有偏失,体现为pixel-wise的最终预测结果不准确,这最主要表现在物体的边缘位置。为了解决这个问题作者采用了fully-connected CRF方法,将网络的输出作为CRF的输入,利用不同位置的像素类别信息关系,通过建立概率图的方式,有效缓解了边缘定位不准确的问题。在DeepLab V3中移除了。

网络结构

(1)使用VGG16作为backbone,和FCN网络一样将全连接层的权重转成了卷积层的权重,构成全卷积网络。第一个全连接层的改空洞卷积,通道数为1024,卷积核大小为3×3(FCN中是7×7),dilate rate设为12时(LargeFOV)效果比设为4时好。对于第二个全连接层(FC2)卷积核个数也由4096采样成1024。

(2)Maxpool略有不同,VGG论文中是kernel=2,stride=2,但在DeepLabV1中是kernel=3,stride=2,padding=1

(3)skip subsampling:将最后两个Maxpool层的stride全部设置成1,不再下采样。并且最后三个3×3卷积采用了空洞卷积,系数r=2

实验

下表为在PASCAL VOC2012验证集上,改变第一个全连接层kernel size和空洞卷积rate后网络的性能和训练速度。

  • DeepLab-CRF-7x7:直接将FC1按照FCN论文中的方法转换成7x7大小的卷积层,并且膨胀因子r=4(receptive field=224)。
  • DeepLab-CRF:将7x7下采样到4x4大小的卷积层,同样膨胀因子r=4(receptive field=128),可以看到参数减半,训练速度翻倍,但mean IOU下降了约4个点。
  • DeepLab-CRF-4x4:在DeepLab-CRF的基础上把膨胀因子r改成了8(receptive field=224),mean IOU又提升了回去了。
  • DeepLab-CRF-LargeFOV:将7x7下采样到3x3大小的卷积层,膨胀因子r=12(receptive field=224),相比DeepLab-CRF-7x7,参数减少了6倍,训练速度提升了3倍多,mean IOU不变

DeepLab V2

亮点: ASPP(Atrous Spatial Pyramid Pooling)

 

上图(a)为DeepLab-LargeFOV主干网络VGG16最后的全连接改卷积的部分,图(b)将Pool5输出的特征层并联4个分支,每个分支分别通过一个3x3的空洞卷积层,1x1的卷积层,1x1的卷积层(卷积核的个数等于num_classes)。最后将四个分支的结果进行Add融合即可。 如右图 所示,为了对中心像素(橙色)进行分类,ASPP通过使用具有不同rate的多个空洞卷积来获得多尺度特征。不同颜色的框表示中心像素在不同rate下的感受野。如果是以ResNet101做为Backbone的话,每个分支只有一个3x3的膨胀卷积层,卷积核的个数等于num_classes。

在论文中有给出两个ASPP的配置,ASPP-S(四个分支膨胀系数分别为2,4,8,12)和ASPP-L(四个分支膨胀系数分别为6,12,18,24),下表是对比LargeFOV、ASPP-S以及ASPP-L的效果。这里只看CRF之前的(before CRF)对比,ASPP-L优于ASPP-S优于LargeFOV

网络结构

(1)以ResNet101作为backbone,将Layer3中的Bottleneck1的3×3卷积(stride=2)的stride设置为1,即不在进行下采样,同时3x3卷积层全部采用空洞卷积,系数为2。在Layer4中也是一样,取消了下采样,所有的3x3卷积层全部采用空洞卷积,系数为4。

(2)在backbone输出的Feature Map上并联四个分支,每个分支的第一层都是使用的空洞卷积,但不同的分支使用的膨胀系数不同(即每个分支的感受野不同,从而具有解决目标多尺度的问题)。当以ResNet101为Backbone时,每个分支只有一个3x3的空洞卷积层,卷积核的个数等于num_classes。

实验

  • MSC表示多尺度输入,即先将图像缩放到0.5、0.7和1.0三个尺度,然后分别送入网络预测得到score maps,最后融合这三个score maps(对每个位置取三个score maps的最大值)。
  • COCO就代表在COCO数据集上进行预训练。
  • Aug代表数据增强,这里就是对输入的图片在0.5到1.5之间随机缩放。

使用ResNet-101取代VGG16作为backbone后,mIOU由65.76%提升到68.72。MSC提升了2.55%,COCO预训练提升了2.01%,数据增强提升了1.6%,LargeFOV(3×3空洞卷积,rate=12)提升了0.6%,池化金字塔提升了0.8%,利用CRF后处理后达到了77.69%。

DeepLab V3

文中有给出两个模型,分别是cascaded modelASPP model,在cascaded model中是没有使用ASPP模块的,在ASPP model中是没有使用cascaded blocks模块的。作者说ASPP model比cascaded model略好点。包括在Github上开源的一些代码,大部分也是用的ASPP model。

Cascaded model

上图中,Block1,Block2,Block3,Block4是原始ResNet网络中的层结构,后面又增加了额外的Block5,Block6,Block7,结构和Block4一样,即由三个残差结构构成。如图(a)中所示,这么设计的原因是引入的stride使在更深的block中捕获long range information变得容易。比如图(a)中整个图像特征可以总结在最后一个小分辨率特征图中。但是连续的stride削弱细节信息,因此加入空洞卷积,并且根据output_stride调整空洞卷积的rate。图(b)是论文中提出的cascaded model,但在Block4中将第一个残差结构里的3x3卷积层以及捷径分支上的1x1卷积层步距stride由2改成了1(即不再进行下采样),并且所有残差结构里3x3的普通卷积层都换成了空洞卷积层

从下表可以看出,随着添加更多的block,模型性能会提高,但提高的幅度会变小。增加block7使得ResNet-50略微降低了性能,但仍提高了ResNet-101的性能。

下表为以ResNet-50为backbone使用7个block时不同output_stride下的mIOU。当output_stride增大且应用空洞卷积时,mIOU从20.29%提升到75.18%,说明在语义分割中使用更多block级联时空洞卷积是很有必要的

上面blocks中真正采用的膨胀系数应该是图中的rate乘上这里的Multi-Grid参数。下表是以cascaded model(ResNet101作为Backbone为例)为实验对象,研究采用不同数量的cascaded blocks模型以及cascaded blocks采用不同的Multi-Grid参数的效果。通过实验发现,当采用三个额外的Block时(即额外添加Block5,Block6和Block7)将Multi-Grid设置成(1, 2, 1)效果最好。

 

Parallel model(ASPP)

虽然论文大篇幅的内容都在讲cascaded model以及对应的实验,但实际使用的最多的还是ASPP model,ASPP model结构如下图所示:

这里的ASPP结构有5个并行分支,分别是一个1x1的卷积层,三个3x3的膨胀卷积层,以及一个全局平均池化层(后面还跟有一个1x1的卷积层,然后通过双线性插值的方法还原回输入的W和H)。然后通过Concat的方式将这5个分支的输出进行拼接(沿着channels方向),最后在通过一个1x1的卷积层进一步融合信息

在并行分支加入image-level feature是因为作者为了解决空洞卷积带来的一个问题:

随着空洞卷积的rate增大,卷积核有效参数越来越少。比如标准卷积conv3×3,rate=1,只有在feature map最外面一圈会有卷积核参数超出边界而无效,当rate变大,越来越多外圈的位置是有卷积核参数失效的,用极限思想思考一下,如果rate=size(feature map),那么每次卷积都是卷核中心对应的feature map像素点被计算了,卷积核参数也只有中心那个点没有失效,退化成了1×1卷积核

为了解决这一问题,并且包含全局上下文信息,作者在并联结构中加入image-level feature。做法是先对输入的feature map全局平均池化(global average pooling),后接256通道的1×1卷积层,BN层,最后用户双线性插值的方法上采样到目标大小,即与ASPP输出的feature map尺寸相同。

下表是ASPP模型在output_stride=16的情况下,multi-grid和image-level features的效果。首先,在三个3×3卷积的并行分支中采用rate=(6,12,18),然后block4中使用三种不同的multi-grid,可以看出multi-grid=(1,2,4)效果最好。多加一个并行分支rate=24会使得mIOU下降0.12%,使用image-level features可以提升0.63%

两个模型比

  • MG代表Multi-Grid,刚刚在上面也有说在ASPP model中采用MG(1, 2, 4)是最好的。
  • ASPP三个3×3的空洞卷积rate分别为6,12,18
  • Image Pooling代表在ASPP中加入全局平均池化层分支。
  • OS代表output_stride,在训练时将output_stride设置成16,验证时将output_stride设置成8效果会更好。
  • MS代表多尺度,和DeepLabV2中类似。不过在DeepLab V3中采用的尺度更多scales = {0.5, 0.75, 1.0, 1.25, 1.5, 1.75}。
  • Flip代表增加一个水平翻转后的图像输入。
  • COCO代表在COCO数据集上进行预训练。挑选COCO数据集中有VOC定义的类别的图,将VOC中不包含的类别当作背景类。

ASPP模型的效果(79.77%)好于Cascaded模型(79.35%),所以deeplab v3一般也是指ASPP的结构。

DeepLab V3+

空间金字塔池化模块网络能够通过不同空洞率的、具有不同感受野的空洞卷积或池化操作,编码多尺度上下文信息,而编码器-解码器结构可以通过逐步恢复空间信息来捕获更清晰的目标边界。deeplab v3+结合了这两种方法的优点。添加了解码器模块细化分割结果,特别是沿着对象边界。同时进一步探索了Xception模型,并将深度可分离卷积应用于空间空间金字塔池化和解码器模块,从而得到一个更快更强的编解码器网络。

空洞可分离卷积(atrous seperable convolution)

 

上图中(a)是深度卷积,单独的为每个channel进行卷积操作;(b)是点卷积用来融合channel间的信息。(a)和(b)就组成了深度可分离卷积。那如果将(a)中的标准卷积操作替换为空洞卷积,如图(c)所示就实现了带有空洞卷积的深度可分离卷积,论文称之为空洞可分离卷积(atrous seperable convolution)。论文应用空洞可分离卷积极大的减少所提出模型的计算复杂度与此同时维持了与原模型相似或者更好的模型效果。

Encoder

将Deeplab v3作为编码器模块,输出特征图包含256个通道数。DeepLab v3+以Xception作为骨干网络,并对其进行了微调(如下图所示):

  • 更深的Xception结构,原始middle flow迭代8次,微调后迭代16
  • 所有max pooling结构被stride=2的深度可分离卷积替代
  • 每个3x3的depthwise convolution后都跟BNRelu 

Decoder

DeepLabv3直接将特征上采样16倍,无法成功地恢复目标分割的细节。因此,作者提出了一个简单而有效的解码器模块,如下图红色框内。编码器特征首先提前上采样4倍,然后与网络主干中具有相同空间分辨率的相应低级特征连接。同时应用一个1×1的卷积调整通道数(256个),在连接之后,应用几个3×3卷积来细化特征,然后使用双线性插值,将特征上采样4倍。

评估decoder中1×1卷积的作用

使用resnet-101,Conv2的特征图和256个3×3卷积,分别将low level features减少到8,16,32,48,64通道数,其中48通道效果更好

设计3×3卷积结构

concat特征图之后,利用2个256通道的3×3卷积效果比用1个和3个要好,减少通道数或者减小kernel size都会使得效果变差。下面的Conv3是指,将特征图上采样两倍和Conv3特征图concat,再与Conv2特征图concat。

效果

当使用Xception作为DeepLabv3+的backbone时,为了比较精度和速度的变化,观察了mIOU以及Multiply-Adds。得益于空洞卷积,模型在训练时能够在不同分辨率下获取特征以及在模型验证时使用单一模型。

  • OS代表output_stride,在训练时将output_stride设置成16,验证时将output_stride设置成8效果会更好。
  • Decoder表示是否使用本文提出的decoder模块
  • MS代表多尺度,和DeepLabV2中类似。不过在DeepLab V3中采用的尺度更多scales = {0.5, 0.75, 1.0, 1.25, 1.5, 1.75}。
  • Flip代表增加一个水平翻转后的图像输入。
  • SC表示是否采用深度可分离卷积在ASPP以及decoder模块中
  • COCO代表在COCO数据集上进行预训练。挑选COCO数据集中有VOC定义的类别的图,将VOC中不包含的类别当作背景类。
  • JFT表示模型是否在JFT上预训练

以resnet-101为骨干网络时mIOU为80.57%,相同策略下以Xception为骨干网络时为81.63%,Decoder提升了0.29%

 

 

参考

1. DeepLabV3网络简析

2. DeepLab系列(v1,v2,v3,v3+)总结

3. 我对DeepLab V3的理解(基于V1和V2)

4. DeepLab系列

5. DeepLabv3+

本文转载于网络 如有侵权请联系删除

相关文章

  • 每天坚持20分钟go画图

    常用的图表软件Echarts百度出品BizCharts商业化React编写chart.jshightCahrts画图https://github.com/go-echarts/go-echarts摘自github上面的例子,非常好用强大哦packagemain import( "math/rand" "net/http" "github.com/go-echarts/go-echarts/v2/charts" "github.com/go-echarts/go-echarts/v2/opts" "github.com/go-echarts/go-echarts/v2/types" ) //generaterandomdataforlinechart funcgenerateLineItems()[]opts.LineData{ items:=make([]opts.LineData,0) fori:=0;i<7;i++{ items=append(items

  • 分布式系统之道:Lamport 逻辑时钟

    引子@禅与计算机程序设计艺术 Lamport认为,在动手写代码之前,要先思考和写作的重要性。图灵奖得主、分布式系统先驱、LaTeX之父LeslieLamport认为,对于程序员而言,对数学思维的强调永远不会过分,要写出好代码,不能惧怕数学。但基本上,程序员和许多计算机科学家都被数学吓坏了。 Whatwaswrongwiththeiroriginalalgorithm? Well,theydidn’thaveanalgorithm,justabunchofcode.Veryfewprogrammersthinkintermsofalgorithms.Whentryingtowriteaconcurrentsystem,ifyoujustcodeitwithouthavingalgorithms,there’snowaythatyourprogramisnotgoingtobefullofbugs. ---LeslieLamport,2013年图灵奖得主:如何写出数学上完美的算法关键问题分布式系统解决了传统单体架构的单点问题和性能容量问题,另一方面也带来了很多的问题,其中一个问题就是多节点

  • laravel jwt 无感刷新token

    为保证和前端交互过程中,用户可以自动刷新token1.创建一个中间件文件,命名为RefreshToken<?php namespaceApp\Http\Middleware; useAuth; useClosure; useTymon\JWTAuth\JWTAuth; useTymon\JWTAuth\Exceptions\JWTException; useTymon\JWTAuth\Http\Middleware\BaseMiddleware; useTymon\JWTAuth\Exceptions\TokenExpiredException; useSymfony\Component\HttpKernel\Exception\UnauthorizedHttpException; classRefreshTokenextendsBaseMiddleware { functionhandle($request,Closure$next) { //检查此次请求中是否带有token,如果没有则抛出异常。 $this->checkForToken($request); /

  • 05.序列模型 W2.自然语言处理与词嵌入(作业:词向量+Emoji表情生成)

    文章目录作业1:1.余弦相似度2.单词类比3.词向量纠偏3.1消除对非性别词语的偏见3.2性别词的均衡算法作业2:Emojify表情生成1.Baselinemodel:Emojifier-V11.1数据集1.2模型预览1.3实现Emojifier-V11.4在训练集上测试2.Emojifier-V2:UsingLSTMsinKeras2.1模型预览2.2Kerasandmini-batching2.3Embedding层2.3建立Emojifier-V2测试题:参考博文笔记:W2.自然语言处理与词嵌入作业1:加载预训练的单词向量,用cos(θ)余弦夹角测量相似度使用词嵌入解决类比问题修改词嵌入降低性比歧视importnumpyasnp fromw2v_utilsimport*复制这个作业使用50-维的GloVevectors表示单词words,word_to_vec_map=read_glove_vecs('data/glove.6B.50d.txt')复制1.余弦相似度#GRADEDFUNCTION:cosine_similarity defcosine_sim

  • 原创 | 一半人写不出冒泡排序,你的同龄人都躺下了

    今天这篇不是正经的吹水文,属于有感而发吧。前段时间在知乎上回答了一个问题“计算机学院的学生该怎样提高自己的编程能力?”,下面的回答五花八门,有些人分享各种各样的资料,什么学Java的,学操作系统的,等等。还有些人说要学好算法、数据结构刷LeetCode的,还有些人讲怎么做网站的,就是没有一个人说一句好好学习的。其实我挺失望的,因为我觉得这一点看起来耳熟能详甚至是烂熟的东西才恰恰是很多人需要的。当年有一篇网红文,叫做《摩拜创始人胡玮炜套现15亿:你的同龄人正在抛弃你》。但其实你如果了解一下现状的话,会发现你的同龄人非但没有抛弃你,反而都躺下了,一副再也不想起来的样子。惊人的现状轮子哥曾经在知乎里讲过这么一个事,当年他毕业的时候,有一个公司(我依稀记得是微软)来上海招聘。第一轮笔试出的算法题是冒泡排序,全场只有一半的学生写了出来。没毕业的人听这个估计会觉得很夸张,这不是考试必考的东西么?科班出身的一定会的东西啊?就算不是科班出身的,也是必学的内容,怎么还能不会呢?但是在我看来,这简直太正常了,我的版本的故事估计会让你们更惊讶。我毕业的时候是在2016年,差不多四年多之前。我们计算机学院一个

  • 动态执行脚本

    提到动态执行脚本,大家想到的肯定是eval或newFunction(),在nodejs中有专属的vm模块,可以完成相应的sandbox作用。浏览器中动态执行脚本eval()函数会将传入的字符串当做JavaScript代码进行执行,返回字符串中代码的返回值;如果参数不是字符串将原封不动返回。如果你间接的使用eval(),比如通过一个引用来调用它,而不是直接的调用eval。从ECMAScript5起,它工作在全局作用域下,而不是局部作用域中。functiontest(){ letx=2,y=4; console.log(eval('x+y'));//直接调用,使用本地作用域,结果是6 letgeval=eval;//等价于在全局作用域调用 console.log(geval('x+y'));//间接调用,使用全局作用域,throwsReferenceError因为`x`未定义 (0,eval)('x+y');//另一个间接调用的例子 }复制eval中函数作为字符串被定义需要“(”和“)”作为前缀和后缀letfctStr1=

  • C语言网络编程-tcp服务器实现

    5种io模型tcp服务器分为了5种io复用模型,分别是:阻塞io模型    非阻塞io模型io复用信号驱动io异步io 本文会讲前面3种io模型的tcp服务器实现(本文只做tcp服务器实现,客户端逻辑处理,接收数据等缓冲区不做深入说明)简单实现首先,我们需要理解下tcp服务器的创建过程:1:通过socket函数创建一个套接字文件2:通过bind函数将本地一个地址和套接字捆绑3:使用listen函数监听外部请求4:使用accept函数接收外部请求5:read,write,close用于收,发,关闭客户端数据好了,我们了解了tcp服务器的创建过程,就开始实现吧:#include <stdio.h> #include <arpa/inet.h>//inet_addr() sockaddr_in #include <string.h>//bzero() #include <sys/socket.h>//socket #include <unistd.h> #include <stdlib.h>//exit() #defi

  • SGMII接口前导码小于7个字节55的情况

    在使用XilinxFPGA芯片中SGMIIIP核进行千兆以太网调试时,经常会遇到以太网接口收到的前导码长度不足7个字节55的情况,但这种情况确实正常现象。这就要求在设计代码处理前导码时不能将55的个数作为判据,而是只要有55转换为D5,就应该认为前导码接收成功了。SGMII接口基本功能测试SGMII接口(开启自协商)调试分为三个步骤,先测试SGMII最基本功能仿真、再测试SGMII最基本功能自回环上板、最后直接测试开启自协商功能后上板1、测试SGMII基本功能仿真:(1)打开sgmiiIP,将接口选择为sgmii接口,关闭MDIO接口,其它选项默认,生成IP核;(2)根据IP核生成exampledesign,将speed_is_10_100、speed_is_100设置为0(1000Mbps模式),将configuration_vector设置为5‘b00010(关闭SGMII自协商,开启PMA回环,具体参考手册63页table2-39),将userclk2作为跟GMII接口同步的时钟(用来驱动MACGMII接口侧,也可以用来驱动其它模块);(3)开启仿真,测试自回环(也可以通过修改参

  • fis3 commonJs中的moduleId

    本文作者:IMWeb袁飞翔原文出处:IMWeb社区未经同意,禁止转载 首先看一个有趣的问题//fis-conf.js fis.hook('commonjs') .match('/modules/common/utils',{ isMod:true, moduleId:'utils'//为utils设置一个moduleId,希望以后能直接require('utils') }) .match('::package',{ postpackager:[ fis.plugin('loader',{ resourceType:'commonJs' }) ] })复制<!--main.html--> <!DOCTYPEhtml> <htmllang="en"> <head> <metacharset="UTF-8"> <title></title

  • 腾讯大禹抗D携手清华,上演最新DDoS攻防|GeekPwn2019

    DDoS(分布式拒绝服务)攻击由于往往能造成大面积的网络瘫痪,导致企业业务中断,被称为攻击中的“核武器”。但你能想象吗,攻击者甚至无需控制僵尸网络,仅通过个人电脑、低带宽网络,就可以调用全球CDN资源发起DDoS攻击,让你的服务器访问缓慢甚至瘫痪?在10月24日国际安全极客大赛GeekPwn2019上海站现场,来自清华-奇安信联合研究中心的安全团队和腾讯安全大禹DDoS防护团队一起,展示了双方共同的研究成果,对一种全新的DDoS攻击方式进行了演示——在主办方搭建的网站环境下,选手通过一台普通笔记本电脑和低带宽网络,调用全球CDN资源发起大规模DDoS攻击,瞬间占满3GB带宽,让目标网站的访问速度慢了10倍,随后腾讯安全大禹DDoS防护团队对攻击流量进行了清洗。主持人黄健翔宣布演示开始后,清华-奇安信联合研究中心的五名成员开始操作一台笔记本电脑,短短十几秒之后,背后大屏幕上的监测数据就开始出现变化,出流量带宽迅速升高,几秒后就达到了挑战要求的3GB峰值,与此同时被攻击网站的访问开始出现严重延迟。根据监控屏幕上的“地图炮”显示,选手成功通过一台笔记本电脑调用了全球的CDN资源对目标发起了攻

  • SpringAop源码分析(基于注解)三:创建代理对象

    我们先回到Bean初始化之后,调用BeanPostProcessor后置处理器的地方。//AbstractAutoProxyCreator.java //在Bean初始化之后回调 @Override publicObjectpostProcessAfterInitialization(@NullableObjectbean,StringbeanName)throwsBeansException{ if(bean!=null){ ObjectcacheKey=getCacheKey(bean.getClass(),beanName); //判断缓存中是否有 if(!this.earlyProxyReferences.contains(cacheKey)){ //没有,为bean生成代理对象 returnwrapIfNecessary(bean,beanName,cacheKey); } } returnbean; }复制wrapIfNecessary代码://AbstractAutoProxyCreator.java protectedObjectw

  • 161bytes的PE文件是如何炼成的~

    161bytes的PE文件是如何炼成的~本文视你对PE文件的熟悉程度,初学者,大概会花掉你两个小时左右的时间完全理解。 最近在网上看到有大神做了个161bytes的hello world,正巧毕业前忧郁闲着,就花几个小时的时间把这个程序结构厘清了一遍,算是重新更深入地学习一次PE文件,写下本文和大家交流。 预备工具:一个xp系统,win7下它跑不动。Winhex,记得弄个破解版。其它的一些你习惯的PE查看工具(我试了几个都不能很好解析这个PE,其实PE解析工具就是在模仿windows解析PE文件,如果程序员本身都对PE文件没有一个深入的理解,写出来的工具模仿windows加载器不够像,就不足够应付畸形的却能够正常运行的PE) 下面先附上十六进制。 4D5A0000504500004C010100E97700000000007869616F00280002000B0148656C6C6F20576F726C642100000C0000005553455233320000000040000400000004000000300000009D000000040000000C0000003

  • Android开发笔记(二十九)使用SharedPreferences存取数据

    SharedPreferences使用场景 共享参数(SharedPreferences)是Android上的一个轻量级存储工具,存储结构是类似map的key—value键值对形式。它主要用于保存app的基础设置,比如说app当前已安装的版本号,这样下次app版本更新时就能根据之前的版本号作相应处理。因为app每次更新都可能创建新的数据表,从版本7升级到版本10,对比版本9升级到版本10,前一种升级可能要创建更多的表,所以此时很有必要从SharedPreferences中读取之前的版本号,这样才能根据不同版本号做不同的分支处理。 另外,SharedPreferences还可用于保存Activity状态,当Activity暂停时,将此activity的状态保存到SharedPereferences中(主要是保存该activity必须的一些参数信息);当Activity重载时,系统回调方法onSaveInstanceState时,再从SharedPreferences中将值取出。 SharedPreferences存储数据 挺简单的,直接贴出示例代码,其中getSharedPref

  • 002android初级篇之ViewPager及PagerSlidingTabStrip listview的使用

    ViewPagerViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类。ViewPager类需要一个PagerAdapter适配器类给它提供数据。ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。 在编写ViewPager的应用的使用,还需要使用两个组件类分别是PagerTitleStrip类和PagerTabStrip类,PagerTitleStrip类直接继承自ViewGroup类,而PagerTabStrip类继承PagerTitleStrip类,所以这两个类也是容器类ps:view中的资源发生变动,相应的PageAdapter必须调用notifyDataSetChanged。在退出使用ViewPager的界面时,记得在退出之前调用其removeAllViews方法,避免频繁进出该界面时内存不断上涨;参考链接PagerSlidingTabStrip介绍及使用,让ViewPage

  • 总结五种常见的排序算法

    1 概述    本文对比较常用且比较高效的排序算法进行了总结和解析,并贴出了比较精简的实现代码,包括选择排序、插入排序、归并排序、希尔排序、快速排序等。算法性能比较如下图所示:2 选择排序 选择排序的第一趟处理是从数据序列所有n个数据中选择一个最小的数据作为有序序列中的第1个元素并将它定位在第一号存储位置,第二趟处理从数据序列的n-1个数据中选择一个第二小的元素作为有序序列中的第2个元素并将它定位在第二号存储位置,依此类推,当第n-1趟处理从数据序列的剩下的2个元素中选择一个较小的元素作为有序序列中的最后第2个元素并将它定位在倒数第二号存储位置,至此,整个的排序处理过程就已完成。    代码如下:publicclassSelectionSort{ publicvoidselectionSort(int[]array){ inttemp; for(inti=0;i<array.length-1;i++){ for(intj=i+1;j<=array.length-1;j++){//第i个和第j个比较j可以取到最后一位,所以要用j<=array.length-1 if(a

  • PhpSpreadsheet_php读取文件内容

    大家好,又见面了,我是你们的朋友全栈君。1、实例化Spreadsheet对象<?php namespaceapp //给类文件的命名空间起个别名 usePhpOffice\PhpSpreadsheet\Spreadsheet; //Xlsx类保存文件功能类 usePhpOffice\PhpSpreadsheet\Writer\Xlsx; //实例化Spreadsheet对象 $spreadsheet=newSpreadsheet();复制2、Spreadsheet对象方法介绍<?php namespaceapp //给类文件的命名空间起个别名 usePhpOffice\PhpSpreadsheet\Spreadsheet; //实例化Spreadsheet对象 $spreadsheet=newSpreadsheet(); //1获取活动工作薄 $sheet=$spreadsheet->getActiveSheet(); //2获取单元格 $cell=$sheet->getCell('A1');//方法1 $cell=$sheet->g

  • System Toolkit for Mac(mac系统维护软件)v5.9.6中文激活版

    SystemToolkitMAC版是一款功能强大的系统维护软件,SystemToolkitMAC版可以预览系统基本信息,监测处理器和内存使用情况。SystemToolkitforMac(mac系统维护软件)功能介绍      •系统信息      跟踪所有系统负载。这包括CPU负载,内存使用率,网络速度和流量以及开放的网络连接。所有信息都可以在菜单栏的额外和覆盖窗口中显示。使用仪表板来查看最重要的参数。      •菜单栏额外      您可以根据需要添加任意数量的菜单栏小部件。可以将每个菜单栏小部件配置为显示信息。      •叠加窗口      覆盖窗口始终保持在其他窗口的顶部。所以即使你有一个全屏应用程序运行,你可以使用覆盖窗口跟踪你的系统。就像菜单栏小部件一样,覆盖窗口可以配置为显示任何系统信息-包括硬件传感器数据。      •硬件传感器      注意所有硬件传感器数据。这包括处理器,内存,电池和主板的温度,功率,电压和电流。该应用程序还显示了内部粉丝的速度。      •蓝牙设备电池电量      系统工具包显示电池电量蓝牙输入设备。支持以下设备:AppleMagicMo

  • 四元数

    .x的骨骼动画关于旋转部分,采用的是四元数存储。 即w,x,y,z 可以认为w是旋转的角度x,y,z是旋转轴 实际上它们有如下关系 w=cos(a); x=sin(a)*Vx*i; y=sin(a)*Vy*j; z=sin(a)*Vz*k; 其中a为旋转角度, Vn=(Vx,Vy,Vz)为旋转轴 而ijk是四元数的三个维度,可以认为是虚部  有i*i=-1, j*j=-1,k*k=-1 并有i*j=-k,任意两个的乘积都有类似的关系 四元数构造了一个代数上的巧合,即一个向量v与四元数(四元数的模为1)做乘法,得到的结果相当于把 v绕向量Vn=(Vx,Vy,Vz)在与Vn垂直的平面内旋转; 所有引擎都是这么定义旋转q*v*q(-1)这样可以保存模为1,但转了两倍的角度。 比想像中的要简单,网上也有很多论文推导了四元数旋转公式。 笔者将在后继简要整理说明四元数旋转的推导过程,

  • 每天一个linux命令(53):route命令

    原文地址;http://www.cnblogs.com/peida/archive/2013/03/05/2943698.html   Linux系统的route命令用于显示和操作IP路由表(show / manipulate the IP routing table)。要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现。在Linux系统中,设置路由通常是为了解决以下问题:该Linux系统在一个局域网中,局域网中有一个网关,能够让机器访问Internet,那么就需要将这台机器的IP地址设置为Linux机器的默认路由。要注意的是,直接在命令行下执行route命令来添加路由,不会永久保存,当网卡重启或者机器重启之后,该路由就失效了;可以在/etc/rc.local中添加route命令来保证该路由设置永久有效。 1.命令格式: route [-f] [-p] [Command [Destination] [mask Ne

  • Redis启动命令

      启动redis   打开cmd窗口,执行命令:redis-serverredis.windows.conf

  • Dubbo源码构建

    代码签出 通过以下的这个命令签出最新的项目源码: gitclonehttps://github.com/apache/incubator-dubbo.gitdubbo复制 分支 我们使用master作为主干版本的开发,使用分支作为维护版本。可以通过https://github.com/apache/incubator-dubbo/tags来查看所有版本的标签。 构建 Dubbo使用maven作为构建工具。 要求 Java1.5以上的版本 Maven2.2.1或者以上的版本 构建之前需要配置以下的MAVEN_OPTS exportMAVEN_OPTS=-Xmx1024m-XX:MaxPermSize=512m复制 使用以下命令做一次构建 mvncleaninstall复制 可以通过以下的构建命令来跳过单元测试 mvninstall-Dmaven.test.skip复制 构建源代码jar包 通过以下命令以构建Dubbo的源代码jar包,方便用来调试Dubbo源代码 mvncleansource:jarins

相关推荐

推荐阅读