第 2 部:訓練模型 Training the Model

前言大綱

在本教程的這一部分中,您將:

  • 安裝 TensorFlow。
  • 下載預訓練的模型權重(用於傳遞學習)。
  • 訓練狗玩具尋找模型。
  • 在 Spot 上及時可視化我們模型的性能。

我們將密切關注 本教程 this tutorial,並對來自 Spot 的數據稍作修改。 我們遵循此示例來演示大多數 開箱即用out-of-the-box 的模型易於與 Spot 配合使用。 我們已經包含了您在此過程中需要的關鍵 Spot 特定提示。

安裝 TensorFlow、CUDA 和 cuDNN

有 很多 many, 關於如何做到這一點的 很多 many 優秀指南。 我們將在這裡介紹基本步驟,但最好在別處找到不同系統的詳細信息。

安裝 NVIDIA 驅動程序、CUDA 和 cuDNN

  • 我們不會在此處介紹系統特定的 NVIDIA 驅動程序、CUDA 或 cuDNN 安裝。 使用上面的鏈接獲取安裝指南。
  • 您必須安裝 CUDA 10.1 版
    • 10.1 以外的 CUDA 和 cuDNN 版本將無法使用。

安裝 TensorFlow

輸入您的 Spot API virtualenv

my_spot_env 替換為您在 Spot  快速入門指南Spot Quickstart Guide 中創建的 virtualenv 的名稱:

source my_spot_env/bin/activate

如果這有效,您的提示現在應該有 (my_spot_env) 在前面。 

安裝 TensorFlow

python -m pip install --upgrade pip
python -m pip install tensorflow-gpu==2.3.1 tensorflow==2.3.1 tensorboard==2.3.0 tf-models-official==2.3.0 pycocotools lvis
python -m pip uninstall opencv-python-headless
  • Tensorflow 喜好安裝非 GUI 版本的 OpenCV,這會給我們以後帶來問題
  • 我們可以安全地卸載它,因為我們已經安裝了 OpenCV。

測試 TensorFlow 和 CUDA 安裝

(my_spot_env) $ python
>>> import tensorflow as tf
>>> print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))
Num GPUs Available:  1

如果這對您不起作用,您需要弄清楚您的安裝有什麼問題。 常見問題有:

  • NVIDIA 驅動程序不工作。
  • 安裝了錯誤的 CUDA 版本(我們使用的是 10.1)。
  • 沒有安裝 cuDNN 或安裝了錯誤的 cuDNN 版本。

安裝 TensorFlow 物件檢測的 API

為簡單起見,我們將使用 tensorflow 模型的特定版本。 更進階的用戶可以自己 下載和編譯download and compile protobufs

  • 1. 下載包含預編譯文件的 套件,並將其保存在 fetch 文件夾中
  • 2. 解壓: 

source my_spot_env/bin/activate
  • 3. 安裝對象檢測 API:

    cd models-with-protos/research
    python -m pip install .

    你是怎麼做這個套件? 

    • 檢查了修訂版 
      • 9815ea67e2122dfd3eb2003716add29987e7daa1
    • 編譯的protobufs:
    cd models/research
    protoc object_detection/protos/*.proto --python_out=.
    • 複製並安裝物件檢測 tf 安裝文件:
      cp object_detection/packages/tf2/setup.py .
      python -m pip install .

        準備訓練數據

        現在,我們將數據拆分為訓練集和測試集,然後將 XML 標籤轉換為 TensorFlow 接受的格式。

        對數據進行分區

        我們希望從訓練集中保留一些數據,以便我們可以進行測試以確保我們的模型不會嚴重過度擬合數據。

        目標是按如下方式組織我們的數據:

        dogtoy/
        ├── images
        │   ├── left_fisheye_image_0000.jpg
        │   ├── left_fisheye_image_0001.jpg
        │   └── ...
        └── annotations
            ├── test
            │   ├── right_fisheye_image_0027.xml
            │   └── ...
            └── train
                ├── right_fisheye_image_0009.xml
                └── ...
        
        

        您可以手動執行此操作,但我們將使用腳本。

        • 下載 腳本 script 並將其放在 ~/fetch 文件夾中。
        • 運行腳本:
        cd ~/fetch
        python split_dataset.py --labels-dir dogtoy/annotations/ --output-dir dogtoy/annotations/ --ratio 0.9

        這會將您的 XML 標籤文件複製到 train 和 test 文件夾中,隨機拆分它們。 腳本複制只是為了更加安全,而不是刪除您精心標記的文件!

        創建標籤地圖

        創建一個名為 label_map.pbtxt 的文件並將其放入 dogtoy/annotations 中,內容如下:

        item {
            id: 1
            name: 'dogtoy'
        }

        將標籤轉換為 .record 格式

        TensorFlow 採用與 labelImg 產生的格式不同的格式。 我們將使用此 腳本 script 進行轉換。

        • 下載腳本並將其放在 fetch 目錄中。
        • 運行它:

        python generate_tfrecord.py --xml_dir dogtoy/annotations/train --image_dir dogtoy/images --labels_path dogtoy/annotations/label_map.pbtxt --output_path dogtoy/annotations/train.record

        • 再次為測試集運行它:

        python generate_tfrecord.py --xml_dir dogtoy/annotations/test --image_dir dogtoy/images --labels_path dogtoy/annotations/label_map.pbtxt --output_path dogtoy/annotations/test.record

        下載轉換學習模型

        我們不想從頭開始訓練模型,因為這會花費很長時間並且需要大量輸入數據。 相反,我們將得到一個模型,該模型經過訓練可以檢測很多東西,並指導它專門檢測我們的狗玩具。

        • 製作一個預訓練模型文件夾:
        mkdir dogtoy/pre-trained-models
        

        cd dogtoy/pre-trained-models
        tar -zxvf ssd_resnet50_v1_fpn_640x640_coco17_tpu-8.tar.gz
        

        訓練模型

        我們幾乎準備好訓練了!

        設置模型參數

        • 為我們的新模型創建一個文件夾:
        cd ~/fetch/dogtoy
        mkdir -p models/my_ssd_resnet50_v1_fpn
        

        • 複製預訓練的模型參數:
        cp pre-trained-models/ssd_resnet50_v1_fpn_640x640_coco17_tpu-8/pipeline.config models/my_ssd_resnet50_v1_fpn/
        

        • 打開 models/my_ssd_resnet50_v1_fpn/pipeline.config 並更改:
        num_classes to 1
        
        batch_size to 4
        
        fine_tune_checkpoint to "dogtoy/pre-trained-models/ssd_resnet50_v1_fpn_640x640_coco17_tpu-8/checkpoint/ckpt-0"
        
        fine_tune_checkpoint_type to "detection"
        
        Under train_input_reader:
            label_map_path: "dogtoy/annotations/label_map.pbtxt"
            input_path: "dogtoy/annotations/train.record"
        
        Under eval_input_reader:
            label_map_path: "dogtoy/annotations/label_map.pbtxt"
            input_path: "dogtoy/annotations/test.record"
        
        為了幫助您保持正軌,這裡有一個清單:
        • train_input_reader
          •  label_map_path
          •  input_path
        • eval_input_reader
        • 7 to go

        訓練模型

        • 將訓練腳本複製到更方便的位置:
        cd ~/fetch
        cp models-with-protos/research/object_detection/model_main_tf2.py .
        
        • 開始訓練:
        python model_main_tf2.py --model_dir=dogtoy/models/my_ssd_resnet50_v1_fpn --pipeline_config_path=dogtoy/models/my_ssd_resnet50_v1_fpn/pipeline.config --num_train_steps=20000
        
        • 如果一段時間後一切順利,您將開始看到如下輸出:
        INFO:tensorflow:Step 100 per-step time 0.340s loss=6.323
        INFO:tensorflow:Step 200 per-step time 0.352s loss=6.028
        INFO:tensorflow:Step 300 per-step time 0.384s loss=5.854
        
        • 我們可以使用 nvidia-smi 進行監控。在新終端中
        watch -n 0.5 nvidia-smi
        
        • 最後,在一個 新的終端中,我們可以使用 tensorboard 查看輸出:
        source my_spot_env/bin/activate
        cd ~/fetch
        tensorboard --logdir=dogtoy/models --bind_all
        

        訓練期間的評估

         在訓練期間,我們可以根據測試集評估網絡的當前狀態。 

        • 在新終端中:
        source my_spot_env/bin/activate
        cd ~/fetch
        CUDA_VISIBLE_DEVICES="-1" python model_main_tf2.py --model_dir=dogtoy/models/my_ssd_resnet50_v1_fpn --pipeline_config_path=dogtoy/models/my_ssd_resnet50_v1_fpn/pipeline.config --checkpoint_dir=dogtoy/models/my_ssd_resnet50_v1_fpn
        

        讓我們分解一下這是做什麼的。
         CUDA_VISIBLE_DEVICES="-1"
        設置一個環境變數,告訴 CUDA 沒有可用的 GPU。
        • 我們這樣做是因為訓練使用了我們所有的 GPU 內存。
        • 這會強制評估在 CPU 上運行,在那裡我們仍然有可用的內存。
        • CPU 會很慢,但沒關係,因為它只會每 5 分鐘左右評估一次模型。
        model_main_tf2.py --model_dir=dogtoy/models/my_ssd_resnet50_v1_fpn --pipeline_config_path=dogtoy/models/my_ssd_resnet50_v1_fpn/pipeline.config

        • 和上面一樣。
        --checkpoint_dir=dogtoy/models/my_ssd_resnet50_v1_fpn

        • 告訴腳本在評估模式下運行並將其指向我們的訓練輸出。
        當運行後,您將在 TensorBoard 中看到新圖表,顯示對我們的訓練集進行評估的結果,每 1,000 步訓練一次。
        • 這些結果更值得信賴,因為它們來自網絡在訓練期間未見過的圖像。

        這些數字是什麼意思?

        • mAP(平均精度)是一個度量,它描述 (a) 模型的預測邊界框與您標記的邊界框重疊的程度以及 (b) 類標籤出錯的頻率。
        • 查看如何測量深度學習對象檢測器的準確性部分? 這篇文章的一個很好的解釋。

        我為什麼在乎?

        • 您可以使用這些圖表來判斷您的模型是否已完成訓練。
        • 如果看起來您已經完成,請隨時進行 ^C 培訓。 檢查點會自動保存。

        TensorBoard 提供了一個 圖像 選項卡,它將以圖形方式顯示您的模型結果。看一看。

        故障排除

        Failed to get convolution algorithm. This is probably because cuDNN failed to initialize
        

        • 您可能沒有 GPU 內存。 通常在這種情況下,您會看
          • Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
        • 使用環境變量運行: TF_FORCE_GPU_ALLOW_GROWTH="true"
          • 您可以在訓練行之前設置環境變量:
          • TF_FORCE_GPU_ALLOW_GROWTH="true" python model_main_tf2.py --model_dir=dogtoy/models/my_ssd_resnet50_v1_fpn --pipeline_config_path=dogtoy/models/my_ssd_resnet50_v1_fpn/pipeline.config --num_train_steps=20000
        • 嘗試關閉 nvidia-smi 中顯示的項目以釋放 GPU 內存。 
        • 有關其他選項,請參閱 tensorflow 文檔
          • A checkpoint was restored (e.g. tf.train.Checkpoint.restore or tf.keras.Model.load_weights) but not all checkpointed values were used
        • 我們無法加載預訓練模型。檢查 fine_tune_checkpoint_type 是否設置為“檢測detection
        • 最後一條消息是:Use tf.cast instead,然後什麼也沒有發生。 
          • 仔細檢查您的 train.record 文件是否為空:
          • ls -lah ~/fetch/dogtoy/annotations/train.record
          • -rw-r--r-- 1 user users 9.3M Mar  2 14:17 /home/user/fetch/dogtoy/annotations/train.record  ^^^^<---- not zero!

        訓練完成後,前往第 3 部分獲取最新的檢查點,將其轉換為在線模型,並可視化結果。

        下一步 >>  第 3 部:評估模型 Evaluating the Model


        參考資料

        特色、摘要,Feature、Summary:

        關鍵字、標籤,Keyword、Tag:

        留言

        這個網誌中的熱門文章

        Ubuntu 常用指令、分類與簡介

        iptables的觀念與使用

        網路設定必要參數IP、netmask(遮罩)、Gateway(閘道)、DNS

        了解、分析登錄檔 - log

        Python 與SQLite 資料庫

        Blogger文章排版範本

        Pandas 模組

        如何撰寫Shell Script

        查詢指令或設定 -Linux 線上手冊 - man

        下載網頁使用 requests 模組