日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/7/25 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度卷积网络CNN与图像语义分割 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載請注明出處:? http://xiahouzuoxin.github.io/notes/html/深度卷積網絡CNN與圖像語義分割.html
  • 級別1:DL快速上手
  • 級別2:從Caffe著手實踐
  • 級別3:讀paper,網絡Train起來
  • 級別4:Demo跑起來
    • 讀一些源碼玩玩
    • 熟悉Caffe接口,寫Demo這是硬功夫
    • 分析各層Layer輸出特征
  • 級別5:何不自己搭個CNN玩玩
    • Train CNN時關于數據集的一些注意事項
  • 級別6:加速吧,GPU編程
  • 關于語義分割的一些其它工作

說好的要筆耕不綴,這開始一邊實習一邊找工作,還攤上了自己的一點私事困擾,這幾個月的東西都沒來得及總結一下。這就來記錄一下關于CNN、Caffe、Image Sematic Segmentation相關的工作,由于公司技術保密的問題,很多東西沒辦法和大家詳說只能抱歉了。在5月份前,我也是一個DL和CNN的門外漢,自己試著看tutorials、papers、搭Caffe平臺、測試CNN Net,現在至少也能改改Caffe源碼(Add/Modify Layer)、基于Caffe寫個Demo。這里希望把學習的過程分享給那些在門口徘徊的朋友。沒法事無巨細,但希望能起到提點的作用!“乍可刺你眼,不可隱我腳”。

級別1:DL快速上手

  • UFLDL:?http://deeplearning.stanford.edu/tutorial/

    這是stanford Ng老師的教材,也剛好是以CNN為主,Ng老師教材的特色就是簡潔明白。一遍看不懂多看兩遍,直到爛熟于心,順便把里面的Matlab Exercises完成了。

  • http://deeplearning.net/tutorial/

    PRML作者給的Python入門DL的tutorial,基于Theano Framework,有些偏向于RNN的東西。

  • 一句簡單的話描述:“深度學習就是多層的神經網絡”。神經網絡幾十年前就有了,而且證明了“2層(1個隱層)的神經網絡可以逼近任意的非線性映射”,意思就是說,只要我的參數能訓練好,2層神經網絡就能完成任意的分類問題(分類問題就是將不同類通過非線性映射劃分到不同的子空間)。但2層神經網絡存在的問題是:

    如果要逼近非常非常復雜的非線性映射,網絡的權值W就會很多,造成Train時候容易出現的問題就是Overfitting。所以大事化小,將復雜問題進行分割,用多層網絡來逼近負責的非線性映射,這樣每層的參數就少了。自然而然的網絡就從2層變成了多層,淺網絡(shallow)就變成了深網絡(deep)。

    但科研界的大牛們會這么傻嗎,十幾年前會想不到用多層網絡來進行非線性映射?看看CNN最早的工作:http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf?那是98年的,Train了一個5層的CNN來進行MINIST數據集的數字圖片分類。多層神經網絡一直不火我覺得有這么兩個原因:

  • 神經網絡中非線性的映射的極值優化問題本身是一個非凸問題,本身數學理論上的就對非凸優化問題缺少嚴格有效最優化方法的支撐。直到現在也依然對各層Layer的輸出解釋不清不楚,但效果就是好,這還得歸功于各種大神藏之捏之的各種Tricks
  • 數據與計算能力的問題。十來年前哪來隨隨便便就這么大的硬盤,哪里去找像ImageNet這樣1000類的數據集。“大數據是燃料,GPU是引擎”,正是因為大數據的出現和GPU編程的出現帶動了DL的進展,這些在10年前是做不來的。我在CPU與GPU上跑自己簡化的Googlenet,GPU比CPU快10倍。
  • DL只是一個概念而已。對于做圖像和視覺的就該一頭扎到CNN(Convolutional Neural Netwok),做自然語言的就該投入到RNN(Recurrent Neural Network)。我是做圖像的。CNN的學習資料除了上面Ng的tutorial外,還有一個Stanford Li Fei-Fei教授的課程cs231:Convolutional Neural Networks for Visual Recognition,http://cs231n.github.io/convolutional-networks/?是Notes中一份關于CNN非常詳細的資料。

    級別2:從Caffe著手實踐

    先看看這個熱個身:賈揚清:希望Caffe成為深度學習領域的Hadoop,增加點學習的欲望,畢竟現在多少人靠著Hadoop那玩意兒掙著大錢。

    接著請認準Caffe官方文檔:?http://caffe.berkeleyvision.org/?和Github源碼:?https://github.com/BVLC/caffe?。毫不猶豫fork一份到自己的Github。然后就是照著INSTALL來Complie和Config Caffe了,值得注意的是,安裝OpenCV的時候推薦使用源碼安裝。

    先自己熟悉Caffe的架構,主要參考資料就是官網文檔,我自己剛開始的時候也寫了個小的ppt筆記:Diving into Caffe.pptx

    還有兩份不錯的Caffe tutorials:

  • Standford CS231課程的Caffe tutorial
  • Oxford的Caffe tutorial
  • 接著就是要自己動手,實打實地分析一個CNN,比如LeNet、AlexNet,自己在紙上畫一畫,像下面那樣

    LeNet

    AlexNet

    搞明白下面這些玩意的作用,沒見過的就google一個個的查:

  • Convolution
  • Pooling
  • ReLU: Rectified Linear Units
  • LRN: Local Response Normalization
  • finetune
  • dropout
  • 搞明白SGD中weight的更新方法,可以參考Caffe網站上tutorial的Solver部分:http://caffe.berkeleyvision.org/tutorial/solver.html?。

    好了,現在試著去跑跑${CAFFE_ROOT}/example下LeNet的example吧。

    級別3:讀paper,網絡Train起來

    當去搜索ICRL、CVPR、ICCV這些最前沿的計算機視覺、機器學習會議的時候,只要是涉及圖像相關的深度學習實驗,大都是基于Caffe來做的。所以,只要抓住1~2篇popular的paper深入,把論文中的CNN在Caffe上復現了,就能找到一些感覺了。在這期間,下面一些經典論文是至少要讀一讀的:

  • LeNet-5:?Gradient-Based Learning Applied to Document Recognition?CNN首篇paper,雖然是1998年的文章,但依然值得仔細一讀,熟悉下CNN這玩意兒。
  • AlexNet:?ImageNet Classification with Deep Convolutional Neural Networks?自我感覺是促進CNN的扛鼎之作,似乎很多所謂的Tricks在這篇文章中能找到,看這篇文章就是來學Tricks的。你在這里能看到諸如Overlap Pooling、LRN、帶momentum的SGD等等。
  • Googlenet:?Going Deeper with Convolutions?ImageNet競賽Number1,有效的Inception結構給我映像深刻。
  • VGGNet:?Very Deep Convolutional Networks for Large-Scale Image Recognition?ImageNet競賽Number2,典型的卷積+Pooling方式構建深層網絡,但是由于沒有Googlenet中Inception的1x1的convolution用于減小網絡厚度,時間上要比Googlenet慢一些。論文中從A-E由淺到深訓練深度網絡的方法值得在搭建自己的網絡時學習,這個后面再表。
  • OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks?這篇paper至少告訴我一件事,深度網絡提取的特征對圖片Classification、Detection、Segmentation等都有效。也就是說,我拿一個Net到ImageNet去Train一個1000類的分類model出來,我又要把這個Net用于圖片Detection,這篇paper告訴你:好了,不用再Train一個Detection model了,我的Classification model直接給你用,你除了需要把后端的Softmax改一改之外,其它啥都不用改,這個Net照樣跑得和Classification任務中一樣的好。
  • 具體到用CNN做Sematic Segmentation,利用到全卷積網絡,對下面兩篇進行了精讀,并且都Caffe上復現過并用于分割任務,

  • FCNN:?Fully Convolutional Networks for Semantic Segmentation
  • Deeplab:?Semantic Image Segmentation with Deep Convolutional Nets and Fully Connected CRFs
  • 下面是幾個月前我看過這兩篇paper后做得ppt:

  • FCN for Sematic Segmentation.pptx
  • Semantic Image Segmentation With Deep Convolutional Nets and Fully Connected CRFs.ppt
  • 這兩篇paper有一個共同點,都用到了multiscale的信息(也就是將High Layer的輸出與Low Layer的輸出進行結合),這對促進分割效果有很大的作用。值得一提的是,在Train multiscale的model時,由于存在反卷積或上采樣的操作,Layer相對復雜,很難一大鍋扔進去還Trian得很好,所以通常會先Train一個無multiscale的model,再用該model去finetune含multiscale的Net。

    級別4:Demo跑起來

    讀一些源碼玩玩

  • caffe.proto

  • Convolution Layer

    CNN里面最重要的運算就是卷積,要知道Caffe是怎么做卷積的,就看看src/caffe/layers/conv_layer.cpp。Caffe里的卷積計算:

    Caffe里的卷積操作

    Caffe計算卷積時先將圖片中用于卷積的每個patch拉成一個行向量,若stride=1,則卷積的patch個數剛好是W*H,則將原圖片保存成一個[WxH,KxKxD]矩陣,同理,濾波器也存成一個[M,KxKxD]矩陣,卷積計算只要計算這兩個矩陣的乘積,矩陣乘積的工作剛好可以交給BLAS來進行優化,也就是為了用BLAS優化而進行這種轉化,從中可以看出,Caffe里的卷積還是挺耗內存空間的!

  • SoftmaxLossLayer

    所謂的輸出的Loss計算使用的一般是Softmax或Sigmoid的交叉譜,具體可看這里SoftmaxWithLossLayer

  • DataLayer

  • 自己添加一個Layer(比如Segmentation中常用的精度指標是IoU而不是簡單的Accuracy)
    • 在caffe.proto中的message LayerParameter部分增加Layer Type和layerParameter,并在caffe.proto中聲明該message LayerParameter(protobuf里的message類似C里的struct)
    • 在include的某個頭文件中聲明LayerClass
    • 在src/caffe/layers/中新建一個.cpp,實現LayerSetup、Shape、Forward_cpu以及Backward_cpu
    • 為建立LayerClass與proto中Layer聲明的關聯,在上面的.cpp中還要使用INSTALL_CLASS(...)和REGISTER_LAYER_CLASS(...)

    上面僅僅是我隨手寫在草稿紙上的隨筆,其實自己看看源碼,依葫蘆畫瓢寫一個簡單的Layer就知道了。

  • 熟悉Caffe接口,寫Demo這是硬功夫

    Caffe提供了好用的接口,包括matlab、C++、Python!由于特殊原因,我不能公開我C++和matlab的Demo源碼以及其中的一些后處理技術,暫且只能給大家看一些分割的結果:

    Sematic Segmentation Result

    還有一個視頻語義分割的結果,大家看看,熱鬧熱鬧就好,

    height="498" width="510" src="http://xiahouzuoxin.github.io/notes/images/%E6%B7%B1%E5%BA%A6%E5%8D%B7%E7%A7%AF%E7%BD%91%E7%BB%9CCNN%E4%B8%8E%E5%9B%BE%E5%83%8F%E8%AF%AD%E4%B9%89%E5%88%86%E5%89%B2/TG.mp4" frameborder="0" allowfullscreen="" style="margin: 0px; padding: 0px; font-family: Consolas, helvetica, sans-serif, arial, freesans, clean; font-size: 13px; line-height: 20.7999992370605px;">

    分析各層Layer輸出特征

    我一開始以為看看各層Layer的輸出,能幫助我改進Net,可卻發現錯了,除了前幾層還能看出點明亮或邊緣信息外,網絡后端Layer的輸出壓根就沒辦法理解。extract_featmat.cpp是我基于extract_features.cpp改的一個Caffe tool,放到tools目錄下編譯就好了,使用方法看help:

    <code class="sourceCode cpp" style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);"> <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">void</span> print_help(<span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">void</span>) {LOG(ERROR)<<<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"This program takes in a trained network and an input image, and then</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" extract features of the input data produced by the net.</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"Usage: extract_featmat [options]</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" -model [pretrained_net_param]</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" -proto [feature_extraction_proto_file]</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" -img [rgb_image_name]</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" -blobs [extract_feature_blob_name1[,name2,...]],refrence .prototxt with"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" </span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">blob:</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">. [all] for all layers. </span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" -wr_prefix [output_feat_prefix1[,prefix2,...]], conrespond to -blobs</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" -wr_root [output_feat_dir], optional, default </span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">./</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">, make sure it exist</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">" -gpu [gpu_id],optional,if not specified,default CPU</span><span class="ch" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">\n</span><span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"</span>;}</code>

    下面圖是一些Layer的輸出blob,從結果可以看出,前面的layer還能看到一些邊緣信息,后面的layer就完全看不出原圖像相關的信息了,

    不同Layers的Feature變化

    級別5:何不自己搭個CNN玩玩

    雖然還是個新手,關于搭建CNN,還在慢慢在找感覺。我覺得從兩方面:

  • 利用已有的網絡,使勁渾身解數找它們的缺點,改進它們

    熟讀Googlenet和VGGnet那兩篇paper,兩者的CNN結構如下:

    GoogleNet

    VGGNet

    VGG不是Weight Filter不是非常厚么,卷積操作復雜度就高。而Googlenet通過Inception中1x1的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時關于數據集的一些注意事項

  • 論數據集的重要性
  • Train一個Net的經驗也很重要,還是那句話,“數據是燃料”,CNN訓練一定要保證足夠的數據量(就我現在知道,Train一個深層的全卷積至少要4萬張圖片以上),否則很容易出現過擬合或者說泛化能力特別差,就像下面那樣。下面分別是DatasetSize=4K與DatasetSize=40K同一Net Train出來的Prediction結果。 在訓練時,僅從精度上來看,兩個Net訓練時得到的差距不大,IoU都在90%左右,但實際predict時,4K train出的model是如此的難看!

    論Train CNN數據集大小的重要性

  • CNN對目標出現在圖片的位置、大小、方向等信息非常敏感,為增加網絡泛化能力,最好對數據進行先multiscale、mirror、crop等操作。比如下面就是我用來對圖片進行scale的一段matlab代碼(這段代碼主要是通過resize、填白來scale,但不改變圖片長寬比)。當然,scale的方式不局限于此,也可以直接resize,改變圖片長寬比。
  • <code class="sourceCode matlab" style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">function ImageScale(in_dir,out_dir) <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% Author: zuoxin,xiahou</span> if ~exist(out_dir,<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'dir'</span>)mkdir(out_dir); end ims = dir(fullfile(in_dir,<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'*.jpg'</span>)); gts = dir(fullfile(in_dir,<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'*.bmp'</span>)); N = length(ims); if N ~= length(gts)error(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'NUM(Images)~=NUM(GroudTruth)'</span>); end for i=<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:Nim = imread(fullfile(in_dir,ims(i).name));gt = imread(fullfile(in_dir,gts(i).name));<span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% Check for size errors</span>if ndims(im) < <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">3</span>[h,w] = size(im);k=<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>;else[h,w,k] = size(im);end[h_gt,w_gt,k_gt] = size(gt);if h~=h_gt || w~=w_gterror(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'size(im)~=size(gt)'</span>);endif h>wts = h;elsets = w;endSIZE = <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">500</span>;if h>wim = imresize(im, [SIZE,w*SIZE/ts]);gt = imresize(gt, [SIZE,w*SIZE/ts]);elseim = imresize(im, [h*SIZE/ts,SIZE]);gt = imresize(gt, [h*SIZE/ts,SIZE]); end<span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% Update Size</span>if ndims(im) < <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">3</span>[h,w] = size(im);k=<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>;else[h,w,k] = size(im);end[~,~,k_gt] = size(gt);if h>w <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% h>w, padding width (bg:0 fg:1)</span>pad_ = SIZE-w;left_pad = floor(pad_/<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">2</span>);right_pad = ceil(pad_/<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">2</span>);scale_im = [<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*ones(h,left_pad,k), im, <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*ones(h,right_pad,k)];scale_gt = [<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*zeros(h,left_pad,k_gt), gt, <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*zeros(h,right_pad,k_gt)];else <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% h<w, padding height</span>pad_ = SIZE-h;top_pad = floor(pad_/<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">2</span>);bot_pad = ceil(pad_/<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">2</span>);scale_im = [<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*ones(top_pad,w,k); im; <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*ones(bot_pad,w,k)];scale_gt = [<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*zeros(top_pad,w,k_gt); gt; <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*zeros(bot_pad,w,k_gt)];end <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% Other Scales</span>ts = [<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">0.6</span>,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1.4</span>];for s = <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:numel(ts)im = imresize(scale_im,ts(s));gt = imresize(scale_gt,ts(s));<span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% padding/crop to SIZExSIZE</span>if size(im,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>) < SIZE <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% Padding</span>right_pad = SIZE - size(im,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">2</span>);bot_pad = SIZE - size(im,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>);im = [im, <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*ones(size(im,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>),right_pad,k)];im = [im; <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*ones(bot_pad,size(im,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">2</span>),k)];gt = [gt, <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*zeros(size(gt,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>),right_pad,k_gt)];gt = [gt; <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>*zeros(bot_pad,size(gt,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">2</span>),k_gt)];else <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% Crop</span>im = im(<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:SIZE,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:SIZE,:);gt = gt(<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:SIZE,<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:SIZE,:);end gt(gt>=<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">128</span>) = <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">255</span>;gt(gt<<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">128</span>) = <span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">0</span>; out_im = fullfile(out_dir,...[ims(i).name(<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:end-<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">4</span>),<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'_'</span>,num2str(ts(s)),<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'.jpg'</span>]);out_gt = fullfile(out_dir,...[ims(i).name(<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:end-<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">4</span>),<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'_'</span>,num2str(ts(s)),<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'.bmp'</span>]);imwrite(im,out_im);imwrite(gt,out_gt);end end end</code>

    下面是mirror圖片的matlab腳本:

    <code class="sourceCode matlab" style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">function image_mirror(d) <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% mirror all images under @dir directory</span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% and store the mirrored images under @dir</span>files=dir(fullfile(d,<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'*.jpg'</span>)); n=length(files); for i=<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:nsrc_file=fullfile(d,files(i).name);out_file=fullfile(d,[files(i).name(<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:end-<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">4</span>),<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'_mr.jpg'</span>]);if ~exist(out_file,<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'file'</span>) && ~(strcmp(src_file(end-<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">5</span>:end-<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">4</span>),<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'mr'</span>))im = imread(src_file);out=im(:,end:-<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="float: left; margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>,:);<span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% imshow(out);</span>imwrite(out, out_file);fprintf(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'%s\n'</span>,fullfile(d,files(i).name));end end</code>
  • 關于輸入圖片尺寸的問題
  • 對于非分割的問題,比如識別,我覺得在200x200 pixles左右就足夠了(看大家都這么用的,這個自己沒測試過)。但對于分割的問題,圖片的size對分割結果影響還是很大的,用全卷積網絡的測試結果:輸入圖片的size從500x500降低到300x300,IoU果斷直接降了3個點,太恐怖了!!但size太大,卷積時間長,所以這就是一個精度和時間的折中問題了。

    級別6:加速吧,GPU編程

    呃,這一級還沒練到,但遲早是要做的,說了“大數據是燃料,GPU是引擎”的,怎么能不懂引擎呢……

    關于語義分割的一些其它工作

  • CRF:CRF在圖像分割中是最常見的refine后處理手段。在CNN中目標是做成end-2-end的CRF,實習這段時間也做過不少這部分的工作,Oxford有篇CRF-RNN的paper,將denseCRF重新解釋成RNN來進行end-2-end的Training
  • 結合grabcut交互式分割,或者SLIC超像素分割等方法進行邊緣精細化的處理
  • 不閑扯淡了……

  • 注:由于“實習上班+實驗室+論文+刷leetcode+私事”占用時間的關系,好不容易抽出一個上午+一個晚上整理了一下,暫時想到這么多,算列個提綱吧,文章中不少具體細節有機會再補充。

    總結

    以上是生活随笔為你收集整理的深度卷积网络CNN与图像语义分割的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。