1. 程式人生 > >MXNet應用之一:Large Scale Image Classification

MXNet應用之一:Large Scale Image Classification

Tutorial地址:

一、MXNet簡介

1.概述(摘自開源中國社群)

    MXNet(輕量級機器學習庫) 是一款設計為效率和靈活性的深度學習框架。它允許你混合符號程式設計和指令式程式設計,從而最大限度提高效率和生產力。在其核心是一個動態的依賴排程,它能夠自動並行符號和命令的操作。

有一個圖形優化層,使得符號執行速度快,記憶體使用高效。這個庫便攜,輕量,而且能夠擴充套件到多個 GPU和多臺機器。

中文文件地址:


從上到下分別為各種主語言的嵌入,程式設計介面(矩陣運算,符號表達式,分散式通訊),兩種程式設計模式的統一系統實現,以及各硬體的支援。

MXnet的設計和實現可以參考

包含詳細的講解和例項(引用部落格)

一、Large Scale Image Classification

   訓練大量影象的對神經網路提出了幾個挑戰。 即使使用最新的GPU,也不可能使用單個GPU在合理的時間內使用大量影象來訓練大型網路。 通過在單個機器中使用多個GPU可以稍微減輕這個問題。 但是,可以連線到一臺機器(通常為816個)的GPU數量有限制。 本教程介紹如何使用包含多個GPU的多臺計算機來訓練大型網路的TB級資料。

1.前提:

MXNet. 請參閱安裝和安裝中的作業系統說明:

二、Large Scale Image Classification

   訓練大量影象的對神經網路提出了幾個挑戰。 即使使用最新的

GPU,也不可能使用單個GPU在合理的時間內使用大量影象來訓練大型網路。 通過在單個機器中使用多個GPU可以稍微減輕這個問題。 但是,可以連線到一臺機器(通常為816個)的GPU數量有限制。 本教程介紹如何使用包含多個GPU的多臺計算機來訓練大型網路的TB級資料。

1.前提

  • MXNet. 請參閱安裝和安裝中的作業系統說明:

  • OpenCV Python  

    pip install opencv-python

2.預處理

  大資料訓練的第一步是下載資料並對其進行預處理。 對於本教程,我們將使用完整的ImageNet資料集。 請注意,下載和預處理此資料至少需要2 TB的磁碟空間。 強烈建議使用

SSD而不是HDDSSD在處理大量小影象檔案方面要好得多。 預處理完成後,影象被打包到recordIO檔案中,硬碟應該適合訓練。

  在本教程中,我們將使用AWS儲存例項進行資料預處理。 儲存例項i3.4xlarge在兩個NVMe SSD磁碟上具有3.8 TB的磁碟空間。 我們將使用軟體RAID將它們組合成一個磁碟,並將其安裝在〜/ data

sudo mdadm --create --verbose /dev/md0 --level=stripe --raid-devices=2 \
    /dev/nvme0n1 /dev/nvme1n1
sudo mkfs /dev/md0
sudo mkdir ~/data
sudo mount /dev/md0 ~/data
sudo chown ${whoami} ~/data
現在我們有充足的空間下載資料集了

2.1下載資料集

  在本教程中,我們將使用可從http://www.image-net.org/download-images下載的完整ImageNet資料集。 fall11_whole.tar包含所有影象。 該檔案大小為1.2 TB,可能需要很長時間才能下載。

下載後,解壓檔案。

export ROOT=full
mkdir $ROOT
tar -xvf fall11_whole.tar -C $ROOT
這應該給你一個tar檔案的集合。 每個tar檔案表示一個類別,幷包含屬於該類別的所有影象。 我們可以解壓縮每個tar檔案,並將影象複製到以tar檔名稱命名的資料夾中。

2.2刪除不常見的類用於遷移學習(可選)

  訓練網路資料的一個常見原因是將其用於轉換學習(包括特徵提取或微調其他模型)。 根據這項研究,影象太少的類無助於遷移學習。 因此,我們可以刪除少於一定數量影象的類。 以下程式碼將刪除少於500張影象的類。

BAK=${ROOT}_filtered
mkdir -p ${BAK}
for c in ${ROOT}/n*; do
    count=`ls $c/*.JPEG | wc -l`
    if [ "$count" -gt "500" ]; then
        echo "keep $c, count = $count"
    else
        echo "remove $c, $count"
        mv $c ${BAK}/
    fi
done

2.3生成驗證集

  為了確保我們不會對資料進行過擬合,我們將建立一個與訓練集分開的驗證集。 在培訓期間,我們將經常監測驗證集上的損失。 我們通過從每個類中挑選五十個隨機影象並將它們移動到驗證集合來建立驗證集。

VAL_ROOT=${ROOT}_val
mkdir -p ${VAL_ROOT}
for i in ${ROOT}/n*; do
    c=`basename $i`
    echo $c
    mkdir -p ${VAL_ROOT}/$c
    for j in `ls $i/*.JPEG | shuf | head -n 50`; do
        mv $j ${VAL_ROOT}/$c/
    done
done

