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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Fast R-CNN: 我变快了,也变强了!

發布時間:2024/9/15 编程问答 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fast R-CNN: 我变快了,也变强了! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊“小詹學Python”,選擇“置頂”公眾號

重磅干貨,第一時間送達

本文經作者授權轉載,禁二次轉載


來源 | @知乎?Uno Whoiam

原文 |?https://zhuanlan.zhihu.com/p/62273673



Fast R-CNN 即 Fast Region-based Convolutional Network,你的直覺沒錯,它就是R-CNN的升級版。


論文鏈接:https://arxiv.org/abs/1504.08083


在細說 Fast R-CNN 之前,不妨先看看 R-CNN 有什么令人詬病的地方:?


1. 慢,實在是慢,別說實時檢測了,47s的等待讓坐在電腦前的記幾仿佛是一只智障。?

2. 訓練麻煩,AlexNet、SVMs 以及 bounding-box regression 得一個接一個地訓練。?

3. 訓練占用大量時間和空間(硬盤),除開訓練三個模型的時間,SVMs 和 bounding-box regression 的訓練樣本得用 AlexNet 一次又一次地前向傳播提取特征、標注樣本數據、保存在硬盤里的喲,每一張圖片的每一個proposal都得跑一次喲,想想都覺得惡心。而作者而說明了,需要GPU花2.5天的時間才能處理完5K張VOC07trainval里的圖片,產生的訓練樣本占用的空間得好幾百個GB。想想都覺得惡心\嘔。順便溫馨提示一下,每張圖生成的樣本最好單獨生成一個文件夾保存,別把這這個數量級的樣本放在同一個文件夾里喲,即使是最好的SSD也招架不住這樣的文件夾,當你幡然醒悟想要rm -r -f dir 重新來過時,漫長的等待足夠讓您好好睡一覺了,別問我為什么知道這么多~淚目。


隨著 Fast R-CNN 的到來,以上問題也就不復存在辣!相比 R-CNN,除了各種快(見下段原論文引用)Fast R-CNN 有以下幾個特性:


Fast R-CNN trains the very deep VGG16 network 9× faster than R-CNN, is 213× faster at test-time, and achieves a higher mAP on PASCAL VOC 2012. Compared to SPPnet, Fast R-CNN trains VGG16 3× faster, tests 10× faster, and is more accurate.


1. 更高的mAP。

2. 不用分段訓練,整個網絡可以通過使用多任務損失函數,一次性訓練好。

3. 訓練可以更新網絡層中的所有權重。

4. 無需苦逼生成訓練樣本緩存在硬盤上,節省了空間。


Fast R-CNN 的整體網絡如下圖所示:



接下來按照物體檢測的大框架:候選框->特征提取->分類->精調位置。一步步來說吧。


一、提出候選框?


和R-CNN一樣,候選框的提出使用 selective search 方法。


selective search:

http://www.huppelen.nl/publications/selectiveSearchDraft.pdf https://blog.csdn.net/mao_kun/article/details/50576003


二、特征提取


使用深度卷積神經網絡進行特征提取,在論文中作者分別使用了從小到大三種網絡進行實驗:?


1. S: CaffeNet 即小型版的 AlexNet?

2. M: VGG_CNN_ M_ 1024 一看名字就知道是小型一點的 VGG?

3. L: VGG-16?


值得注意的是,以上網絡的全連接層都被去掉了,這意味著:輸入的尺寸大小勞資不用管辣哈哈哈哈哈!!!(想起R-CNN里RBG大神辛辛苦苦想了四種辦法將Proposal區域變成 227 x 227 再喂給 AlexNet 就覺得熏疼)


也就是說,特征提取網絡最終輸出的是 C 層的 Feature Maps 。?


等等,好像有什么不對?我想要得到的是圖片中某個Proposal區域的特征向量啊,沒特征向量我怎么判斷這個Proposal區域到底有沒有物體嘛!?


這就需要用到 ROI max-pooling 了。對于這個細節網上很少有可以把它說清楚的,本文將結合 Pytorch 實現代碼,保證讓您看得明明白白的。


