Rest Term

Blog

OpenCVのDeep Learningモジュールの紹介

opencv3.0

opencv_contrib レポジトリに dnn という名前のディレクトリがひそかに出来ており、中を覗いてみると cv::dnn モジュールにDeep Learning関連の実装が含まれていたので軽く試してみました。Google Summer of Code (GSoC) 2015で発表され、GitHubにて実装が公開されたという経緯のようです。

It would be cool if OpenCV could load and run deep networks trained with popular DNN packages like Caffe, Theano or Torch. - Ideas Page for OpenCV Google Summer of Code 2015 (GSoC 2015)

* 2015/12/22 追記
12/21にOpenCV3.1がリリースされ、ここで紹介したDeepLearningモジュールが本体に取り込まれたようです。

環境

  • CentOS 7.1 / Ubuntu 14.03 (x86_64)
  • GCC 4.8.x
  • OpenCV 3.0.0 (+ opencv_contrib master branch)
  • GeForce GTX 760

有名なディープラーニングフレームワークである CaffeTorch で作成されたモデルの読み込みも出来るようになっているので、必要であれば Protocol Buffer などの関連ライブラリのインストールも必要です。ここでは両方試します。

Protocol Bufferは比較的新しいものが必要です。少なくともv2.3.0系だとコンパイルエラーが発生しました。CentOS 6.x系だとソースコードをコンパイルして入れるか、RPM Searchから対応するrpmファイルを探してくる必要があります。v2.5.0以上なら問題なさそうです。Ubuntuでも同様です。

また、CaffeやTorch本体のインストールはモデルを利用するだけであれば必要ありません。ただし、テストデータを生成するスクリプトを走らせる際はそれぞれインストールが必要になるので注意してください。

導入

opencv_contribレポジトリのソースを組み込んだビルド方法は公式サイトにも説明がありますが、僕の環境で指定したCMakeの設定を載せておきます。ぜひ参考になれば。GPU環境(+ CUDA Toolkit)が入っていればオプションを明示的に追加しなくても、自動的にGPU環境に対応したMakefileを作ってくれました。

Torchモデルの読み込みをサポートするには、opencv_dnn_BUILD_TORCH_IMPORTER オプションを有効にする必要があるので注意してください(ただしTorchモデルの読み込み機能は2015/12現在は未実装部分が多い、後述)。また、ここではサーバ機にインストールするのでGUI関連のツールキットは入れていません。パフォーマンス向上のために Eigen3(eigen3-devel) / TBB(tbb-devel) を入れておくのはオススメです。

実装

まずは付属のサンプルコードを参考にして、C++インタフェースからCaffe用の学習済みモデルの読み込みと予測(分類)処理を試してみます。
my cat これ入力

実行結果

雑種なんだよなぁ。小型犬より体が大きいからシャムよりラグドールに近いんじゃないかと思うのですが、両親を見たことないからわかりません。。

cv::dnnモジュールは高級なインタフェースが提供されているので書きやすいです。あと、OpenCV側でglogの出力をエミュレートしていてなかなか凝ってるなと思いました。チュートリアルやサンプルコードの内容だとこれ以上の詳しい情報が得られないので、cv::dnnモジュールの実装とDoxygenリファレンスを見ながらいろいろ試してみます。

cv::dnn::Blob クラスはネットワークの各レイヤーにおける内部パラメータ、入出力データを扱うための基本となるクラスで、実装上では cv::Mat または cv::UMat の薄いラッパークラスになっています。現在の実装では cv::UMat に未対応の機能も多いのでここでは cv::Mat を使ったコードのみ載せます。

複数の画像を一括で分類する

cv::dnn::Blob オブジェクトには複数の画像データ(バッチと呼ばれる)を格納することができます。最近のOpenCVのインタフェースは入力に cv::Mat ではなく cv::InputArray を渡すメソッドが多いようです。よくわからない人は std::vector<cv::Mat> を作って渡せばOKです。

Blobの形状(次元数等)については cv::dnn::BlobShape 構造体で管理していて、cv::dnn::Blob#shape メソッドで取得できます。operator<< をオーバーロードしているのでストリームにそのまま渡すこともできるので便利です。

