為理解空洞卷積的詳細作用以及對應的操作,對RFBNet進行復現。
代碼位置:https://github.com/ruinmessi/RFBNet
完成下載后,執行./make.sh時出現下面的錯誤:
根據網上一篇博客說是Cython模塊沒有安裝的原因,但是安裝后,仍然沒有效果
看着錯誤一步步進行更改:
1、根據錯誤提示,(PyObject *(*)(PyObject *, PyObject * const *, Py_ssize_t))meth函數給的參數太多,根據需要刪除一個參數,而看一下每個參數的概念以及對應的類型名稱,最后決定應當刪除NULL。
2、顯示在PyThreadState中沒有exc_type、exc_value、exc_traceback成員變量,通過查閱資料,以及看PyThreadState的源碼了解到在版本1.5后,變量名稱使用curexc_type、curexc_value以及curexc_traceback代替。所以這個錯誤只需要直接進行對應變量名的替換即可。
需要改的內容分別在utils/nms/cpu_nms.c、utils/nms/gpu_nms.c、utils/pycocotools/_mask.c,將這些文件進行上述修改即可。
此時執行完成./make.sh
在完成make.sh,配置好相關信息后,使用train_RFB.py文件進行訓練,此時我是直接使用RFB_mobile版本的checkpoints,使用VOC數據集進行訓練,同時設置size為300。
python train_RFB.py -d VOC -v RFB_mobile -s 300
-d:dataset的格式,VOC或COCO -v:使用的RFBNet的版本,RFB_vgg、RFB_mobile、RFB_E_vgg -s:圖片的size
其中還有一些其他的參數,可以從train_RFB.py代碼中詳細查看,其中最主要的要設定網絡的basenet
在此基礎上,通過對應的github下載了mobilenet_feature.pth,當然下載vgg16的操作也是類似的,這些都只是一個預訓練的模型。
在這個過程中,我也遇到了一些問題,因為當時的服務器上的0卡GPU已經被兩個程序占用,剩余的內容非常小,而且RFBNet中的代碼使用CUDA又是從服務器中的第一個GPU開始啟動的,所以最后出現了
RumtimeError: CUDA Error, out of memory.
當時我很奇怪,明明還有其他的GPU卡沒有被占用,為什么不能直接調用,最后發現是程序本身的問題,或者也可以說是CUDA配置的問題。默認的CUDA_VISIBLE_DEVICES是包含所有的GPU卡的,而且沒有預先定義CUDA_VISIBLE_DEVICES在使用時也會出錯;在網上看到的一個解決方法就是更改默認的可見GPU的序號,使用如下代碼:
import os os.environ[‘CUDA_VISIBLE_DEVICES’]=’2,3’
在程序設置過程中,CUDA_VISIBLE_DEVICES被視為一個字符串,需要用引號進行賦值,但是在設置過程中,一直出現大致是說CUDA_VISIBLE_DEVICES不存在的意思,最后查看了一下聲明的變量里面確實沒有這個,所以需要在命令行中執行一下命令:
export CUDA_VISIBLE_DEVICES=0,1,2,3,4
不管其他,我覺得系統的變量還是最好能將整個服務器所有的GPU的序號都包括進去是比較好的,在使用的時候可以在當前程序中直接指定修改使用哪個GPU會更好。
之后就可以按照自己的需要進行訓練或者測試了
1)我在訓練時,使用RFB_mobile,共進行了epoch=200多次,最后保存的pth在205次。這個訓練代碼可以每10次進行保存一次。
2)然后使用最后的訓練結果進行測試
python test_RFB.py -d VOC -v RFB_mobile -s 300
當然在test_RFB.py文件中也需要對對應的checkpoints的路徑進行更改。
這里的mAP僅有70.2%,我覺得一方面是因為我只訓練了200多個epoch,總共有1500個左右,訓練不夠充分,同時也有使用了RFB_mobile模型的緣故,如果直接使用RFB_vgg可能效果會更好。
最后,我認為對於復現代碼,最好是能夠自己獨立解決報錯的信息,在這個過程中可以發現以前編輯的代碼與現在的不同之處,同時也能夠鍛煉一下自己解決問題的能力,而不是直接就上網開始搜對應的教程什么的。