20190828のTensorFlowに関する記事は3件です。

Windowsで姿勢推定(tf pose estimation)

はじめに

姿勢推定アルゴリズムOpenPoseのTensorflow版としてtf pose estimationが公開されています。
inference_result2.png

これをWindows+Anaconda仮想環境で動かしてみた備忘録です。
初心者のため説明などふわふわしてますがご了承ください。

環境

Windows 10
conda 4.7.11
CUDA 10.1
GeForce RTX 2080

本記事ではAnacondaやCUDA等のインストールには触れません。
Anacondaで仮想環境を作るとこから入ります。

環境を作る前に

tf pose estimation のダウンロード

まず下記Githubからファイルをダウンロードして好きなところに解凍して置いておきます。
https://github.com/ildoonet/tf-pose-estimation

Windows Subsystem for Linux をインストール

本記事の手順ではbashを使いますので、作業に入る前に使えるようにしときます。
手順は下記とかをご参考に。
https://qiita.com/Aruneko/items/c79810b0b015bebf30bb

環境構築

仮想環境の作成

Anaconda (powersell) promptで下記コマンドでpython3.6の仮想環境を作ります。
Anaconda Navigatorからも簡単に作れますが、たまに壊れるときがあるのでコマンドから作っています。

conda create -n myenv python=3.6 

python3.7でもデモを動かす分には大丈夫でした。
作った仮想環境をactvateして作業していきます。

conda activate myenv 

ライブラリインストール

必要なライブラリを仮想環境にインストールします。
tf pose estimationが必要とするものはrequirements.txtに記載してあるのですが、その前に以下のライブラリをインストールしておくとスムーズです。
バージョンは動作確認したものを記載。
- cython 0.29.13
- numpy 1.16.4
- git 2.20.1
- swig 3.0.12
- opencv 3.3.1
- tensorflow-gpu 1.14.0 (GPU無い場合は tensorflow )

全部conda installで入れました。

次に、ダウンロードしたtf-pose-estimation-masterに移動して、requirements.txtをインストールする、んですが。
その中のpycocotoolのインストールがうまくいきません。
ので、先に下記コマンドで別にpycocotoolを入れておくかrequirements.txtを書き換えておくかしないといけません。

pip install "git+https://github.com/philferriere/cocoapi.git#egg=pycocotools&subdirectory=PythonAPI"

できたらrequirements.txtに記載の必要なライブラリをまとめてインストールします。

pip install -r requirements.txt

必要なライブラリが揃いました。

あとは手順通りにやっていきます。

C++ライブラリのビルド

cd tf_pose\pafprocess
swig -python -c++ pafprocess.i && python setup.py build_ext --inplace

パッケージインストール

cd ..\..\
python setup.py install

modelのダウンロード

cd models\graph\cmu
bash download.sh

環境構築はこれでOKのはず。

Run

tensorRTのコメントアウト

環境構築ができたので早速動かせるかと思いきや、run.pyしてみたらtensorRTが無いとerrorが出ました。
tensorRT は windows の python にはまだ対応していない為使えないみたいです。
なのでコード内で使っているところをコメントアウトします。
(最適化して速度を早くするものらしく、動かす分には無くても問題ないようです)

tf_pose/estimator.py
- 14行目 import文
- 315行目~328行目 if文

動かしてみる

とりあえず何も考えずカメラで試す。

python run_webcam.py 

Escで終了。

モデルは4種類用意されており、指定しない場合cmuモデルが使われます。
- cmu (trained in 656x368)
- mobilenet_thin (trained in 432x368)
- mobilenet_v2_large (trained in 432x368)
- mobilenet_v2_small (trained in 432x368)

速度はmobilenetの方が早く、精度はcmuが良い印象?
モデルを指定するときは、上記コマンドの後ろに--model=モデル名を付けて指定できます。

静止画

python run.py --model=mobilenet_thin --image=./images/p1.jpg

Figure.png

静止画はデフォルトではこんな感じにpyplotで出力されます。
推定関節のヒートマップと、関節をつなぐために求められたクトルマップです。
Result画像を保存したい場合、run.py 54行目imageがデータですのでcv2.imwrite(出力名.jpg, image)で保存できます。

静止画とカメラは問題なく動きますが、動画用のファイルにはバグがあるみたいで推定してくれません。
下記コードで動きました。
(拝借したコードなのですが、どこから持ってきたかわからなくなったのでソースを見つけたら貼り付けます。)
こちらで解決してくれたものです。

ついでに推定骨格を描画した動画を保存するコード入れています。
保存する場合は4行あるコメントアウトを全て外してください。

run_video.py
import argparse
import logging
import time

import cv2
import numpy as np

from tf_pose.estimator import TfPoseEstimator
from tf_pose.networks import get_graph_path, model_wh

logger = logging.getLogger('TfPoseEstimator-Video')
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)

fps_time = 0


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='tf-pose-estimation Video')
    parser.add_argument('--video', type=str, default='')
    parser.add_argument('--resize', type=str, default='0x0',
                        help='if provided, resize images before they are processed. default=0x0, Recommends : 432x368 or 656x368 or 1312x736 ')
    parser.add_argument('--resize-out-ratio', type=float, default=4.0,
                        help='if provided, resize heatmaps before they are post-processed. default=1.0')
    parser.add_argument('--model', type=str, default='mobilenet_thin', help='cmu / mobilenet_thin')
    parser.add_argument('--show-process', type=bool, default=False,
                        help='for debug purpose, if enabled, speed for inference is dropped.')
    parser.add_argument('--showBG', type=bool, default=True, help='False to show skeleton only.')
    args = parser.parse_args()

    logger.debug('initialization %s : %s' % (args.model, get_graph_path(args.model)))

    w, h = model_wh(args.resize)
    if w > 0 and h > 0:
        e = TfPoseEstimator(get_graph_path(args.model), target_size=(w, h))
    else:
        e = TfPoseEstimator(get_graph_path(args.model), target_size=(432, 368))

    cap = cv2.VideoCapture(args.video)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fps = cap.get(cv2.CAP_PROP_FPS)

    if cap.isOpened() is False:
        print("Error opening video stream or file")

    # fourcc = cv2.VideoWriter_fourcc(*'DIVX')
    # writer = cv2.VideoWriter('./video/output.mp4', fourcc, fps, (width, height))

    while cap.isOpened():
        ret_val, image = cap.read()

        logger.debug('image process+')
        humans = e.inference(image, resize_to_default=(w > 0 and h > 0), upsample_size=args.resize_out_ratio)
        if not args.showBG:
            image = np.zeros(image.shape)

        logger.debug('postprocess+')
        image = TfPoseEstimator.draw_humans(image, humans, imgcopy=False)

        logger.debug('show+')
        cv2.putText(image, "FPS: %f" % (1.0 / (time.time() - fps_time)), (10, 10),  cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
        cv2.imshow('tf-pose-estimation result', image)
        fps_time = time.time()
        # writer.write(image)
        if cv2.waitKey(1) == 27:
            break

    cv2.destroyAllWindows()

    # writer.release()
    cap.release()

logger.debug('finished+')

動かすときは同様に

python run_video.py --video=./video.mp4

相変わらずエラー文出ますね、、時間があれば見直します。

結果

  • さっきのやつ
    output.png

  • 借りてきたふちこさんズ
    0828_144201.png
    逆さまは以外はぱっと見認識できてるように見えますが…。
    よく見ると関節の位置がちらほらずれてます。変な体勢は難しいみたいです。
    これはウェブカメラのキャプチャーですが、FPSは画像のとおりcmuモデルでFPS24、mobilenet_thinモデルだとFPS30くらい出ていました。CPUだとその1/10くらい遅くなります。
    ちなみに13体のふちこさんを貸していただいたのですが、全員載せられませんでした。ごめんなさい。

  • サイゼにいる天使
    output.png

カメラでも試しましたが、上半身だけはOKで肩以上がフレームアウトしていると認識してくれない感じでした。
たまに背景に居ないはずの人間を認識します。これ見ると肩が入っていることが重要なんでしょうか。

微妙な結果ばかり載せてすみません。
助けてくださった先輩方、ありがとうございます。

以上!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TensorFlow Object Detection APIを使ってFaster R-CNN、R-FCN、SSDを比較してみた

5行まとめ

  • TensorFlow Object Detection APIには各種モデルが準備されており、簡単に試すことができた。
  • SSDは推論がとても早いが学習に時間がかかる。
  • R-FCNは推論時間でSSDに劣るが、検出精度がSSDより高め。学習時間と精度のバランスも良い。
  • ラベル付けの補助としてR-FCNを使い、推論時間が重要な場面での最終的な検出器としてSSDを使うのが良さそう。
  • ラベル付け(アノテーション)は苦行。

概要

 TensorFlow Object Detection APIを使い、独自のデータセットで物体検出(Object Detection)を行ってみました。
使用したモデルは、Faster R-CNN、R-FCN、SSDの3つです。本記事では同一のデータセットに対して3つのモデルを適用し、その精度、速度などを比較しています。

 当然ながらデータセットとモデルの組み合わせによって特性は異なるので、「あるデータセットではこうだった」という参考程度にどうぞ。

用語

  • R-CNN: Region CNN
  • R-FCN: Region-based Fully Convolutional Networks
  • CNN: Convolutional Neural Network
  • SSD: Single Shot multibox Detector
  • mAP: mean Average Precision
  • IoU: Intersection over Union

環境

 学習、推論に用いた環境は以下の通りです。

  • ハードウェア:
    • CPU: Intel Core i5 7600
    • メモリ: 16GB
    • GPU: GeForce GTX1070 8GB
  • ソフトウェア:
    • OS: Ubuntu 18.04.3 LTS
    • Docker: 18.09.7
    • docker-compose: 1.24.1
    • nvidia-docker: 2.2.0
    • NVIDIAドライバ: 410.104
    • Python: 3.6.8
    • TensorFlow: 1.14.0
    • TensorFlow Object Detection API: コミットID 62184a96e740a3ecd65018acda42a11062b6d43d
    • COCO API: コミットID: 636becdc73d54283b3aac6d4ec363cffbb6f9b20
    • Pythonパッケージ:
      • Click: 7.0
      • contextlib2: 0.5.5
      • Cython: 0.29.13
      • opencv-python: 4.1.0.25
      • Pillow: 6.1.0

データセット

 今回使用したデータセットは独自のもので、残念ながら詳細はお伝えできません。規模は以下の通りです。

  • ラベル: 2種類
  • ラベル数(正解バウンディングボックス数):
    • ラベルA: 2,224
    • ラベルB: 47
    • 合計: 2,271
  • ラベル付けされた画像数(バウンディングボックスなしも含む): 2,274枚
    • うち、ラベルを含む画像数: 1,212枚
  • 学習データ/テストデータの割合: 9:1

 「ラベルB」のラベルが不足しているため十分な学習が行えておらず、平均精度に悪影響を及ぼしているかもしれません。ただ、今回は相対的な精度だけを見ており、絶対的な精度は見ていないのであまり影響ないものと思われます。
また、ラベルを含まない画像(ネガティブサンプル)は使用していません。

 蛇足ながら、ラベル付け(アノテーション)によって腱鞘炎(っぽい状態)になりました。みなさんもラベル付けに使うツール(ソフトウェア、ハードウェア)には十分に気を配り、ラベル付けを行いましょう。健康第一です。

ベースモデル

 今回はTensorFlow Object Detection APIのModel Zooで提供されている、COCOにより事前学習済みのモデルをベースとして使用しました。
ベースとしたモデルデータと設定ファイルは以下の通りです。

No モデル 学習済みモデル 設定ファイル
1 Faster R-CNN faster_rcnn_resnet101_coco faster_rcnn_resnet101_coco.config
2 R-FCN rfcn_resnet101_coco rfcn_resnet101_coco.config
3 SSD ssd_mobilenet_v2_coco ssd_mobilenet_v2_coco.config

学習時間/推論時間

 今回はすべてのモデルにおいて30,000ステップの学習を行いました。また、データセットの1割、122枚をテストデータとして推論を行いました。
1回あたり10枚ずつ推論を行い、初回の推論時にはモデルのロードなどの初期化が行われています。そのため、初回を除く推論時間も併記しています。

  • SSDの推論時間は、Faster R-CNN、R-FCNの10分の1以下。
  • SSDの学習時間は、Faster R-CNN、R-FCNの2倍程度。
No モデル 学習時間 推論全体 初回を除く110枚の推論 左記1枚あたり 初回を含む122枚の推論 左記1枚あたり
1 Faster R-CNN 155分 45.816500秒 34.694372秒 0.315403秒 43.957657秒 0.360308秒
2 R-FCN 146分 39.321194秒 28.740958秒 0.261281秒 37.311630秒 0.305833秒
3 SSD 295分 3.885033秒 1.333236秒 0.012120秒 2.947371秒 0.024158秒

定量的な精度

 30,000ステップ時点での評価結果は以下の通りです。TensorFlow Object Detection APIの評価方法coco_detection_metricsを使用しています。

  • Precision:
    • すべての項目においてSSD、R-FCN、Faster R-CNNの順番で精度が良い。
  • Recall:
    • SSDの方が基本的に良いが、R-FCNの方が良いこともある。
No 項目 Faster R-CNN R-FCN SSD
1 Average Precision (AP) @[ IoU=0.50:0.95, area= all, maxDets=100 ] 0.218 0.230 0.327
2 Average Precision (AP) @[ IoU=0.50 , area= all, maxDets=100 ] 0.419 0.439 0.717
3 Average Precision (AP) @[ IoU=0.75 , area= all, maxDets=100 ] 0.206 0.209 0.259
4 Average Precision (AP) @[ IoU=0.50:0.95, area= small, maxDets=100 ] 0.165 0.189 0.209
5 Average Precision (AP) @[ IoU=0.50:0.95, area=medium, maxDets=100 ] 0.245 0.247 0.486
6 Average Precision (AP) @[ IoU=0.50:0.95, area= large, maxDets=100 ] 0.505 0.545 0.534
7 Average Recall (AR) @[ IoU=0.50:0.95, area= all, maxDets= 1 ] 0.160 0.179 0.289
8 Average Recall (AR) @[ IoU=0.50:0.95, area= all, maxDets= 10 ] 0.271 0.396 0.375
9 Average Recall (AR) @[ IoU=0.50:0.95, area= all, maxDets=100 ] 0.299 0.405 0.378
10 Average Recall (AR) @[ IoU=0.50:0.95, area= small, maxDets=100 ] 0.267 0.434 0.254
11 Average Recall (AR) @[ IoU=0.50:0.95, area=medium, maxDets=100 ] 0.290 0.291 0.535
12 Average Recall (AR) @[ IoU=0.50:0.95, area= large, maxDets=100 ] 0.558 0.583 0.600

定性的な精度

 正解データとモデル3つの推論結果の合計4枚を並べ、定性的な精度を確認してみました。数値では示せないので、参考程度にどうぞ。

  • 全体:
    • 全体的に検出精度は良好で今回の用途では実用的。
      • 特に対象物が正面から写っている場合は、ほぼ検出できている。
    • 対象物の側面しか写っていない場合は、検出できたりできなかったり。
  • Faster R-CNN:
    • もっとも精度が高い印象。
  • R-FCN:
    • 擬陽性(誤検出)が他のモデルに比べて多いように感じる。
  • SSD:
    • バウンディングボックスが大きめに出力されがち。
    • 偽陰性(検出漏れ)が他のモデルに比べて多いように感じる。
    • 小さい物体の検出精度が低め。

付録: Dockerfile

 今回、学習と推論はDocker(nvidiaランタイム)上で行いました。model_builder_test.pyより後のパッケージは推論処理で使っているだけで、TensorFlow Object Detection APIとしては不要です。

FROM tensorflow/tensorflow:1.14.0-gpu-py3-jupyter

RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \
    git-core \
    protobuf-compiler \
  && rm --recursive --force /var/lib/apt/lists/*

RUN git clone https://github.com/tensorflow/models.git /opt/tensorflow/models \
  && cd /opt/tensorflow/models/ \
  && git checkout 62184a96e740a3ecd65018acda42a11062b6d43d \
  && cd /opt/tensorflow/models/research/ \
  && protoc --python_out . object_detection/protos/*.proto
ENV PYTHONPATH ${PYTHONPATH}:/opt/tensorflow/models/research
ENV PYTHONPATH ${PYTHONPATH}:/opt/tensorflow/models/research/slim

COPY requirements.txt /root/
RUN pip3 install --requirement /root/requirements.txt

RUN git clone https://github.com/cocodataset/cocoapi.git /opt/cocoapi \
  && cd /opt/cocoapi/ \
  && git checkout 636becdc73d54283b3aac6d4ec363cffbb6f9b20 \
  && cd /opt/cocoapi/PythonAPI/ \
  && make \
  && cp --recursive --verbose pycocotools /opt/tensorflow/models/research/

RUN cd /opt/tensorflow/models/research/ \
  && python3 object_detection/builders/model_builder_test.py

RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \
    libsm6 \
    libxext6 \
    libxrender-dev \
  && rm --recursive --force /var/lib/apt/lists/*
RUN pip3 install opencv-python==4.1.0.25
requirements.txt
Click==7.0
contextlib2==0.5.5
Cython==0.29.13
Pillow==6.1.0
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

超シンプル "Keras" を用いた機械学習実行まで

TensorFlowをより使いやすくしたフレームワーク"Keras"
比較的手軽にDeep Learningを実感できます。

今回は、とりあえずKerasを実行することにのみ重点を置いて、
極力無駄なものを省いて超シンプルに記述しました。
Kerasを用いた学習までのざっくりとした下記の流れに沿ってコーディングしていきます。

  1. y(目的変数)ワンホットエンコーディング化
  2. modelの宣言
  3. Compile
  4. 学習(fit)

今回はテストデータとしてKaggleのTitanicデータを利用。
前処理については下記ブログを参照ください
【Beginner】【AI】【機械学習】Light GBM: Titanic: Machine Learning from Disaster

1.y(目的変数)ワンホットエンコーディング化

2019.0828更新
importファイルを載せていなかったので追記致します

import numpy as np
import pandas as pd
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
from sklearn.utils import shuffle
import tensorflow as tf
from tensorflow.keras import layers

Kerasに読み込ませるデータはワンホットエンコーディング化する必要があるらしい。
今回は生きるか死ぬかの0 or 1で登録するため不要かもしれないですが。。
一応、kerasにはワンホットエンコーディングを簡単にできるライブラリがあるのでそれの紹介も兼ねて記述。

#教師データの学習
#目的変数
train_y = df006["Survived"]
#説明変数
#arrayかつ型がfloat32で無ければ学習の際にエラーがでるのでここで変換
train_x = df006.drop(labels=["Survived"],axis=1).as_matrix().astype('float32')

#kerasのnp_utilに含まれるto_categoricalによってワンホットエンコーディング化
train_y_onehot = np_utils.to_categorical(train_y)

2.Modelの宣言

宣言方法にはいろいろあるらしい。
下記を参照すると良くわかります。
TensorFlow公式:単純なモデルの構築

今回は最も単純な全結合ネットワークを記述

#modelの宣言
#シーケンシャルモデル:単純に層を積み重ねる
model = tf.keras.Sequential()
# ユニット数が64の全結合層をモデルに追加します:
model.add(layers.Dense(64, activation='relu'))
# 全結合層をもう一つ追加します:
model.add(layers.Dense(64, activation='relu'))
# 出力ユニット数が10のソフトマックス層を追加します:
model.add(layers.Dense(10, activation='softmax'))

3.Compile

モデル構築後にcompileメソッドにより学習方法を構成します。

#modelのコンパイル:学習方法の構成
model.compile(optimizer=tf.train.AdamOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

これにも代表的なものが他に2つほどあるようなので上の公式サイトより要確認

4.学習(fit)

#modelの学習
model.fit(train_x,train_y,epochs=30,batch_size=32)

結果

image.png

全然制度良くならない。。。
学習までは出来ているのでデータの処理に問題があるようです。
要修正。

ここまで読まれた方申し訳ございません。
近々修正更新します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む