catalinaの備忘録

ソフトウェアやハードウェアの備忘録。後で逆引きできるように。

UWPで音声認識APIを試してみる

画像の分類問題に少し飽きてきました。かたりぃなです。
機械学習を使った画像の分類方法を色々と試していますが、どれも私のやりたいことと少しずれている感じがしていて少し煮詰まった感があります。

音声認識に挑戦(ライブラリを叩くだけ)

画像や映像よりも先行しているイメージのある音声の識別ってどういう理論なのだろうと思いつつPRMLの後ろのほうの章をじっくり読んでいますが、まだまだ修行が足りないらしくよくわかりません。
時系列のデータ扱うのって色々面倒だなーと思い始めています。
そういえばWindowsの左下で「何でも聞いてください」と言ってる人がいますね。マイクアイコン付いてますし、試してみましょう。
Hololensでこれが使えれば遊びの幅が広がりそうなので購入するための言い訳に使えます。

Microsoft音声認識APIを試す

まずは自分のプログラムで試す前にCortanaさんに話しかけてみます。
思った以上にお利口さんで、動画サイト見ながらマイクに音声を入れてもしっかり識別してくれます。
ユーザー見えのふるまいとしてCortanaさんがやってくれることは次のようなことでした。

  • 音声を認識して文字列にする
  • 文字列をもとにアプリやブラウザを起動する

試した単語は次の4つです。最後のは意地悪テストの域に入るので、まあ充分実用的な精度で識別できています。
発音の識別だけでなく形態素解析までやってくれてるんでしょうか。なんかすごい。

  • 「ぺいんと」

  候補「ペイント」のアプリを表示後にペイントを起動

  • 「はいぱーぶいまねーじゃー」

  候補「Hyper v マネージャ」を表示後にブラウザで検索結果を表示

  • 「とらんぷし」

  候補「トランプ氏」を表示後にブラウザで「トランプ氏」の検索結果を表示

  • 「じぇんきんすし」

  候補「jenkinsし」を表示後にアプリ候補「天気」を表示

HyperVマネージャを起動してくれなかったのはちょっと残念です。Cortanaさんのすぐ隣にいるのに。
ジェンキン寿司は古いネタなのかCortanaさんには通じませんでした。

公式ドキュメントはこちら
https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.speechrecognition.aspx

簡単に試せそうなものを先人が示してくれているのでコピペして動かします。
UWPで音声認識 - かずきのBlog@hatena

まとめ

10行未満のコードで簡単に音声認識ができました。
これなら気軽にアプリに組み込むことができそうです。
Hololensのような端末で何か作ることを考えたときに、こういったユーザーインターフェイスは従来のそれと比較して重要度が相対的に高くなると思います。
どこまで細かいことができるのかはまた別途試してみたいところです。
では今回はこれくらいで。

HoloLensの開発環境を試してみた

やっとうちのメインマシンがWindows10Proになったので試してみました。かたりぃなです。

とはいっても実機は無いのでエミュレータです。

 

実験環境

実験環境はこんな感じです。HyperVを有効化しておくことを忘れずに。

HyperVとは?

いわゆるMicrosoftの仮想化技術です。私自身使うのは初めてです。

今回使うHyperVはクライアントHyperVと呼ばれているもので、VMWareとかVirtualBoxと同系列になります。Windows上で他OSを動かすのに使います。

 

必要なツールをインストールする

公式サイトみながらやればいいんですが、英語読むの面倒な人はこのあたりを参考にすればいけると思います。

HoloLens Emulatorアプリ開発入門(1):HoloLensのAR世界を疑似体験できる、エミュレーターの基礎知識とインストール、基本的な使い方 (3/3) - @IT

 

おおまかな手順としては

  1. HyperV仮想化の有効化
  2. VisualStudioのインストール
  3. Hololensエミュレータのインストール

です。

VisualStudioのインストール時にUWP関係のものにチェックを付けるのをお忘れなく。

 

自作プログラムを準備

プログラムはXAMLのhelloworldでもいいのですが、私がやりたいことを試すためにDirectX11のテンプレートから始めることにします。

言語はC++cxでやってみます。とはいってもまだコードは書きません。サンプル動かしてみてエミュレータ上で動くアプリがどんなものかを見るだけ。

公式発表ではDirectX11 laterとのことですが、DirectX12はマニュアル見た限りすごく低レベルなAPIに思えたので、11でいってみます。

https://developer.microsoft.com/en-us/windows/holographic/install_the_tools

プロジェクト作成から実行までの手順はVisualStudioに慣れている人ならいつもの手順ですね

  1. 新規プロジェクトを選択
  2. DirectX11のテンプレートをダウンロード(立方体が回ってるやつ)
  3. ビルド
  4. 実行

まあ普通にWindows上でアプリが起動するかと思います。

HoloLens上で実行してみる

以前にMicrosoft SurfaceRT向けに何か作ろうかなと試したことがありました。手順はその時と同じです。ツールバーから実行環境を指定するだけです。

f:id:Catalina1344:20161106204757p:plain

なんか未来ちっくな名前の人がいますね。これです。

f:id:Catalina1344:20161106204807p:plain

 

これでHololensEmulator上へのアプリのデプロイとデバッグが開始されます。

 

エミュレータの設定は?

どうやらこれで自動的にHoloLensの仮想マシンがHyperV上に生成されるらしく、HyperVマネージャを起動して確認するとそれっぽい名前の仮想マシンが作られていることがわかります。

手元の環境ではデフォルト設定でも軽快にエミュレータは動作したので、しばらくはこれで色々やってみることにします。

 

トラブルシューティング

今回詰まったポイントは2つでした。

VisualStudioのHoloLensデバッグセッションが開始できない

HoloLensエミュレータは起動しているのにデバッグセッションが開始できないとVisualStudioに言われることがあります。

どうやらエミュレータ上にアプリをデプロイするにはアカウント設定を終える必要があるっぽいので、手持ちのMicrosoftアカウントを設定します。

英語キーボード設定になっているので記号入力で詰まってしまいますが、試しにタイプしながらやればすんなりいきました。

HoloLensエミュレータの操作に慣れる

慣れてきたので思い出しましたが、FPSゲームっぽい操作感覚です。

  • 左クリックとドラッグ=頭の向きを変える
  • 右クリック=視点カーソル?地点の選択
  • WSAD=移動

です。

スペースキーを押すと空間マップが表示されます。手元のカメラではこんなの作れない(kinnectがあればもうちょっと色々できるのかな?)ので、サンプルとして準備されている空間マップを切り替えてみると楽しめると思います。

 

まとめ

HoloLensエミュレータを動かしてみただけでもそれなりに楽しめました。

次回はもう一歩進んで何か面白いことができればなと思います。

Microsoft hololensへの期待

久しぶりのブログ記事です。かたりぃなです。

MicrosoftHMD(ヘッドマウントディスプレイ)のデベロッパー向けエディションが日本で発売されるという話を耳にして歓喜しています。

Microsoft HoloLens の日本での提供について | News Center Japan

APIリファレンスも一通り流し読みしたので、私自身の見解を簡単に整理したいと思います。読み間違い・勘違いも含まれている可能性がありますので、詳細は公式サイトをあたってください。

hololensとは?

公式サイト:Microsoft HoloLens | Official Site

 AR(拡張現実)とVR(仮想現実)のさらに進んだ概念としてのMR(複合現実)を実現するためのデバイスです。

利用側からみた特徴としては

  • Windows10搭載
  • 透過型ディスプレイ
  • スピーカ、マイク、カメラなどの現実世界と情報をやり取りするためのデバイスを内蔵

といったところでしょうか。

アプリ開発側からみた特徴としては

  • Intel32bitCPUと、それに付随するDSPか何のでリアルタイム演算
  • Windows10のストアアプリとして配信可能(UWPアプリ)
  • 3DグラフィックのレンダリングはDirectX11世代
  • Unity対応
  • 開発用エミュレータを動作させるにはHyperVが必要

さっそくエミュレータを試そうとしみましたが、残念ながらうちのOSはWindows10-Homeのため、HyperVを動かせないので環境作るためにしばらく保留状態です。

またWindows8以降から標準搭載されているWindowsストアでのアプリを配布ですが、Windows8発売当初は開発者向けには「ストアアプリ」と銘打ってVisualStudio用のテンプレートの配布などが行われていましたが、今は複数のデバイスにパッケージを共通化して配布するための仕組みとして「UWP(ユニバーサルウインドウズプラットフォーム)」が標準となっています。開発言語としてはC#,C++/cxなどが利用できるようです。

C++/cxって何ぞ?と思って今色々試している最中ですが、利用目的から解釈すると「ストアアプリで配布するアプリを作るためにMicrosoftがマネージド拡張を施したc++」です。

開発環境はこれくらいにして、ハードウェア的な課題も既に見えていて次のようなものがあります

  • 視野角が狭い
  • バッテリー駆動時間(2~3h)

特に視野角についてはMicrosoftも認識しているようで、今後改善していくようです。

 

VRとAR

hololensの仕組みの詳細に入る前に、世間一般を賑わせているVRとの違いについて。Oculusとか最近だとPSVRなんかが有名で、視界全体を覆うHMDを使うことで仮想空間への没入感を高めてユーザー体験を向上させようというアプローチです。

VRは仮想世界を主とし、そこに対していかにしてユーザー体験を向上させるかといったアプローチですが、ARは現実世界ありきで、そこに対して付加価値を提供していくかといったアプローチになります。

MRはさらに進んだ概念で現実世界と仮想世界の融合を目指すもので、どちらかといえばARの延長上(ARを包含するといったほうが正しいのかな)にある概念です。

 

hololensの原理を考える

原理はあちこちの記事で述べられているので関連しそうな技術要素だけ簡単に整理します。

現実世界に立体像を表示するという研究や成果は既にあって、例えば日本では

空中ディスプレイ エアリアルイメージングパネル

なんかがあります。

ここで案内されている展示場所に行けば実体験できるので、直接行けるなら実体験したほうが早いと思います。実際に触ると感動とともに課題なんかも見えやすいので。

実際に試させてもらいましたが、空中に結像されたメニューをそのまま選択する方式はユーザーにフィードバックが無いためちょっと難しいと感じました。

こういった技術を応用すれば現実世界で目的の場所に結像はできるわけですが、次はその位置を確定する必要があります。このあたりはおそらく

  • kinectと同様の深度センサを使って奥行を検出
  • 空間マッピングのためのアルゴリズム(ptam?dtam?slam?)
  • hololens自身の位置推定に加速度センサとジャイロセンサを使う

あたりかなと思っています。ptamとかよくわかってませんが。

機能を個別にみていくとhololensは基本的な機能は揃っているわけで、あとは拡張現実感を出すためのノウハウが必要になると思います。

加速度と角速度を使った姿勢推定ではカルマンフィルタや相補フィルタが有名です。

拡張現実感を出すためには現実と仮想の世界の間での誤差が小さいほど良い結果になりますが、この誤差を小さくする(外れ値とかノイズ対策?)機能としてアンカー(詳細は開発者マニュアルを参照)を置いてオブジェクトを固定するという解決ができそうです。

 

何ができるの?

応用分野の話になるので少しそれますが、こういうのとか楽しそう。海外のほうが先行してますね。

