catalinaの備忘録

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

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

今回はこれくらいで。

機械学習の基本的な概念と歴史を追ってみた

世間ではコンピュータに囲碁、将棋、チェスなどをやらせて人間を破ったなど思考する機械の話題が賑やかですね。
技術的なキーワードでは機械学習やディープラーニングになるのですが、詳しくいことがわからないので色々と調べてみました。
ディープラーニングの基礎となる機械学習について調べてみたので、自分の理解と考えを整理するためにもブログ記事として書いてみようと思います。なのでこのエントリには見落としや勘違いなど、間違いが含まれていると思います。
なお文献によって用語が異なっていたりするので、このブログでも統一がとれていないかもしれません。

着目点

「人間の仕事が機械に取って代わられる」という記事が週刊誌や新聞に掲載されていたりします。本当にそうなのでしょうか?
こうのネタは定期的に出てきていますが、結局のところ機械に置き換えられることによって人間の仕事の質が変化してきただけだと私は思っています。
とはいえ、最近のAI,ディープラーニングなどの技術の中身を知らないまま歴史からの推論だけで決めつけてしまっていてはちょっと勿体ないですし、エンジニアという視点で自分が置かれている環境に影響を与えうる要素に対して意見をもつなら、何かしらの技術的根拠をもとに結論を出したいところです。
今回調べた内容だけでは最近もてはやされているディープラーニングまでたどり着けなかったので、一通り調べてみてそのうえで自分なりの答えを出したいと思います。

そもそも学習とは

まず人間についての学習とは何かという点について、調べてみました。
人間工学などの書籍をあたってみると大きな分類として

  • 自律的学習
  • 帰納的学習
  • 演繹的学習
  • 知識学習

などがあります。

これら学習の概念を整理すると「学習とは"問題解決のために用いる自己の能力"を向上させる手段」
といえます。

ここから安直に考えると「機械学習とは上記の学習を機械で行うこと」と一言になります。しかしそれだけでは私自身の何の学習にもなっていません。
機械学習の歴史をたどって、機械(コンピュータ)に学習させるという点を掘り下げて考えてみます。

機械学習の歴史

図書館で本を借りて色々と調べてみました。
いくつかの文献をあたってみたところ、必ず出てくる有名なものがあるのでここに並べてみます。

それぞれの概要を理解した範囲で簡単に整理してみます

神経回路網アプローチと記号論アプローチ

神経回路網アプローチとは、最近流行のディープラーニングもそうですが、神経網モデルをコンピュータ上で表現し、その神経網に学習をさせようというアプローチです。
対する記号論アプローチは、述語表現やルールとして記述されたモデルによって学習をさせようというアプローチです。
またこれとは別にPAC学習というアプローチもあるようですが、今回の資料だけでは詳細情報は得られませんでした。

神経回路網アプローチ

パーセプトロンニューラルネットワークそしてバックプロパゲーション

パーセプトロンは一つの神経細胞を表します。パーセプトロン複数の入力を受け、複数の出力を行います。
パーセプトロンの入力は入力値に対して重みを掛け、入力の合計値にバイアス値が足されます。これを活性化関数(古くからの実装ではシグモイド関数)に受け渡すことで出力が決定されます。
ここで学習結果は重みの値となります。
このパーセプトロンを組み合わせたものがニューラルネットワーク(NN)と呼ばれるものです。
NNには2種類あって、階層型と相互結合型(再帰型)に大別されます。
現在広く使われているものは階層型NNのようです。
階層型では層の呼び方としてN層ニューラルネットワークなどと呼ばれます。
このとき、入力層、中間層(隠れ層)、出力層の3つの呼び方で入出力が区別されます。
入力にも出力にもあたらない層が隠れ層です。

さて、パーセプトロンに話を戻して、
先にあげたアルゴリズムのままでは何がすごいのかイマイチわからないので、次のような例を考えます。

  1. 2入力1出力のパーセプトロンで、2入力の重みをそれぞれ1とし、バイアスを1.5とした場合
  2. 2入力1出力のパーセプトロンで、2入力の重みをそれぞれ1とし、バイアスを0.5とした場合
  3. 1入力1出力のパーセプトロンで、入力の重みを-1, バイアスを-0.5とした場合

手で計算して真理値表を書くと見覚えのある表になるのですが、このパーセプトロンはそれぞれ、AND,OR,NOTの論理回路になります。
これは重み値とバイアス値がある値をとるとき、基本論理回路(ゲート)として振る舞うことができるということを意味します。
すなわちコンピュータが学習によってコンピュータの基本素子ともいえる論理回路を構成できてしまうということです。
あとは組み合わせ次第でどんな回路も作れますし、加算器や乗算器、シフト回路、果ては記憶素子としてのFF(フリップフロップ)やラッチを作ることだってできそうです。
機械学習の結果で論理回路が構成されるなら、機械学習の結果次第で何でもできる!!
なんとなく機械学習の神経網アプローチってすごい気がしてきました。

機械学習としてニューラルネットワークを利用するためには、学習の結果をパーセプトロンに反映する必要があります。
このために教師アリ学習として扱ったとき、「NNから得られた出力信号」と「期待する結果」とを比較することで誤差を知ることができます。
この誤差をもとに重みを調整すればよいのですが、この計算方法はローゼンブラット式とヘブの学習と呼ばれる式で違っていました。
学習結果の反映のためのパラメータ調整の話になってくると思うので、ここでは複数の方式があるということだけ記しておくことに留めます。

バックプロパゲーションですが、乱暴に概要だけを述べるならば、「学習結果を出力パーセプトロンから入力方向へどんどん遡っていき、中間層(入力でも出力でもない層。隠れ層とも呼ばれる)の誤差を小さくしていく(学習を行う)こと。」といえます。
このバックプロパゲーションがどうやら革命的なことらしく、この技術が登場するまではニューラルネットワークの研究の冬の時代と呼ばれていたらしい。
この技術が登場したおかげで、パーセプトロンを多層にできるようになったとのことです。

NNの実際の応用事例ですが、たとえば画像からのパターン認識などに利用できるようです。
簡単な例では16x16ピクセルのグレースケール画像に示されるアルファベットの認識。
この例では入力は16x16=256次元のベクトルとし、入力層に割り付けます(入力層は256個のパーセプトロン)。
出力層は26種類のアルファベットのいずれか1つなので出力層の26個のパーセプトロンのうち最もよく反応したものを識別結果とする。
などがあります。

私の中でもまだ理解が追い付いていない&疑問が残ったままの要素として、次の2つがあります。

  • NNでは過学習が問題となったようだが、これに対するフォローはどうするのだろう
  • 隠れ層の数はどのようにして決めるのが適切なのだろう

まだ概論しか触っていないので、これらの問題はもっと深い部分で解決しているのかもしれません。

ニューラルネットワークに対する個人的見解

NNは今後もどんどんと進化する可能性はありそうです。
相互結合型(再帰型)のほうも興味深いのですが、今回あたってみた資料では情報が古いせいか相互結合型NNの情報が少ない状態でした。相互結合型NNは結果の収束の判別方法などまだ理解しきれていない点が多いですが、個人的にはすごく興味深い話だと思います。
NNをゼロから実装するのは手間がかかりすぎるので簡単に実験できないかと調べてみたところ、例えばopencvのmlモジュールに含まれていますし、R言語でもNNetパッケージが提供されています。
opencvのmlモジュールでは多層NNが実現できますが、学習結果を可視化する手間がちょっとかかりそうなので、試してはいません。
R言語のNNetパッケージは3層(隠れ層が1個のみ)のNNしか使えないのがちょっと残念ですが、学習結果のNNを可視化するパッケージが某大学の某教授が公開してくれていますので、動作概念を確認するのに利用できました。
R言語での多層NNパッケージも調べればあるのかもしれませんが、それはまたの機会ということで。
NNを試してみて思ったことは、動作検証の方法が統計的手法になりがちなので、いままでやってこなかった統計的手法についても調べていく必要がありそうです。

記号論的アプローチ

ウィンストンのアーチ

「積み木のパーツの中から3つだけ使ってアーチを作れと」言われれば、ブログ書いたりネット見たりしている我々ならすぐにできるものですね。
技術の無駄遣いをする人ならもっととんでもないものをつくってくれるかもしれませんが。
アーチの回答ですが、人間がやるとすれば次のような解が導き出されます

  1. 柱を2個立てる
  2. 柱の上に何かを1個載せる

これを使って「コンピュータにアーチの概念を学習させる」という論文が「ウィンストンのアーチの概念の学習」と呼ばれるものです。

概念は非常に分かりやすく直観的なものでした。
直方体や円柱、三角などの積み木を意味ネットワークと呼ばれるグラフで表現し、ノードを積み木の属性、ノード間のつながりで積み木の関係を表現します。
このグラフがアーチの概念を表すまで正の例、負の例を与えて学習をさせるというものです。
興味深いのは、神経網的アプローチで神経細胞の出力を数値で表すのに対し、こちらはmust,notなどの論理式で表すということでした。
負の例の中でもニアミスは概念を学習するうえで非常に重要な位置をしめているとのこと。
上記の人間がやる例でも見落としになっていますが「柱同士がくっついていてはダメ」という概念を学習によって得られるとしています。
柱同士がくっついている負の例(touchというノード間のつながりをデータとして与える)を与え、帰納的に学習させるというものでした。

ウィンストンのアーチ自体は帰納的にコンピュータに概念を学習させるという良い例だと思います。
この方法論をそのまま再現しても意味はありませんが、論理的な学習手順のアプローチの基本原理として非常に参考になる例でした。
問題点もわかっていて、ニアミスは良い学習になるが、学習済みモデルとの差が1要素のみであることなど制約は大きいです。
この理論を発展させたものが決定木であり、決定木を弱識別機として多数組み合わせたものがランダムフォレストです。

決定木

決定木は与えられた訓練事例から、事例の正負を判断するための木を使ったアルゴリズムです。
アルゴリズムとしては

  • ハントの Concept Learning system
  • クィンランの ID3
  • C4.5

こちらのアルゴリズム帰納的に概念を学習させるモデルで、画像処理ライブラリなどに含まれていたりします。

決定木は与えられた事例集から、それを識別するための概念による分類を行うために利用できます。
例えば、ある有名キャラクターを概念的に識別することを考えると

  • 性別(o女性,x男性)
  • 髪の色(o金,xピンク,x緑)
  • 髪の長さ(oロング,xショート,xなし)
  • 肌の色(o肌色,x茶褐色)

などと識別するための木を作ることができます。これが概念の木(=決定木)そのものになります。
先のキャラクターの例で考えたとき、あるキャラクターそのものを言い当てられるのは当然として、そのキャラクターと同様の特徴をもつ母集団全体の性質を決定木は示していることになります(女性、金髪、ロング、肌色)。
また、決定木の高速化に大きく寄与していると考えられるアルゴリズムとして「エントロピーや情報獲得率を考慮した木の構築」が挙げられます。
これは特徴を言い当てて答えを絞り込むために、「何を優先的にチェックすべきか」を学習によって獲得していることに相当します。
エントロピーとその正規化について考えると、学習のデータセットにデータベースでいう主キーに相当するものが含まれていたりすると、その主キーのみで全てが決定できるため、情報量が最大となってしまい、期待した決定木が生成できません。
言葉でいうと「場合の数」が多い概念(髪の色を500種類に分類した など)が優先されてしまうということですね。
(これは学習データセットに対する識別率は100%だが、汎用性は皆無な木が生成されてしまうことになります。)
そのため、エントロピーの正規化した情報獲得率とも呼ばれる方法が利用されるようです。

ファジィ理論

バブル崩壊と叫ばれていたころ、家電製品でどこもかしこもファジィファジィと謳っていたのを記憶しています。
父に聞くと「ふつうの機械はON/OFFしかできないけど、ファジィなら「いい塩梅」に調整してくれるんだよ」と答えてくれたのを覚えています。
今回図書館で借りた本だけでは詳しい情報は得られませんでしたが、父の教えてくれた答えは「だいたい合っている」気がします。

ファジィ理論ではこのような「だいたい合っている」が示す範囲を「ファジィ集合」と「メンバシップ関数」で特性づけた集合で表すそうです。
メンバシップ関数がその集合に属す度合を示します。
ファジィ集合は集合演算が定義されていますが、一般的に呼ばれる集合(クリスプ集合)とは若干異なるものです。

今回あたった資料では概念だけしか紹介されていませんでしたので、概念イメージのみに留めます。
私が理解した範囲でのファジィ制御の概念として、
あるアナログ入力値に対して上記の「ON/OFFしかできない」と「いい塩梅」の制御を行ったときの概念イメージを表現したとき

  • ON/OFFのみでは、制御範囲は理想的なステップ応答のような矩形になる
  • いい塩梅では、目標値を中央とした分布(メンバシップ関数で変わる)に属するファジィ集合に応じた制御

となりそうです。
実際の家電制御では計算量が増えてしまう分布からの計算ではなく三角形近似などで十分であるケースがほとんどのようです。

ファジィ理論ニューラルネットワーク

人工知能の概論と歴史を駆け足で追ってみましたが、ファジィ理論ニューラルネットワークを組み合わせることでもっと効率的な学習が行えるかもしれませんね。
と思ってネットで調べてみたらありました。ファジィ・ニューラルネットワークというらしいです。まんまですね。

感想・今後の展望

今まで理屈を知らなかったものを知るということは非常に楽しいものです。
また、新しい知識を得てもまたわからないことが出てくるのでそれはそれで楽しいものです。
最近話題の機械学習はもっぱらニューラルネットワークが基礎的技術となっていますが、試しにR言語でnnetパッケージ動かしてみたところ、結果がわかりにくすぎる状態でした。(学習結果のネットワークを見てもそれが期待する結果なのかどうか判断できない)
学習結果の尤もらしさを人間が客観的かつ迅速に判断する仕組みづくりがどこかで必要なんじゃないかなぁと思います。
それがいわゆる統計的アプローチにつながっていくのだろうと予想しています。
神経回路網的アプローチに対する記号論的アプローチでは述語表現や概念グラフが学習結果として現れるので、学習結果を人間が確認するのも簡単そうです。
しかしながら、今回は単純な例しか考えませんでしたが、複雑な学習になってくると学習結果の確認すること自体が現実的ではない巨大な概念グラフになってしまうでしょう。
色々と調べて考えてみた結果、ビッグデータデータマイニングと騒がれたときと類似した問題解決手法とそれぞれの課題が見えてきました。
また、根底にある考え方として2種類(記号アプローチと神経アプローチ)のアプローチがありましたが、それぞれアプローチは異なるものの、どこかで一本の糸につながりそうでつながらない状態です。
まだ考えの整理が追い付いていない部分が多々ありますが、自分なりに考えてみて、色々やってみたいと思います。

今回はアルゴリズム機械学習人工知能の仕組みと歴史を中心に調べましたが、次回は少し趣向を変えて統計的アプローチ周りを見てみたいと思います。
具体的には統計的決定論と呼ばれるものですね。ベイズとかマルコフとか。