『TensorFlow』SSD源碼學習_其一:論文及開源項目文檔介紹


一、論文介紹

讀論文系列:Object Detection ECCV2016 SSD

一句話概括:SSD就是關於類別的多尺度RPN網絡

基本思路:

  • 基礎網絡后接多層feature map
  • 多層feature map分別對應不同尺度的固定anchor
  • 回歸所有anchor對應的class和bounding box

網絡結構簡介

  • 輸入:300x300

  • 經過VGG-16(只到conv4_3這一層)

  • 經過幾層卷積,得到多層尺寸逐漸減小的feature map

  • 每層feature map分別做3x3卷積,每個feature map cell(又稱slide window)對應k個類別和4個bounding box offset,同時對應原圖中6(或4)個anchor(又稱default box)

    • 38x38, 最后3x3, 1x1三個feature map的每個feature map cell只對應4個anchor,分別為寬高比: 1:1兩種,1:2, 2:1兩種,因此總共有 38 x 38 x 4 + 19 x 19 x 6 + 10 x 10 x 6 + 5 x 5 x 6 + 3 x 3 x 4 + 1 x 1 x 4 = 8732 個anchor
    • 其他feature map的feature map cell對應6個anchor,分別為寬高比: 1:1兩種,1:2, 2:1兩種,1:3, 3:1兩種
    • 每層的feature map cell對應的anchor計算方法如下
    • 位置:假設當前feature map cell是位於第i行,第j列,則anchor的中心為(i+0.5,j+0.5),注意,這個值需要處理放縮到0-1之間作為相對位置
    • 縮放因子:

    Scale

    其中s_min為0.2,s_max為0.9,m為添加的feature map的層數,縮放因子就是為不同feature map選擇不同的大小的anchor,要求小的feature map對應的anchor盡量大,因為越小的feature map,其feature map cell的感受野就越大

    • anchor寬高:

      width

      height

      其中,a_r∈{1,2,3,1/2,1/3},可以理解為在縮放因子選擇好anchor尺寸后,用a_r來控制anchor形狀,從而得到多尺度的各種anchor,當a_r=1時,增加一種s_k=sqrt(s_{k-1}*s_{k+1}),於是每個feature map cell通常對應6種anchor。

  • 網絡的訓練目標就是,回歸各個anchor對應的類別和位置

實際送入分類/回歸器的樣本選擇問題

  • 正樣本 選擇與bounding box jaccard overlap(兩張圖的交集/並集)大於0.5的anchor作為正樣本

  • 樣本比例 Hard negative mining:由於負樣本很多,需要去掉一部分負樣本,先整圖經過網絡,根據每個anchor的最高類置信度進行排序,選擇置信度靠前的樣本,這樣篩選出來的負樣本也會更難識別,並且最終正負樣本比例大概是1:3

Loss

還是一如既往的location loss + classification loss,並為location loss添加了系數α(然而實際上α=1)進行平衡,並在batch維度進行平均

SSD Loss

  • x是x_{ij}^{p}的集合x_{ij}^{p}={1,0},用於判斷第i個anchor是否是第j個bounding box上的p類樣本
  • c是c_{i}^{p}的集合,c_{i}^{p}是第i個anchor預測為第p類的概率
  • l是預測的bounding box集合
  • g是ground true bounding box集合

其中定位loss與faster rcnn相同

Location loss

這個式子里的k不是很明確,其實想表達不算背景0類的意思,且前景類只為match的類算location loss

分類loss就是很常用的softmax交叉熵了

classification

相關內容各篇代碼介紹部分還會涉及,可加深理解:

『TensorFlow』SSD源碼學習_其二:基於VGG的SSD網絡前向架構 

『TensorFlow』SSD源碼學習_其三:搜索網格生成

『TensorFlow』SSD源碼學習_其四:數據介紹及TFR文件生成

『TensorFlow』SSD源碼學習_其五:TFR數據讀取&數據預處理

『TensorFlow』SSD源碼學習_其六:標簽整理

『TensorFlow』SSD源碼學習_其七:損失函數

『TensorFlow』SSD源碼學習_其八:網絡訓練

二、開源代碼文檔

原項目地址:SSD-Tensorflow

Fork版本項目地址:SSD

根據README的介紹,該項目收到了tf-slim項目中包含了多種經典網絡結構(分類用)的啟發,使用了模塊化的編程思想,可以替換檢查網絡的結構,其模塊組織如下:

  • datasets:  數據及接口,interface to popular datasets (Pascal VOC, COCO, ...) and scripts to convert the former to TF-Records;
  • networks:  網絡結構定義,definition of SSD networks, and common encoding and decoding methods (we refer to the paper on this precise topic);
  • pre-processing:  預處理和數據增強,pre-processing and data augmentation routines, inspired by original VGG and Inception implementations.

項目給提供了兩個已訓練的VGG網絡,輸入分別為300和512。

除此之外,還有一個迷你的SSD展示ipynb腳本,可以快讀演示預測ssd_notebook

腳本tf_convert_data.py

將數據轉換為一組TF-Record文件,調用示意如下:

DATASET_DIR=./VOC2007/test/
OUTPUT_DIR=./tfrecords
python tf_convert_data.py \
    --dataset_name=pascalvoc \
    --dataset_dir=${DATASET_DIR} \
    --output_name=voc_2007_train \
    --output_dir=${OUTPUT_DIR}

