機械学習

簡単な迷路探索でQ学習を使ってみた

簡単な迷路探索でQ学習を使ってみた

dfdfadfasdfa

Q学習(強化学習の一種)を用いて,固定迷路を解くエージェントを実装する.

迷路は固定で,大きさは8×3.左上がスタート,右下がゴールとして.ゴールに到達した時報酬をもらい,イテレーション終了.これを難度も繰り返す.

実験結果はこのようになりました.↓

100イテレーションおきにを動画で出力してあります.

スタートからゴールに行くまでにかかったターン数をグラフにしてみると,次のようになった.

fdasfasdfas

このグラフを見るとわかると思うが,約1500ターンを境目に逆にかかるターン数が増加している.これがなぜなのか調査する必要があると考える.

調査項目

alpha = 学習率 gamma = 割引率 goal = ゴール時報酬

alpha = 0.01 gamma = 0.99 goal=1.0 10000itersで全然学習せず

alpha = 0.01 gamma = 0.99 goal=100 1500がピーク

OPENCL版NNPropagatorを開発しました!

OpenCL版NNPropagatorを開発しました!

高速なニューラルネットワークの学習のために,OpenCLを使い学習の高速化をしました.

NNPropagatorの理念に基づき,OpenCL版の実装も,トリッキーな最適化を施したものではなく,アルゴリズムが把握しやすいものになっています.

参考に,私の環境では,後日投稿予定の「CNNでMNIST実装」では,数千倍程度の高速化となりました.OpenCL_Logo

OpenCLとは?

OpenCLとは,マルチコアCPUやGPU、Cellプロセッサ、DSPなどによる異種混在の計算資源を利用した並列コンピューティングのためのクロスプラットフォームなフレームワークです。どんな計算資源でも同一のコードで並列プログラミングをすることができます.OpenCLのカーネルはOpenclC言語というC言語ライクな言語で記述することができ,非常に使いやすいです.

NNPropagatorでの使い方

NNPropagatorでの使い方は,CPU版と比べて一切変化しません.

あたらしい種類の層を追加するときに,OpenCLコードで書く必要があります.

 

 

AdaGrad,RMSProp,+L2Normを実装しました[NNPropagator]

AdaGrad,RMSProp,+L2Normを実装しました

NNPropagatorについて,新しくAdaGrad,RMSProp,+L2Normを実装しました.

どんどん新しいものを追加予定ですが,公開はもう少し先になりそうです.

では今回新しく追加したものについての話をしましょう.

dfsfsfsf
サムネ

重み更新アルゴリズム

今回追加された3つは,すべて重み更新に関する仕組みです.

ニューラルネットワークは,まずニューラルネットワークを構造を定義し,構造内の学習すべきパラメータを適切な値にすることによって回帰・分類問題を解くことになります.

このとき,現在一般的に使われているパラメータ推定方法として,誤差伝搬法が用いられています.

誤差伝搬法とは,小さいほうが適切なパラメータとなる,パラメータからスカラー値への写像関数=誤差関数を導入し,誤差関数のパラメータ変数での勾配を計算して誤差関数の値が小さくなる方向にパラメータを変化させる,ということを繰り返し行うことでパラメータを推定する手法です.数式で書くと,

\[w←w -\mu \frac{\partial L}{\partial w}\]

となります.ここで\(\mu\)は,適切な十分に小さな値(<1)です.この計算式を難度も繰り返すことにより,十分な回数であれば極小値にたどり着くことができます.

この方式は,NNPropagatorではGradアルゴリズムで定義されています.

AdaGrad,RMSPropとは?

しかしながら,Gradアルゴリズムには問題点があります.代表的なものを3つ上げるとすれば,

1.十分に\(\mu\)を小さくしなければ極小値にたどりつけない.しかし小さくすると学習が遅くなる.

2.Gradアルゴリズムでたどり着くのは極小値であって,最小値ではない.本当に辿り着きたいのは最小値である.

3.パラメータが莫大やほぼゼロの値をとるとき,学習が発散・停止する.(深層学習)

が挙げられます.

このうち1.の問題点を回避しようと考えだされたものがAdaGrad,RMSPropです.これらのアルゴリズムは,\(\mu\)を学習中に変化させることで,早く極小値にたどり着くことができるように設計されました.

L2Normとは?

さらに,3.の問題点を解決しようと考えだされたものが,L2Normalization(L2ノルム正規化)です.

L2Normは,上式の更新アルゴリズムに,パラメータに比例する減少項を追加することにより,パラメータが大きくなり過ぎないように調整されます.この方法では,パラメータがある範囲に束縛された状況下においての,誤差関数を最小化する点を求めることができると証明されています.

また,L2Normには過学習を抑制する,というメリットもあります.

感想

このアルゴリズムを実装して早速使ってみましたが,L2NormはかなりDeepLearningで役に立ちました.パラメータが抑制されることによって誤差の発散がかなりおさえられ,学習が破綻することが少なくなりました.また,RMSProp,AdaGradによって高速で精度良いパラメータを算出できることも確認しました.詳しくは,後日書く「CNNでMNIST実装」に書こうと思います.

時系列データを学習するニューラルネットワーク「RNN」が使えるようになりました(NNPropagator)

「NNPropagator」誠意開発中!

前回,ニューラルネットワークのライブラリを独自に開発を進めていくということをお知らせいたしましたが,今回も開発状況をお知らせ致します.

この「NNPropagator」では,簡単にニューラルネットワークの構造を定義し学習ができる,シンプルなライブラリである,と前回書きました.これは,ニューラルネットワークが層構造をなしているという点から,「層」を「結合」させるという簡単なコードを書くことでニューラルネットワークを定義する事ができる,というものです.これは,TensorflowやChainerなどの機械学習ライブラリと同様な仕組みとなっています.

この層構造を基本に置くことの利点のうちの1つは,新たな仕組みを比較的容易にライブラリに追加することができるということにあると考えることもできます.では,前回から追加された機能の1つを説明してきます.

今回の主題は,「未来方向ディレイコネクタ」です.

ディレイコネクタ

前回までのニューラルネットワークでは,可変長の時系列データを扱うことはできませんでした.データ系列に時系列データを用いると,異なる時刻間で情報に相関が存在する場合,相関がないとして独立したデータとしてニューラルネットワークに学習させる方法や,固定時刻でニューラルネットワークの入力次元=時間幅として学習させる方法など,制限のあるやりかたで時系列データを処理することはできますが,本来可変であるはずの時系列データを扱うのには,少し不便と言わざるを得ません.

そこで登場するのが再帰結合型ニューラルネットワーク「RNN」です.このネットワークは,一部の層間結合に「遅れ(delay)」を導入することで,ネットワークを拡張します.具体的には,次のようになります.前回のニューラルネットワークの構造に比べると,新しいものは三角マークの結合ですね.+マークは,ただ結合を加算合流させるためのものです.

DelayConnect N

この三角マークは遅延結合と言って,制御理論ではおなじみですが入力されたデータを単位時間保持し,その後出力する結合です.この結合によって,過去の情報を現在へ伝える事ができ,過去との層間のあるデータを扱うことができるようになります.

では実装!

とは言っても,やっぱり実際にやってみなければなんだかよくわかりませんよね.実例を以って体感してみましょう.

今回学習に挑戦するのは,簡単な遅延出力器です.ランダムなパルス幅のパルス信号を1単位時間だけ遅らせて出力することを学習させます.

パルス信号
パルス信号の例

入力データにランダムなパルス幅のパルス信号,出力データ(教師データ)に,入力データを1つだけ未来方向にずらしたものをセットし,上図のネットワークを定義しNNPropagatorで学習を実行します.
<NNPropagatorでのネットワークの定義は次のようになりました.delay=Trueでディレイコネクタであることを明示します.

<br />
NNList = [<br />
    OneConnection(1,3,connect = [&quot;plus0&quot;],name=&quot;W&quot;),<br />
    PlusConnection(connect = [&quot;V&quot;,&quot;U&quot;],name=&quot;plus0&quot;),<br />
    OneConnection(3,3,connect = [&quot;plus0&quot;],name=&quot;U&quot;,delay=True),<br />
    OneConnection(3,1,name=&quot;V&quot;)]<br />

実行結果

学習した結果は,次のようになりました.青が入力データで,緑がニューラルネットワークが出した出力データです.

RNN D0 RESULT

見事に1単位時間だけ位相をずらすニューラルネットワークが学習できましたね!これでおしまいです.

余談

上のように定義したRNNでは,勾配消失/勾配爆発問題が発生すると説明されることが多いです.実際,学習係数を順伝播NNと同じにしてやってみると数値が発散してしまうことが確認できました.これを解決する方法がたくさん開発されていますが,今回は割愛します.

 

追記(2016/3/18)

かなり良い学習結果が得られたので追記

出力層の手前にSigmoid層を入れたことによりものすごい改善が起きたことをここに記す.

rnn_delay_good

ニューラルネットワークライブラリ「NNPropagator」を開発中です!

「NNPropagator」とは?

「NNPropagator」とは,Pythonで動く,機械学習研究者,特に初学者のための機械学習を簡単に行えるライブラリです(予定).ニューラルネットワークに特化したライブラリとなっております.

順伝搬ニューラルネットワーク,リカレントニューラルネットワーク,畳み込みニューラルネットワーク,深層ネットワークなど,様々なネットワークを簡単に実装することができます(予定).

そもそも,なぜ新しいニューラルネットワークライブラリを作ったのか,と疑問に思うかもしれません.現在では,有名な機械学習ライブラリとしてTensorFlow, Chainer, Caffe, DeepDream, 画風変換など,豊富な選択肢のライブラリがあります.これらのライブラリではダメなのでしょうか?

結論を言ってしまえば,上に挙げたライブラリで十分です.ですが,私が気になったのは次の点です.すなわち,「ライブラリに頼っているだけでは何の成長もしない」ということです.自らの手でプログラミングをして,試行錯誤の中で解決策を見つける,それが成長の糧となるのだと思います.

よって,「NNPropagator」では,次のことを目標にしています.

  • 機械学習の実装を学ぶのに適切な量のコードのみで構成
  • 実装を直感的に組み合わせることのできる構造
  • これに加えて,十分に実用的であること.

この目標のもとでライブラリを開発することにより,「後学者が実装を学びやすく,なおかつ実用に供する機械学習ライブラリ」が完成するのではないかと考えています.今回は,「NNPropagator」は開発途中であるので,「NNPropagator」の使用方法だけを説明していきたいと思います.開発が進み次第,コードや組み込み方法などを公開していく予定です.

「NNPropagator」を使ってみる!

注:これは開発中のライブラリですので,実装が変わる可能性があります.

まず,次のコードを見てください.

<br />
NNList = [ SimpleConnection(1,50),<br />
           SigmoidConnection(50),<br />
           SimpleConnection(50,1) ]<br />
NetWork = ForwardNN(NNList)<br />
NetWork.setLossFunc(&quot;Square Error&quot;)<br />
NetWork.setDataSet(xd,yd)<br />
NetWork.learn(threshold = 0.1)<br />

実はなんと,このコードだけで,入力層1,隠れ層50,出力層1の多層パーセプトロンの定義と学習が完了するのです!
これだけで,以下の式に基づいた関係式を(xd,yd)で定義された教師データにもとづいて,パラメータ (W_1) と (W_2) を学習する,と言ったプログラムを書いていることになります!ただしsig(x)はシグモイド関数です.
\begin{aligned}
y = W_2 sig( W_1 x )
\end{aligned}

チャートで表すと,次のようになっています.

testNN01

このように,簡単にニューラルネットワークを実装できます.実際にプログラムを実行して,学習したデータを視覚化したものがこちらです.

NNPropagater_test01

今回は,二次関数を「NNPropagator」に学習してもらいました.上図の緑が学習元データ系列で,青線が学習した関数です.見事に学習できていますね.

今回の「NNPropagator」の紹介は以上ですが,開発を進め次第どんどん情報を公開したいと思います.

さらに,この「NNPropagator」を2016年度KCS「AI講習会」で使用しようと考えています.お楽しみに!

 

 

「NNPropagator」サポート予定のネットワーク(太字は実装済み2016/3/31更新)

・ネットワーク:順伝搬ニューラルネットワークリカレントニューラルネットワーク

・順伝搬NN に使えるNN:全結合層畳み込み層Pooling層,Batch Normalization層,活性化層(Sigmoid,Tanh,MaxOut,ReLU

・リカレントNN に使えるNN 自己結合層,LSTM,GRU

・最適化アルゴリズム Grad(通常),AdaGradRMSProp,Adam

・誤差関数 交差エントロピー,最小二乗

・たくさんつなげることで,深層NNに対応.

顔特徴認識システムを開発中です.

顔特徴認識システムVer 0.0.0の処理結果画像です.

失敗している点もありますが,おおよそ特徴点が認識できています.(下画像)

Face Rec. System created by UMU

●画像の認識結果は,左上のみ訓練データで,その他はテストデータ(訓練用データに含まれない)の認識結果です(画像はランダムに選んでいます).目,鼻,口などの位置に(おおよそ)正しく緑点が配置されています.上段中の画像では眉毛の認識に失敗していますね.

現在開発中の顔特徴認識システムでは,顔領域画像のみから,目,鼻,口,眉毛などの位置を認識することが可能です.認識速度は,Ver 0.0.0において1000FPS(1秒間に1000枚の認識が可能)となっています.

詳細を知りたい場合はコンタクト

・今後の展望

開発停止中の諭吉ブレンダーと合わせて顔を諭吉にする案.

ARに使う案.

Face Rigの無料版を作る案

など

(参考文献:多いので省略します)

モンティ・ホール問題を解く


モンティ・ホール問題を確率の議論を使って,解いてみましょう.
次の確率変数を定義します.
\[x_1:ドアX(X=A,B,C)に新車がある確率変数\]
\[x_2:ドアX(X=A,B,C)をプレイヤーが選ぶ確率変数\]
\[x_3:ドアX(X=A,B,C)を司会者が選ぶ確率変数\]
モンティホール問題で解かなければならないのは,次式
\[\sum_{x_1=x_2}P(x_1|x_2,x_3),\sum_{x_1\neq x_2}P(x_1|x_2,x_3)\]
の大小であるといえます.言葉で説明すると,
左は,プレイヤーが選んでいたドアをそのまま選ぶときに新車を手に入れる確率であり,
右は,プレイヤーが選んでいたドアではないドアを選ぶときに新車を手に入れる確率です.
これを解くためには,条件付き分布
\[P(x_1|x_2,x_3)\]
の大きさの比がわかればよいです.
ここで
\[P(x_1|x_2,x_3)\propto^{ベイズ} P(x_3|x_2,x_1)P(x_1|x_2)\propto^{ベイズ} P(x_3|x_2,x_1)P(x_2|x_1)P(x_1)\]
\[\propto^{条件付き独立} P(x_3|x_2,x_1)P(x_2)P(x_1)\propto^{定数} P(x_3|x_2,x_1)\]
が成り立つので,結局,\(P(x_3|x_2,x_1)\)がわかればよいということになりますね.
ここで,\(P(x_3|x_2,x_1)\)を書き下すと,
\[x_1=x_3で0,x_2=x_3で0,それ以外でx_2=x_1で1/2,x_2\neq  x_1で1\]
が成り立つので,結局,
\[\sum_{x_1=x_2}P(x_1|x_2,x_3):\sum_{x_1\neq x_2}P(x_1|x_2,x_3)=1/2\times 6:1\times 6=1:2\]
となり,プレイヤーが選んでいたドアではないドアを選ぶときに新車を手に入れる確率のほうが,プレイヤーが選んでいたドアをそのまま選ぶときに新車を手に入れる確率の2倍であることが示せました.
数式で扱うとモンティ・ホール問題も簡単に解けますね.

以上.

RFを実装した

figure_1

▲いいかんじに回帰できてますね.

figure_2

▲一つだけだと外れ値によって間違えているところがあっても

▼頑健に推定できることがわかる.

figure_3

・思ったこと

木の最大階層パラメータ,木の数,識別関数の個数,は人間が決めているが,

変な数値にするとうまく回帰できない(闇)

以上.

これから機械学習を勉強する人のためのpython install memo

*python install on cygwin (windows)

launch cygwin installer, select Python.

*python install(3.x) on windows

install from installer(www.python.org/downloads)

launch cmd.(INST=installed directory contains ‘python.exe’)

INST>python -m ensurepip

INST>python -m pip install numpy

INST>python -m pip install Pillow

INST>python -m pip install matplotlib