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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ROI Pooling层解析

發(fā)布時間:2024/9/21 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ROI Pooling层解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

ROI Pooling的意義

ROIs Pooling顧名思義,是Pooling層的一種,而且是針對RoIs的Pooling,他的特點是輸入特征圖尺寸不固定,但是輸出特征圖尺寸固定;

什么是ROI呢? ROIRegion of Interest的簡寫,指的是在“特征圖上的框”; 1)在Fast RCNN中, RoI是指Selective Search完成后得到的“候選框”在特征圖上的映射,如下圖所示; 2)在Faster RCNN中,候選框是經(jīng)過RPN產(chǎn)生的,然后再把各個“候選框”映射到特征圖上,得到RoIs。
  • 1
  • 2
  • 3
  • 4


圖1 Fast RCNN整體結(jié)構(gòu)

往往經(jīng)過rpn后輸出的不止一個矩形框,所以這里我們是對多個ROI進行Pooling。

ROI Pooling的輸入

輸入有兩部分組成:
1. 特征圖:指的是圖1中所示的特征圖,在Fast RCNN中,它位于RoI Pooling之前,在Faster RCNN中,它是與RPN共享那個特征圖,通常我們常常稱之為“share_conv”;
2. rois:在Fast RCNN中,指的是Selective Search的輸出;在Faster RCNN中指的是RPN的輸出,一堆矩形候選框框,形狀為1x5x1x1(4個坐標+索引index),其中值得注意的是:坐標的參考系不是針對feature map這張圖的,而是針對原圖的(神經(jīng)網(wǎng)絡(luò)最開始的輸入)

ROI Pooling的輸出

輸出是batch個vector,其中batch的值等于RoI的個數(shù),vector的大小為channel * w * h;RoI Pooling的過程就是將一個個大小不同的box矩形框,都映射成大小固定(w * h)的矩形框;

ROI Pooling的過程


如圖所示,我們先把roi中的坐標映射到feature map上,映射規(guī)則比較簡單,就是把各個坐標除以“輸入圖片與feature map的大小的比值”,得到了feature map上的box坐標后,我們使用Pooling得到輸出;由于輸入的圖片大小不一,所以這里我們使用的類似Spp Pooling,在Pooling的過程中需要計算Pooling后的結(jié)果對應(yīng)到feature map上所占的范圍,然后在那個范圍中進行取max或者取average。

這是我個人的公共號:
講解經(jīng)典的深度學(xué)習(xí)方法~

Caffe ROI Pooling的源碼解析

1. LayerSetUp

template <typename Dtype> void ROIPoolingLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {ROIPoolingParameter roi_pool_param = this->layer_param_.roi_pooling_param();//經(jīng)過Pooling后的feature map的高pooled_height_ = roi_pool_param.pooled_h();//經(jīng)過Pooling后的feature map的寬pooled_width_ = roi_pool_param.pooled_w();//輸入圖片與feature map之前的比值,這個feature map指roi pooling層的輸入spatial_scale_ = roi_pool_param.spatial_scale(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2. Reshape

template <typename Dtype> void ROIPoolingLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {//輸入的feature map的channel數(shù)channels_ = bottom[0]->channels();//輸入的feature map的高height_ = bottom[0]->height();//輸入的feature map的寬width_ = bottom[0]->width();//設(shè)置輸出的形狀NCHW,N=ROI的個數(shù),C=channels_,H=pooled_height_,W=pooled_width_top[0]->Reshape(bottom[1]->num(), channels_, pooled_height_,pooled_width_);//max_idx_的形狀與top一致max_idx_.Reshape(bottom[1]->num(), channels_, pooled_height_,pooled_width_); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3. Forward

template <typename Dtype> void ROIPoolingLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,const vector<Blob<Dtype>*>& top) {//輸入有兩部分組成,data和roisconst Dtype* bottom_data = bottom[0]->cpu_data();const Dtype* bottom_rois = bottom[1]->cpu_data();// Number of ROIsint num_rois = bottom[1]->num();int batch_size = bottom[0]->num();int top_count = top[0]->count();Dtype* top_data = top[0]->mutable_cpu_data();caffe_set(top_count, Dtype(-FLT_MAX), top_data);int* argmax_data = max_idx_.mutable_cpu_data();caffe_set(top_count, -1, argmax_data);// For each ROI R = [batch_index x1 y1 x2 y2]: max pool over Rfor (int n = 0; n < num_rois; ++n) {int roi_batch_ind = bottom_rois[0];//把原圖的坐標映射到feature map上面int roi_start_w = round(bottom_rois[1] * spatial_scale_);int roi_start_h = round(bottom_rois[2] * spatial_scale_);int roi_end_w = round(bottom_rois[3] * spatial_scale_);int roi_end_h = round(bottom_rois[4] * spatial_scale_);//計算每個roi在feature map上面的大小int roi_height = max(roi_end_h - roi_start_h + 1, 1);int roi_width = max(roi_end_w - roi_start_w + 1, 1);//pooling之后的feature map的一個值對應(yīng)于pooling之前的feature map上的大小//注:由于roi的大小不一致,所以每次都需要計算一次const Dtype bin_size_h = static_cast<Dtype>(roi_height)/ static_cast<Dtype>(pooled_height_);const Dtype bin_size_w = static_cast<Dtype>(roi_width)/ static_cast<Dtype>(pooled_width_);//找到對應(yīng)的roi的feature map,如果input data的batch size為1//那么roi_batch_ind=0const Dtype* batch_data = bottom_data + bottom[0]->offset(roi_batch_ind);//pooling的過程是針對每一個channel的,所以需要循環(huán)遍歷for (int c = 0; c < channels_; ++c) {//計算output的每一個值,所以需要遍歷一遍output,然后求出所有值for (int ph = 0; ph < pooled_height_; ++ph) {for (int pw = 0; pw < pooled_width_; ++pw) {// Compute pooling region for this output unit:// start (included) = floor(ph * roi_height / pooled_height_)// end (excluded) = ceil((ph + 1) * roi_height / pooled_height_)// 計算output上的一點對應(yīng)于input上面區(qū)域的大小[hstart, wstart, hend, wend]int hstart = static_cast<int>(floor(static_cast<Dtype>(ph)* bin_size_h));int hend = static_cast<int>(ceil(static_cast<Dtype>(ph + 1)* bin_size_h));int wstart = static_cast<int>(floor(static_cast<Dtype>(pw)* bin_size_w));int wend = static_cast<int>(ceil(static_cast<Dtype>(pw + 1)* bin_size_w));//將映射后的區(qū)域平動到對應(yīng)的位置[hstart, wstart, hend, wend]hstart = min(max(hstart + roi_start_h, 0), height_);hend = min(max(hend + roi_start_h, 0), height_);wstart = min(max(wstart + roi_start_w, 0), width_);wend = min(max(wend + roi_start_w, 0), width_);//如果映射后的矩形框不符合bool is_empty = (hend <= hstart) || (wend <= wstart);//pool_index指的是此時計算的output的值對應(yīng)于output的位置const int pool_index = ph * pooled_width_ + pw;//如果矩形不符合,此處output的值設(shè)為0,此處的對應(yīng)于輸入?yún)^(qū)域的最大值為-1if (is_empty) {top_data[pool_index] = 0;argmax_data[pool_index] = -1;}//遍歷output的值對應(yīng)于input的區(qū)域塊for (int h = hstart; h < hend; ++h) {for (int w = wstart; w < wend; ++w) {// 對應(yīng)于input上的位置const int index = h * width_ + w;//計算區(qū)域塊的最大值,保存在output對應(yīng)的位置上//同時記錄最大值的索引if (batch_data[index] > top_data[pool_index]) {top_data[pool_index] = batch_data[index];argmax_data[pool_index] = index;}}}}}// Increment all data pointers by one channelbatch_data += bottom[0]->offset(0, 1);top_data += top[0]->offset(0, 1);argmax_data += max_idx_.offset(0, 1);}// Increment ROI data pointerbottom_rois += bottom[1]->offset(1);} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

總結(jié)

以上是生活随笔為你收集整理的ROI Pooling层解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。