天天看點

Fast R-CNN訓練自己的資料集時遇到的報錯及解決方案

最近使用Fast R-CNN訓練了實驗室的資料集,期間遇到一些報錯,主要還是在配置環境上比較麻煩,但可以根據提示在網上找到解決這些錯誤的辦法。這裡我隻記錄一些難改的報錯,以後再遇見這些時希望能盡快解決~

報錯彙總:

1、assert (boxes[:, 2] >= boxes[:, 0]).all()

2、targets_dh = np.log(gt_heights / ex_heights)

3、AssertionError: assert (gt_heights > 0).all()

4、ModuleNotFoundError: No module named 'lib.utils.cython_bbox'

解決方法:

報錯1:assert (boxes[:, 2] >= boxes[:, 0]).all()

這個錯誤表示調用append_flipped_images函數時,自己的資料集标注出現矩形越界,導緻後面的計算溢出。在嘗試了網上說的幾種方法無果後,我決定先想辦法找到是哪些圖檔出現問題。需要在lib/datasets/imdb.py檔案的assert (boxes[:, 2] >= boxes[:, 0]).all()這句前面加上一行:

print(self.image_index[i])  #列印出圖像名      

列印出目前正在處理的圖像名,運作train.py後報錯前最後一個列印的圖像名就是出問題的圖像啦,打開Annotation中該圖像的标注是不是有矩形越界的情況。經查,還真有兩個目标的Xmax被标注成了1047。注意每次重新運作前都要删掉./data/cache中的緩存檔案。

報錯2:targets_dh = np.log(gt_heights / ex_heights)

這個錯誤盡量不要看網上說的降低learning_rate,降低了學習率很可能隻會延遲報錯的時間。

折騰好久終于明白,這個錯誤還是自己的資料集标注出現問題。源碼是針對pascal_voc資料集寫的,預設資料集沒有錯誤,是以對x和y的标注都沒有檢查,在上一報錯中,我們隻檢查了圖像中對x的标注,是以後面還需對圖像中y的标注進行檢查。

點選報錯的代碼,會自動找到lib/datasets/imdb.py檔案中targets_dw = np.log(gt_widths / ex_widths)的位置。在其前面加上:

1     print(gt_widths)
2     print(ex_widths)
3     print(gt_heights)
4     print(ex_heights)
5     assert (gt_widths > 0).all()
6     assert (gt_heights > 0).all()
7     assert (ex_widths > 0).all()
8     assert (ex_heights > 0).all()      

加上後運作train.py檔案,發現運作日志有新的報錯3:AssertionError: assert (gt_heights > 0).all(),表示height方向資料存在錯誤,也就是圖像中的y,是以應該是y的标注錯誤。接下來,我們就要對y的标注進行檢查。打開imdb.py檔案,找到_get-widths函數和append_flipped_images函數所在位置,如下圖:

Fast R-CNN訓練自己的資料集時遇到的報錯及解決方案

整體替換為下面代碼:

1     def _get_widths(self):
 2         return [PIL.Image.open(self.image_path_at(i)).size[0]
 3                 for i in range(self.num_images)]
 4     #源碼中沒有擷取圖像高度資訊的函數,需要補充上
 5     def _get_heights(self):
 6       return [PIL.Image.open(self.image_path_at(i)).size[1]
 7               for i in range(self.num_images)]
 8 
 9     def append_flipped_images(self):
10         num_images = self.num_images
11         widths = self._get_widths()
12         heights = self._get_heights()#add to get image height
13         for i in range(num_images):
14             boxes = self.roidb[i]['boxes'].copy()
15             oldx1 = boxes[:, 0].copy()
16             oldx2 = boxes[:, 2].copy()
17             print(self.image_index[i])
18             assert (boxes[:,1]<=boxes[:,3]).all()#assert that ymin<=ymax
19             assert (boxes[:,1]>=0).all()#assert ymin>=0,for 0-based
20             assert (boxes[:,3]<heights[i]).all()#assert ymax<height[i],for 0-based
21             assert (oldx2<widths[i]).all()#assert xmax<withd[i],for 0-based
22             assert (oldx1>=0).all()#assert xmin>=0, for 0-based
23             assert (oldx2 >= oldx1).all()#assert xmax>=xmin, for 0-based
24             boxes[:, 0] = widths[i] - oldx2 - 1
25             boxes[:, 2] = widths[i] - oldx1 - 1
26             #print ("num_image:%d"%(i))
27             assert (boxes[:, 2] >= boxes[:, 0]).all()
28             entry = {'boxes' : boxes,
29                      'gt_overlaps' : self.roidb[i]['gt_overlaps'],
30                      'gt_classes' : self.roidb[i]['gt_classes'],
31                      'flipped' : True}
32             self.roidb.append(entry)
33         self._image_index = self._image_index * 2      

然後運作,當出現中斷報錯就檢視運作日志上最後一個列印出的圖像名,找到對應的标注檔案檢查。改過後記得要删掉./data/cache中的緩存,然後再運作,直到所有圖像的y标注錯誤都修改完後就大功告成啦!

報錯4:ModuleNotFoundError: No module named 'lib.utils.cython_bbox'

這個錯誤可能是因為沒有生成訓練所需的cython_bbox.py檔案,或者已有的cython_bbox.py檔案不能在本地正常運作。

解決辦法是從cmd中先進入./data/coco/PythonAPI目錄,分别運作下面兩條指令:

python setup.py build_ext --inplace      
python setup.py build_ext install      

然後,在cmd中進入./lib/utils目錄,運作下面一條指令:

python setup.py build_ext --inplace      

這樣,就重新運作了setup.py,重新生成了訓練所需的檔案,報錯就解決了。

感悟:直面bug,找到問題源頭就更容易解決。

這次内容就分享到這裡了,希望與各位老師和小夥伴們交流學習~