ちなみにCaffeのC++インタフェースでも MemoryDataLayer の入力として std::vector<cv::Mat> を渡すことができます。

その際、prototxtファイルのdataレイヤーも MemoryDataLayer に変更しておきます。

caffe::Layer#AddMatVector メソッドに std::vector<cv::Mat> を入力データとして渡します。第二引数には学習時にラベルデータを渡す仕様になっていますが、予測時には適当なデータを入れておけばOK(ただし nullptr は渡せません)。CaffeのC++インタフェースはBoostをよく使っていることもあり、ついtypedefしたくなるほど読みにくくなることがあるんですよね。

話が逸れましたが、OpenCVの使い方に戻ります。複数の画像を入力とした場合のSoftmax(prob)層のBlobは [入力データ数、クラス数] の大きさの二次元データになり、クラス毎の確率(信頼度)が格納されています。確率上位5位までの予測結果を出力する場合も上述のサンプルコードと同様に書くことができます。現在の実装だとCaffeのArgmaxレイヤーが読み込めないみたいなのでソートする処理も別途書く必要がありました。

画像特徴量の抽出 + SVM/ロジスティック回帰での学習

Softmax(prob)層の出力から確率を得るのではなく、中間層の出力を特徴量として抽出したい場合も簡単です。読み込んだモデルのレイヤー定義(レイヤーの名前)を事前に控えておいてください。わかりやすいようにここではCaffeのリファレンスモデル(CaffeNet)を使います。prototxtファイルは以下にあります。

cv::dnn::Net#getBlob メソッドに該当レイヤーの名前を指定してBlobとして取るだけです。注意すべきは、getBlobメソッドはBlobの一時オブジェクトを返すので、大量の画像をバッチ入力した場合はコピーコストが相当大きくなってしまいます。Caffeの caffe::Net#blob_by_name メソッドのようにスマートポインタで包んだBlobを返してくれると助かるのですが。

Caffe C++インタフェースで特徴抽出する場合は以下のように書きます。前述の通りまずは MemoryDataLayer に画像を入力しておきます。

floatのポインタで取れるので、後は取り回ししやすいオブジェクトにデータを詰め替えて利用することになるでしょう。CaffeのAPIは戻り値がスマートポインタだったり生ポインタだったり統一されていないので注意が必要です。

cv::dnnモジュールで抽出した特徴量を使ってSVM(cv::ml::SVM)やロジスティック回帰(cv::ml::LogisticRegression)のモデルを学習するサンプルコードをGitHubに上げてありますので参考までに。SVMの学習する部分だけここでも紹介しておきます。

OpenCVのSVM実装は昔と比べると使いやすくなっていて、特に cv::ml::SVM#trainAuto メソッドが便利で、内部でグリッドサーチと交差検証までしてくれます。なにより他のライブラリを併用せずに済むのがプログラマにとっては一番のメリットかもしれません。

Torchモデルの読み込み

Torchモデルの読み込み機能も実装に含まれていましたが、まだ対応しているレイヤーの種類が不十分で未実装な処理も多いので使うのは難しそうです。簡単な構造のネットワークなら一応読み込めました。読み込み処理のコードはCaffeのモデル読み込みとほとんど同じです。

nn.LogSoftMax もまだ対応していないので実際は使えないモデルですが。

cv::dnn::createCaffeImporter から cv::dnn::createTorchImporter に変更するだけです。nn.View は nn.Reshape で代替できますが、nn.LogSoftMax が対応していないと使うのは難しいです。

また、モデルの学習については未サポートとのことです。

Functionality of this module is designed only for forward pass computations (i. e. network testing). A network training is in principle not supported.

OpenCVはマルチプラットフォーム対応ライブラリなので、他のフレームワークで作ったモデルをAndroidやiOS等のデバイス上で読み込んで利用できるようにすると便利そうです。

おまけ: データセットモジュール cv::datasets

画像認識関連の検証で便利なデータセットを読み込むためのモジュールも opencv_contrib レポジトリで提供されています。せっかくなのでこのモジュールの紹介もしておきます。