首先,啥是Proposal區域?在Fast R-CNN中,Proposal區域就是用 selective search 在圖片上生成的可能含有被檢測物體的框框們,而這個框框,可以用左上角和右下角的坐標表示,即: (x1,y1,x2,y2) ,它們都是 [0,1] 范圍內的 float 數,表示框框在圖片中的相對位置。?


現在我們的目標是:對于一個Proposal框,在神經網絡輸出的C 層 Feature Maps找到對應的部分。具體該怎么做呢?如果整張圖片的經過特征提取網絡生成的 Feature Maps 尺寸是 (C,W,H) ,那么框框對應的坐標是:



其中 Floor 表示下取整, Ceil 表示上取整。這個框出來的部分就代表著Proposal區域經過神經網絡提取到的特征,另外 C 保持不變,將其平展開成一維向量后就表示Proposal區域的特征向量辣。?


新的問題來了,Proposal框大小不同也就意味著對應的 Feature Maps 上的大小不同,大小不同平鋪出來的一維特征向量也不同,那怎么辦??


這就是 ROI max-pooling 需要做的事情了:將不同尺寸Proposal區域所對應的 Feature Maps 變成相同尺寸的,在 Pytorch 中可以使用 torch.nn.AdaptiveAvgPool2d 來實現,無論輸入的 Feature Maps 是什么尺寸,它都可以通過調整stride、padding等參數給你輸出成統一大小的尺寸。下面是 Pytorch 代碼:


class SlowROIPool(nn.Module): def __init__(self, output_size): super().__init__() self.maxpool = nn.AdaptiveMaxPool2d(output_size) self.size = output_size def forward(self, images, rois, roi_idx): n = rois.shape[0] h = images.size(2) w = images.size(3) x1 = rois[:,0] y1 = rois[:,1] x2 = rois[:,2] y2 = rois[:,3] x1 = np.floor(x1 * w).astype(int) x2 = np.ceil(x2 * w).astype(int) y1 = np.floor(y1 * h).astype(int) y2 = np.ceil(y2 * h).astype(int) res = [] for i in range(n): img = images[roi_idx[i]].unsqueeze(0) img = img[:, :, y1[i]:y2[i], x1[i]:x2[i]] img = self.maxpool(img) res.append(img) res = torch.cat(res, dim=0) return res
def __init__(self, output_size):
super().__init__()
self.maxpool = nn.AdaptiveMaxPool2d(output_size)
self.size = output_size

def forward(self, images, rois, roi_idx):
n = rois.shape[0]
h = images.size(2)
w = images.size(3)
x1 = rois[:,0]
y1 = rois[:,1]
x2 = rois[:,2]
y2 = rois[:,3]

x1 = np.floor(x1 * w).astype(int)
x2 = np.ceil(x2 * w).astype(int)
y1 = np.floor(y1 * h).astype(int)
y2 = np.ceil(y2 * h).astype(int)

res = []
for i in range(n):
img = images[roi_idx[i]].unsqueeze(0)
img = img[:, :, y1[i]:y2[i], x1[i]:x2[i]]
img = self.maxpool(img)
res.append(img)
res = torch.cat(res, dim=0)
return res


注:?

代碼來源:https://github.com/GitHberChen/Fast-RCNN-Object-Detection-Pytorch/blob/master/README.ipynb

images:shape為[N,C,H,W],為N張圖片經VGG輸出的 Feature Maps?

rois:單張圖片中包含N組Proposal框的 (x1,y1,x2,y2)?

roi_idx:rois對應的圖片序號


三、分類以及邊框回歸


簡單,分類通過將上面提取出的特征向量使用全連接網絡輸出 N+1 類的置信度即可,而邊框回歸也是通過全連接網絡輸出 (N+1) x 4 個數。?


另外一個細節是,論文中采用了 SVD 對這兩個全連接層的計算進行了加速:?


(這篇博客寫得不錯,推薦閱讀)


圖像分類任務中,用于卷積層計算的時間比用于全連接層計算的時間多,而在目標檢測任務中,selective search算法提取的建議框比較多【約2k】,幾乎有一半的前向計算時間被花費于全連接層,就Fast R-CNN而言,RoI池化層后的全連接層需要進行約2k次【每個建議框都要計算】,因此在Fast R-CNN中可以采用SVD分解加速全連接層計算;