「遊戯王」のデュエルシーンが現実に!マイクロソフト製ARメガネ「HoloLens」でリアル再現した動画が話題に - Character JAPAN

 

以前PCのUSBカメラでやってみたもの

ARの原理実験 - catalinaの備忘録

 

カードゲーム好きなのでよく遊んでいますが、これをそのまま実現することはやっぱり困難があると思います。

既に分かっている課題は

  • カード種別の認識をどうやるの?
  • モデルデータをだれが作るの?

あたりです。

データが無いのは諦める(え?)として、カード種別は非常に膨大で、発売元が存続する限りは増えるので、画像分類問題のラベル(種類)が増えても有限時間内で種別を判断できるアルゴリズムがほしいなと思っています。(それが今まさに読んでるPRMLだったりするわけですが。)

 

まとめ

horolensは夢を現実にしてくれる気がします。そんな夢を買うために$3000という金額が必要になるわけですが。

本職は技術屋なので、自分への投資と思って買うのもアリかなと思いつつも悩みます。

まだ正式な発売まで時間はありますし、開発者向けのあとの一般向け販売ではもうちょっと手を出しやすいお値段になるとは思うので、情報を集めて整理しつつ考えましょう。

では今回はこのあたりで。

windows10でchainer+CUDA+cuDNNをGPUで動かしてみた

ディープラーニング用のフレームワークを何か動かしてみました。かたりぃなです。 以前にCPU版のみのchainerを動かしてみたことはあるのですが、今回はGPU版に挑戦です。 今回の記事は動かすことよりもトラブルシューティングが主な内容になります。

作業前の自分の作業環境でchainerに関連しそうなものはこんなものでした。 最初はVMWareやDockerを使おうかとも考えていましたが、仮想環境からGPUがどう見えるのかとか調べるのが面倒になってきたので、Windows上で直接動かします。

  • ソフトウェア

  • ハードウェア

    • GeForce GTX670
    • IntelCore-i7 3.4G
    • RAM 8GB

以下のサイトを参考にして必要なものをインストールしていきました。

参考にさせていただいたサイト

Windows上にChainer v1.5+CUDA+cuDNNを一番簡単に入れれる方法 - Qiita

WindowsでChainerをGPUを使って動かす - TadaoYamaokaの日記

Windows環境でChainerのGPUを使えるようにするまで - Qiita

chainerの準備

基本的なインストール手順は先人が示してくれているのでそれに従います。

  1. anaconda(python3.5)を入れる
  2. cuda-toolkit(7.5)を入れる
  3. chainerを入れる

というわけで試しに動かしてみます。 chainerのexamplesにmnistがあるのでこれを走らせます。 コマンドは

python train_mnist.py -g 0

です。

とりあえず動かすことはできました。 動かすまでにいろいろと問題があったので、問題が起きたポイントごとに原因と解決策を整理します。 その前にトラブルシューティングの基本的なことを一つ。 上記pythonコマンドを打ってエラーが出た場合、以下の情報が表示されます。

  • コマンドが戻り値0以外で終了した(異常終了した)
  • 異常終了したコマンドラインとパラメータ

エラーになったコマンドを実際に打ってみてエラー情報を確認しつつ進めます。

cuda-toolkit7.5はvisualstudio2013までしかサポートしていない。

nvcc(cudaコンパイラ)が出すエラーなのですが、visual studio2013付属のコンパイラまでしかサポートしないというエラーメッセージを出してきます。 おとなしくvisual studio community 2013をインストールします。 昔のvisual studioは最新版(手元の環境では2015)がインストール済みの場合は古いバージョンはインストールさせてくれなかった気がしますが、今回はすんなりインストールできました。

Windowsのユーザー名が日本語

何をいまさら的なところで足元をすくわれました。 windows10にアップグレードしたときにmicrosoftアカウントを作ったのですが、そのとき適当に作ったアカウントが日本語名でした。 日本語ユーザー名で作業しているとpythonがパス文字列をUTF8デコードするところでエラーになります。 今までwindowsで作業するときはVM上か、VisualStudioで作業する場合でもD:\myproject\とかで作業していたのであまり問題にはなりませんでした。 どうしてpythonだけエラーになるのだろうと調べてみましたが、アプリケーション固有の設定情報(ここではanaconda/python)が置かれる場所がここでした。 C:\Users\日本語ユーザー名\AppData\

python側の文字コードの設定を変更するだけでもいけるのかもしれませんが、また同じ轍を踏みそうなのでアルファベットのみのユーザー名を作り直します。 Microsoftアカウントはクラウド連携するので次のような手順で作り直します。 一旦クラウドから切り離してローカルで作業するのがポイントですね。

  • ユーザーアカウント作り直し&データ移行の手順
    • 作業中のユーザーアカウント(microsoftアカウント)をクラウドから切り離してローカルアカウントでログインしなおす
    • ローカルアカウントで新規にユーザーアカウントを作成
    • 新しく作成したユーザーアカウントに必要なデータ(AppDataとかDeskTopとか)をコピー
    • 新しく作成したローカルユーザーアカウントでログインしなおした後、microsoftアカウントに紐づける

コンパイラのパスが通っていない

nvcc(cudaコンパイラ)がvisual studio 2013のコンパイラのパスを認識できない状態だとこんなエラーになります。

nvcc fatal   : Cannot find compiler 'cl.exe' in PATH

環境変数PATHの設定しましょう。 visualstudio2013のcl.exeは私の環境ではこの場所に置かれていました。 C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin

感想と今後の予定