現在の実装で画像分類用途に使えるものは ImageNet/MNIST/PASCAL VOC/SUN の4つのデータセットが用意されています。CIFAR-10あたりも欲しいですね。

mnist train0.png (← cv::Matなのでそのまま保存できる)

MNISTデータセットの読み込み処理の実装ですが、レガシーなC言語での実装になっていてファイルポインタのNULLチェックすらされていないので、もしファイルが存在しない場合は例外やアサートもなく即座にSEGVします、注意。

画像処理領域に限らないですけど、データセットは提供方法やフォーマットが統一されているわけではありませんから、データ入出力の処理を書くのは地味に面倒なんですよね。こちらの使い方のサンプルコードもGitHubに上げてあります。

おわりに

CaffeやTorch単体ではアプリケーション開発は困難ですが、DeepLearningの機能をOpenCVの文脈に持ってくることができれば、テストの書きやすい綺麗なアプリケーションコードが作成しやすくなるかと思います。また、数あるコンピュータビジョンライブラリの中でもOpenCVのコミュニティは特に大きく、サンプルやチュートリアル等の手厚いサポートも期待できるという安心感があるので、今現在の実装に不備が多かったとしてもマルチプラットフォーム対応等も含めて徐々に整備されていくのでしょう。また、opencv_contrib レポジトリ内には他にも魅力的な機能満載のモジュールがたくさんあるので興味があれば試してみることをオススメします。

今年もたくさんのAdvent Calendarが作られてますね。参加者が少なくて閑散としていたり、管理者ががんばって空枠を埋めている風景を見ながらお酒を飲むのが好きです。また来年ですね。

 

Tags: , , ,

TypeScript入門 – 機械学習の実装 1 Denoising Autoencoder

TypeScript_Logo
以前からなんとなく興味があった TypeScript を初めて使ってみましたので感想などを。

TypeScript lets you write JavaScript the way you really want to.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
Any browser. Any host. Any OS. Open Source.

TypeScriptとは

TypeScript はマイクロソフトによって開発されたフリーでオープンソースのプログラミング言語である。TypeScript は JavaScript に使用するかどうかが任意の静的型付けとクラスベースオブジェクト指向を加えたスーパーセットとなっている。C# のリードアーキテクトであるアンダース・ヘルスバーグが TypeScript の開発に関わっている。- Wikipedia

とのことです。静的型付けとクラスベースでの実装が可能だということですね。

まとめ

時間のない人のため。

TypeScript + AngularJS でニューラルネットワークのアルゴリズムの一つであるDenoising Autoencodersを実装しました。このDenoising Autoencoderを構成要素として何層も積み重ねるとStacked Denoising Autoencoderとなり、Deep Learning(深層学習)とも呼ばれます。

* ソースコード

* デモ (Angular Material利用)

(Google Chrome 44.0, Firefox 40.0 で動作確認済)

環境

  • CentOS 7.0 (x86_64), Windows 7 Home Premium (x64)
  • TypeScript 1.5
  • Emacs 24.3
  • Visual Studio Community 2013

導入

LinuxでもTypeScriptの導入は簡単でした。

Emacs環境の構築

Emacs(emacs-nox)で開発する場合。typescript-tools というものが便利らしいので使わせていただきました。

この設定をしておけば、コード補完やFlymakeなどの便利機能がTypeScriptでも利用できるようになります。

Visual Studio Community環境の構築

WindowsならVisual Studio一択かと。便利です。さすがMicrosoft製といったところでしょうか。Visual StudioにTypeScript開発用のプラグインを入れます。

あとユニットテストには今回 Jasmine というフレームワークを初めて使いました。これもプラグインを入れるだけです。テストランナーには Chutzpah というのをこちらも初めて使いました。[Tools] - [NuGet Package Manager] から簡単にインストールできます。

nuget_packages

あとはEmacs emulation等のプラグインも入れました。

機械学習アルゴリズムの実装

