2017年1月22日日曜日

筑波サーキット ジムカーナ練習会に参加してきました!

フレに誘われ、折角FRのスポーツカーを買ったんだし!ということでジムカーナ練習会に参加してきました!

ジムカーナはサーキットと違って、駐車場みたいなアスファルトの平らな広場があって、そこに自分たちでカラーコーンを置いてコースを作りそこを走る感じです。
今回は練習会ということでタイム競い合ったり、出走順が決まってたりといったややこしいことは何もなく列に並んで順番にコースを走って楽しむという感じでした。
途中、初心者向けにコースを開放してくれてドリフトやサイドターンの練習をさせてもらえました。メチャメチャ楽しかった!

サーキットでドリフトっていうと危ない?とか車が壊れたりする?みたいな不安があったけど、参加してみたら全然そんなことはなくメチャメチャ安全でした。
なにしろコースはカラーコーン置いてるだけなのでコースアウトしても普通にアスファルト上だし、その広いエリアに1台で走るのでスピンして止まったりしても別の車とぶつかる心配もないしもちろん人も居ない。あと、ジムカーナは速いスピードで走るというよりは小回りをたくさんして加減速、ターンをたくさんする感じなので速度も時速100kmあたりが最速で、大体60キロあたりまでを加減速してることが多い。パイロンにぶつかっても写真みたいに踏んじゃうだけなんで大した事ないです。

スポーツカーが色々揃うのでお互い貸しあって乗り比べができたり、隣に乗せてもらって上手い人の運転見せてもらったりと本当に楽しかった!このRX-8はフレので乗せてもらったけどクラッチの重さとか全然違くてびっくりした。乗り味は似てる感じだったかな、タイヤもノーマルらしいのでそのあたりが一緒だったからかも。ただパワーはこっちの方があるように感じた。


86はやっぱり滑りやすい気がする、そういう味付けにしてるのかもしれないけどお陰ですげー楽しめました。あと電子制御系のON/OFFによる違いが体感できたのも良かった。車両安定システムであるVSCとかホイールスピンしないようにしてくれるTRCとか、全OFFで走るともう簡単にスピンするしぐるぐる回れる!楽しい!

というわけで、めちゃめちゃ楽しい一日でした。そして、腕が筋肉痛だ・・・

2017年1月8日日曜日

DeepLearningで手書き数字認識Windowsアプリを作ってみた

2016年はDeepLearningが研究レベルの何の役に立つのか分からないところから、ビジネスまでは行かないけど実際にこんなことできちゃうよ!っていう具体例が色々出てきたなぁという感じの年でした。

Googleのディープラーニング「AlphaGo」がプロ棋士に完勝 - ITmedia ニュース
個人的には、これがインパクト強かった。AIの時代来たかっ!って感じw

というわけで、かなり興味が出てきたので実際に学習した過程をメモがてら残しておく・・・

読んだ参考書とか


定番、オライリーのDeep Learning本

これが一番参考になりました。Pythonでサンプルが書かれてます。私も最初Pythonなんて使ったこと無くて、C#とかで書いてほしいなぁとか思ってたんだけど、実際読んでみたらパイソンの環境セットアップから基本的な言語仕様まで書かれてて、何の問題もなく読めるし書けるし試せる感じでした。


どうも、Deep Learning関連の研究者はPythonを好む人が多いみたいで、いろんなライブラリや学習データの整形なんかの処理がPythonで書かれてることが多いので、ここで一度軽く学んで環境を設定してみると良さそうな感じでした。


「よくわかる人工知能 最先端の人だけが知っているディープラーニングのひみつ」
こちらは、学習の参考というよりは完全に読み物として・・・

かなりドリーミーな話を含んだ内容になっていて読んでて面白かった。「さすがにねぇわ!」とか思いながらw

未来に夢描くもののイメージとか、最先端の人はこういう未来を考えてるのか~とかそういう感じで読ませてもらいました。

環境設定

Python Anaconda
まずはPythonのセットアップ。どうもこのアナコンダ?とかいうパッケージがDeepLearningで使うにはいいらしい。
Anaconda を利用した Python のインストール (Windows) – Python でデータサイエンス
言われるがままインストール。パス通してやればもうpythonってコマンドラインで打つと使えるようになります。
起動するとインタプリタモードで動くので試しに「1+3」とかやると「4」と返ってくるので、なるほどヨシヨシと・・・


CNTK(Microsoft Cognitive Toolkit)
Windowsアプリを作るんで、Windows環境と相性の良さそうなマイクロソフト製のライブラリを使います。
CNTK環境構築からMNISTサンプル実行まで (Windows環境, 2016/06/29時点) - Qiita
詳しいセットアップ手順はここを参考にさせてもらいました。
ライブラリがGPU版とCPU版があってもちろんGPU版の方が何倍も早いんだけど、CUDAとかのセットアップが必要なんで、とりあえずはCPU版でテストしました。
あとで、GPU版に置き換えましたが、すんなり置き換わりました。

ここに書いてある、コンソールでのテストまでは実行しておいてください。その過程で作られたバイナリを使うので・・・

VisualStudio C#
えっと、これはいいよね。普通にセットアップしてください。

cntkライブラリをC#から使う

VisualC#でWindowsフォームアプリ新規作成でまず作り
「ソリューションエクスプローラー」の「参照設定」を右クリックして「参照の追加」
「参照マネージャー」の「参照(B)」ボタンから、CNTKをインストールしたフォルダに有る「EvalWrapper.dll」を選択するとC#から使うためのクラス定義とかがインポートされます。

Form1.csの先頭に
using Microsoft.MSR.CNTK.Extensibility.Managed;
で、まず使いやすいように・・・

List outputs;
            using (var model = new IEvaluateModelManagedF()) //CNTKで評価するための基本オブジェクトかな?
            {
                //上のCNTKのコンソールテスト時に使った.cntkファイルを指定して初期化
                //下記コードはカレントディレクトリにファイル名をmodel.cntkに
                //リネームしてコピーしてあることを前提
                string config = File.ReadAllText(@"model.cntk"); 
                model.Init(config);

                //上のCNTKのコンソールテスト時学習で出力された学習済みネットワークバイナリファイルを指定
                //Output/Models/以下に吐き出された01_OneHidden とかの拡張子が無いファイルが出力結果になってる
                //下記コードはカレントディレクトリにファイル名をmodel(拡張子なし)に
                //リネームしてコピーしてあることを前提
                string modelFilePath = @"model";
                model.CreateNetwork(string.Format("deviceId=-1\nmodelPath=\"{0}\"", modelFilePath));

                //入力用のデータ 詳しくはGetInputs関数で解説
                Dictionary< string, List< float >> inputs = GetInputs();

                //セットアップした学習済みネットワークモデルで入力データを評価
                //結果がoutputs配列に0~9のそれぞれのスコアみたいな形で入る。一番大きな値が認識結果
                //「ol.z」とかは、model.cntkの定義に従うので別の定義の場合は別の文字列になる
                //「ol.z」はどうも「OutputNodes = (ol)」の時はこれでいいみたい
                //「outputNodes = (z)」の時は「z」みたいな感じ。
                outputs = model.Evaluate(inputs, "ol.z", 10);
            }

続いてGetInputs関数
var result = new Dictionary< string, List< float >>();
            //inputsの形式は Dictionary<ラベルID, 入力パラメータリスト> となってるみたい
            //cntkで指定してる「features」というラベルが入力データとなる
            result.Add("features", new List());
            var v = result["features"];

            //PictureBoxコンポーネントにマウスで自由に白で手書きできるようにしておいて、その結果を使う。
            var bitmap = (Bitmap)pictureBox1.Image;

            //IMAGE_SIZEはMNIST形式の28ピクセル
            //28x28だとあまりにも小さいのでSCALE_NUMを4として4倍の大きさの
            //PictureBoxコンポーネントに書いたものを平均化して使う
            for (int y = 0; y < IMAGE_SIZE; y++)
            {
                for (int x = 0; x < IMAGE_SIZE; x++)
                {
                    var param = 0.0f;
                    for (int xx = 0; xx < SCALE_NUM; xx++)
                    {
                        for (int yy = 0; yy < SCALE_NUM; yy++)
                        {
                            //白で描画してるのでRGBのどの値でもいい
                            param += bitmap.GetPixel(x * SCALE_NUM + xx, y * SCALE_NUM + yy).R;
                        }
                    }
                    param /= (SCALE_NUM * SCALE_NUM); //4x4の16ピクセルの合計値を平均化0~255の値に丸める
                    v.Add(((float)param));
                }
            }
            return result;
これでコアな部分の実装は完了。あとはどのタイミングで認識するかとか、手書き描画の線の太さをどうするかとかそのへんは各自お好みで・・・

実験結果

01_OneHidden
シンプルな1次元配列でのネットワークだと、認識率は5割ぐらいな印象。8とかまず認識しない。
02_Convolution
二次元畳み込み?のネットワークだと認識率は7割ぐらいのイメージ。7と9を良く誤認する。あと真ん中に書かないと結果が狂いやすい
03_ConvBatchNorm
これは、どうもGPUが必要みたいでCPUのだと未実装な関数みたいなエラーで止まってしまう。 グラボを買ってCUDAをインストールしてってやらないといけない。 結果はあまり印象としては変わらず7割ぐらい。ただ学習はメチャはや!100倍ぐらい早いかもしれん。さすがGPU
04_OneConvBN とかのGPU用
ここまでくるとかなり認識率が上がってくる印象。8割~9割ぐらい思った通りになる。 ただ、やっぱり7と9が誤認されやすい・・・ どうも7のサンプルデータの書き方で縦棒にチョンと横線いれる文化があるところの数字のサンプルが多いのか9の真ん中の横棒と混乱しやすくなってるのかも?このあたりからは実際に使う環境にあった学習データがあったほうが思い通りになりそうな感じだったな

まとめ

というわけで、DeepLearning使ってみたまとめレポートでした。アプリのバイナリ?いや、なんかライセンスとかどこまで配っていいのかわからないのでちと配布しづらいっす。cntkフォルダにある関連するDLLをがさごとコピーして学習済みネットワークデータとセットにすれば、とりあえずPythonもCNTKも環境の無いマシンでも動きました。
学習は時間掛かるけど、評価自体は結構早い。マウスMoveイベントごとに評価してリアルタイムに文字を書き換えを評価し続けるような作りをしても割りともたつくこと無く動きました。

2017年1月1日日曜日

初日の出@大洗 2017



というわけで、大洗まで初日の出見に行ってきました。
たまにはこういうイベントもいいものです・・が 冬の海辺とか予想はしてたが寒い!
スキー用のインナー来てマフラー、イヤーマフにサイクリング用手袋で準備してったんですが、それでも寒かった。
指先がやっぱり寒かったんで手袋はスキー用のでよかったかもしれん・・・

海岸沿いで大洗神社もあって普通に初日の出スポットみたいです。すごい人が集まってました。

神社の方もすごい参拝の列

神社の方はちゃんとガルパン聖地らしく、こんなものまで用意されてたw

そうこうしているうちにだんだん夜明けが近づいてきた。

初日の出ーーーー

キーーターーー
というわけで徹夜明けで変なテンションになって楽しんできました。
今年もいい年でありますように・・・