【行動認識 #8】OpenPoseのBodyParts推定をTensorFlowでCPU実行する方法 (Linux : Ubuntu 16.04 LTS)
OpenPoseのBodyParts推定をTensorFlowでCPU実行する方法について。(想定環境はUbuntu 16.04 LTS)
どうしてもTensorFlowで動かしたい人はやってみてもいいかも。(そんな人いる?)
個人的にはTensorFlowのアーキテクチャの方が好きですが。
OpenPoseの大枠を知りたいなら前回を参考。
motojapan.hateblo.jp
アプローチ
OpenPoseのBodyParts推定モデルはCaffeで提供されるので、これをTensorflowモデルに変換すればできるはず。
手順
1. OpenPoseのCaffeモデルをダウンロード
本家からportable OpenPose demo 1.0.1.をダウンロード。
この中に pose_deploy_linevec.prototxt(モデル情報)、pose_iter_440000.caffemodel(重み情報)が格納されている。
2. Caffeモデル/重みをTensorFlow用に変換
ここ(caffe-tensorflow)のconvert.pyで変換できるらしい。
このスクリプトで、.prototxt→.py、.caffemodel→.npyに変換される。
例えば、model.py/model.npyに変換したとする。
変換方法、変換済みファイルを扱う基本実装の参考
テンソルフローでfinetuning | OpenBook
3. Tensorflowモデルを読み込んでヒートマップを推論
下記で読み込み。
重要なのは、placeholderのテンソル順序で次の通り。
[batch_size, image_height, iamge_width, color_channel]
import tensorflow as tf # networkはmodel.pyを編集して各自定義(例えばBodyPartsNet) from model import BodyPartsNet # 入力(画像)用テンソルを準備 # [batch_size, image_height, iamge_width, color_channel] x = tf.placeholder(tf.float32, [None, H, W, 3]) # 出力(ヒートマップ)用テンソルを準備 pred = net.layers['Mconv7_stage6_L2'] #モデルの読み込み net = BodyPartsNet({'iamge': x}) sess = tf.Session() sess.run(tf.initialize_all_variables()) #重みの読み込み net.load('model.npy', sess)
後は、forwardのsession.runをすれば動くはず。
BodyParts出力順は本家の通り以下の順。
POSE_COCO_BODY_PARTS { {0, "Nose"}, {1, "Neck"}, {2, "RShoulder"}, {3, "RElbow"}, {4, "RWrist"}, {5, "LShoulder"}, {6, "LElbow"}, {7, "LWrist"}, {8, "RHip"}, {9, "RKnee"}, {10, "RAnkle"}, {11, "LHip"}, {12, "LKnee"}, {13, "LAnkle"}, {14, "REye"}, {15, "LEye"}, {16, "REar"}, {17, "LEar"}, {18, "Bkg"}, }
caffe-tensorflowエラー対策
caffe-tensorflowは環境によって時折エラーがでるのでいくつか対策が必要。
エラーケース1:TypeError: Descriptors should not be created directly, but only retrieved from their parent.
convert.pyでの変換時のエラー
TypeError: Descriptors should not be created directly, but only retrieved from their parent.
対策:
protobufのバージョン変更。
pip install protobuf==3.0.0b2
エラーケース2:TypeError: concat() got an unexpected keyword argument 'concat_dim'
networkにconcatが含まれる場合の実行時エラー
TypeError: concat() got an unexpected keyword argument 'concat_dim'
対策:
concatの呼び出し記述が古いのが原因。
tensorflow 1.0.0に対応した記述にNetwork.pyを変更(下記のような感じ)
@layer def concat(self, inputs, axis, name): - return tf.concat(concat_dim=axis, values=inputs, name=name) + return tf.concat(axis=axis, values=inputs, name=name)