stMind

about Tech, Computer vision and Machine learning

インストール済みのcudnnのバージョン確認

#include <cudnn.h>
#include <iostream>

int main(int argc, char** argv) {
    std::cout << "CUDNN_VERSION: " << CUDNN_VERSION << std::endl;
    return 0;
}
$ nvcc cudnn_version.cpp -o cudnn_version
$ ./cudnn_version
CUDNN_VERSION: 5110

このプログラムはこのIssueで知ったのですが、CUDNNってNVIDIAのサイトからダウンロードした後はディレクトリにコピーするだけなので、どのバージョンをインストールしたのかぱっと見はわからなくなってしまうので、パスの通った所に実行ファイルをおいておくと何気に便利かもしれません。

failed to install chainer with cuda 8.0 / cuDNN v6 · Issue #2501 · chainer/chainer · GitHub

flickr8k dataset

Deep Visual-Semantic Alignments for Generating Image Descriptions

image caption用のflickr8k datasetは、アノテーションとVGGの特徴量は上記リンクからダウンロード可能ですが、対応する画像自体は別途ダウンロードする必要があります。各画像のダウンロード先URLをFlickr Services: Flickr API: flickr.photos.getSizesを使って取得して、バッチ的に取得するスクリプトを書きました。8k枚の画像をダウンロードするので、すごい時間がかかるのが難点ですが...

github.com

上手に考えるための引き出しを増やす

新しい分かり方

新しい分かり方

新しいアイデアを必要とする状況というのは意外と多く、その度に同じような事しか考えられず、自分はアイデアを考える才能がないなあと思ったりする人もいるかもしれないけれど、それって才能の問題ではなく、実は考える技術が下手なだけなのかもしれない。事実をそのまま受け取るのではなくて、差分を見つけたり、異なる立場から解釈してみたり、言うは易く行うは難し、そんな考え方のテクニックを何とも不思議な作品を通して体験する事ができる本。

www.masahicom.com

コンパイルエラーで個人的にわりとよく使うコマンド

OSX El Capitan 10.11.6です。

locate, export

例えば、とあるmakeを実行したらwchar.hが見つからないと言われました。

$ make
g++ libRegionBPP/libRegionBPP.cpp -c -std=c++98 -pedantic -W -Wall -fopenmp -O3 -fPIC
In file included from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/bits/postypes.h:40:0,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/iosfwd:40,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/ios:38,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/ostream:38,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/iostream:39,
                 from libRegionBPP/libRegionBPP.cpp:29:
/usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/cwchar:44:19: fatal error: wchar.h: No such file or directory
 #include <wchar.h>
                   ^
compilation terminated.
make: *** [libRegionBPP.a] Error 1

インクルードディレクトリにパスが通ってないのでしょう。まずは、wchar.hの場所を探して、そこにパスを通すことにします。

$ locate wchar.h
...
/usr/include/wchar.h
...
$ export CPATH=$CPATH:/usr/include

設定出来たらもう一度makeです。

$ make
g++ libRegionBPP/libRegionBPP.cpp -c -std=c++98 -pedantic -W -Wall -fopenmp -O3 -fPIC
In file included from /usr/include/string.h:176:0,
                 from libRegionBPP/libRegionBPP.cpp:34:
...
/var/folders/bq/xh66g4d17rn1xkjsmj4md4qm0000gn/T//cczqQzWW.s:3576:11: note: change section name to "__const"
        .section __DATA,__const_coal,coalesced
                 ^      ~~~~~~~~~~~~
ld: library not found for -lSystem
collect2: error: ld returned 1 exit status
make: *** [prog_dSP] Error 1

locate, export, ln

ライブラリが見つからないのだが、これもライブラリディレクトリにパスが通ってないのでしょう。

$ locate libSystem.dylib
...
/usr/lib/libSystem.dylib
$ export LIBRARY_PATH=$LIBRARY_PATH:/usr/lib
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib

再度makeしてみるも同じエラーになって、/usr/local/libも加えたりしてみたものの解消せず。根本的な解決になってないのだけど、makeファイルの中でカレントディレクトリが動的ライブラリの検索パスになっているので、シンボリックリンクをカレントディレクトリに作成することに。

$ ln -s /usr/lib/libSystem.dylib libSystem.dylib

otool

まだまだmakeは続く。で、ここでは、これもよくみるSymbol not found

$ make
...
/Applications/MATLAB_R2015a.app/bin/mex -v -cxx CC='g++' CXX='g++' LD='g++' -output structuredPrediction structuredPrediction.o -L. -lSPRegion -lDH -lRegionBPP -lgomp
dyld: Symbol not found: __ZN5boost13log2_mt_posix10basic_coreIcE11open_recordERKNS0_19basic_attribute_setIcEE
  Referenced from: /Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib
  Expected in: /usr/local/lib/libboost_log.dylib
 in /Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib
/Applications/MATLAB_R2015a.app/bin/mex: line 365: 87163 Trace/BPT trap: 5       $MATLAB/bin/maci64/mex $args
make: *** [structuredPrediction.mexa64] Error 133

otoolでlibmwfl.dylibの依存関係を調べて、

$ otool -L /Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib 
/Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib:
    @rpath/libmwfl.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
    @rpath/libmwresource_core.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libmwi18n.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libmwMATLAB_res.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_date_time.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_filesystem.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_log.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_serialization.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_signals.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libtbb.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

rpathになってて、どこのライブラリがリンクされてるかはわからなかったけど、よくよくエラーを見てみると、/Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylibなのに、/usr/local/lib/libboost_log.dylibが使われているから?locateでlibboost_log.dylibの場所を探す。

$ locate libboost_log.dylib
/Applications/MATLAB_R2015a.app/bin/maci64/libboost_log.dylib
/usr/local/Cellar/boost/1.57.0/lib/libboost_log.dylib
/usr/local/Cellar/boost/1.59.0/lib/libboost_log.dylib
/usr/local/Cellar/boost/1.64.0_1/lib/libboost_log.dylib
/usr/local/lib/libboost_log.dylib

そういえば、/usr/local/libをLD_LIBRARY_PATHに設定してしまってたな。/usr/local/libは外して、makeするとようやくコンパイル出来た。

まとめ

これだけでは解決しないことも多いけど、locate, export, ln, otoolくらいで出来る場合も多い印象です。

openposeのjsonを解析する

昨日は、ナチョがウェストブロム戦で見せた奇跡のクリアをopenposeで関節推定してみました。openposeは、関節位置をファイル出力するオプションを用意しているので、jsonで出力して黒背景に関節位置を描画しましたが、その時の解析手順を簡単にまとめておきます。

jsonファイル出力

openpose実行時にwrite_keypoint_jsonを指定します。

$ ./build/examples/openpose/openpose.bin --image_dir ~/data/nacho --write_keypoint_json ~/data/results

ファイルの中身はこんな感じ。pose_keypointsが関節位置で、people以下に検出した人数分が出力されます。

{
        "version":1.0,
        "people":[
        {
            "pose_keypoints":[
                247.668,514.465,0.89905,247.702,527.27,0.87725,236.549,527.306,0.878132,233.307,541.693,0.918291,236.415,544.831,0.709778,258.863,527.235,0.795694,263.66,540.037,0.772329,269.998,554.436,0.744358,246.054,556.101,0.807442,246.055,575.247,0.484067,0,0,0,258.864,556.007,0.797664,260.464,573.657,0.435004,266.807,583.267,0.163514,246.067,511.293,0.856283,249.24,509.715,0.886759,241.254,514.496,0.671889,250.916,514.453,0.700287
            ],
            "face_keypoints":[
                
            ],
            "hand_left_keypoints":[
                
            ],
            "hand_right_keypoints":[
                
            ]
        }
    ]
}

pose_keypointsは(x座標, y座標, 信頼度) x 関節数18で、54個の値が含まれています。それから、関節位置の順番ですが、 openpose/poseParameters.hpp at master · CMU-Perceptual-Computing-Lab/openpose · GitHubに定義された通り(POSE_COCO_BODY_PARTS)になっていて、backgroundは関節位置には含まれませんので注意。さらに、関節位置の結合順序は、POSE_COCO_PAIRSに定義されてます。親切。

pythonjsonをパース

pythonは3.6.1です。シンプルにやると、

  • jsonをload
  • 検出された人数分のループ
    • 関節の全ペアのループ
    • ペアをcv2.lineで描画

たまに関節位置が求められなくて信頼度0.0になっているところだけ注意する必要があります。

import json
import numpy as np
import cv2

# jsonのロード
with open('nacho_0_keypoints.json', 'r') as f:
    data = json.load(f)

# 黒背景画像の用意
img_ = cv2.imread('original.jpg')
img = np.zeros_like(img_)

# 関節毎の描画色
colors = [(255.,     0.,    85.), (255.,     0.,     0.), (255.,    85.,     0.), (255.,   170.,     0.), (255.,   255.,     0.), (170.,   255.,     0.), (85.,   255.,     0.), (0.,   255.,     0.), (0.,   255.,    85.), (0.,   255.,   170.), (0.,   255.,   255.), (0.,   170.,   255.), (0.,    85.,   255.), (0.,     0.,   255.), (255.,     0.,   170.), (170.,     0.,   255.), (255.,     0.,   255.), (85.,     0.,   255.)]

# 検出された全員について
for d in data['people']:
     kpt = np.array(d['pose_keypoints']).reshape((18, 3))
     # 関節位置の全ペアについて
     for p in pairs:
         pt1 = tuple(list(map(int, kpt[p[0], 0:2])))
         c1 = kpt[p[0], 2]
         pt2 = tuple(list(map(int, kpt[p[1], 0:2])))
         c2 = kpt[p[1], 2]
         # 信頼度0.0の関節は無視
         if c1 == 0.0 or c2 == 0.0:
             continue
         # 関節の描画
         color = tuple(list(map(int, colors[p[0]])))
         img = cv2.line(img, pt1, pt2, color, 7)

cv2.imshow('nacho', img)

参照

以上のことは、下記を参照しています。

github.com

NLP for arsenal.com is difficult

スポナビライブの画面を開いたら、バギーズ戦の配信開始まで「1日と...」って明日かよー。

www.arsenal.com

最近というか、今年に入ってarsenal.comが変わった。試合毎に記事がまとまって見れるようになって、例えば上の vs Chelseaの記事は11本分がスクロールして見れるようになっている。スマホ対応ってことなんかな。

https://www.ostmodern.co.uk/projects/arsenal/arsenal-com/www.ostmodern.co.uk

2013年に以前のサイトから大規模なre-designがあって、その年と次の年はBest Website Awardをもらったとか。初めて知りましたよ。Ostmodernってデザイン会社が担当したみたい。 デザインは良くなったかもしれないけど、スクレイピングしてゴニョゴニョとかやりにくくなったような... 監督の発言だけを取り出したいんだけど、ある記事では使えるけど、別の記事では同じやり方は使えないとか。

明日の試合が終わったら、またちょっと試してみるかな。