腳本caffe_to_tensorflow.py

可以把caffe的模型轉換為checkpoints,供程序使用:

CAFFE_MODEL=./ckpts/SSD_300x300_ft_VOC0712/VGG_VOC0712_SSD_300x300_ft_iter_120000.caffemodel
python caffe_to_tensorflow.py \
    --model_name=ssd_300_vgg \
    --num_classes=21 \
    --caffemodel_path=${CAFFE_MODEL}

腳本train_ssd_network.py

用於訓練模型,

  • 可以自定義訓練的明細(dataset, optimiser, hyper-parameters, model, ...)
  • 可以載入ckeckpoints后fine-tune

使用VGG-300模型進行微調的示意如下,

DATASET_DIR=./tfrecords
TRAIN_DIR=./logs/
CHECKPOINT_PATH=./checkpoints/ssd_300_vgg.ckpt
python train_ssd_network.py \
    --train_dir=${TRAIN_DIR} \
    --dataset_dir=${DATASET_DIR} \
    --dataset_name=pascalvoc_2012 \
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \
    --checkpoint_path=${CHECKPOINT_PATH} \
    --save_summaries_secs=60 \
    --save_interval_secs=600 \
    --weight_decay=0.0005 \
    --optimizer=adam \
    --learning_rate=0.001 \
    --batch_size=32

腳本eval_ssd_network.py

使用checkpoint文件來檢驗訓練效果,調用示意如下:

EVAL_DIR=./logs/
CHECKPOINT_PATH=./checkpoints/VGG_VOC0712_SSD_300x300_ft_iter_120000.ckpt
python eval_ssd_network.py \
    --eval_dir=${EVAL_DIR} \
    --dataset_dir=${DATASET_DIR} \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=test \
    --model_name=ssd_300_vgg \
    --checkpoint_path=${CHECKPOINT_PATH} \
    --batch_size=1

這個腳本可以在訓練腳本運行的同時運行,動態的監測當前訓練效果,此時命令如下:

EVAL_DIR=${TRAIN_DIR}/eval
python eval_ssd_network.py \
    --eval_dir=${EVAL_DIR} \
    --dataset_dir=${DATASET_DIR} \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=test \
    --model_name=ssd_300_vgg \
    --checkpoint_path=${TRAIN_DIR} \
    --wait_for_checkpoints=True \
    --batch_size=1 \
    --max_num_batches=500

而且文檔描述的很不簡單,eval腳本可以監測到GPU空閑,

one can pass to training and validation scripts a GPU memory upper limit such that both can run in parallel on the same device. If some GPU memory is available for the evaluation script, the former can be run in parallel as follows:

腳本ssd_vgg_preprocessing.pyssd_vgg_300/512.py

one may also want to experiment with data augmentation parameters (random cropping, resolution, ...) in ssd_vgg_preprocessing.py or/and network parameters (feature layers, anchors boxes, ...) in ssd_vgg_300/512.py

預訓練分類網絡擴展為SSD

可以嘗試構建一個基於標准體系結構的新的SSD模型(VGG, ResNet, Inception,…),並在其之上設置multibox層(使用特定的錨點,比率,…)。為此,還可以只加載原始架構的權重,並隨機初始化網絡的其余部分,從而對網絡進行微調。例如,在vgg16架構的情況下,可以將一個新模型訓練如下:

DATASET_DIR=./tfrecords
TRAIN_DIR=./log/
CHECKPOINT_PATH=./checkpoints/vgg_16.ckpt
python train_ssd_network.py \
    --train_dir=${TRAIN_DIR} \
    --dataset_dir=${DATASET_DIR} \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \
    --checkpoint_path=${CHECKPOINT_PATH} \
    --checkpoint_model_scope=vgg_16 \
    --checkpoint_exclude_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box \
    --trainable_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box \
    --save_summaries_secs=60 \
    --save_interval_secs=600 \
    --weight_decay=0.0005 \
    --optimizer=adam \
    --learning_rate=0.001 \
    --learning_rate_decay_factor=0.94 \
    --batch_size=32

在前一個命令中,訓練腳本隨機初始化checkpoint_exclusive de_scope的權重,並從檢查點文件vgg_16加載。ckpt網絡的剩余部分。注意,我們還指定了trainable_scope參數,以便此時只訓練新的SSD組件,並保持VGG網絡的其余部分不變。一旦網絡收斂到良好的第一個結果(例如~0.5 mAP),就可以對整個網絡進行如下微調:

DATASET_DIR=./tfrecords
TRAIN_DIR=./log_finetune/
CHECKPOINT_PATH=./log/model.ckpt-N
python train_ssd_network.py \
    --train_dir=${TRAIN_DIR} \
    --dataset_dir=${DATASET_DIR} \
    --dataset_name=pascalvoc_2007 \
    --dataset_split_name=train \
    --model_name=ssd_300_vgg \
    --checkpoint_path=${CHECKPOINT_PATH} \
    --checkpoint_model_scope=vgg_16 \
    --save_summaries_secs=60 \
    --save_interval_secs=600 \
    --weight_decay=0.0005 \
    --optimizer=adam \
    --learning_rate=0.00001 \
    --learning_rate_decay_factor=0.94 \
    --batch_size=32

在TF-Slim模型頁面上可以找到許多流行的深度架構的預先訓練權重。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM