1. 程式人生 > >[訓練測試過程記錄]SSD:Single Shot Detector 用於場景文字檢測

[訓練測試過程記錄]SSD:Single Shot Detector 用於場景文字檢測

sudo apt-get install libopenblas-dev
同樣,安裝後,再重新編譯即可解決

資料集準備部分:

使用coco-text資料集

1.將coco-text資料集格式化為pascal_voc的資料集格式,格式方法詳見部落格:[訓練測試過程記錄]Text-Detection-with-FRCN中的第二部分:準備資料集,這裡不再贅述。

2.將formatted_dataset更名為VOC2007,並放入資料夾$home/data/VOCdevkit下面。

3.建立Imdb格式的資料:

cd $CAFFE_ROOT
# Create the trainval.txt, test.txt, and test_name_size.txt in data/VOC0712/
./data/VOC0712/create_list.sh
# You can modify the parameters in create_data.sh if needed.
# It will create lmdb files for trainval and test with encoded original image:
#   - $HOME/data/VOCdevkit/VOC0712/lmdb/VOC0712_trainval_lmdb
#   - $HOME/data/VOCdevkit/VOC0712/lmdb/VOC0712_test_lmdb
# and make soft links at examples/VOC0712/
./data/VOC0712/create_data.sh

注意:

1.修改create_list.sh和create_data.sh下面的資料集路徑

create_list.sh:

#root_dir=$HOME/data/VOCdevkit/
root_dir="改為自己的資料集目錄'
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 VOC2007 VOC2012
  #這裡只有VOC2007資料夾
  for name in VOC2007
  do
    if [[ $dataset == "test" && $name == "VOC2012" ]]
    then
      continue

create_data.sh:

cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$cur_dir/../..

cd $root_dir

redo=1
#data_root_dir="$HOME/data/VOCdevkit"
data_root_dir="改為自己的資料集目錄"
dataset_name="VOC0712"
mapfile="$root_dir/data/$dataset_name/labelmap_voc.prototxt"
anno_type="detection"
2.修改labelmap_voc.prototxt下的資料集類別

由於這裡只有背景和text兩類,因此改為:

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


訓練部分:
# It will create model definition files and save snapshot models in:
#   - $CAFFE_ROOT/models/VGGNet/VOC0712/SSD_300x300/
# and job file, log file, and the python script in:
#   - $CAFFE_ROOT/jobs/VGGNet/VOC0712/SSD_300x300/
# and save temporary evaluation results in:
#   - $HOME/data/VOCdevkit/results/VOC2007/SSD_300x300/
# It should reach 77.* mAP at 120k iterations.
python examples/ssd/ssd_pascal.py
問題1:num_test_image的數目不對

解決方法:需要將4952換成測試圖片的數量,例如coco-text的測試集數目為840。

#Evaluate on whole test set.
#num_test_image = 4952
num_test_image = 840
test_batch_size = 8
# Ideally test_batch_size should be divisible by num_test_image,
# otherwise mAP will be slightly off the true value.
test_iter = int(math.ceil(float(num_test_image) / test_batch_size))


問題2:loss = nan

由於是場景文字資料集的原因,初始迭代產生的loss特別大,我自己訓練是到了iteration 40的時候,就開始變成Loss = nan了。

原因:梯度爆炸。梯度變得非常大,使得學習過程難以繼續。

一般措施:減小solver.prototxt的base_lr,至少減小一個數量級。如果有多個loss layer,需要找出哪個損失層導致了梯度爆炸,並在train_val.prototxt中減小該層的loss_weight,而非是減小通用的base_lr。參考:使用caffe訓練時Loss變為nan的原因

解決方法:

將base_lr變為原來的10倍。在/examples/ssd/ssd_pascal.py的第229行和232行處進行修改,將0.004改為0.0004和將0.00004改為0.000004。

# If true, use batch norm for all newly added layers.
# Currently only the non batch norm version has been tested.
use_batchnorm = False
lr_mult = 1
# Use different initial learning rate.
if use_batchnorm:
   #base_lr = 0.0004
    base_lr = 0.00004
else:
    # A learning rate for batch_size = 1, num_gpus = 1.
    #base_lr = 0.00004
    base_lr = 0.000004
PS:降低學習率可能會帶來loss收斂速度很慢的問題。之前想過更換訓練模型,也就是將官方給點的pretrained model:fully convolutional reduced (atrous) VGGNet換成訓練好了的SSD300*模型。但是由於維度不一樣,將num_classes的維度由21換到了2,所以只能使用官方給的pretrained model。目前除了降低base_lr,還沒有想到其他更好的辦法。