ある程度の規模以上のWebサイトを作るのにはTypeScriptが有用そうだとは思いますが、僕にWeb制作の能力はないので、Webサイトではなくライブラリをいくつか作っていこうと思います。今回は流行りのDeep Learning(深層学習)を教材にTypeScriptに慣れていこうという趣旨で進めてみます。画像処理用途であれば CNN(Convolutional Neural Network) を実装するのが妥当ですけど、CNNは個人的に食傷気味なので今回は Autoencoder というCNNとは異なるニューラルネットワークアルゴリズムのひとつをTypeScriptで書いてみます。

ここで、deeplearning.net というDeep Learning関連の有名なサイトがあります。このサイトはPythonでDeep Learningのアルゴリズムをstep by stepで実装していくというチュートリアルになっています。

僕も1年ちょっと前にひととおりチュートリアルをやってみましたが、Python(Theano)ベースだとあっという間に実装できてしまって達成感がなかったので、ここは他のスクリプト言語でやってみようと思って前から勉強してみたかったTypeScriptを選びました。ブラウザのJavaScriptエンジンの数値計算能力のベンチマークもできそうですかね。

Denoising Autoencoder

今回の目的はTypeScriptの習得であってアルゴリズムの勉強ではないのですが、せっかくなので概要だけ説明します。Autoencoder (オートエンコーダ)というのは、日本語では自己符号化器と呼ばれていて、出力が入力と同じになるように符号化の方法(パラメータ)を学習するニューラルネットワークです。下の図は入力層が5ノード、隠れ層(中間層)が3ノード、出力層が5ノードのAutoencoderの例になります。5次元の情報を3次元に圧縮(符号化)し、それを復元(復号化)する、元の入力をよく表す特徴を学習する次元圧縮器として働きます。データ内の不要な情報を削ぎ落として、本質だけを取り出すようなイメージです。

autoencoder1

Denoising Autoencoderというのは名前の通り、ノイズを加えられた入力を符号化し、そのノイズを取り除くように元の入力を復元するAutoencoderになります。データの特徴を上手く表現しつつ、ノイズも取り除くように学習するので結果的に性能が高くなります。また、このDenoising Autoencoderを構成要素として何層も積み重ねたものをStacked Denoising Autoencoderと呼び、Deep Learningとも呼ばれるアルゴリズムの1つになります。現在はCNNばかりでAutoencoder系は昔ほど使われていません。

実装

