stMind

about Arsenal, Arsene Wenger, Tech, Computer vision and Machine learning

スーパーカーについて知っていること

最近、YoutubeでライブのPV見て、そこについてるコメントを見てなんか書いてみたくなった。

2005年に解散したスーパーカーは、自分の青春時代そのものだった気がする。当時はまだネットが一般的に使われる前だったし、スマホなんてものは当然なかったから、とにかくインタビューが掲載されている雑誌があれば購入し、スペシャで特集が放送されればビデオに録画して、頑張って東京までライブ見に行ったりしていた。

解散ライブも幸運にもチケット取れて、もしかしたらファーストアルバムの曲やらずに解散あるかも?と心配して行ったけど、creamsodaとかLuckyとか見れて最高に感慨深かった。まあ、MCゼロで歌声以外に声を発することなく終わって、しかもアンコールはなしだったのは、やっぱそうかーと思ったな。

スーパーカーは色々と変わったバンドだと思うんだけど、変わったエピソードといえば、このようなものを雑誌とかで読んだような気がする。でも、本当なのかどうかはわからないけど。

  • ジュンジくんがミキちゃんのバンドメンバー募集に反応したのは、メンバー募集の紙にクマの絵が書いてあったから
  • creamsodaのPVでメンバーが乗っているアメ車は所ジョージさん所有のもの
  • Luckyには当初サビがなかったが、シングルカットされることが決まって「ラッキーなのにね」のところが追加された
  • DRIVEにドラムがないのは、録音されたのがコーダイの加入前だったため
  • ナカコーの声が小さすぎてドラムの音にかき消されてしまうため、初期のライブの配置では真ん中にジュンジくん、両サイドにミキちゃんとナカコーのボーカルだった
  • ナカコーの歌声が無機質な感じなのは、ジュンジくんがナカコーに気持ちを込めて歌わないようにと言っていたため

そういえば、解散した後だったか、スーパーカーのラジオ「オールOK」が一夜限りで復活して、そのときに質問募集してたので、ネットで質問送ったらなんと採用されたという!それで、どう使っていいか分からない鉛筆みたいなのが送られてきたんだよね。でも、当時は会社の寮に住んでて、ラジオが聞けない環境で、どういう風に答えてくれたのか分かってないんだよなぁ... どこかに音源ないだろうかなぁ。

f:id:satojkovic:20181014210823j:plain:w300

Encountered errors while installing torch

ld: library not found for -lSystem
collect2: error: ld returned 1 exit status

Error: Build error: Failed compiling module lfs.so
ld: library not found for -lreadline
collect2: error: ld returned 1 exit status

Error: Build error: Failed compiling module readline.so
/Users/satojkovic/torch/extra/cutorch/lib/THC/THCHalf.cu(40): error: class "__half" has no member "x"

/Users/satojkovic/torch/extra/cutorch/lib/THC/THCHalf.cu(41): error: class "__half" has no member "x"

/Users/satojkovic/torch/extra/cutorch/lib/THC/THCHalf.cu(42): error: class "__half" has no member "x"

/Users/satojkovic/torch/extra/cutorch/lib/THC/THCHalf.cu(80): error: class "__half" has no member "x"

/Users/satojkovic/torch/extra/cutorch/lib/THC/THCHalf.cu(88): error: class "__half" has no member "x"

/Users/satojkovic/torch/extra/cutorch/lib/THC/THCHalf.cu(92): error: class "__half" has no member "x"

/Users/satojkovic/torch/extra/cutorch/lib/THC/THCHalf.cu(122): error: class "__half" has no member "x"

make[1]: *** [lib/THC/CMakeFiles/THC.dir/all] Error 2
make: *** [all] Error 2

Error: Build error: Failed building.

Tensorflow Object Detection APIのCPU処理時間 on MacBook Pro

計測環境

  • MacBook Pro Late 2013モデル
    • CPU: 2.8GHz Corei7
    • Mem: 8GB 1600MHz DDR3
  • デフォルトで指定されているssd_mobilenet_v1_coco_2017_11_17

計測はTensorflowのtimelineを使用。

def run_inference_for_single_image(image, graph):
  with graph.as_default():
    with tf.Session() as sess:
      # timeline
      options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
      run_metadata = tf.RunMetadata()

      # 他の処理...

      # Run inference
      output_dict = sess.run(tensor_dict,
                             feed_dict={image_tensor: np.expand_dims(image, 0)}, options=options, run_metadata=run_metadata)

      # 他の処理...

      # Save timeline
      fetched_timeline = timeline.Timeline(run_metadata.step_stats)
      chrome_trace = fetched_timeline.generate_chrome_trace_format()
      with open('timeline.json', 'w') as f:
        f.write(chrome_trace)

  return output_dict     

計測結果

chrome://tracingで確認。読み取れる情報は

  • 全体で130ms程度
  • 最も時間がかかっているのは、TensorArrayScatterV3

