實戰 | 源碼入門之Faster RCNN

2021-03-02 計算機視覺life
前言

學習深度學習和計算機視覺,特別是目標檢測方向的學習者,一定聽說過Faster Rcnn;在目標檢測領域,Faster Rcnn表現出了極強的生命力,被大量的學習者學習,研究和工程應用。網上有很多版本的Faster RCNN的源碼,但是很多版本代碼太過於龐大,對新入門的學習者學習起來很不友好,在網上苦苦尋找了一番後終於找到了一個適合源碼學習的Faster Rcnn的pytorch版本代碼。


根據該版本的作者講該代碼除去注釋只有兩千行左右,並且經過小編的一番學習之後,發現該版本的代碼真的是非常的精簡幹練,讀起來「朗朗上口」,並且深刻的感覺到作者代碼功底之深厚。在此先附上源碼的地址(https://github.com/chenyuntc/simple-faster-rcnn-pytorch) ,並對源碼作者(陳雲)表示由衷的感謝和深深地敬意。


本文章主要的目的是對該版本代碼的主要框架進行梳理,希望能夠對一些想學習源碼的讀者有一定的幫助。

代碼的主要文件

-data文件中主要是文件的與dataset相關的文件

-misc中有下載caffe版本預訓練模型的文件,可以不看

-model文件中主要是與構建Faster Rcnn網絡模型有關的文件

-utils中主要是一些輔助可視化和驗證的文件

-train.py是整個程序的運行文件,下面有一部分會做介紹

-trainer.py文件主要是用於訓練,模型的損失函數的計算都在這個文件中

train

先來看一下train.py裡的主要內容:

def train(train(**kwargs)):    
  opt._parse(kwargs)
  dataset = Dataset(opt)      
  dataloader = data_.DataLoader(dataset, \
                                batch_size=1, \
                                shuffle=True, \
                                
                                num_workers=opt.num_workers)
  testset = TestDataset(opt)  
  test_dataloader = data_.DataLoader(testset,
                                     batch_size=1,
                                     num_workers=opt.test_num_workers,
                                     shuffle=False, \
                                     pin_memory=True
                                     )
  faster_rcnn = FasterRCNNVGG16()    
  trainer = FasterRCNNTrainer(faster_rcnn).cuda()  

  for epoch in range(opt.epoch):
        trainer.reset_meters()
        for ii, (img, bbox_, label_, scale) in tqdm(enumerate(dataloader)):
            scale = at.scalar(scale)
            img, bbox, label = img.cuda().float(), bbox_.cuda(), label_.cuda()
            trainer.train_step(img, bbox, label, scale)  

從train.py中的主要函數可以看出,主要的步驟涉及訓練數據和測試數據的預處理,網絡模型的構建(Faster RCNN),然後就是迭代訓練,這也是通用的神經網絡搭建和訓練的過程。在Faster Rcnn網絡模型中主要包含Extractor、RPN和RoIhead三部分。網絡中Extractor主要是利用CNN進行特徵提取,網絡採用的VGG16;RPN是候選區網絡,為RoIHead模塊提供可能存在目標的候選區域(rois);RoIHead主要負責rois的分類和微調。整體的框架圖如下圖所示:

圖片來源於陳雲的知乎

Dataset

在本版本的代碼中讀取的數據格式為VOC,Dataset和TestDataset類分別負責訓練數據和測試數據的讀取及預處理。在預處理部分主要的操作就是resize圖像的大小、像素值的處理以及圖像的隨機翻轉。主要的內容如下:

class Dataset:     
    def __init__(self, opt):
        self.opt = opt
        self.db = VOCBboxDataset(opt.voc_data_dir)  
        self.tsf = Transform(opt.min_size, opt.max_size) 
        

    def __getitem__(self, idx):
        ori_img, bbox, label, difficult = self.db.get_example(idx)
        img, bbox, label, scale = self.tsf((ori_img, bbox, label))
        return img.copy(), bbox.copy(), label.copy(), scale

    def __len__(self):
        return len(self.db)
class TestDataset:
    pass          

FasterRCNNVGG16

下面主要介紹Extractor、RPN和RoIHead三部分結構

Extractor

extractor, classifier = decom_vgg16() 

Extractor部分主要使用的VGG16的網絡結構,同時使用預訓練好的模型提取圖片的特徵。論文中主要使用的是Caffe的預訓練模型,根據代碼的作者講該版本的預訓練模型效果比較好。


為了節約顯存,作者將前四層卷積層的學習率設置為0,Conv5_3的輸入作為圖片的特徵輸入到RPN網絡中。根據網絡結構,Conv5_3部分的感受野為16,也就是相較於輸入的圖片大小,feature map的尺寸為(C,H/16,W/16).該部分網絡結構圖如下所示:

具體的decom_vgg16()代碼如下:

def decom_vgg16():    
    
    if opt.caffe_pretrain:  
        model = vgg16(pretrained=False)  
        if not opt.load_path:
            model.load_state_dict(t.load(opt.caffe_pretrain_path)) 
    else:
        model = vgg16(not opt.load_path)

    features = list(model.features)[:30]    
    classifier = model.classifier          

    classifier = list(classifier)
    del classifier[6]
    if not opt.use_drop:                
        del classifier[5]
        del classifier[2]
    classifier = nn.Sequential(*classifier)  

    
    for layer in features[:10]:
        for p in layer.parameters():
            p.requires_grad = False

    return nn.Sequential(*features), classifier

RPN

Faster RCNN中最突出的貢獻就是提出了Region Proposal Network(RPN),將候選區域提取的時間開銷幾乎降為0。該模塊的主要作用提供可能存在目標的候選區域rois。模塊結構圖如下所示:

圖片來源於陳雲的知乎

class RegionProposalNetwork(nn.Module):   

  def __init__():
  
  def forward(self, x, img_size, scale=1.):
      
      
      
      n, _, hh, ww = x.shape
      anchor = _enumerate_shifted_anchor(   
          np.array(self.anchor_base),
          self.feat_stride, hh, ww)

      n_anchor = anchor.shape[0] // (hh * ww)  
      h = F.relu(self.conv1(x))  

      rpn_locs = self.loc(h)     
      rpn_locs = rpn_locs.permute(0, 2, 3, 1).contiguous().view(n, -1, 4)
      rpn_scores = self.score(h)  
      rpn_scores = rpn_scores.permute(0, 2, 3, 1).contiguous()
      rpn_softmax_scores = F.softmax(rpn_scores.view(n, hh, ww, n_anchor, 2), dim=4) 
      rpn_fg_scores = rpn_softmax_scores[:, :, :, :, 1].contiguous()
      rpn_fg_scores = rpn_fg_scores.view(n, -1)
      rpn_scores = rpn_scores.view(n, -1, 2)

      rois = list()
      roi_indices = list()
      for i in range(n):
          roi = self.proposal_layer(            
              rpn_locs[i].cpu().data.numpy(),
              rpn_fg_scores[i].cpu().data.numpy(),
              anchor, img_size,
              scale=scale)
          batch_index = i * np.ones((len(roi),), dtype=np.int32)
          rois.append(roi)
          roi_indices.append(batch_index)

      rois = np.concatenate(rois, axis=0)
      roi_indices = np.concatenate(roi_indices, axis=0)
      return rpn_locs, rpn_scores, rois, roi_indices, anchor

RoIHead

RoIhead主要任務是對RPN網絡選出的候選框進行分類和回歸,在RoIhead中作者提出了RolPooling方法將不同尺度的候選區域全部pooling到一個尺度上。模塊結構圖如下所示:

class VGG16RoIHead(nn.Module):                         
    def __init__(self, n_class, roi_size, spatial_scale,
                 classifier):
        
        super(VGG16RoIHead, self).__init__()

        self.classifier = classifier                   
        self.cls_loc = nn.Linear(4096, n_class * 4)    
        self.score = nn.Linear(4096, n_class)          

        normal_init(self.cls_loc, 0, 0.001)            
        normal_init(self.score, 0, 0.01)

        self.n_class = n_class                         
        self.roi_size = roi_size                       
        self.spatial_scale = spatial_scale             
        self.roi = RoIPooling2D(self.roi_size, self.roi_size, self.spatial_scale)

    def forward(self, x, rois, roi_indices):
        
        pool = self.roi(x, indices_and_rois)     
        pool = pool.view(pool.size(0), -1)       
        fc7 = self.classifier(pool)              
        roi_cls_locs = self.cls_loc(fc7)         
        roi_scores = self.score(fc7)             
        return roi_cls_locs, roi_scores

運行代碼

整體來說該版本的代碼環境相當簡單,配置起來相當容易,沒有什麼坑,認真閱讀作者的readme就好。在utils文件中有一個config.py文件,在裡邊可以修改文件讀取的路徑,學習率等參數,自己運行時根據自己的情況進行修改即可。小編運行自己的數據(非VOC2007)結果如下圖:

總結

本篇文章主要的目的是推薦一個適合源碼學習的Faster rcnn版本給大家,並對代碼框架做了初步的介紹,希望對大家的源碼學習有一定的幫助,由於整個算法實現的代碼較為複雜,且細節比較多,很難通過一篇文章進行詳細的說明,如果大家對本版本的代碼感興趣,可以自己閱讀源碼學習。在學習源碼的時候我個人是有很多感想的,作為一個小白,通過源碼的學習真的學習到了很多,之前論文閱讀過幾遍,別的版本的代碼也拿來訓練過數據,但是讀了這個的源碼,又如發現了新大陸,很多算法的細節和精髓才算有了深刻的理解,真的是紙上得來終覺淺,絕知此事要coding。除了算法本身,在一些代碼的實現上也有很多的學習,真的感受到代碼作者的功力深厚,再次對作者表示深深地敬意.最後留個問題,在閱讀源碼的時候,發現作者使用了visdom進行可視化,如運行的截圖,小編還知道pytorch中一個可視化工具tensorboardX,但都不是很熟悉,還請知情人士在下方留言,詳細的講解一下兩種可視化工具的優劣。由於小編是一個剛入門(入坑)的學習者,文章中的不當之處還請大家諒解和提出,很希望能與大家一起討論學習。

最後再次放上源碼連結:

https://github.com/chenyuntc/simple-faster-rcnn-pytorch

參考:

https://zhuanlan.zhihu.com/p/32404424

https://www.cnblogs.com/kerwins-AC/p/9734381.html

相關焦點

  • 深度學習目標檢測系列:faster RCNN實現|附python源碼
    在掌握基本原理後,下面進入實戰部分。本文將使用一個非常酷且有用的數據集來實現faster R-CNN,這些數據集具有潛在的真實應用場景。問題陳述數據來源於醫療相關數據集,目的是解決血細胞檢測問題。任務是通過顯微圖像讀數來檢測每張圖像中的所有紅細胞(RBC)、白細胞(WBC)以及血小板。
  • Faster RCNN 官方源碼解讀
    否則請先點擊閱讀上一篇文章:白裳:一文讀懂Faster RCNNtorchvision 中 FasterRCNN 代碼文檔如下:https://pytorch.org/docs/stable/torchvision/models.html#faster-r-cnnpytorch.org
  • 【源頭活水】Sparse R-CNN:簡化版fast rcnn
    算法,是faster rcnn算法的前身,由於其巨大計算量以及無法端到端訓練,故而提出區域提取網絡RPN加上fast rcnn的faster rcnn算法。1.2 faster rcnnfastrcnn的做法不是一個完全端到端的做法,比較麻煩,性能也一般,故faster rcnn提出採用可學習的RPN網絡代替
  • Faster R-CNN
    Mask r-cnn[C]//Computer Vision (ICCV), 2017 IEEE International Conference on. IEEE, 2017: 2980-2988.
  • 筆記 | Faster RCNN詳解結構介紹
    Detection with Region Proposal Networks論文作者:Shaoqing Ren, Kaiming He, Ross Girshick, Jian Sun論文地址:Towards Real-Time Object Detection with Region Proposal Networks論文代碼:rbgirshick/py-faster-rcnn
  • 卷積神經網絡 物體檢測 Faster-RCNN
    繼204年rcnn,2015年SPPnet、fast rcnn後,2016年,hekaiming和rbg合作提出了faster rcnn(一作是renshaoqing),以解決region proposal的耗時問題;
  • Mask R-CNN
    是對faster r-cnn的擴展,與bbox識別並行的增加一個預測分割mask的分支。Mask R-CNN 可以應用到人體姿勢識別。並且在實例分割、目標檢測、人體關鍵點檢測三個任務都取得了現在最好的效果。效果圖
  • 目標檢測技術之Faster R-CNN詳解
    此外,ResNet讓使用殘差網絡和批量歸一化來訓練深度模型變得簡單,這在VGG發布之初並未出現。既然我們有了處理過的圖像,則需要找到proposals,即用於分類的興趣區域(RoI)。上文中提到,anchors是解決可變長度問題的方法,但是沒有詳細講解。我們的目標是在圖像中找到邊界框,它們呈矩形,有不同的尺寸和長寬比。
  • 詳解目標檢測Faster R-CNN
    即,數學地表述,如果圖片尺寸 w×h,特徵圖的尺寸則是 w/r×h/r. 其中,r 是下採樣率(subsampling ratio). 如果在卷積特徵圖空間位置定義 anchor,則最終的圖片會是由 r 像素劃分的 anchors 集. 在 VGG 中,r=16.
  • 經典目標檢測方法Faster R-CNN和Mask R-CNN|基於PaddlePaddle深度...
    圖 4 Mask R-CNN:像素級別的目標檢測  基於 PaddlePaddle 實戰  環境準備:需要 PaddlePaddle Fluid"Fast r-cnn." Proceedings of the IEEE international conference on computer vision. 2015.  https://arxiv.org/abs/1504.08083  Ren, Shaoqing, et al.
  • 一文看懂近年火到不行的CNN圖像識別:從R-CNN到Mask R-CNN
    如何將原始圖像的感興趣區域和特徵圖精確對齊?來源:https://arxiv.org/abs/1703.06870源碼如果你有興趣自己試驗一下這些算法,這裡是相關的源碼庫:Faster R-CNN- Caffe: rbgirshick/py-faster-rcnn- PyTorch: longcw/faster_rcnn_pytorch
  • 潮科技行業入門指南 | 深度學習理論與實戰:提高篇(14)——Mask R...
    編者按:本文節選自《深度學習理論與實戰:提高篇 》一書,原文連結http://fancyerii.github.io/2019/03/14/dl-book/。作者李理,環信人工智慧研發中心vp,有十多年自然語言處理和人工智慧研發經驗,主持研發過多款智能硬體的問答和對話系統,負責環信中文語義分析開放平臺和環信智慧機器人的設計與研發。
  • 深度學習筆記 | 第7講:CNN目標檢測發家史之從R-CNN到yolo
    R-CNN 作為將深度學習引入目標檢測算法的開山之作,在目標檢測算法發展歷史上具有重大意義。R-CNN 算法是兩步走方法的代表,即先生成候選區域(region proposal),然後再利用 CNN 進行識別分類。由於候選框對於算法的成敗起著關鍵作用,所以該方法就以 Region 開頭首字母 R 加 CNN 進行命名。
  • 機器視覺目標檢測補習貼之R-CNN系列 — R-CNN, Fast R-CNN, Faster R-CNN
    推薦閱讀:馬爾科夫決策過程之Markov Reward Process(馬爾科夫獎勵過程)【深度學習實戰
  • 經典解讀 | Cascade R-CNN詳細解讀
    連結 | https://zhuanlan.zhihu.com/p/42553957源碼連結:https://github.com/zhaoweicai/cascade-rcnnPytorch復現:https://github.com/guoruoqian/cascade-rcnn_Pytorch寫這篇文章是希望對原文進行解析,幫助大家理解文章的精髓,如有錯誤的地方還希望指正。
  • 有救了,這絕對是一舉掌握RCNN、Fast RCNN、Faster RCNN最好的辦法!
    本號強烈推薦你參加《目標檢測RCNN實戰訓練營》,從檢測模型教學逐步深入,幫你輕鬆掌握目標檢測,輕鬆提升CV算法核心能力。內容不錯,推薦給你們。聚焦人工智慧實戰訓練。從原理剖析到項目實訓,聚焦目標檢測模型實戰訓練,訓練營助力你的成長。如果你是以上人群,那麼這次訓練營十分適合你。掌握銷量RCNN全家桶,進階目標檢測,實現人生進階發展!本次訓練營為期3天,從RCNN到Fast RCNN,再到Faster RCNN,逐步幫你深入了解目標檢測,掌握向前計算過程和訓練過程。
  • 令人「細思極恐」的Faster-R-CNN
    前言每次回顧Faster R-CNN的相關知識(包括源碼),都會發現之前沒有注意到的一些細節,從而有新的收穫,既驚恐又驚喜,可謂「細思極恐」!源碼是一位大佬寫的,基於Pytorch框架,是Faster R-CNN的精煉版,作為學習和參考來說相當不錯,我自己也擼了一遍,這裡也附上大佬源碼的連結:Faster R-CNN 精煉版。Faster R-CNN Network一.
  • 【R教程】《即刻R入門》What is R?
    【陸勤看點】R是一個源碼和其它文件的容器,安裝它,加載它,就可以使用它,很方便,很強大。小編一直專注於機器學習和數據挖掘,會經常應用R來實踐哦。Summary《即刻R入門》第一課解決R是什麼?這個核心問題。通過這個問題的認識,可以感受到R的作為。
  • python人工智慧項目實戰,PDF+源碼
    《Python AI項目實戰  Practical Python AI Projects》使用優化建模探索使用PythonAI項目體驗地址 https://loveai.tech閱讀過本文的人還看了以下:分享《深度學習入門:基於Python的理論與實現》高清中文版PDF+原始碼《21個項目玩轉深度學習:基於TensorFlow的實踐詳解》完整版PDF+附書代碼
  • 【從零開始學Mask RCNN】一,原理回顧&&項目文檔翻譯
    訓練你自己的數據集閱讀這個例子作為開始:https://engineering.matterport.com/splash-of-color-instance-segmentation-with-mask-r-cnn-and-tensorflow-7c761e238b46?gi=468916310fd5 。