ニューラルネットワーク部分よりも、ベクトル/行列演算用のクラスを作ったり、AngularJS対応する方が面倒でしたが、TypeScriptの文法や機能を学ぶ良い練習になりました。また、TypeScriptということで Typed Array も利用してみましたが、この程度の規模だと速度面でのメリットはあまりないようでした(? もっと大規模なデータで学習させたらきっと差が出てくるんでしょう。機械学習は一般的に重たい処理ですが Web Workers を利用しなくても計算部分やViewの実装を工夫をすればUIをブロックせずに処理を行うことは簡単です。

Indexed Databaseの利用

また、学習したニューラルネットワークのモデルを保存しておくために Indexed Database も使っています。JavaScriptのObjectデータとして保存されるので、他言語のようにクラスのインスタンスをシリアライズしてそのまま保存するつもりで書いているとつまづくかもしれません。ObjectデータからTypeScriptクラスのインスタンスに変換するアダプタのようなものを用意する必要があります。地味に面倒なので注意。

idb_model

AngularJSの利用

デモページはAngularJSを使って作りました。こちらも [Tools] - [NuGet Package Manager] から簡単にインストールできます。

angular_ts

VisualStudioでの補完も良い感じです。

angularjs_vs2013

ソースコードはGitHubに置いておきます。新しいレポジトリを作るまでもない内容なのでJavaScriptのサンプルを置いているレポジトリに。AngularJS対応部分や、Jasmineを使ったユニットテストのコードもあります。

コンパイル/実行

Visual Studioではメニューバーの再生ボタンみたいなやつを押すだけで、TypeScriptコードをJavaScriptにコンパイルして、Webサーバ(IIS)をlocalhostで起動して、ブラウザで実行してくれるようです。ああ便利。Chutzpahのプラグインを入れていると右クリックメニューからユニットテストとカバレッジ計測を実行できます。

runbutton
chutzpah_contextmenu

現時点では見ても面白くない(というか意味がわからない)デモを置いておきます。

(Google Chrome 44.0, Firefox 40.0 で動作確認済)

10次元の数値データを3次元に圧縮して、復元(再構成)するだけです。もはや Angular Material の練習のためのデモです、。

"train"ボタンで学習開始(デフォルトで学習データ一巡を1000回分)、"save"ボタンで学習したモデルをIndexed Databaseに保存、"load"ボタンで保存されたモデルを読み込み、"delete"ボタンで保存してあるモデルを削除します。今回のサンプルだとほとんど意味はないですが、"train"ボタンを何度も押して繰り返し学習を進めることができます。

画像データを扱う場合はI/O周り等いろいろと実装面で工夫する必要がありますし、次はもっとDeepなネットワークを組んで検証してみたいと思います。

da_demo

感想

TypeScriptは評判通りの使いやすい言語だと実感しました。ECMAScriptの仕様に準拠しようとする姿勢にも好感が持てます。CoffeeScriptと比べるとコードは長くなりがちですけど、IDEの支援が強力なため軽快に開発を進めることができます。

JavaScriptに変換する言語においてはコンパイル時の最適化も注目される要素のひとつだと思いますが、デッドコードの削除くらいなら変換後のJavaScriptの可読性も落ちないと思いますし、その辺りから最適化周りも取り組んでくれると助かります。数値計算用途の場合、例えば number[] を Float32Array などのTyped Arrayに適切に変換してくれたら良いですね。

TypeScriptを触ってまだ間もないですが、使いやすさは十分に体験することができました。これからはTypeScriptでライブラリ等をどんどん作っていきたいと思います。

参考書籍

 

Tags: , , ,

PC新調しました 2015

だいたい3年ちょっと使いましたので、パソコンを新しく組み立てました。

* 2012年 PC新調しました

2012年に新調した後に、SSDやHDD、ビデオカードなど細かくちょこちょこアップデートしてました。最終的に今回の新調前で組んでいた構成は以下の通り。

その他のDVDドライブとかケースファンとか些細なパーツはずっと使い回していました。この構成だとAdobe製品を使ったりとか、動画エンコードする時とかは多少不満はありましたが、普通のPCゲームする分には特に問題ありませんでした。開発系の作業はほとんどリモートサーバ上で行っていたのでスペックはあまり関係ありません。500W電源でGTX760を差していたのは少しだけ不安でしたがこれも特に問題なかったです。

今回はSSD、ビデオカードを使い回して他のパーツは新しく買いました。HDDは1台追加して6TBの容量を確保しました。安かったので。

CPUはSandy BridgeからDevil's Canyon(Haswell世代)に移行。K付きなのでオーバークロックして運用予定です。i7-4790Kも考えましたが、プラス1万円出すほどでもないなと思ったので今回はi5で。

DSC03947

電源は初めてのプラチナ電源。安心感があります。SilverStoneのものと比べて箱はダサいですが。

DSC03949
DSC03950

ケースはAntecの NSK3480 からFractal Designの CORE 1500 に変更。どちらもMicro-ATXケースですが大きさ(特に奥行き)が全然違います。CORE 1500の剛性はまずまずだと思いますが、NSK3480と比べるとペラペラです。

DSC03954
DSC03956
DSC03957

メモリはCorsair(4GB*4)からCFD(8GB*2)のものに変更、XMPでDDR3-1866にオーバークロックします。ヒートスプレッダはダサいけど嫌いじゃないです。余ったCorsairのメモリはLinuxサーバ用にします。

DSC04101

UEFI画面。まぁまぁ見やすいです。

DSC04104

3Dゲームや動画エンコード、RAW現像など高負荷をかけるPCなのでCPUはオーバークロックして4.3GHz(VCCIN 1.808v / Vcore Adaptive 1.225v)で様子見。いろいろ調整してみましたが、電圧周りの設定が昔より多いのでまだまだ吟味できていません。Prime95は2時間ほど動かして特に問題はなかったですけど6時間は難しいかも。x264による動画エンコードはCPU 55℃前後で問題なく処理できています。

aisuite
WEI20150713

GPUはまだ変えていません。GTX 760をDeep Learning用のLinuxサーバ用に、GTX 980を新しく買ってこのPCに付けようかなと考えています。

それなりに満足のいく構成になってきたのでこれでしばらく使ってみようと思います。

 

Tags:

Packt Publishingのテクニカルレビュアーになった話

Packt Publishing という出版社がイギリスにあるんですが、多種多様な技術書を数多く出版しています。O'Reilly本のように翻訳はされてないので日本のエンジニアにはあんまり知られていない(? のかなと思います。

日本の出版社だとまず企画が通りそうにないマニアックなラインナップになっており、例えば scikit-learn や matplotlib などPythonモジュール単体のみを扱ったエッジの効いたタイトルも多いです。表紙のデザインはO'Reillyよりクールな感じで僕は好きです。

今回は OpenCV for Secret Agents という著名なコンピュータビジョンライブラリのOpenCVに関する技術書のレビューをしました。以下が主な内容です。

Use OpenCV in six secret projects to augment your home, car, phone, eyesight, and any photo or drawing

opencv_for_secret_agents_cover
  • Build OpenCV apps for the desktop, the Raspberry Pi, Android, and the Unity game engine
  • Learn real-time techniques that can be used to classify images, detecting and recognizing any person or animal, and studying motion and distance with superhuman precision
  • Design hands-free interfaces that are practical in home automation, in cars, and in discrete surveillance

Raspberry PiやAndroidなどのデバイス上での画像処理についても詳しく説明されています。また、以前このブログでも紹介した猫検出関連の話も載ってます。教師データをどう集めるかという地味だけど大切で重要な作業についても言及されているのは良いですね。

DSC01658

以前、別の出版社の100ページくらいの技術書のレビューはさせていただいたことがあって、その時は100ページ程度なのでたいした負担ではなかったでのですが、今回はその3倍の300ページということでなかなかに大変な作業だったように思います。スケジュールとしては1章につき3日でレビューし続ける必要があったので、通勤時間と会社でのお昼休み、帰宅後にちょっとずつ時間を作って目を通していました。

OpenCV for Secret Agents

レビュー作業では技術的内容の確認の他に、各章毎に総評も行うのですが、「この章で説明が足りない部分はどこか」、「どのように説明すればよりわかりやすいか」などをまとめます。書籍というのはスペースにも制限があるので細かく書き過ぎるわけにもいかないし、短くわかりやすく説明するのは難しいことなんだなと実感しました。最終的には300ページになりましたが、草稿ではもっとページ数は多かったです。

ソースコードは実際に実行して動作確認していたのですが、Raspberry Piは持っていなかったのでその箇所はきちんとレビューできなかったと思います。。Unityのプロジェクトについては今回初めて触りましたが結構楽しかったです。

本にはクレジットだけでなく紹介文も入れていただきどうもありがとうございました。

DSC01656

Secret Agentsというのは秘密諜報員という意味ですが、各章の冒頭部分に 007 (ダブルオーセブン) のシーンを絡めたストーリーが展開されています。この本はデバイス上でのジェスチャー認識や車載カメラでの画像処理についても紹介されており、スパイ映画で出てきそうなシチュエーションと合った内容になっています。

実は「 ~ for Secret Agents」タイトルはシリーズとして出版されているようです。もちろんイギリスでは日本よりも007人気は高いでしょうし、なかなか洒落たタイトルですね。

レビューした本以外には、Practical Data Science Cookbook という本もebook版でいただきました。まだ読んでないのですが、大規模なログデータ分析を行うために必要なスキルについて学べそうです。ありがとうございます。
 
Hi Nikita, Sageer and Packt Publishing team.
Congrats to the author and all those who worked on this book,
and thanks to the editors and publishers who gave me a chance to work on the publication of this book.
All the best.
続きを読む »

 

Tags: