[訓練測試過程記錄]SSD:Single Shot Detector 用於場景文字檢測
阿新 • • 發佈:2019-01-27
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,還沒有想到其他更好的辦法。