とりあえずchainerのサンプルをGPUで動かすことまでできたのでひと段落です。 実行速度はGPUを使ったほうが圧倒的に早くなっています(以前試したCPUのみの場合は30分以上かかっていたものが5分前後になった)。 これくらいの速度ならトライ&エラーしやすそうですね。 速度計測は今回は面倒&興味がないのでやりません。体感できたから良しとします。 今回利用したPCは何年も前に買ったもので、当時出たばかりのDiablo3、バージョンアップごとに重くなっていくA列車で行こう9などの3Dゲームを快適に遊ぶために買ったものだったのですが、意外なところで役に立ってよかったです。

とりあえず最初の一歩は踏み出せました。 今後はchainerの詳しい使い方を調べていこうと思います。

その他参考にした資料など

基礎からがっつりやるならPRMLもよいのですが、難しい内容かつ大判なので通勤電車で軽く読むといったことがしづらい本です。 私は紙のノートに数式ごりごり書いていかないと覚えられないオールドタイプですので。 通勤中はこのあたりの本を読み進めていくのが最近の私のスタイルです。PRMLと比べて小さめサイズというのもありがたいところ。 帰りの電車の中で読んでいると、疲れている時などは丁度いい感じに眠くなれるので、疲労度チェックにも使えます。

イラストで学ぶ ディープラーニング (KS情報科学専門書)

イラストで学ぶ ディープラーニング (KS情報科学専門書)

この本は実践的な内容でした。どんなフレームワークがあるのか、どんなことができるのかといった内容が多いと感じました。 もちろん数学的な説明もしっかりと丁寧になされているので「ディープラーニングってよくわかんないけど、動かして試してみたい」って人向けかと思います。

深層学習 Deep Learning

深層学習 Deep Learning

こちらは機械学習人工知能の歴史的な内容を踏まえての学術的なしっかりとした解説が主な内容でした。 体系的にしっかりと学ぶならこちらのほうがよさそうです。

PRMLを読みすすめるための記号一般を整理する

PRMLを読んでいるとギリシャ文字がよく現れます。 知識の基盤がある人なら「ああ、アレね」と暗黙のパラメータのように読みすすめられるのかもしれませんが、私のレベルでは「以前も調べた気がするけどなんだっけコレ」となってしまいます。 数式中に現れるギリシャ文字は慣例的で、例えばθは角度でiは虚数を意味するなどがありますが、馴染みがない記号が現れるとそれだけで躊躇してしまうことが多々あります。特に書籍を読み始めた当初はなおのこと。

よく使うものは計算ノートの一番後ろのページにメモ書きで残しているのですが、そろそろノートが一杯になってしまうので捨てた後でも振り返れるようにブログに残してみようと思います。 色々と自分で調べて納得したものもありますが、私の場合は老化などの諸々な事情もあって物覚えが悪いというか、忘れっぽくなってきているようなので「なんだっけこれ?調べた気がする」ってときに振り返れるしおりが必要です。

というわけで今回のブログ記事はPRMLの内容そのものではなく、読み進めるための前提条件として必要になった事前知識の整理といったところでしょうか。 幾つかの書籍をあたってみて学問分野ごとにできる限り一般的っぽいものを選んでみたつもりです。 読み方はネットで調べてみましたが、ちょっと自信ありません。分野や現場によって色々あるらしいので。

統計学に関するもの

読み 意味
{\sigma} シグマ 標準偏差標準偏差の自乗が分散なので、分散は{\sigma ^ 2}として表されます
{\rho} ロー 回帰分析における相関係数
{\mu} ミュー 期待値
{\eta} エータ 分布の位置母数パラメータなど
{\lambda} ラムダ 分布の尺度母数パラメータなど
{\phi} ファイ 線形基底関数モデルにおける基底関数など
{\mit \Sigma  } シグマ 分散共分散行列。和の記号と違って、この場合は斜体で表されます
{\propto} プロポーション 比例

日本で比例記号をプロポーションって読み上げる人っているのかちょっと謎ですね。

「(事後分布) {\propto} (尤度)(事前分布)」って書かれていても「事後分布は事前分布と尤度の積に比例する」って読んだほうが早そうですし、実際に書籍を読んでる最中もそう読んでいます。

ベクトル解析に関するもの

読み 意味
{\delta} ラウンドディー 偏微分の記号
{\nabla f} ナブラ fの勾配
{\nabla \cdot f} fの発散
{\nabla \times f} fの回転
{\nabla ^ 2} ラプラシアン
{||V||} ベクトルVのノルム。直観的に解釈するならVの大きさ

書籍では{\nabla f}スカラー場の勾配を簡単に表記するために使われます。 ラプラシアンは線形基底回帰モデルでラプラス基底を使った例などで取り上げられます。 発散や回転は書籍内では現れませんが、ベクトル解析の分野では基礎となるものらしいので、ここでまとめて列挙しておきました。

一般数学

読み 意味
{\lambda} ラムダ 行列の固有値など
{\ln} エルエヌ 自然対数(ネイピア数eを底とする対数)
{M ^ T} 転置 Mで表される行列またはベクトルの転置
{M ^ {-1}} 逆行列 行列Mの逆行列
{\Sigma} シグマ 和の記号
{\theta} シータ 角度。普通はラジアン単位
{\Pi} パイ 積の記号
{\tau} タウ 合成積の区間

{\tau}はこの分類でいいのかちょっと謎ですが、とりあえず忘れないように入れておきました。 合成積というと馴染みありませんが、畳込みとかコンボリューションと言い換えればソフト屋さんなら通じやすいかと思います。 {\Sigma}は今さら感があるのですが分散共分散行列と混同して困ってしまったので、区別する目的で記載しました。

確率と分布

意味
{P(X)} 確率変数Xの分布
{P(X=1)} 確率変数Xが標本値1をとる確率
{P(X,Y)} X,Yの同時確率分布
{P(X|Y)} Yが与えられたもとでのXの条件付き確率
{E[X] } 確率変数Xの期待値
{V[X] } 確率変数Xの分散
{Bi(n,p)} 二項分布。n=1の場合はベルヌーイ分布
{N(\mu,\sigma ^ 2)} 期待値{\mu}と分散{\sigma ^ 2}を分布のパラメータとする正規分布。別名ガウス分布
{Cov(X,Y)} 確率変数XとYの共分散
\displaystyle {P(X)=\sum^{}_{Y} P(X,Y) } 加法定理
{P(X,Y)=P(Y|X)P(X)} 乗法定理
{P(B|A)=\frac{P(A|B)P(B)}{P(A)}} ベイズの定理

加法定理は離散型確率変数での表現になっていますが、連続型確率変数で同時分布から周辺化を行う操作(積分消去)を離散型確率変数に適用したものととらえれば理解しやすいかと思います。 あと数式の厳密性の話になりますが、議論の対象の確率変数(連続型 or 離散型)によってPの大文字/小文字を使い分けるようですが、一旦はすべて大文字で記載しました。

最後に書籍を読むために直接必要となった知識ではありませんが、色々と調べていった中でパターン認識機械学習の応用に使えそうなものをメモしておきます。

名称 URL
線形予測分析 線形予測法 - Wikipedia
ラドン変換 トモグラフィー - Wikipedia

感想と今後

ブログの記事を書くときに間違えていないかなと確認しながら書いているのですが、wikipediaFFTや畳込みのページがすごく進化していて驚きました。 アニメーションが追加されていて直観的に理解しやすくなっています。

Latex初めて使って楽しくなってきたので色々書きましたが、面白い反面なかなか手ごわいですね。 displaystyleつけないとΣの下に式が来なかったりとか。 あとは、はてなブログの問題のようですが、行列の&が記述できないので諦めました。

今回はノートの隅にメモしておいただけのものを確認しながら一通り整理して記事にするだけでも、自分の中で色々と整理できました。 そろそろ何かプログラム書きながら試したりとかしてみたいですね。 では今回はこれくらいで。

機械学習における回帰と分類について考える

暑かったり寒かったりと体調を崩しやすい時期ですね。かたりぃなです。 機械学習について勉強していますが、まずは基礎的な問題として分類と回帰について考えてみます。 wikipediaや以前買った書籍(PRML)を見ても理論の大半は数式で表されていましたが、ここではできるだけ言葉で整理します。 自分の言葉で表現することによって数式の厳密性は失われますが、私自身の理解を深めることになると思っています。 特に自分自身が経験してきた仕事の内容で比喩することで考えを整理していくきっかけになると思います。 (そもそも本の内容をただコピペしてしまうと著作権的にも問題になりますし。)

回帰と分類

教師あり学習 - Wikipedia

教師あり学習における回帰と分類はそれぞれ以下のように解釈できます。

入力値と出力値のペアが与えられたとき、この入出力の間にある変換を求めることです。 出力値が連続な場合は回帰、離散値の場合は分類になります。 そしてこの変換を求めることが学習になります。

とは言っても抽象的でつかみづらいので実際の例をもとにもう少し概念を掘り下げてみます。

回帰

組み込みソフトウェアの開発現場での話ですが、あの分野では性能や品質が重視されます。 その背景には

  • ソフトウェアのアップデートが簡単にはできない
  • 性能要件を満たさないと製品として世に出すことができない
  • 不具合が起きた分野によってはリコールや訴訟、そしてブランドイメージの低下などの大きな被害となりうる

などがあります。 インターネットに接続されている機器であればネット経由でのバージョンアップによる修正という余地はありますが、バージョンアップ対象のモジュールによってはアップデート自体がリスクとなりうるケースもあります。 具体的な例として、カーネル本体やファイルシステム、周辺機器のデバイスドライバなどをアップデートするには相応のリスクが伴います。 (アップデート中に電源を切られると、ユーザーランド上のアプリケーションならやり直せますが、カーネルファイルシステムなんかをアップデート中にそんなことされてしまうと、何が起きるかわからない)

私が回帰による分析というものに初めて触れたのがこの品質周りの課題について調べている時でした。 ソフトウェアのバグを取り除いていったとしても、一般にハードウェアは経年劣化というものがついてまわります。 物理的な動作が含まれるハードウェアはもちろんですし、外見上は物理的な動作を含まないように見えるデバイスも劣化が進みます。 フラッシュメモリなどの書き込み回数の上限などがその一例ともいえます。

このような劣化の要因・品質特性を調べるとき、劣化による影響がどのように現れるのかを考えると

  • 劣化の原因は何か
  • 劣化すると何がおきるのか
  • 劣化の速度はどれくらいなのか
  • 工場出荷時の品質はどのくらいのものなのか

などがすぐ思いつきます。 これを分析する最も基本的なものが線形回帰による分析です。回帰直線などを求めるアルゴリズムとしては最小二乗法などが有名です。

話を簡単にするために、上記の品質の例をY=aX+b という中学数学で習う比例のグラフにあてはめられるという前提のもとで考えることにします。 劣化の要因は経年劣化であるとします。すると工場出荷時の品質が切片bであり、劣化の速度が傾きaとして表現できます。また劣化の要因は経年劣化なので機器の実稼働時間とします。 すると、

ある期間稼働した時点での品質(Y)= 劣化の速度(a) x 実稼働時間(X) + 出荷時の品質(b)

となります。 あとはどのくらい劣化したら品質を保てなくなるのか(摩耗劣化であれば、機器から異音がし始める時期など)を推測できます。 これで品質特性がわかった!とはできないのが世の中というものです。 実際にこれをそのまま使ってしまった場合の問題点として

  • 関係(この例ではY=aX+b)の前提が無いことが多い(測定して分析するまではどのような式が近似に適しているかわからない)
  • 影響している要因(品質工学でいう因子、今回の例では経年劣化)が何であるのかが不明であること

があります。それぞれの問題点について個別に考えていきます。 まずは式そのものについて考えると、例えばY=aX2+bという特性かもしれないし、もっと複雑な次数で表される特性かもしれません。 品質特性についてはバスタブ曲線と呼ばれるグラフ形状が有名です。

影響している要因について、実際には稼働時間ではなくて電源ON/OFF回数が影響していた場合などが考えられます。 要因(品質工学的に因子と呼ばれる)特定するには、デバイスのデータシートにそれら示されていることもありますが、データシート記載の実験環境と実運用環境は往々にして異なるので、そういったものに関してはリスクとコストを天秤にかけたうえで実験・測定する必要があります。 しかしながら、劣化に関する実験と測定を行うには多大な時間がかかります。これは摩耗劣化の例でわかるかと思います。

こういった要因を考えるのは非常に難しいもので、実際に測定してみないと何が影響しているか判断しづらい場面というものが多々あります。システムが複雑化している最近のデジタル家電なんか特にそうです。 こういった難しさというものはタグチメソッド田口玄一氏の有名な言葉「技術者の最大欠陥は何が起きるのかわからないと手を打てないということだ」でよく表されるものだと思います。

話が発散しそうなのでここで回帰とは何かをもう一度整理すると、

  • 関係Y=aX+bなどを求めること(そもそもこの式自体を求めることも含めて)が回帰である
  • 求めた式を使って予測することが回帰からの推論である(何年後くらいに壊れることが予想されるか)

と理解できます。 製品の品質という課題については品質工学(タグチメソッドや実験計画法など)の分野になるのでここで終わります。 ここまでの考えをもとに機械学習の観点から見てみると、

  • 上記の式の右辺にあたるもの(関数)を求めることが学習である(Y=3X+2であるなど)
  • 求めた関数を使って予測を行うことが推論である(Y=3X+2という学習結果があれば、未知の値Xが与えられても目的変数Yを求められる)

といえます。 機械学習の分野で学習(学習段階)と決定(推論段階)が分けて考えられている理由も納得できました。

分類

回帰における目的変数Yが離散的な場合が分類と呼ばれる問題です。 といっても抽象的すぎるので、具体例で考えます。

身近な例ではゲームにおける当たり判定が分類問題として扱うことができます。 話を簡単にするために2Dゲームの矩形で考えます。 当たり判定の基本となるアルゴリズムは矩形と矩形の重なった領域があるかどうかです。 重なった領域があればヒット、なければノーヒットです。 ここで目的変数Yが「当たった、当たっていない」であり、離散値は2値でヒット、ノーヒット(プログラム的表現するならばbool値)です。

単純なゲームであればすべての矩形の当たり判定をチェックすることで目的は十分に達成できます。 しかしCAVE(怒首領蜂など)や東方などに代表される弾幕シューティングのように、判定を行う対象物が数百とか数千の敵弾といったことになると少し工夫する必要が出てきます。 画面上にある数千の弾丸すべてを毎映像フレームごとにチェックするのは厳しいでしょう。スマホタブレットのCPUなどでは尚のことです。 私がこの問題について考えていた当初はもっと貧弱なCPU環境でした(Pentium-133MHz、SSEはおろかMMXもない時代)。

限られたCPUやメモリ資源の中でこの問題を解決するには、全部の当たり判定を総当たりで処理していくのではなく「当たっているかもしれない」対象物を絞り込みができればよさそうです(そもそも計算する必要すらなくなる)。 これはパターン認識機械学習の分野からみると、ブースティングの一例として考えられます。 ブースティングの基本的な考え方は「弱い識別機をたくさんくっつけて(カスケードして)強い識別機をつくれないだろうか」といったもので、 顔認識で有名なhaar-like分類器などがこれに該当します。

話を戻して、弾幕の当たり判定を弱い識別機で効率よくやるにはどうするか考えてみます。 具体例として、画面サイズは1600x1200, 弾丸の判定は2x2ドット, 自機の食らい判定は4x4ドット、画面上の敵弾の数は10000の一様分布としてみます。 総当たりで計算すると10000回の矩形判定をすることになって大変なので、まずは弱い識別機でふるいにかけます。 やり方は色々ありますが、ここでは画面全体から分割して考えることにします。 まず画面全体に対して自機の位置が右下隅に追い詰められているとしてp(1500,1100)にいるとしたとき、まず左半分にある弾丸には当たるわけがないので、 敵弾のX座標値が800以下のものは処理しないことにします。これで判定対象は1/2にまで減りました。 Y座標についても同様にして、判定対象はさらに1/2になります。 こうすることで、画面全体の10000個だったものを1/4、つまり2500個にまで絞り込むことができました。 これを必要な限り繰り返すことで、当たり判定を行う候補を絞り込んでいきます。 ポイントは、最初に大きなふるいにかけるので、自機から遠い弾丸にほど早い段階で判定から取り除かれることになります。

と言ってもこの例ではさほど高速化はできません。 もともとが矩形同士の当たり判定という単純な処理なので、絞り込む段階でやっている判定内容は、詳細な当たり判定チェックと同等になってしまうからです。

機械学習から少しそれますが、せっかく振り返ったので書いてみます。 じゃあ、どうやったら高速に処理できるか考えていた当初の記憶を振り返ってみると、分岐予測が外れたときのペナルティが大きすぎるので、できるだけ分岐処理(C/C++でいうif)を行わないのが理想でした。 結論としては、画面上をマスで分割(16x16とか)して、どこのマスに入っているかを弾丸の移動段階であらかじめ求めておき、当たり判定の段階では自機の入っているマスの弾丸のみ当たり判定を行うといったものでした。 たとえば1600x1200の画面を16x16のマスに区切ると、100x75個のマスで画面上を表現できるので、所属するマスを決める処理自体は分岐予測も除算も使わずに記述できるというわけですね。 たとえばこんな風に。(xpos,yposともに16bit幅という前提で書いてます。)

x_index = (xpos & 0xFF00) >> 8;
y_index = (ypos & 0xFF00) >> 8;
table[x_index][y_index] = ごにょごにょ;

マスのサイズを16x16にしたのはここでの演算を高速にするためのもので、マスクとシフトだけで済ませられます。 機種依存していいなら上記のコードよりもさらに早くxposとyposの上位8bitをテーブル参照のインデックスとして使うだけで済みます。(x86アセンブラ的にやるとahかalレジスタ読むだけで済んでいた気がします) あとは自機が所属するマスを求めて、そこのマスに入っている弾丸とだけ当たってるかどうか調べれば済みます。 自機がマスを跨いでいると面倒だった記憶があります。(とはいっても、この例では最大4マスチェックすれば済みますが)

このマスに区切って考えるという方法は2Dゲームの例では非常に有効ですが、機械学習という観点からは次元の呪いという問題にハマることになります。 機械学習では入力データは2Dゲームの例よりももっと次元数が高くなる(たとえば16x16pixelを256次元のベクトルデータとして扱うなど)ので、この方法をそのまま使うことは現実的でなくなってしまいます。

感想と展望

よくよく考えるとこのエントリ自体が回帰分析の一種として考えられそうです。 回帰分析をしていた当時は諸事情もあって限られた範囲内での分析しか行えませんでしたが、今やるとしたらもっと色々試せる気がします。 具体的には

  • 統計結果がある分布に従うことがわかったとき、出荷台数をもとに数年後の修理台数やコストを予測する
  • 予測されるコストをもとに品質保証にかけるコストとのトレードオフを算出する

などがありそうです。

話ついでに。PRMLの下巻買ってみました。 上巻よりさらに手ごわくなった内容ですが色々と興味深い内容ですので、色々試しつつも整理していきたいと思います。 上下巻を比較すると上巻が基礎理論、下巻が実用に向けてのさらに発展した内容+実例といった内容です。

なんか長くなってしまったので今回はこれくらいで。

色々と本を読んでみた

桜の花も散ってしまって春から夏へと季節の移り変わりを感じます。かたりぃなです。
タイトルどうしようかと考えましたが、記事の内容が整理しきれない気配なのでここで一旦投稿としました。

図書館を歩いていてふと開いた本で新しい世界が開けました。
こういった不意に得られる情報というものが私はとても好きです。電子書籍にはない良さです。
デジタルに比べてアナログな書籍の良いところは

  • ふとした瞬間に有意義な情報が得られる偶然性(目的以外の一見ノイズとも思える情報の中から得られるものもある)
  • 人間の脳のアナログな記憶にアナログな本はマッチしている(何度も開いてクセがついている、後半のほうといったアナログな参照ができる)

だと思っています。

少し話がそれましたが、今回はニューラルネットワークの続きを少し調べてみたので簡単に整理してみようと思います。
脳科学については専門外なので解釈が乱暴で厳密性・正確性に欠ける部分が多々あると思いますが、ここでは機械学習(そしてディープラーニング)について理解することが目的なので正確性は犠牲にします。私にとっては脳をコンピュータ上で再現することが目的ではありませんので。
ニューラルネットワークの基本概念はこれで一段落にします。

ニューラルネットワークにおける教師無し学習

特徴抽出細胞(feature-extracting-cell)

色々と文献を漁ってみたところ、動物はどうやってものを認識しているのかという生物学的な話にまでさかのぼるようです。
まず「特徴抽出細胞」とはネコを使った実験で発見されたものらしいです。
その昔、ネコの脳の視覚野と呼ばれる部分に特定の傾きのスリット光に反応するニューロンが発見されたそうです。
またスリット光に反応するニューロンは集団をなしていて、ニューロンが反応するスリット光の傾きは連続的に変化していた。と。
なんか日本語おかしいですね。。。
どうやらこれを機械学習の観点から応用したらしく、ポイントは

  • 学習モデルの構造として単純な入力処理だけを行う視細胞と複雑な処理を行う視覚野の2つのモジュールに分けられる
  • 視細胞と視覚野の間にニューラルネットワークを構成
  • 特徴抽出細胞は後天的に形成されたものである
  • 特徴抽出細胞は教師無し学習によって得られたもの

だと理解しました。

この視細胞と視覚野を結ぶニューラルネットワークのことをトポロジカルマッピングというらしいです。
トポロジカルマッピングの代表的なモデルとして

  • willshaw-malsburg
  • kohonen

のモデルがあるそうです。

このままではよくわからないままなので、前回の記事のアルファベット認識の例で考えてみます。
機械学習の基本的な概念と歴史を追ってみた - catalinaの備忘録
このときの例の16x16pixel(256次元)のグレースケール画像を使った場合では、我々が画像を認識するうえで当然のように考えているものを落としてしまっていることになります。
もっと具体的にいうと、ピクセル間の距離や並びという概念が抜け落ちることになります。
ここで情報を再構成するための話が、先の生物学の話に出てきた猫のスリット光に反応する視覚野で得られる情報そのものなのですが、視細胞で得られた情報を視覚野で再構成(256次元から二次元に落とす)するための数理モデルのお話のようです。
wikipediaでいうとこのあたりでしょうか。自己組織化写像
自己組織化写像 - Wikipedia