2.4將影象包裝到記錄檔案中

  MXNet可以直接讀取影象檔案,建議將影象檔案打包到recordIO檔案中,以提高效能。 MXNet提供了一個工具(tools / im2rec.py)來執行此操作。 要使用此工具,需要在系統中安裝MXNet和OpenCV的python模組。

  將環境變數MXNET設定為指向MXNet安裝目錄,並將NAME指定為資料集的名稱。 在這裡,我們假設MXNet安裝在〜/ mxnet

MXNET=~/mxnet
NAME=full_imagenet_500_filtered
  要建立recordIO檔案,我們首先在recordIO檔案中建立我們想要的影象列表,然後使用im2rec將列表中的影象打包到recordIO檔案中。 我們在train_meta中建立這個列表。 培訓資料約1TB。 我們把它分成8個部分,每個部分的大小大約為100 GB。
mkdir -p train_meta
python ${MXNET}/tools/im2rec.py --list True --chunks 8 --recursive True \
train_meta/${NAME} ${ROOT}
  然後,我們調整影象的大小,使得短邊長為480畫素長,並將影象打包到recordIO檔案中。 由於大多數工作是磁碟I / O,因此我們使用多個(16)執行緒來快速完成工作。
python ${MXNET}/tools/im2rec.py --resize 480 --quality 90 \
--num-thread 16 train_meta/${NAME} ${ROOT}
  一旦完成,我們將rec檔案移動到名為train的資料夾中
mkdir -p train
mv train_meta/*.rec train/
  我們對驗證集進行類似的預處理。
mkdir -p val_meta
python ${MXNET}/tools/im2rec.py --list True --recursive True \
val_meta/${NAME} ${VAL_ROOT}
python ${MXNET}/tools/im2rec.py --resize 480 --quality 90 \
--num-thread 16 val_meta/${NAME} ${VAL_ROOT}
mkdir -p val
mv val_meta/*.rec val/
  我們現在在train和val目錄中分別具有recordIO格式的所有訓練和驗證影象。 我們現在可以使用這些.rec檔案進行訓練

3.訓練

  ResNet已經顯示其在ImageNet競爭中的有效性。 我們的實驗也轉載了文中報道的結果。 當我們將層數從18增加到152時,我們看到驗證準確性有了很大提高。 鑑於這是一個巨大的資料集,我們將使用152層的Resnet。

  由於巨大的計算複雜性,即使最快的GPU需要一天以上的單次傳輸資料。 我們經常需要數十個迭代,訓練收斂到良好的驗證準確性。 雖然我們可以在機器中使用多個GPU,但機器中的GPU數量通常限制為8或16.為了更快的訓練,在本教程中,我們將使用多臺機器,每個機器包含多個GPU來訓練模型。

3.1 安裝

  我們將使用16臺機器(P2.16x例項),每臺機器包含16個GPU(特斯拉K80)。 這些機器通過20 Gbps乙太網互連。AWS CloudFormation使得建立深入學習群集非常容易。 我們遵循本頁面的說明,並建立一個具有16個P2.16x例項的深入學習群集。我們在第一臺機器中載入資料和程式碼(我們將把這臺機器稱為主機)。 我們將資料和程式碼共享給使用EFS的其他機器。如果您手動設定叢集,而不使用AWS CloudFormation,請記住執行以下操作:

  (1)使用USE_DIST_KVSTORE = 1編譯MXNet以啟用分散式培訓。

  (2)在主節點中建立主機檔案,其中包含叢集中所有計算機的主機名。 例如,

      $ head -3 hosts
      deeplearning-worker1
      deeplearning-worker2
      deeplearning-worker3
     通過從檔案呼叫只有主機名的ssh,可以將ssh從master中ssh轉換成任何這些機器。 例如,
     $ ssh deeplearning-worker2
     ===================================
     Learning AMI for Ubuntu
     ===================================
     ...
     [email protected]:~$
3.2 執行訓練

   叢集設定完成後,登入到master並從$ {MXNET} / example / image-classification執行以下命令

     ../../tools/launch.py -n 16 -H $DEEPLEARNING_WORKERS_PATH python train_imagenet.py --network resnet \
     --num-layers 152 --data-train ~/data/train --data-val ~/data/val/ --gpus 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 \
     --batch-size 8192 --model ~/data/model/resnet152 --num-epochs 1 --kv-store dist_sync
   launch.py啟動在叢集中的所有機器中提供的命令。 必須使用-H開關將叢集中的計算機列表提供給launch.py。 這是用於launch.py的選項的描述。

4.Scalability

  使用大量機器進行培訓的一個常見問題是可擴充套件性。 我們已經對可擴充套件性進行了基準測試,在叢集上執行多個流行網路,最多256個GPU,加速非常接近理想。這種可擴充套件性測試在16個P2.16xl例項上執行,總共256個GPU。 我們使用AWS深度學習AMI與CUDA 7.5和CUDNN 5.1安裝。我們修復每個GPU的批量大小常數,並且每次後續測試的GPU數量翻一番。 使用了同步的SGD(-kv-store dist_device_sync)。 所使用的CNN位於這裡。

  

   每秒處理的影象數量如下表所示:


   下圖顯示了加速使用的GPU數量,並將其與理想的加速比較。