Caffe 学习系列(七):MobileNet-YOLO 安装与训练

Caffe 学习系列(七):MobileNet-YOLO 安装与训练

基于darknet实现mobilenet
基于darknet框架实现DepthwiseConvolutional层
深度学习(七十)darknet 实现编写mobilenet源码

1.1 下载与安装

下载

git clone https://github.com/eric612/MobileNet-YOLO

严格按照以下教程安装即可,注意 Opencv 版本
MobileNet-YOLO 安装教程

1.2 MobileNet-YOLO训练

训练过程基本与MobileNet-SSD类似,只需配置好网络文件中的路径即可
以 yolov2 为例

1.2.1 数据集生成
  1. 在 home/chris/MobileNet-YOLO/data/VOCdevkit 目录下创建 cucumber 目录,该目录中存放自己转换完成的VOC数据集,即Annotation/ImageSets/JPEGImages 等多个文件夹;
  2. 在 home/chris/MobileNet-YOLO/examples 目录下创建 cucumber 目录;
  3. 在 home/chris/MobileNet-YOLO/data 目录下创建 cucumber 目录,同时将data/VOC0712下的 create_list.sh,create_data.sh,labelmap_voc.prototxt
    这三个文件copy到 cucumber 目录下,分别重命名为create_list_cucumber.sh,create_data_cucumber.sh, labelmap_voc_cucumber.prototxt
  4. 对上面新生成的两个create文件进行修改,主要修改是将 VOC0712 相关的信息替换成 cucumber

labelmap_voc_cucumber.prototxt 修改内容:

item {
  name: "none_of_the_above"
  label: 0
  display_name: "background"
}
item {
  name: "sea cucumber"
  label: 1
  display_name: "cucumber"
}

create_list_cucumber.sh 修改内容:

root_dir=$HOME/MobileNet-YOLO/data/VOCdevkit/  # 修改此处
sub_dir=ImageSets/Main
bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for dataset in trainval test
do
  dst_file=$bash_dir/$dataset.txt
  if [ -f $dst_file ]
  then
    rm -f $dst_file
  fi
  for name in cucumber  # 修改此处

create_data_cucumber.sh 修改内容:

data_root_dir="$HOME/MobileNet-YOLO/data/VOCdevkit" 
dataset_name="cucumber"
mapfile="$root_dir/data/$dataset_name/labelmap_voc_cucumber.prototxt"
1.2.2 网络文件路径修改

在 home/chris/MobileNet-YOLO/models/yolov2/ 目录下,修改mobilenet_yolo_solver.prototxt,mobilenet_yolo_test.prototxt 和 mobilenet_yolo_train.prototxt 文件

mobilenet_yolo_test.prototxt :

  data_param {
    source: "/home/chris/MobileNet-YOLO/data/VOCdevkit/cucumber/lmdb/cucumber_test_lmdb/"
    batch_size: 1
    backend: LMDB
  }
  annotated_data_param {
    batch_sampler {
    }
    label_map_file: "/home/chris/MobileNet-YOLO/data/cucumber/labelmap_voc_cucumber.prototxt"
  }
  ... ...
  # 跳到最后
  ... ...
  # 跟 darknet 下的 cfg 文件一样,将输出层的 num_output 和 classes 根据自己的情况修改
  layer {
  name: "conv22_indoor"
  type: "Convolution"
  bottom: "conv17"
  top: "conv22"
    param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 30     # 修改这里,若是yolov3,classes=1时,num_output = 18
    kernel_size: 1
    pad: 0
    stride: 1
    weight_filler {
      type: "msra"
    }
	bias_filler {
      value: 0
    }
  }
}
layer {
  name: "conv23_indoor"
  type: "Convolution"
  bottom: "conv20"
  top: "conv23"
    param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 30    # 修改这里
    kernel_size: 1
    pad: 0
    stride: 1
    weight_filler {
      type: "msra"
    }
	bias_filler {
      value: 0
    }
  }
}

layer {
  name: "detection_out"
  type: "YoloDetectionOutput"
  bottom: "conv22"
  bottom: "conv23"
  top: "detection_out"
  include {
	phase: TEST
  }
  yolo_detection_output_param {
    num_classes: 1      # 修改这里
    coords: 4
    confidence_threshold: 0.25
	nms_threshold: 0.45

    biases: 1.08
    biases: 1.19
    biases: 3.42
    biases: 4.41
    biases: 6.63
    biases: 11.38
    biases: 9.42
    biases: 5.11
    biases: 16.62
    biases: 10.52
  }
}
layer {
  name: "detection_eval"
  type: "DetectionEvaluate"
  bottom: "detection_out"
  bottom: "label"
  top: "detection_eval"
  include {
    phase: TEST
  }
  detection_evaluate_param {
    num_classes: 2       # 修改这里( 背景 + 1 )
    background_label_id: 0
    overlap_threshold: 0.5
    evaluate_difficult_gt: false
  }
}

mobilenet_yolo_train.prototxt:

  data_param {
    source: "/home/chris/MobileNet-YOLO/data/VOCdevkit/cucumber/lmdb/cucumber_trainval_lmdb/"
    batch_size: 2  # 调小,不然 CPU 内存不够用
    backend: LMDB
  }
  annotated_data_param {
	yolo_data_type : 1
	yolo_data_jitter : 0.3
    label_map_file:  "/home/chris/MobileNet-YOLO/data/cucumber/labelmap_voc_cucumber.prototxt"
  }
  ... ...
  # 跳到最后
  ... ...
  layer {
  name: "conv22_indoor"
  type: "Convolution"
  bottom: "conv17"
  top: "conv22"
    param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 30    # 修改这里
    kernel_size: 1
    pad: 0
    stride: 1
    weight_filler {
      type: "msra"
    }
	bias_filler {
      value: 0
    }
  }
}
layer {
  name: "conv23_indoor"
  type: "Convolution"
  bottom: "conv20"
  top: "conv23"
    param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 30    # 修改这里
    kernel_size: 1
    pad: 0
    stride: 1
    weight_filler {
      type: "msra"
    }
	bias_filler {
      value: 0
    }
  }
}
layer {
  name: "Region_Loss1"
  type: "RegionLoss"
  bottom: "conv22"
  bottom: "label"
  top: "det_loss1"
  loss_weight: 1
  region_loss_param {
    side: 13
    num_class: 1    # 修改这里
    coords: 4
    num: 5
    softmax: 1
    jitter: 0.2
    rescore: 1
    
    object_scale: 5.0
    noobject_scale: 1.0
    class_scale: 1.0
    coord_scale: 1.0
    
    absolute: 1
    thresh: 0.6
    random: 0

    biases: 1.08
    biases: 1.19
    biases: 3.42
    biases: 4.41
    biases: 6.63
    biases: 11.38
    biases: 9.42
    biases: 5.11
    biases: 16.62
    biases: 10.52
  }
}
layer {
  name: "Region_Loss2"
  type: "RegionLoss"
  bottom: "conv23"
  bottom: "label"
  top: "det_loss2"
  loss_weight: 1
  region_loss_param {
    side: 13
    num_class: 1    # 修改这里
    coords: 4
    num: 5
    softmax: 1
    jitter: 0.2
    rescore: 1

mobilenet_yolo_solver.prototxt:

train_net: "models/yolov2/mobilenet_yolo_train.prototxt"
test_net: "models/yolov2/mobilenet_yolo_test.prototxt"
test_iter: 4952
test_interval: 1000
base_lr: 0.0005
display: 10
max_iter: 120000
lr_policy: "multistep"
gamma: 0.5
weight_decay: 0.00005
snapshot: 1000
snapshot_prefix: "models/yolov2/mobilenet_yolo_deploy"
solver_mode: CPU   # 修改为 CPU
debug_info: false
snapshot_after_train: true
test_initialization: false
average_loss: 10
stepvalue: 20000
stepvalue: 60000
iter_size: 1  # 修改为 1
type: "RMSProp"
eval_type: "detection"
ap_version: "11point"
show_per_class_result: true

返回至 MobileNet-YOLO 目录下,运行以下命令即可

sh train_yolo.sh

train_yolo.sh:去掉使用 GPU

#!/bin/bash
LOG=log/train-`date +%Y-%m-%d-%H-%M-%S`.log
./build/tools/caffe train --solver models/yolov2/mobilenet_yolo_solver.prototxt --weights models/MobileNet/mobilenet_iter_73000.caffemodel
1.2.3 网络结构修改

修改网络结构时,注意卷积层间的链接,同时可将网络可视化以便于观察

# caffe网络可视化工具
http://ethereon.github.io/netscope/#/editor

注意:

layer {
  name: "conv3/relu"
  type: "ReLU"
  bottom: "conv3"
  top: "conv3"
}

layer {
  name: "conv6/dw"
  type: "DepthwiseConvolution"
  bottom: "conv3"    # 注意此处
  top: "conv6/dw"
  param {
    lr_mult: 0.1
    decay_mult: 0.1
  }

小技巧:以上网络结构修改时也可使用 caffe 可视化工具辅助检查
比如:修改 num_output 时,即修改两个紫色层

在这里插入图片描述

1.3 遇坑记录

安装的 CPU 版本,编译时 Opencv 报错,又卸载了原本安装的3.3.0,改为教程里的3.3.1 编译正常通过。

1.3.1 CMakeLists.txt 修改
caffe_option(CPU_ONLY  "Build Caffe without CUDA support" ON) #  OFF 修改为 ON
caffe_option(USE_CUDNN "Build Caffe with cuDNN library support" OFF IF NOT CPU_ONLY)
caffe_option(USE_NCCL "Build Caffe with NCCL library support" OFF)
caffe_option(BUILD_SHARED_LIBS "Build shared libraries" ON)
caffe_option(BUILD_python "Build Python wrapper" ON)
set(python_version "2" CACHE STRING "Specify which Python version to use")
caffe_option(BUILD_matlab "Build Matlab wrapper" OFF IF UNIX OR APPLE)
caffe_option(BUILD_docs   "Build documentation" ON IF UNIX OR APPLE)
caffe_option(BUILD_python_layer "Build the Caffe Python layer" ON)
caffe_option(USE_OPENCV "Build with OpenCV support" ON)
caffe_option(USE_LEVELDB "Build with levelDB" OFF)
caffe_option(USE_LMDB "Build with lmdb" ON)
caffe_option(ALLOW_LMDB_NOLOCK "Allow MDB_NOLOCK when reading LMDB files (only if necessary)" OFF)
caffe_option(USE_OPENMP "Link with OpenMP (when your BLAS wants OpenMP and you get linker errors)" OFF)
1.3.2 Opencv 卸载方法
cd build
make uninstall
cd ..
sudo rm -r build
sudo rm -r /usr/local/include/opencv2 /usr/local/include/opencv /usr/include/opencv /usr/include/opencv2 /usr/local/share/opencv /usr/local/share/OpenCV /usr/share/opencv /usr/share/OpenCV /usr/local/bin/opencv* /usr/local/lib/libopencv
1.3.4 check failed:mdb_status==0(2vs.0)No such file or directiry

解决方法:仔细查看prototxt文件里面的各种路径

1.3.5 Check failed: *ptr host allocation of size 297369600 failed

原因:CPU内存不足,将 batch_size 调小即可
参考:caffe调参中的batch_size和iter_size

1.3.5 测试报错(一)

报错内容:Check failed: target_blobs.size() == source_layer.blobs_size() (2 vs. 1) Incompatible number of blobs for layer conv0
原因分析:bias_term: false

The problem is with your bias term in conv1. In your train.prototxt it is set to false. But in your deploy.prototxt it is not and by default that is true. That is why weight loader is looking for two blobs.

解决办法:将 deploy.prototxt 中提示报错的层的 bias term = false

1.3.6 测试报错(二)

报错内容:图像中目标物体标签为 aeroplane,而不是自己设置的标签
原因分析:拆看脚本文件可知,他利用的是编译得到的 ssd_detect 进行检测的

./build/examples/ssd/ssd_detect models/yolov3_x/mobilenet_yolov3_lite_deploy.prototxt models/yolov3_x/mobilenet_yolov3_lite_deploy.caffemodel

但是在 MobileNet-YOLO/examples/ssd/ssd_detect.cpp 文件中,规定的类如下:

char* CLASSES[81] = { "__background__",
"person", "bicycle", "car", "motorcycle",
"airplane", "bus", "train", "truck", "boat",
"traffic light", "fire hydrant", "stop sign", "parking meter",
"bench", "bird", "cat",
"dog", "horse", "sheep", "cow",
"elephant", "bear", "zebra", "giraffe" ,
"backpack", "umbrella", "handbag", "tie" ,
"suitcase", "frisbee", "skis", "snowboard" ,
"sports ball", "kite", "baseball bat", "baseball glove" ,
"skateboard", "surfboard", "tennis racket", "bottle" ,
"wine glass", "cup", "fork", "knife" ,
"spoon", "bowl", "banana", "apple" ,
"sandwich", "orange", "broccoli", "carrot" ,
"hot dog", "pizza", "donut", "cake" ,
"chair", "couch", "potted plant", "bed" ,
"dining table", "toilet", "tv", "laptop" ,
"mouse", "remote", "keyboard", "cell phone" ,
"microwave", "oven", "toaster", "sink" ,
"refrigerator", "book", "clock", "vase" ,
"scissors", "teddy bear", "hair drier", "toothbrush" ,
};
#else
char* CLASSES[21] = { "__background__",
"aeroplane", "bicycle", "bird", "boat",
"bottle", "bus", "car", "cat", "chair",
"cow", "diningtable", "dog", "horse",
"motorbike", "person", "pottedplant",
"sheep", "sofa", "train", "tvmonitor" };
#endif

因此,需将该文件中的类修改为自己的类别后,重新编译即可。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

la_fe_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值