頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


TensorFlow、MPS、SceneKitで強化学習

強化学習で倒立振子をやってみようとした。いわゆるDQNってやつ。
学習にはTensorFlow。
振り子の描画にはMacアプリのSceneKit。振り子の動きはSceneKitの物理演算を使う。振り子を動かす時にNNの出力が必要なのでTensorFlowが学習させた後の係数をMacアプリ側でもらって、Metal Performance Shaderを使うようにしてる。
MacアプリでTensorFlow使って学習させる方法が不明なのでMacアプリと同時にPythonを実行させておき、進行状況を示すファイルを双方で監視し、処理を行ったり来たりするようにしてる。

物理エンジンを使う状況で強化学習をやりたかったのでこんなややこしいことになってる。
面倒だけど他に方法が思いつかなかったので、、、まあ素直に機械学習のライブラリもある(らしい)Unity使えばよかったのかな、知らんけど。
WWDC2018でmacOSでCreate MLなる新フレームワークで学習ができるようになったけど、今回の用途には使えなさそう。

ともかくこんな感じで倒立振子に挑戦したんだが、、、これが予想外に難易度高かった。

倒立振子で学ぶ DQN (Deep Q Network)
↑これ見たら簡単にできそうな気がするけど、実際はとんでもなく難易度が高かった。

いくつかツイートで動画をあげてたけど、、、




とまあ結局挫折しました。
ここまでいろいろとやりましたよ、、、
・層を増やす
・損失関数にHuber関数を使う
・(総報酬の高かった)エピソードを記録しといて学習に使う(Experience Replay)
・報酬のクリッピング
などいろいろと試行錯誤したんだけどダメでした。

他にもやったことがあるのでまた別記事で。







コストコのクロスバイクを調整してもらった

コストコでクロスバイクを買った
↑この続き。
買ってから1ヶ月も経たないうちに、というか最初からイオンバイクで調整してもらったものの重いギアあたりでカチカチと音がしてた(前で当たってるわけでもないのに)。
それはそんなもんなのかなあ?程度に思ってたが、だんだん調子が悪くなってきて、5段目に入れようとしたら飛んでしまったり、入らなかったり(で、忘れた頃に入ったり、戻ったり)とか、まあ意図通りにギアが変わってくれなくなった。
ホント自転車に乗るのが楽しくなくなってしまい、「そう言えばコストコって返品できるんだよなあ?」とか考えたりもしてた。

買ってすぐに調整してもらったイオンバイクとは別なところでみてもらおうと思い、ラビットストリートというロードバイクなどを扱ってる専門店に持ち込んで調整してもらった(事前に他店で買った自転車でもOKとのことだったので)。

担当してくれたスタッフさんの話だと、フレームとハンガーの接続部分で歪みがある、とのこと。じゃあ不良品?自転車をメーカに送り返すのか?そんなのできるんかな?とか考えてたが、こういうのは「よくあること」らしい。そのずれをチェック・修正する工具もありそれを使ってどれだけずれてるのかを見せてくれ、えいやと力で修正してた。

その自転車屋を出ていざ乗ってみると、、、今までのカチカチするような音はなくなり、超絶静か!ギアも完全に意図通りに変えることができるようになった!今までのストレスが嘘のように自転車に乗るのが楽しくなった。餅は餅屋ってとこやねえ。
ありがとう、ラビットストリート!!!
ちなみに今回の調整代はリア側だけなので税別1,500円でした。

これで体作って来年は淡路島1周(アワイチ)に挑戦するか!って気になってきた。


※参考
とっても怖いディレイラーハンガーの曲がりについて | Fertile-soil
rabbitstreet | ロードバイク・スポーツバイク専門店 Rabbit Street ラビットストリート
2018年 淡路島ロングライド150公式WEBサイト


Metal Performance Shaderで同期処理っぽく記述する

機械学習などでMetal Performance Shaderを使ってNNの計算をする時、GPUに渡してそれが終わったら結果が得られるようになるって流れなので、コードの見通しが悪くなる。

a = [self inference:s];

ってな感じで記述できればいいんだけど、実際は

[self inference:s];

ってしといて結果が出た後の処理は別なところに書かないといけない↓
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
    //続きはこんなところ!
}];
なんとかならないのかなあと思ったらsemaphoreなる仕組みがある。

Objective-Cで非同期処理を同期処理にする方法。 | 三度の飯とエレクトロン

↑これを参考にてコードを書き直してみたところ、、、

a = [self inference:s];

という感じの記述ができて意図通り動いた!
計算に時間がかかるとまずい場合もあるかもしれないが、今やってることに対しては計算時間も短く問題なさそう。


