最近使用Faster 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'
5、error: Unable to find vcvarsall.bat
解決方法:
報錯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函數所在位置,如下圖:
整體替換為下面代碼:
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,重新生成了訓練所需的文件,報錯就解決了。
報錯5:error: Unable to find vcvarsall.bat
在構建coco的相關環境時,出現這個錯誤,找不到vcvarsall.bat,這是因為沒有安裝c++的配置文件。我的解決方法是下載vs2015版,在安裝時記得勾選c++相關的組件,安裝成功后把vs2015添加到環境變量,這樣就成功解決該報錯啦。
感悟:直面bug,找到問題源頭就更容易解決。
這次內容就分享到這里了,希望與各位老師和小伙伴們交流學習~