【引言】最近接手了公司的关于虫子识别的项目,使用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上搜索