從零開(kāi)始機(jī)器學(xué)習(xí)-4 教會(huì)你的AI識(shí)別特定的物體(下)

本文由 沈慶陽(yáng) 所有,轉(zhuǎn)載請(qǐng)與作者取得聯(lián)系!
在繼續(xù)進(jìn)行之前,我們先來(lái)看一下Google Tensorflow Models中的Object Detection API的Github頁(yè)面。
其內(nèi)容主要有:快速上手、環(huán)境搭建、Object-Detection API的運(yùn)行和一些額外內(nèi)容。通過(guò)閱讀這些,對(duì)理解和運(yùn)用Tensorflow的Object-Detection API具有極大的幫助。
另外,運(yùn)用機(jī)器學(xué)習(xí)算法進(jìn)行研究,其實(shí)質(zhì)是尋找目標(biāo)函數(shù)的過(guò)程。通過(guò)構(gòu)建機(jī)器學(xué)習(xí)模型(形成函數(shù)集),用訓(xùn)練數(shù)據(jù)做驅(qū)動(dòng),尋找與訓(xùn)練數(shù)據(jù)匹配,并且在測(cè)試數(shù)據(jù)中表現(xiàn)優(yōu)異的函數(shù)。因此構(gòu)建合適的機(jī)器學(xué)習(xí)模型,顯得尤為關(guān)鍵。
Tensorflow detection model zoo頁(yè)面,我們可以找到TensorFlow項(xiàng)目維護(hù)者們通過(guò)COCO、Kitti和Open Images等訓(xùn)練數(shù)據(jù)集預(yù)先訓(xùn)練好的模型。

COCO-trained models {#coco-models}

Model name Speed (ms) COCO mAP[^1] Outputs
ssd_mobilenet_v1_coco 30 21 Boxes
ssd_inception_v2_coco 42 24 Boxes
faster_rcnn_inception_v2_coco 58 28 Boxes
faster_rcnn_resnet50_coco 89 30 Boxes
faster_rcnn_resnet50_lowproposals_coco 64 Boxes
rfcn_resnet101_coco 92 30 Boxes
faster_rcnn_resnet101_coco 106 32 Boxes
faster_rcnn_resnet101_lowproposals_coco 82 Boxes
faster_rcnn_inception_resnet_v2_atrous_coco 620 37 Boxes
faster_rcnn_inception_resnet_v2_atrous_lowproposals_coco 241 Boxes
faster_rcnn_nas 1833 43 Boxes
faster_rcnn_nas_lowproposals_coco 540 Boxes
mask_rcnn_inception_resnet_v2_atrous_coco 771 36 Masks
mask_rcnn_inception_v2_coco 79 25 Masks
mask_rcnn_resnet101_atrous_coco 470 33 Masks
mask_rcnn_resnet50_atrous_coco 343 29 Masks

由于我們追求實(shí)時(shí)的檢測(cè)速度,所以此處選用速度最快的ssd_mobilenet_v1_coco模型。

編寫(xiě)訓(xùn)練的配置文件

使用wget命令或其他下載器下載相應(yīng)的config配置文件。此處選用的ssd_mobilenet_v1_coco配置文件下載路徑為:
https://github.com/tensorflow/models/blob/master/research/object_detection/samples/configs/ssd_mobilenet_v1_coco.config
打開(kāi)ssd_mobilenet_v1_coco.config配置文件

# SSD with Mobilenet v1 configuration for MSCOCO Dataset.
# Users should configure the fine_tune_checkpoint field in the train config as
# well as the label_map_path and input_path fields in the train_input_reader and
# eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
# should be configured.

model {
  ssd {
    num_classes: 1
    box_coder {
      faster_rcnn_box_coder {
        y_scale: 10.0
        x_scale: 10.0
        height_scale: 5.0
        width_scale: 5.0
      }
    }
    matcher {
      argmax_matcher {
        matched_threshold: 0.5
        unmatched_threshold: 0.5
        ignore_thresholds: false
        negatives_lower_than_unmatched: true
        force_match_for_each_row: true
      }
    }
    similarity_calculator {
      iou_similarity {
      }
    }
    anchor_generator {
      ssd_anchor_generator {
        num_layers: 6
        min_scale: 0.2
        max_scale: 0.95
        aspect_ratios: 1.0
        aspect_ratios: 2.0
        aspect_ratios: 0.5
        aspect_ratios: 3.0
        aspect_ratios: 0.3333
      }
    }
    image_resizer {
      fixed_shape_resizer {
        height: 300
        width: 300
      }
    }
    box_predictor {
      convolutional_box_predictor {
        min_depth: 0
        max_depth: 0
        num_layers_before_predictor: 0
        use_dropout: false
        dropout_keep_probability: 0.8
        kernel_size: 1
        box_code_size: 4
        apply_sigmoid_to_scores: false
        conv_hyperparams {
          activation: RELU_6,
          regularizer {
            l2_regularizer {
              weight: 0.00004
            }
          }
          initializer {
            truncated_normal_initializer {
              stddev: 0.03
              mean: 0.0
            }
          }
          batch_norm {
            train: true,
            scale: true,
            center: true,
            decay: 0.9997,
            epsilon: 0.001,
          }
        }
      }
    }
    feature_extractor {
      type: 'ssd_mobilenet_v1'
      min_depth: 16
      depth_multiplier: 1.0
      conv_hyperparams {
        activation: RELU_6,
        regularizer {
          l2_regularizer {
            weight: 0.00004
          }
        }
        initializer {
          truncated_normal_initializer {
            stddev: 0.03
            mean: 0.0
          }
        }
        batch_norm {
          train: true,
          scale: true,
          center: true,
          decay: 0.9997,
          epsilon: 0.001,
        }
      }
    }
    loss {
      classification_loss {
        weighted_sigmoid {
        }
      }
      localization_loss {
        weighted_smooth_l1 {
        }
      }
      hard_example_miner {
        num_hard_examples: 3000
        iou_threshold: 0.99
        loss_type: CLASSIFICATION
        max_negatives_per_positive: 3
        min_negatives_per_image: 0
      }
      classification_weight: 1.0
      localization_weight: 1.0
    }
    normalize_loss_by_num_matches: true
    post_processing {
      batch_non_max_suppression {
        score_threshold: 1e-8
        iou_threshold: 0.6
        max_detections_per_class: 100
        max_total_detections: 100
      }
      score_converter: SIGMOID
    }
  }
}

train_config: {
  batch_size: 24
  optimizer {
    rms_prop_optimizer: {
      learning_rate: {
        exponential_decay_learning_rate {
          initial_learning_rate: 0.004
          decay_steps: 800720
          decay_factor: 0.95
        }
      }
      momentum_optimizer_value: 0.9
      decay: 0.9
      epsilon: 1.0
    }
  }
  fine_tune_checkpoint: "ssd_mobilenet_v1_coco_2017_11_17/model.ckpt"
  from_detection_checkpoint: true
  # Note: The below line limits the training process to 200K steps, which we
  # empirically found to be sufficient enough to train the pets dataset. This
  # effectively bypasses the learning rate schedule (the learning rate will
  # never decay). Remove the below line to train indefinitely.
  num_steps: 200000
  data_augmentation_options {
    random_horizontal_flip {
    }
  }
  data_augmentation_options {
    ssd_random_crop {
    }
  }
}

train_input_reader: {
  tf_record_input_reader {
    input_path: "data/train.record"
  }
  label_map_path: "training/object-detection.pbtxt"
}

eval_config: {
  num_examples: 8000
  # Note: The below line limits the evaluation process to 10 evaluations.
  # Remove the below line to evaluate indefinitely.
  max_evals: 10
}

eval_input_reader: {
  tf_record_input_reader {
    input_path: "data/test.record"
  }
  label_map_path: "training/object-detection.pbtxt"
  shuffle: false
  num_readers: 1
}

修改第9行

num_classes: 1

修改第175行

input_path: "data/train.record"

修改第177行和第191行

label_map_path: "training/object-detection.pbtxt"

修改第189行

input_path: "data/test.record"

第9行指定了我們訓(xùn)練的目標(biāo)類(lèi)目,由于此處只訓(xùn)練了一個(gè)目標(biāo),所以數(shù)值為1。第175行指定了訓(xùn)練的輸入的train Record的文件位置。第177和191行指定了label map的位置,該文件在下面會(huì)創(chuàng)建。第189行指定了測(cè)試數(shù)據(jù)的位置。以上配置按需修改。
我們來(lái)到training目錄下,新建名為object-detection.pbtxt的空白文檔并打開(kāi)。輸入如下內(nèi)容,保存。

item {
  id: 1
  name: 'pen'
}

開(kāi)始訓(xùn)練

將項(xiàng)目目錄下的data文件夾、images文件夾、ssd_mobilenet_v1_coco_2017_11_17文件夾、training文件夾和ssd_mobilenet_v1_coco.config配置文件復(fù)制到models/research/object_detection目錄下,病選擇合并。
打開(kāi)命令行,并進(jìn)入models/research目錄下。將Object Detection的庫(kù)加入Python變量。

# From tensorflow/models/research/
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim

注:export的效力僅及于該次登陸操作。
在控制臺(tái)進(jìn)入models/research/object_detection目錄下,輸入如下命令運(yùn)行訓(xùn)練程序

python3 train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/ssd_mobilenet_v1_coco.config 

當(dāng)你的終端開(kāi)始輸出如下內(nèi)容的時(shí)候則證明訓(xùn)練程序正常開(kāi)始運(yùn)行了。

INFO:tensorflow:Restoring parameters from training/model.ckpt-1
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Starting Session.
INFO:tensorflow:Saving checkpoint to path training/model.ckpt
INFO:tensorflow:Starting Queues.
INFO:tensorflow:global_step/sec: 0
INFO:tensorflow:Recording summary at step 1.
INFO:tensorflow:global step 2: loss = 2.2202 (2.397 sec/step)
INFO:tensorflow:global step 3: loss = 2.5926 (1.749 sec/step)
INFO:tensorflow:global step 4: loss = 1.7984 (1.980 sec/step)
INFO:tensorflow:global step 5: loss = 1.5214 (1.734 sec/step)
INFO:tensorflow:global step 6: loss = 1.7882 (1.147 sec/step)

TensorBoard可視化學(xué)習(xí)

使用TensorBoard可以將學(xué)習(xí)的過(guò)程可視化。
TensorBoard 涉及到的運(yùn)算,通常是在訓(xùn)練龐大的深度神經(jīng)網(wǎng)絡(luò)中出現(xiàn)的復(fù)雜而又難以理解的運(yùn)算。
為了更方便 TensorFlow 程序的理解、調(diào)試與優(yōu)化,Google的Tensorflow發(fā)布了一套叫做 TensorBoard 的可視化工具。你可以用 TensorBoard 來(lái)展現(xiàn)你的 TensorFlow 圖像,繪制圖像生成的定量指標(biāo)圖以及附加數(shù)據(jù)。
TensorBoard的界面如下:


TensorBoard界面

在TensorFlow程序運(yùn)行的時(shí)候,你的training文件夾下會(huì)出現(xiàn)event文件。重新打開(kāi)一個(gè)終端,使用如下命令配置TensorBoard。

jack@jack~/tensorflowProject/object_detection/models/object_detection$ tensorboard --logdir='training'

運(yùn)行之后,會(huì)出現(xiàn)如下提示

TensorBoard 1.7.0a20180302 at http://127.0.0.1:6006 (Press CTRL+C to quit)

使用瀏覽器打開(kāi)http://127.0.0.1:6006,則成功地打開(kāi)了TensorBoard的界面。
當(dāng)你的TensorBoard中的TotalLoss差不多小于1,且穩(wěn)定的時(shí)候就可以停止訓(xùn)練了。
此時(shí)你的training目錄下將會(huì)有看似如下的文件存在。


訓(xùn)練生成的模型checkpoint

訓(xùn)練程序在第375、772、970等步驟時(shí)保存了模型文件。確保你的相應(yīng)步數(shù)時(shí)的模型有.index、.meta和.data-00000-of-00001后綴的文件存在。
再回到training的上級(jí)目錄,開(kāi)啟終端,輸入如下命令。

python export_inference_graph.py \
    --input_type image_tensor \
    --pipeline_config_path training/faster_rcnn_inception_v2_coco.config \
    --trained_checkpoint_prefix training/model.ckpt-1167 \
    --output_directory pen_graph;

當(dāng)程序沒(méi)有報(bào)錯(cuò)的時(shí)候,證明我們將圖已經(jīng)導(dǎo)出到pen_graph目錄下了。


導(dǎo)出的訓(xùn)練好的圖

測(cè)試訓(xùn)練的模型

我們回到object detection目錄下,使用juypter notebook打開(kāi)object_detection_tutorial.ipynb文件。
修改其第60行

# What model to download.
MODEL_NAME = 'pen_graph'

# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'

# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = os.path.join('training', 'object-detection.pbtxt')

NUM_CLASSES = 1

修改其第64行

# For the sake of simplicity we will use only 2 images:
# image1.jpg
# image2.jpg
# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
PATH_TO_TEST_IMAGES_DIR = 'test_images'
TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(3, 8) ]

# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)

我們找到object_detection文件夾下的test_images文件夾。將7張包含鋼筆的圖片重命名為image1-8.jpg?;氐絁upyter Notebook,點(diǎn)擊Cell->Run All,并到頁(yè)面最下方觀察。
頁(yè)面最下方將會(huì)對(duì)在test_images文件夾下名為image3-8.jpg的圖片進(jìn)行目標(biāo)檢測(cè),并標(biāo)出其中的鋼筆。


對(duì)訓(xùn)練好的模型的測(cè)試

至此,我們已經(jīng)成功訓(xùn)練好了模型。可以照著前一篇的文章修改,使用攝像頭進(jìn)行目標(biāo)檢測(cè)。

覺(jué)得寫(xiě)的不錯(cuò)的朋友可以點(diǎn)一個(gè) 喜歡? ~
謝謝你的支持!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容