【引言】最近接手了公司的關於蟲子識別的項目,使用MXNet框架開發,但是實際用的是Deformable-ConvNets. Deformable-ConvNets為微軟研究研究院提出的可變卷積網絡,可用於對圖像中大小不一的物體識別,不是單單識別圖中的貓和狗(它們都一般大小),而識別圖像中不同種類的蟲子(蟲子本身小,而且難以區分),在這樣的場景下很適合用可變卷積Deformable-ConvNets。
MXNet本身靈活,擴展性強,根據 https://github.com/msracver/Deformable-ConvNets 官方教程摸索着走下來 一步步安裝,其中有不少坑,網上大多教程沒有實質性幫助,有些教程有幫助但是不完全適合自己的軟硬件環境,這里總結一下,也希望能幫助到別人。
目錄:
1 Ubuntu16.04 系統安裝
2 安裝GPU顯卡驅動
3 安裝CUDA並行計算庫
4 安裝cudnn 神經網絡加速庫
5 安裝軟件依賴
6 可變卷積、MXNet 代碼下載配置
7 demo測試
8 訓練自己的數據集
軟硬件環境:
操作系統:Ubuntu16.04 64位
顯卡:GTX1080ti 兩塊
64G內存 5代 I7 處理器,
顯卡驅動:NVIDIA-Linux-x86_64-375.66.run
CUDA :cuda_8.0.61_375.26_linux.run
cudnn: cudnn-8.0-linux-x64-v5.1.tgz
【注】由於 Deformable-ConvNets給的軟件依賴版本叫老,所以這里用的驅動 CUDNN CUDA都用較老版本,新版本速度會更快,但關鍵是環境搭建好,程序跑通~
其他依賴及軟件:
opencv 3.4.0 源碼安裝+pip安裝
cmake cmake-gui pip安裝
openblas 源碼安裝
Cython、EasyDict 1.6、opencv-python 3.2.0.6 mxnet-cu80==0.12.0b20171228 pip安裝
這里所有pip 安裝的組件可以使用conda 安裝 ,需自己安裝Anaconda or miniconda
Talk is cheap , show me the code! 開整
一 Ubuntu16.04 系統安裝
推薦兩款制作U盤啟動盤的軟件:UltraISO (中文:軟碟通) 和 Universal-USB-Installer
下載好Ubuntu16的ISO鏡像文件,燒寫到U盤,U盤內容需提前備份,燒寫時要格式化U盤,燒寫好進入BIOS 選擇U盤啟動
注意:U盤啟動分兩種: 一種是普通的usb disk 啟動 , 另一種是UEFI版的 usb disk , 第二種更快些, 具體安裝這里不詳述
【補充】:Ubuntu自帶Python環境,也可以安裝miniconda 或 anaconda , 本教程安裝了Anaconda2
【建議】:
1.提前換對應的國內源,如apt 阿里源 conda 清華源 pip 豆瓣或阿里源
2. 關閉Ubuntu系統更新
二 安裝GPU顯卡驅動
2.0 建議提前進入系統BIOS,關閉 Secure Boot , 否則當系統自帶驅動刪除后,不能進入Ubuntu系統,同時建議在ubuntu 16系統下修改gcc g++ 版本號為4.9 (其實4.8-5.3都可以,之所以用4.9是因為在安裝不同版本驅動時有對gcc g++有最低版本要求 NVIDIA-375驅動需要至少4.9版本)
【提示】:安裝GPU顯卡驅動有三種方式:本文介紹手動安裝,除此還有apt 下載安裝 , 用Ubuntu系統設置安裝。
2.1干凈刪除系統自帶nouveau驅動
這部分有點麻煩了,因為除了要下載好對應版本的顯卡驅動和安裝外,還需干凈刪除系統自帶的顯卡驅動nouveau,這里是兩次刪除,一次是刪除Ubuntu16系統自帶驅動,第二次是刪除Linux內核里自帶驅動相關配置。
刪除nouveau內核設置
vim /etc/modprobe.d/blacklist.conf
添加下面一行,保存退出
blacklist vga16fb
blacklist nouveau
blacklist rivafb
blacklist rivatv
blacklist nvidiafb
更新下內核
sudo update-initramfs -u
修改后需要重啟系統 : reboot
參考鏈接:https://blog.csdn.net/10km/article/details/61191230
https://blog.csdn.net/eclipse_c/article/details/23302061
2.2 安裝自己提前下載好的驅動程序
sh NVIDIA-Linux-x86_64-375.66.run
顯卡驅動安裝好后,要配置內核文件,防止重啟后內核又讀取nouveau啟動,會出現幺蛾子問題...
使用下面配置NVIDIA內核文件,或自己找到對應文件手動配置
./NVIDIA-Linux-x86_64-375.66.run -K # -K表示只進行內核配置
檢查顯卡驅動是否裝好:
nvidia-smi
這個命令是用於檢查顯卡驅動安裝情況的,而不是CUDA安裝情況!
若能看到有方框,里面顯示着自己安裝顯卡驅動的版本號,還有顯卡型號以及現存使用率,則顯卡驅動安裝成功,恭喜!
三 安裝CUDA並行計算庫
3.1下載
提前下載好對應顯卡型號的CUDA 版本,現在最新是CUDA9.1 我下載了8.0,也不是最新的8.0,只是求穩定,至於CUDA格式 最好是.run 這個沒有錯
3.2 安裝
安裝過程 要安裝CUDA 兩次 + 配置環境變量
第一次安裝 : sh cuda_8.0.61_375.26_linux.run 期間要同意協議,最好安裝examples用於測試CUDA安裝結果,一定不要安裝顯卡驅動,顯卡驅動的安裝用自己在官網上下載的程序安裝
第二次安裝 : sh cuda_8.0.61_375.26_linux.run -silent -driver 等一會就好了,不同一步步來
配置環境變量: 【或需根據自己配置的場景修改路徑】
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64" export CUDA_HOME=/usr/local/cuda-8.0
查看CUDA安裝情況:
nvcc --version
四 安裝cudnn 神經網絡加速庫
提前在NVIDIA官網上下載對應CUDA版本的cudnn ,下載時要注冊 登錄,下載好是個tar.gz文件
解壓 tar -xzf cudnn-8.0-linux-x64-v5.1.tgz ~/ [假設解壓后目錄為cudnn5.1]
cp cudnn5.1/include/cudnn* /usr/local/cuda-8.0/include/ cp cudnn5.1/lib64/libcudnn* /usr/local/cuda-8.0/lib64
五 安裝軟件依賴
由於可變卷積依賴四種軟件: EasyDict Cython opencv mxnet-cu80==0.1.2.0b20171027
opencv在這里最好先用源碼安裝,同時也要用pip 安裝 opencv-python接口庫 (Tips:用pip安裝軟件時可先還pip源為阿里源,下載速度快很多:)
pip install Cython pip install opencv-python==3.2.0.6
conda install -c auto easydict # 可先通過conda安裝 easydict 本步驟也不是必須 pip install easydict == 1.6 # 關鍵是要用pip 安裝easydict 1.6版本 且本行命令后於前一條命令
編譯MXNet源碼時,要用到openblas線性代數庫,需要源碼安裝 openblas,同時安裝 openblas接口 pip或conda安裝都行
conda install openblas
假設 OPENBLAS_HOME = /usr/local/OpenBLAS
openblas源碼編譯安裝 參考教程:
https://blog.csdn.net/xzzppp/article/details/69633789
https://blog.csdn.net/tsq292978891/article/details/79575036
mxnet-cu80包括很多不同的子版本,用pip安裝
EasyDict Cython 這些只是會簡單調用,不需要源碼安裝 , pip 或 conda安裝就行,一定要注意版本
六 可變卷積、MXNet 代碼下載配置
引用:https://blog.csdn.net/zchang81/article/details/73250896
https://blog.csdn.net/u014380165/article/details/73355194
6.1 clone可變卷積代碼庫
git clone https://github.com/msracver/Deformable-ConvNets.git
6.2 運行腳本簡單初始化
Windows 用戶請運行 cmd .init.bat Linux 用戶請運行 sh ./init.sh 該腳本會自動編譯 cython 模塊並創建一些文件夾。(需提前下載好cython)
6.3 mxnet源碼下載,配置, 編譯 , 安裝
mxnet github官網:https://github.com/apache/incubator-mxnet 有多個mxnet版本代碼:如0.11.0 0.12.0 1.1.0 1.2.0 0.10.0
其中按照 https://github.com/msracver/Deformable-ConvNets 的教程下載MXNet 源碼並恢復對應版本號安裝的是mxnet==0.10.0
實驗中還試了 mxnet1.2.0源碼下載,可恢復到指定版本 MXNet@998378a , 0.11.0 0.12.0 1.1.0 試過不能恢復到998378a版本
### 下面的命令clone+恢復版本,編譯安裝的是0.10.0mxnet版本,也可下載1.2.0mxnet源碼,解壓 從git checkeout 開始執行
git clone --recursive https://github.com/dmlc/mxnet.git git checkout 998378a git submodule update # if it's the first time to checkout, just use: git submodule update --init --recursive
拷貝配置文件
cd MXNET_HOME # 跳轉到mxnet源碼目錄下 cp make/config.mk . # 拷貝make文件夾下的config.mk到當前目錄,也就是 MXNET_HOME
要修改make 配置文件
vim config.mk
修改如下選項,路徑引用或根據用戶設置不同有對應不同的修改
ADD_LDFLAGS ='-L/usr/local/OpenBLAS/lib' # 引用源碼編譯的OpenBLAS庫 ADD_CFLAGS ='-I/usr/local/OpenBLAS/include' USE_CUDA = 1 USE_CUDA_PATH = /usr/local/cuda-8.0 USE_CUDNN = 1 ifeq ($(UNAME_S), Darwin) USE_BLAS = apple else USE_BLAS = openblas endif
進入setup-utils目錄設置 mxnet源碼路徑
cd MXNET_HOME/setup-utils vim install-mxnet-ubuntu-python.sh #在Ubuntu環境下安裝編譯安裝python接口,若是其他系統和接口,對應修改相應文件
修改mxnet路徑即可,並保存退出
MXNET_HOME="$HOME/MXNET_HOME/"
運行安裝腳本進行安裝,也可以在MXNET_HOME目錄下,make 編譯安裝
bash install-mxnet-ubuntu-python.sh
make過程可能有報錯:
Collect2:error : ld returned 1 exit status Makefile:450: recipe for target ‘bin/im2rec’ failed Make: *** [bin/im2rec] Error 1 原因:bin/目錄下缺少im2rec 本錯誤不用管,
繼續 cd python; python setup.py install安裝就好
make 過程報錯:
/tmp/ccFNBmkk.o:在函數‘main’中: im2rec.cc:(.text.startup+0x276c):對‘cv::imencode(std::string const&, cv::_InputArray const&, std::vector<unsigned char, std::allocator<unsigned char> >&, std::vector<int, std::allocator<int> > const&)’未定義的引用 collect2: error: ld returned 1 exit status Makefile:327: recipe for target bin/im2rec failed make: *** [bin/im2rec] Error 1
本錯誤是在編譯cpp文件時make引用opencv的動態鏈接庫出現的問題,需要編譯opencv源碼安裝opencv 同時pip安裝python-opencv 接口
opencv版本 3.2.0.6
mxnet安裝完成后,run自帶的圖像分類:
cd mxnet/example/image-classification
python train_mnist.py
在第一次運行的時候會自動下載MNIST數據集。
以上的命令是使用默認的參數運行,即使用mlp網絡,在cpu上計算。
如果使用lenet網絡,在GPU上實現加速,則使用如下命令:
python train_mnist.py --gpus 0 --network lenet
七 Demo 測試
經測試:rfcn和deeplab 的 demo不可同時跑通,因為rfcn和deeplab所依賴的easydict版本不同,初測rfcn依賴pip安裝的easydict==1.6 ; deeplab依賴conda 安裝的easydict==1.4
貌似rfcn和deeplab demo對opencv版本依賴也不一樣,rfcn依賴python-opencv==3.2.0.6 deeplab 依賴opencv3.4.0 【不同opencv版本互斥,故不可同時run demo】
【假設】:Deformable-ConvNets的根目錄為DCN_NETS
根據 https://github.com/msracver/Deformable-ConvNets 教程下載demo_model 和 pretrained_model文件,解壓放到
cd DCN_NETS/model tar -xzf demo_model
cd DCN_NETS/model/pretrained_model tar -xzf pretrained_model
cd DCN_NETS python ./rfcn/demo.py # 默認是使用可變卷積的Demo python ./rfcn/demo.py --rfcn_only
python ./deeplab/demo.py python ./deeplab/demo.py --deeplab_only
八 訓練自己的數據集
為了便於使用可變卷積調用不同版本的MXNet,可將MXNET源碼目錄拷貝到 可變卷積DCN擴展目錄下
對於DCN MXNET 都在/root/下,且是root用戶登錄
cp -r ~/mxnet ~/Deformable-ConvNets/external/mxnet
【注意】 拷貝整個mxnet的代碼工程,而不是mxnet下面的python文件夾
【總結】
1.可變卷積由於在網絡結構中增加了形變層(即學習偏移量),使CNN網絡對圖像中不同像素大小的物體有更好的檢測效果
2.加上該偏移量的學習之后,可變卷積核的大小和位置可以根據當前需要識別的圖像內容進行動態調整,其直觀效果就是不同位置的卷積核采樣點位置會根據圖像內容發生自適應的變化,從而適應不同物體的形狀、大小等幾何形變。
3.通過修改模型結構,對於一個已訓練的模型只需增加很少計算量,就能達到准確率大幅上升且能識別圖中不同大小像素的功能。
4.官方使用MXNet實現可變卷積(官方給的配置教程沒有說明軟件依賴的版本號是個大坑!),除此還有Tensorflow, pytorch, caffe 等實現,可在github上搜索