Tensorflow Object Detection API、CPUでも十分速い。

f:id:satojkovic:20180930221255p:plain

Deep Learning for Videos

sites.google.com

Deep Learningを動画に適用というのはこれから増えてくると思うし、問題を分類した上記ブログを借りて頭を整理しておくとよいなと思った。少し古いが参照論文リストもあるので、目を通すと良さそう。

  1. Video Classification

    • Image Classificationと同じ問題で、入力が動画となっただけ
    • 最もシンプルなアプローチは、動画の各フレームに対してCNNなどで分類スコアを計算し、最後にフレーム全体のスコアに統合
      • ただし、このアプローチでは時系列の情報は失われてしまう
    • LSTMなどを用いて明示的に時系列な情報を用いる方式も提案されてきている
  2. Activity Recognition

    • Video Classificationの問題であるが、動画の中の、特に人の行動を認識する問題
    • Deep Learningを用いた手法がホットな領域
    • 手動設計の特徴を用いていた時代のDense Trajectoriesを改良した方式もある
  3. Action Localization

    • 動画の中でActionを検出する問題(Actionをしている開始フレームから終了フレームまで)

MSCOCO keypoint challengeのWinner solution

blog.mapillary.com

MSCOCO joint recognition challengeで、6つのタスクのうち4つでbest scoreだったのは、Megviiという顔認識技術の企業。人物の関節位置を推定するKeypoint challengeでは、Megviiは2017年でもTopだったようです。

CVPRにも採択されていた論文について、主要な部分だけメモします。

http://openaccess.thecvf.com/content_cvpr_2018/papers/Chen_Cascaded_Pyramid_Network_CVPR_2018_paper.pdf

Cascade Pyramid Network

Megviiの手法はTop-down型のアプローチ(人物検出をして、人物矩形毎に関節推定)で、関節が見えているけれども推定が難しいhard visible partsと、occlusionで見えていないinvisible partsを推定するCascade Pyramid Network(CPN)というアーキテクチャを提案しています。

GlobalNetとRefineNet

f:id:satojkovic:20180916110732p:plain

f:id:satojkovic:20180916121159p:plain

論文の図1がCPNの全体概要図。Hard keypointについては、周辺の情報(コンテキスト)を考慮することで、推定できるようにしようというのがアイデアのよう。

そのための一つ目のステージがGlobalNetで、ResNetをベースにしたネットワークで、conv2からconv5までのfeature mapに3x3のフィルタを適用して、keypoint毎のheatmapを生成するのが基本動作。論文の図2の左にあるのが、生成されたheatmapの例。さらに、Feature Pyramid Networkと同じように、位置精度を高く、かつ周辺情報を利用できるように、深い層のmapをupsamplingしてelement wiseに足し合わせたmapを生成している。図2を見ると、left eyeの方は正解位置の緑点の近くに高いスコアが出ている様子が見えますが、left hipは深い層では正解位置の周辺にスコアが出てますが、位置精度の高い推定は出来てないことがわかります。

そこで、二つ目のステージのRefineNetを用いる。ここでは、GlobalNetで生成された異なる層のfeature mapについて、層毎に異なる回数のbottle neckを適用して冗長なfeature mapを削減していって、全部のmapを結合するようにします(upsamplingしたあとで)。

学習では、GlobalNetはN個のkeypointそれぞれについてL2ロスに基づくパラメータ更新をしますが、RefineNetではその中でロスが大きいM個に絞ってパラメータ更新を実施するようにしています(online hard kyepoint mining)。MS COCOの場合だとN=17で、Mは8のときが最も精度が良い結果となったようです。

Results

http://presentations.cocodataset.org/COCO17-Keypoints-Overview.pdf

2017年の結果です。Top5の差は3%以内ということで近いスコアですが、Megvii社の手法が一位です。

RegressionベースとHeatmapベースではどちらが良い?

モバイル向けのSingle person 2D ポーズ推定のレポジトリのIssueなのですが、興味深い内容だったので紹介します。

github.com

CNNが前提だと思いますが、Keypoint localizationを行う方法として、

  • DeepPoseなど、関節位置を回帰するRegression
  • OpenPoseなど、関節毎のHeatmapを生成し、L2ロスを計算する
  • Mask R−CNNなど、関節毎のHeatmapを生成し、関節位置だけ1となるone hot maskとのcross entropy lossを計算する

のうち、どれが良いのか?という問いかけでした。

作者いわく、このレポジトリでは、まず推定速度だけを考慮してRegressionで実装したようですが、RegressionよりもHeatmapベースの方がmAPとしては良いのではないかなぁ、検証したわけではないけど、という回答をしてます。

質問者も、ここ最近の論文を見ていると、Heatmapベースの方が良さそうというのは同意しつつ、Heatmapベースの中だったら、L2ロスの場合とcross entropy lossだとどちらが良いのかなぁ、と言いつつスレッドが終了していました。