トポロジカルマッピングの理論の中によく表れるキーワードとしてシナプスの競合と協調がありました。

  • 競合とは周囲のシナプスを抑制しあうこと
  • 協調とは周囲のシナプスを興奮させ合うこと

といった意味合いになります。

最近話題のディープラーニングで使われているという畳み込みニューラルネットワークでは、畳み込み層で二次元カーネルによって画像の局所特徴量を得ることに成功しているようです。
局所特徴量を得られているということは、先にあげた単純なニューラルネットワークでは失われていたピクセル間の影響をうまく抽出できているといえます。
ちなみにカーネルと言ってもOSのコアの話ではなく、画像フィルタで一般的に使われるカーネルのお話です。
具体的なカーネルの種類としてsobelやgaussian、laplacianといえば思い出す人も多いのではないでしょうか。
画像フィルタリング — opencv v2.1 documentation

マルコフのモデル

マルコフ性とは、未来の状態は現在の状態からのみ決定され、過去の挙動とは無関係であるとするものです。
情報処理技術者試験の午前問題で単純マルコフ過程が頻出問題だったと記憶しています。
例えば、
ある日の天気が雨であり、翌日が晴れの確率は30%, 曇りの確率は50%, 雨の確率は20%のとき、2日後の天気が晴れとなる確率は?
などです。
実際の出題では曇りの日や雨の日の翌日の天気がどうなるかといった確率をまとめた表と、これが単純マルコフ過程であると限定したうえでの出題なので、単純な確率計算で答えは求められます。

少し複雑なものでマルコフモデルにおいて直接観測されない状態を含むモデルのことを特に隠れマルコフモデルと呼ぶそうです。

このマルコフのモデルをもとに行うシミュレーションがマルコフ連鎖モンテカルロ法として知られていて、マルコフのモデルの下でシミュレーションを繰り返すと、値が収束していくという特性があります。
情報処理の試験が役に立たないと言われるのは、こういった話にまで踏み込まないで簡単な計算問題や概論だけで止まってしまっているからだと思います。

さて、このマルコフ連鎖モンテカルロ法ですが、何に応用できるのかと疑問に思っていました。
色々と調べてみたところ、後述のベイズのモデルにおける推定のための分布を求めるために利用されるようです。
応用分野においてこの2つがセットで語られることが多いのはこういった関係があったからなんですね。

ベイズのモデル

ベイズの定理を使った推測のモデルです。
認識すべき入力パターンがどの母集団から発生したと考えるのが尤もらしいかをベイズの定理をもとに識別します。
事後分布は事前分布と尤度の積に比例するというのが基本的な考えのようですが、まだ理解が追い付いていないので詳細はまたの機会に。

感想と今後の展望

思いっきり話がぶっとびますが、その昔の有名なゲームにCLANNADというのがありました。人生ですね。
ヒロインの一人、一ノ瀬ことみ(ひらがなみっつでことみ。呼ぶ時はことみちゃん)のご両親は物理学者で、この世界を表す数式を研究しているという設定でした。
もしこの現実世界を理路整然とした数式で表現できるとすれば、ディープラーニングの先にあるものはことみちゃんの両親が研究していた数式なのかもしれなません。夢のある話ですね。
とは言っても、我々人類が置かれている事象の内側だけしか観測できないのと同じように、ディープラーニングも与えられた事象に対してのみ働くだけになるかもしれません。

そんなくだらないことを考えつつも機械学習についてもっと知りたいと思ったので、本を買って読みはじめました。
足りない情報や基礎理論は図書館を利用することにしました。

一冊目。ハズレでした。少なくとも私にとっては。
一通りの理論を理解し終えた人が机の上にリファレンスとして置いておくにはいいのかもしれませんが、参考書としての最初の一冊としては情報不足でした。
www.amazon.co.jp

二冊目。図書館で借りて読みました。
確率の基本理論から入って同時分布、条件付確率、そしてベイズの定理へと理論的で分かりやすい本でした。
全部は理解しきれていないので、また復習するときにお世話になりそうです。
www.amazon.co.jp

三冊目。これは買っておきました。
上下巻セットにするとお小遣いがほとんど消えてしまうので、まずは上巻を買いました。
まずは一通り概要を読んでみましたが良書だと思います。
一回読んだだけで全部理解するのは困難なので、演習問題に挑戦しつつじっくり読み進めたいと思います。
www.amazon.co.jp

その他。
図書館で借りて読みました。
3Dグラフィックの行列とベクトルで詰まった人におすすめしたい本です。
上記のパターン認識の本を読んでいると行列やベクトルの計算が出てくるのですが、正直ほとんど忘れてしまっているのでちょっと時間をとって復習してみました。
この本はただの行列の計算方法だけでなく、基底や直交(一次従属、独立)の話から始まり、ベクトルを異なる基底へと変換する……いわゆる座標変換まで丁寧に解説されていました。
行列を習った学生の時分、何の使うかわからない面倒な計算が本当に苦痛で、便利になるどころか計算の手間が増えただけじゃないかとすら思ってました。
3Dグラフィックの分野では必須ともいえるものですが、この「計算が面倒」という先入観も相まって、当時最新鋭のPentium100MHzのPCで行列の乗算なんて重い処理を避けて、どうやって高速化するかなんて考えてました。
上京してきたばかりの貧乏学生には3Dグラフィックアクセラレータ(今でいうGPU)なんて高級品、手が届くはずもないので。
そんな過去を振り返りつつ楽しく読めました。
www.amazon.co.jp

今回はこれくらいで。