具體如何實現呢??


物體分類和窗口回歸都是通過全連接層實現的,假設全連接層輸入數據為 x ,輸出數據為 y ,全連接層參數為 W ,尺寸為 u×v ,那么該層全連接計算為: y=Wx,計算復雜度為 u×v ;


若將W進行SVD分解,并用前t個特征值近似代替,即:



那么原來的前向傳播分解成兩步:



計算復雜度為 u×t+v×t ,若 t<min(u,v)t<min(u,v) ,則這種分解會大大減少計算量;


在實現時,相當于把一個全連接層拆分為兩個全連接層,第一個全連接層不含偏置,第二個全連接層含偏置;實驗表明,SVD分解全連接層能使mAP只下降0.3%的情況下提升30%的速度,同時該方法也不必再執行額外的微調操作。


作者:WoPawn?

來源:CSDN?

原文:https://blog.csdn.net/WoPawn/article/details/52463853


四、損失函數


Fast R-CNN 雖是 two-stage 算法,但可以通過 one-stage 訓練好,這意味著,損失函數包含多個任務目標:



最后附上 Fast R-CNN 結構圖和具體細節:



RCNN ( (seq): Sequential ( (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True) (2): ReLU (inplace) (3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (4): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True) (5): ReLU (inplace) (6): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) (7): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (8): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True) (9): ReLU (inplace) (10): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (11): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True) (12): ReLU (inplace) (13): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) (14): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (15): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) (16): ReLU (inplace) (17): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (18): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) (19): ReLU (inplace) (20): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (21): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True) (22): ReLU (inplace) (23): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) (24): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (25): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) (26): ReLU (inplace) (27): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (28): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) (29): ReLU (inplace) (30): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (31): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) (32): ReLU (inplace) (33): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1)) (34): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (35): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) (36): ReLU (inplace) (37): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (38): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) (39): ReLU (inplace) (40): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) (41): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True) (42): ReLU (inplace) ) (roipool): SlowROIPool ( (maxpool): AdaptiveMaxPool2d (output_size=(7, 7)) ) (feature): Sequential ( (0): Linear (25088 -> 4096) (1): ReLU (inplace) (2): Dropout (p = 0.5) (3): Linear (4096 -> 4096) (4): ReLU (inplace) (5): Dropout (p = 0.5) ) (cls_score): Linear (4096 -> 21) (bbox): Linear (4096 -> 84) (cel): CrossEntropyLoss ( ) (sl1): SmoothL1Loss ( ))
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)
(2): ReLU (inplace)
(3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(4): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)
(5): ReLU (inplace)
(6): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
(7): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
(9): ReLU (inplace)
(10): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)
(12): ReLU (inplace)
(13): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
(14): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
(16): ReLU (inplace)
(17): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(18): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
(19): ReLU (inplace)
(20): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(21): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)
(22): ReLU (inplace)
(23): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
(24): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(25): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)
(26): ReLU (inplace)
(27): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(28): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)
(29): ReLU (inplace)
(30): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(31): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)
(32): ReLU (inplace)
(33): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
(34): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(35): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)
(36): ReLU (inplace)
(37): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(38): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)
(39): ReLU (inplace)
(40): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(41): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)
(42): ReLU (inplace)
)
(roipool): SlowROIPool (
(maxpool): AdaptiveMaxPool2d (output_size=(7, 7))
)
(feature): Sequential (
(0): Linear (25088 -> 4096)
(1): ReLU (inplace)
(2): Dropout (p = 0.5)
(3): Linear (4096 -> 4096)
(4): ReLU (inplace)
(5): Dropout (p = 0.5)
)
(cls_score): Linear (4096 -> 21)
(bbox): Linear (4096 -> 84)
(cel): CrossEntropyLoss (
)
(sl1): SmoothL1Loss (
)
)


參考鏈接:

https://github.com/GitHberChen/Fast-RCNN-Object-Detection-Pytorch/blob/master/README.ipynb



最新干貨,我在看??

總結

以上是生活随笔為你收集整理的Fast R-CNN: 我变快了,也变强了!的全部內容,希望文章能夠幫你解決所遇到的問題。

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