ICCV2015で発表された論文(下記リンクはスライド)でも、Coordinate net(Regression)とHeatmap net(L2ロス)として比較していますが、Heatmapの方が明らかにAccuracyが高く、学習データを増やした場合でもRegressionの方は向上があまり見られないのに対して、Heatmapの方は大幅に改善する結果となっていますね。

http://lear.inrialpes.fr/workshop/allegro2015/slides/zisserman01.pdf

Heatmapの方が優れている点として、学習結果の可視化により解釈が容易になることと、信頼度をモデル化して各ピクセルが保持していて、学習を進めると間違った推定のピクセルが徐々に抑制されていく、ということが論文で述べられていて、結果からみても納得な感じです。

HeatmapのL2ロスとcross entropy lossはどちらがいいか?については、Issueのスレッドの最後で、3つの方式を比較した論文のリンクがはられていました。次は、この論文を読んでみようと思います。

https://arxiv.org/pdf/1711.08229.pdf

MoveMirrorで使われているPose Estimation Algorithm

ポーズをとると似た姿勢を探してくれるブラウザベースのアプリ。面白いなぁ。あと、ブラウザだけでできるのも良いなぁ。

姿勢の推定に使われているのは、Googleの研究チームが発表した論文が基になってます。 さくっと読んでみた内容メモです。

[1701.01779] Towards Accurate Multi-person Pose Estimation in the Wild

medium.com

どのようなアルゴリズム

いわゆるTop-down方式の姿勢推定。Top-down方式は、最初に人の矩形を検出しておき、その中から関節を検出する。それに対してBottom-up方式があり、こちらは画像全体から関節を検出し、検出された関節同士を関連度マップなどに基づいて対応付けしていく方式。OpenPoseはBottom-up方式。

処理の全体像

f:id:satojkovic:20180721193552p:plain

Top-down方式なのでStage1で人の検出、Stage2で関節の検出、となるのだけど、もう少し詳しく記述すると次のような処理を行う。

  1. Stage1では、ResNet101 + atrous convolutionのFaster RCNNで人の矩形を検出。矩形を検出したら、Stage2の矩形アスペクト比に合うように幅もしくは高さを伸ばし、かつランダムに矩形枠を広げた後、353h x 257wにリサイズ。
  2. Stage2もResNet101を使って、heatmaps(K joints)とoffset maps(xとyの2ch * K joints)を生成。最後に、heatmapsとoffset mapsを統合して、より正確なjointを表現するmapsを出力。

Stage2で使うResNet101 + atrous convolution with stride 8は、最終層を1x1 convで3 x K個のFeature mapsを出力するように置き換え(Kは関節数で、ここではK=17)、最後にbilinear upsamplingで入力と同じサイズにリサイズされる。

heatmapとoffset heatmapによる関節のdetection and localization

Stage2の関節推定で、HeatmapとOffset mapを使うのが、この論文の新しいアイデア

Heatmapは、関節位置から一定範囲内のピクセルが1、それ以外が0となるmap。もう一つのOffset mapは、関節位置から一定範囲内のピクセルについて、関節位置に対するオフセットを保持するmap。

学習においては、ResNetの出力する3xKのfeature mapsについて、heatmapの出力mapにsigmoidを適用し、関節毎に各ピクセルのlogistic lossの総和をとったものと、XとYのoffsetの出力feature mapに対して、ground truthとの差を計算したHuber lossとの重み付き和が全体のロスとなる。(論文の式(3)を参照)

f:id:satojkovic:20180724220343p:plain

真ん中の図が、左肘のheatmapで赤が1の領域を表している。一番右の図が、対応するoffset mapで、L2ノルムをgrayscaleで表しているので中心に行くほど値が小さくなっていて、外側の方が値が大きくなっていることがわかる。赤い矢印は、offsetベクトルを示している。

このように二つにわけて学習しているのは、Faster RCNNなどの物体検出の枠組みから着想を得たようで、ピクセル単位で関節の近傍か否か(関節か)の分類と、関節位置をリファインするオフセット値の回帰に分けて、全身の関節位置推定という難しい問題を学習しやすくしている。

Heatmapとoffset mapから関節位置の決定

heatmapとoffset mapが得られたら、関節位置をどのように計算するのか?

heatmapの各点に対して、

  1. offset mapの値を使って、オフセット値を加えた位置を計算
  2. 関節毎にその位置で重みを累積

下の図は、すべての関節を一枚の画像で表した状態。オフセットによって、より関節候補位置がsureになっている様子がわかる。

f:id:satojkovic:20180729200008p:plain

activation mapで最もスコアの高い位置を、各関節位置として求めることができる。

結果

このようなheatmapとoffsetを使った関節位置推定の精度はどうなのか?

COCO Keypointのtest-devとtest-standard setsで2016年のCOCO keypoints challengeのwinnerを超える結果となった。