环境
- Ubuntu14.04
- GTX1070
- gcc4.9.x(默认4.8,需升级)
准备
- 显卡驱动安装
- http://www.nvidia.com/download/driverResults.aspx/130646/en-us (NVIDIA-Linux-x86_64-390.25.run)
# 禁用Ubuntu自带的显卡驱动
sudo vim /etc/modprobe.d/blacklist.conf
blacklist nouveau option nouveau modeset=0
sudo update-initramfs -u
重启电脑
# 切换到文字界面(Ctrl+Alt+F1~F6)
sudo service lightdm stop
sudo ./NVIDIA-Linux-x86_64-375.66.run
再次重启电脑
# 验证显卡驱动是否安装成功
nvidia-smi
- CUDA下载和安装
- https://developer.nvidia.com/cuda-downloads (2018.2.8链接最新是9.0的,下载8.0 https://developer.nvidia.com/cuda-80-ga2-download-archive Linux x86_64 Ubuntu 14.04 runfile(local))
# 注意你是否已经安装过 nvidia 显卡驱动(即第一步),若无法保证已安装的 nvidia 显卡驱动一定正确,那就卸载掉之前安装的 nvidia 显卡驱动,
# 然后开始安装 CUDA 8.0;若可以保证已安装正确的 nvidia 显卡驱动,则直接开始安装 CUDA 8.0,在安装过程中选择不再安装 nvidia 显卡驱动
# 安装CUDA
chmod u+x cudaxxxx
sudo sh cuda_8.0.61_375.26_linux.run
提示是否安装nvidia375驱动(否),其他选项根据提示选择和设置。
# 环境变量配置
sudo vim /etc/profile
export PATH=/usr/local/cuda-8.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:$LD_LIBRARY_PATH
source /etc/profile
# 验证是否安装成功
nvcc –V
# 测试CUDA sample
cd /usr/local/cuda-7.5/samples/1_Utilities/deviceQuery
make
sudo ./deviceQuery
- cudnn下载和安装
- https://developer.nvidia.com/rdp/cudnn-download (需要注册账号,尝试谷歌浏览器对注册不友好,换IE浏览器)Download cuDNN v5.1 (Jan 20, 2017), for CUDA 8.0 / cuDNN v5.1 Library for Linux
# 解压下载的文件
cp cudnn-8.0-linux-x64-v5.1.solitairetheme8 cudnn-8.0-linux-x64-v5.1.tgz
tar -xvf cudnn-8.0-linux-x64-v5.1.tgz
# 安装头文件和库文件
sudo cp cudnn.h /usr/local/cuda/include
sudo cp lib* /usr/local/cuda/lib64/
- Caffe以及相关依赖库安装
- protobuf
- hdf5
- boost
- atlas
- gflags
- lmdb
- google-glog
- opencv(可选)
在Ubuntu上安装命令如下:
# 可选择性安装
sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compiler
sudo apt-get install --no-install-recommends libboost-all-dev
sudo apt-get install libopenblas-dev liblapack-dev libatlas-base-dev
sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev
编译Caffe
# https://github.com/FreeApe/VGG-or-MobileNet-SSD
git clone https://github.com/FreeApe/VGG-or-MobileNet-SSD.git
cp Makefile.config.example Makefile.config
# 修改Makefile.config,比如使用cudnn,gpu/cpu模式选择,禁用/启动LEVELDB等
make -j
make install
make py
编译过程中可能会出现错误:
error: ‘type name’ declared as function returning an array
,因为编译器版本支持问题,升级编译器到4.9或者5.3(已经尝试通过)。
训练超参数详解
solver.prototxt
是一个超参数配置文件,用于告诉caffe如何训练网络。
base_lr:
该参数表示网络的基础(开始)学习速率。该值是一个实数(浮点数)。
lr_policy:
此参数指示学习速率应该如何随时间变化。该值是一个带引号的字符串。
可设置选项包含:
- “step” :以
gamma
参数指示的步长降低学习速率。 - “multistep” :在每个指定的
stepvalue
值下,以gamma
参数指示的步长降低学习速率。 - “fixed” :学习率不会改变。
- “exp” :
gamma
^iter - “poly” : 有效学习率遵循多项式衰减,由max_iter为零。
base_lr *(1-iter / max_iter)^(power)
- “sigmoid” : 有效的学习速率遵循sigmod衰减。
base_lr *(1 /(1 + exp(-gamma *(iter-stepsize))))
在求解器参数协议缓冲区中需定义了base_lr,max_iter,gamma,step,stepvalue和power,并且
iter
是当前迭代次数.
gamma:
这个参数表示每次我们到达下一个“step”时,学习速率应该改变多少。该值是一个实数,可以认为是将当前的学习速率乘以所述的数量以获得新的学习速率。
stepsize:
这个参数表示多久(在一些迭代中)我们应该转移到下一步的训练。这个值是一个正整数。
stepvalue:
这个参数表明了我们应该转移到下一步训练的潜在的许多迭代计数之一。这个值是一个正整数。通常存在多于一个的这些参数,每一个都表示下一步迭代。比如设定5000,表示到了5000次迭代后,就会进入到下一次的学习率迭代区间。
max_iter:
该参数指示网络何时应该停止训练。该值是一个整数,表示哪个迭代应该是最后一个。
momentum:
此参数指示在新计算中将保留多少以前的重量。这个值是一个真实的分数。
weight_decay:
该参数表示大权重(正则化)惩罚的因子。这个值通常是一个真正的分数。
random_seed:
解算器和网络使用的随机种子(例如,在Dropout层中)。
solver_mode:
该参数指示将在解决网络中使用哪种模式。
选项包含:CPU 、GPU
snapshot:
这个参数表示caffe应该输出一个模型和solverstate的频率。这个值是一个正整数。
snapshot_prefix:
此参数指示如何将snapshot 的模型和solverstate的名称作为前缀。这个值是一个双引号的字符串。可以包含路径。
net:
此参数指示要训练的网络的位置(原型文件的路径)。这个值是一个双引号的字符串。也可以用train_net。
iter_size:
通过iter_size求解器字段跨越批次累积梯度。使用这个设置batch_size:16与iter_size:1和batch_size:4与iter_size:4是等价的。
test_iter:
此参数指示每个test_interval应该发生多少次测试迭代。这个值是一个正整数。
test_interval:
该参数表示网络测试阶段的执行频率。
display:
这个参数表示caffe应该多长时间向屏幕输出结果。该值是一个正整数,并指定一个迭代计数。
type:
该参数表示用于训练网络的反向传播算法。该值是一个带引号的字符串。
选项包含:
- Stochastic Gradient Descent “SGD”
- AdaDelta “AdaDelta”
- Adaptive Gradient “AdaGrad”
- Adam “Adam”
- Nesterov’s Accelerated Gradient “Nesterov”
- RMSprop “RMSProp”
训练自己的数据
- 采集(搜集)数据
- 标注数据(labelimg)
- 划分训练集和测试集(可自己写python脚本)
- 制作LMDB文件
- 训练
制作LMDB文件
制作LMDB文件过程中,需要python相关环境,可能需要安装numpy,matplotlib等。
当整个数据集变为VOC格式时,即如下结构:
└── your_dataset
├── create_list.txt
├── create_data.txt
├── labelmap_xxx.prototxt(训练类别映射文件)
├── Annotations
├── batch_rename.py
├── ImageSets
│ └── create_set.py(划分数据集脚本)
│ ├── test.txt(实际采用)
│ ├── train.txt
│ ├── trainval.txt(实际采用)
│ └── val.txt
└── JPEGImages
- 使用create_list.txt创建test.txt、trainval.txt、test_name_size.txt文件,即测试集和训练集的xml和图像映射文件以及测试图像集的大小信息文件。
- 使用create_data.txt根据第一步生成的文件创建lmdb文件,即根据第一步和第二步之后,$caffe_root/data/your_dataset/结构如下:
└── your_dataset
├── test.txt
├── trainval.txt
├── test_name_size.txt
├── lmdb(生成的lmdb文件目录,在$caffe_root/examples/your_dataset/目录下也有对应的lmdb软链接)
├── create_list.txt
├── create_data.txt
├── labelmap_xxx.prototxt(训练类别映射文件)
├── Annotations
├── batch_rename.py
├── ImageSets
│ └── create_set.py(划分数据集脚本)
│ ├── test.txt(实际采用)
│ ├── train.txt
│ ├── trainval.txt(实际采用)
│ └── val.txt
└── JPEGImages
训练
训练相关文件将其放在$caffe_root/examples/your_train_workspace_dir目录下:
└── your_train_workspace_dir
├── MobileNetSSD_deploy.prototxt(最后模型部署网络模型文件)
├── MobileNetSSD_test.prototxt(训练过程中测试网络模型文件)
├── MobileNetSSD_train.prototxt(训练网络模型文件)
├── train.sh(训练脚本)
└── solver_train.prototxt(超参数文件)
solver_train.prototxt 示例:
train_net: "examples/your_train_workspace_dir/MobileNetSSD_train.prototxt"
test_net: "examples/your_train_workspace_dir/MobileNetSSD_test.prototxt"
test_iter: 3
test_interval: 5000
base_lr: 0.0005
display: 10
max_iter: 10000
lr_policy: "multistep"
gamma: 0.5
weight_decay: 0.00005
snapshot: 1000
snapshot_prefix: "snapshot/my_mobilenet_ssd"
solver_mode: GPU
debug_info: false
snapshot_after_train: true
test_initialization: false
average_loss: 10
stepvalue: 5000
stepvalue: 8000
iter_size: 1
type: "RMSProp"
eval_type: "detection"
ap_version: "11point"
train.sh示例:
mkdir -p snapshot
./build/tools/caffe train -solver="examples/your_train_workspace_dir/solver_train.prototxt" \
-weights="examplesyour_train_workspace_dir/mobilenet_iter_73000.caffemodel" \
-gpu 0
最后,执行训练脚本:
cd $caffe_root
./examples/your_train_workspace_dir/train.sh
部署模型,在超参数中设置的最后模型输出文件夹中snapshot/my_mobilenet_ssd
找到已经训练好的模型,然后通过caffe或者其他开源框架,如腾讯开源的ncnn来部署模型。