コードはざっくりこんな感じ。勝手な構造体なんかは気にしないで。
-(MPSResult_t)inferenceForInputs:(Inputs_t)inputs
{
    __block MPSResult_t mpsResult;

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        
        [self->srcImage.texture replaceRegion:self->srcImageRegion
                            mipmapLevel:0
                                  slice:0
                                    withBytes:self->angles
                            bytesPerRow:sizeof(float)*4
                          bytesPerImage:0];
        
        @autoreleasepool{
            id <MTLCommandBuffer> commandBuffer = [self->commandQueue commandBuffer];
            
            [self->h1 encodeToCommandBuffer:commandBuffer sourceImage:self->srcImage destinationImage:self->h1Image];
            [self->h2 encodeToCommandBuffer:commandBuffer sourceImage:self->h1Image destinationImage:self->finalImage];
            
            [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
                
                [self->finalImage.texture getBytes:&self->qResults[0]
                                 bytesPerRow:sizeof(float)*4
                                        fromRegion:self->filnalImageRegion
                                 mipmapLevel:0];
                
                mpsResult.q0 = self->qResults[0];
                mpsResult.q1 = self->qResults[1];
                
                dispatch_semaphore_signal(semaphore);//止めてたのを終える
                
            }];
            
            [commandBuffer commit];
        }
    });
    
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//これで止める
    
    return mpsResult;//結果が出てからリターンする
}



コストコでクロスバイクを買った

コストコのクロスバイクってどうなのよ?というのは専門家でもなんでもないのでよくわからない。
ただ、ロードバイク・クロスバイクを売ってるような専門店にある自転車からすると、、、とにかく安い。

コストコのクロスバイク(eisan)

↑税込で19,980円だった。3x7段変速。なかなかかっこいいんじゃね?!
一度決心して買いに行ったら売り切れだったんだが、1週間後くらいに電話で在庫確認したら「ある」とのことですぐに行き買うことができた。コストコの店員さん、ありがとう!

車に入れた自転車

↑コストコは配達してくれないので車に詰め込んで、近所の自転車屋(イオンバイク)で防犯登録(600円)と初期セッティング(1,620円)をしてもらった。
しかし、どういうわけか一番重いギアに入らない。よく見ると手元にあるギアを示す1から7の数字と実際のが合っていない。手元が7だと6段目に入り、手元が1だと1より低い側、それこそ”0”あたりへ行こうとする。
他店で買った自転車だから嫌がらせされたんだろうか?
すぐにお店に戻って言うと別な人が調整してくれたんだが、ディレイラーにある二つの調整用ネジをいじって対応してた。

リアディレイラーの調整用ネジ

↑ワイヤーとかいじらんでええんか?ネジがえらい飛び出てるで?

まあ、とりあえず1から7速まで入るようにはなった。


乗ってみて気になったことをいくつか。

フロントの方はギアは3枚だけど、手元での変速は何段か知らないけど細かく動かすことができる。そんなこともあって、例えば1速で漕ぎ始めたころには静かでもギアを上げて行くとどこかでフロントディレイラーとチェーンがカチカチと当たって音がすることがある。フロント側を調整すると静かになるんだけど、、、地味にめんどくさい。しかもフロント(左手)ってどっちに回転させればどうなるのかまだ慣れてない。

スタンドが最初から付いてるのはありがたいんだけど、スタンドの出っ張ったとこに左足のかかとが引っかかることが時々ある。スタンドを買い換えたいくらい。

乗り心地は、、、比べるものがないけどママチャリよりは路面の凸凹を拾う感じがする。走りやすい道路とそうでない道路の好みができる。近所にサイクリングロードがあればなあとか思う。

「弱虫ペダル」にもあったけど、サドルの高さはちゃんと合わせよう。楽しさ倍増する。
買って後悔はない、今のところ。



↑なお、仏式の空気入れはAmazonで購入。仏式って初めてだったが、ちゃんとこれで空気を入れることはできてる。なお最大空気圧はタイヤに書いてた。







Macで一太郎のjtdファイルを見る

町内会関連で引き継いだUSBメモリ内に拡張子がjtdのファイルがあってなんだ?と思ったら一太郎のファイルらしい。
なんとかMacで見られないものか(編集はできなくてもいいから)と調べるとこんな記事が↓

Mac上でWindowsのアプリを動かしてみよう!(Boot Campは使いたくない人必見!) | アップル大好きmaroのブログ

これを参考にPlay on Macをダウンロード(妙に時間がかかった)。
XQuartzもインストール。他にもいろいろあったが指示通り。
一太郎ビューアも公式からダウンロード。

すんなりとインストールできたわけじゃないけど、もがいてたらやっと起動した。

Play on Mac
↑ここで一太郎ビューア2014を選択し、実行すると、、、

Wineエクスプローラ

↑Wine エクスプローラなるものが起動し、目当てのjtdファイルを選択すれば見ることができた!



(備考)
High Sierra 10.13.4
Play on Mac 4.2.12
一太郎ビューア 24.0.1.0




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad