深度卷积网络CNN与图像语义分割

说好的要笔耕不缀,这开始一边实习一边找工作,还摊上了自己的一点私事困扰,这几个月的东西都没来得及总结一下。这就来记录一下关于CNN、Caffe、Image Sematic Segmentation相关的工作,由于公司技术保密的问题,很多东西没办法和大家详说只能抱歉了。在5月份前,我也是一个DL和CNN的门外汉,自己试着看tutorials、papers、搭Caffe平台、测试CNN Net,现在至少也能改改Caffe源码(Add/Modify Layer)、基于Caffe写个Demo。这里希望把学习的过程分享给那些在门口徘徊的朋友。没法事无巨细,但希望能起到提点的作用!“乍可刺你眼,不可隐我脚”。

级别1:DL快速上手

DL只是一个概念而已。对于做图像和视觉的就该一头扎到CNN(Convolutional Neural Netwok),做自然语言的就该投入到RNN(Recurrent Neural Network)。我是做图像的。CNN的学习资料除了上面Ng的tutorial外,还有一个Stanford Li Fei-Fei教授的课程cs231:Convolutional Neural Networks for Visual Recognition,是Notes中一份关于CNN非常详细的资料。

级别2:从Caffe着手实践

先看看这个热个身:贾扬清:希望Caffe成为深度学习领域的Hadoop,增加点学习的欲望,毕竟现在多少人靠着Hadoop那玩意儿挣着大钱。

接着请认准Caffe官方文档:和Github源码:https://github.com/BVLC/caffe。毫不犹豫fork一份到自己的Github。然后就是照着INSTALL来Complie和Config Caffe了,值得注意的是,安装OpenCV的时候推荐使用源码安装。

先自己熟悉Caffe的架构,主要参考资料就是官网文档,我自己刚开始的时候也写了个小的ppt笔记:Diving into Caffe.pptx

还有两份不错的Caffe tutorials:

搞明白SGD中weight的更新方法,可以参考Caffe网站上tutorial的Solver部分:。

好了,现在试着去跑跑${CAFFE_ROOT}/example下LeNet的example吧。

级别3:读paper,网络Train起来

当去搜索ICRL、CVPR、ICCV这些最前沿的计算机视觉、机器学习会议的时候,只要是涉及图像相关的深度学习实验,大都是基于Caffe来做的。所以,只要抓住1~2篇popular的paper深入,把论文中的CNN在Caffe上复现了,就能找到一些感觉了。在这期间,下面一些经典论文是至少要读一读的:

具体到用CNN做Sematic Segmentation,利用到全卷积网络,对下面两篇进行了精读,并且都Caffe上复现过并用于分割任务,

这两篇paper有一个共同点,都用到了multiscale的信息(也就是将High Layer的输出与Low Layer的输出进行结合),这对促进分割效果有很大的作用。值得一提的是,在Train multiscale的model时,由于存在反卷积或上采样的操作,Layer相对复杂,很难一大锅扔进去还Trian得很好,所以通常会先Train一个无multiscale的model,再用该model去finetune含multiscale的Net。

级别4:Demo跑起来读一些源码玩玩

上面仅仅是我随手写在草稿纸上的随笔,其实自己看看源码,依葫芦画瓢写一个简单的Layer就知道了。

熟悉Caffe接口,写Demo这是硬功夫

Caffe提供了好用的接口,包括matlab、C++、Python!由于特殊原因,我不能公开我C++和matlab的Demo源码以及其中的一些后处理技术,暂且只能给大家看一些分割的结果:

Sematic Segmentation Result

还有一个视频语义分割的结果,大家看看,热闹热闹就好,

分析各层Layer输出特征

我一开始以为看看各层Layer的输出,能帮助我改进Net,可却发现错了,除了前几层还能看出点明亮或边缘信息外,,网络后端Layer的输出压根就没办法理解。extract_featmat.cpp是我基于extract_features.cpp改的一个Caffe tool,放到tools目录下编译就好了,使用方法看help:

void print_help(void) {LOG(ERROR)<<; }

下面图是一些Layer的输出blob,从结果可以看出,前面的layer还能看到一些边缘信息,后面的layer就完全看不出原图像相关的信息了,

不同Layers的Feature变化

级别5:何不自己搭个CNN玩玩

虽然还是个新手,关于搭建CNN,还在慢慢在找感觉。我觉得从两方面:

利用已有的网络,使劲浑身解数找它们的缺点,改进它们

熟读Googlenet和VGGnet那两篇paper,两者的CNN结构如下:

GoogleNet

VGGNet

VGG不是Weight Filter不是非常厚么,卷积操作复杂度就高。而Googlenet通过Inception中1×1的Convolution刚好是为了减少Weight Filter的厚度,我最近一段时间在尝试做的事就是将VGG中的Layer用Googlenet中的Inception的方式去替代,希望至少在时间上有所改进。

从头搭建一个CNN用于解决实际问题。一个词:搭积木。

先搭一个简单的,比如说就3层:卷积-Pooling-卷积-Pooling-卷积-Pooling,先把这个简单的网络训练以来,效果不好没关系,我们接着往上加,直到满意为止。不明白的看看上面的VGG Net,先在ImageNet上Train出一个A网络,然后增加A的深度(粗体的部分)变成B,再用A去初始化B网络,就逐级增加网络深度。 这里面有一个finetune的技巧,那就是用浅层的网络训练weight结果去初始化或finetune深层网络。这也是为什么不直接一开始就搭建深层网络的原因,前面说过,深度网络的Train是个非凸问题,是个至今难解决的大问题,网络初始化对其收敛结果影响很大,finetune就这样作为Deep Network中一项最重要的tricks而存在了。finetune除了由浅至深逐级初始化帮助收敛外,还有一个作用:将自己的网络在一个非常非常大的数据集上(现在最大的ImageNet)进行Train,这个Train的结果再拿去作为实际要解决的问题中用于初始化,这样能增加网络的泛化能力。 关于更多的问题,现在也是盲人摸象,暂且搁下不提。

Train CNN时关于数据集的一些注意事项论数据集的重要性不敢接受失败的人,往往是那些追求完美的人,

深度卷积网络CNN与图像语义分割

相关文章:

你感兴趣的文章:

标签云: