OpenAI Gym を動かしてみた
OpenAI Gym
OpenAI Gymとは,公式サイトにも"A toolkit for developing and comparing reinforcement learning algorithms.“とあるように,主に強化学習を開発,比較検討するのに使える環境が集まったサイトです.
まずは,チュートリアルを進めてみます.以下のサイトが公式のドキュメントになっています.
上のサイトに従っていけばできますが,一応作業履歴ということでここに書いておきます. こちらのバージョンはPython3.5,anaconda3-4.0.0環境を使っています.
1. OpenGym AIのインストール
pip install gym
が一番簡単でした.
2. 環境を動かしてみる
import gym env = gym.make('CartPole-v0') for episode in range(20): observation = env.reset() for t in range(100): env.render() print(observation) action = env.action_space.sample() observation, reward, done, info = env.step(action) if done: print("finished after {} timestamps".format(t+1)) break
を実行すると,倒立振子が出てきて,20エピソード分実行され,描画されます.
3. Q学習で強化学習してみる
ここからは上のページにない内容ですが,せっかくなので強化学習を試してみます.
https://gym.openai.com/algorithms/alg_0eUHoAktRVWWM7ZoDBWQ9w
上に,どなたかが実装してくださったQ学習のコードが載っています. これをコピペして,Python3用に一部修正し(xrangeやprint)実行します. (私の環境ではenv.monitorがうまく動かなかったので(きちんと調査してはいませんが)env.monitor周りはコメントアウトして,その代わりに毎ループでenv.render()を実行しました.これにより倒立振子が学習されている様子を知ることができます)
うまく動くと,徐々にうまくなっていくことが確認できます.
4. 少し変更
先ほどコピペしたコードを,次を目標に一部変更します.
- 毎回の学習の様子をみる必要はないので,何回かに1回のみにする
- 学習の結果をみるテストメソッドを追加する(学習は行われず,greedyに行われる)
これを追加したコードが次になります.
まとめ
気づいた点をまとめておきます.
- CartPole-v0は200フレームで強制的にdoneになる(うまくいっても行かなくても)
- それ以上経ってからはactionの指示が効かない
- 連続空間でもQ学習は有効であることがわかった
- 連続空間では状態数が多くなりがちなので,離散化が粗すぎても細かすぎても適していないイメージだったが,すんなりと学習できた(学習タスクにもよると考えられる)
今回はせっかくQ学習までやったので,次回は流行りのDQNを試してみたいと思います(と書いていますが実はもう試してあるのでそれをまとめる時間があれば…)
それと
今後,自身がどんなことをやっているきたかの日記としての活用を考えていて,新規性のないやってみたレポートが増えそうな気がしています. 新規性がありそうなものはQiitaにもアップしたいと思っています(がそんなに新規性のある記事がポンポン浮かぶわけでもない)
AnalogDiscovery2を使ってみた
はじめに
PC接続の全部入り計測器,AnalogDiscovery2を使ってみました.
購入はDigilentから行いました.学生だと学割でだいぶ安くなります.送料が5000円近くするのが難点ですが,2万5000円程度でした.
秋月よりかは安くなった.
中身はこちら。
— tellusium (@tellusium) 2016年7月20日
学割+送料で
\17000 + \5000 = \22000くらい。 pic.twitter.com/mVSlUdnEUW
ツイート見ればわかりますが,買ったのが2016/7なので,半年以上眠らせてたことになります(電子回路を扱う機会がなかったのだ…)
I2C信号を観測する
I2C通信を扱う機会があり,久しぶりの電子回路なのとAnalogDiscoveryの存在を思い出し,信号を観測してみることにしました.
細かい回路は省略で.
実際に通信がうまく行かない現象に遭遇し,その原因究明にも使えました.
(原因はArduino内部でのプルアップと外付けプルアップの両方使ってしまっていたことでした)
以下はアドレス0x04に0を送った後,4バイトのデータを受け取った時の信号です.はじめに0x04すなわち0b00001000が送られていることが確認できます.
I2Cの波形を観測してみた
— tellusium (@tellusium) 2017年2月27日
これでAddr=0x04に"0"を送った後,[73, 73, 173, 129]の4byteが通信されている pic.twitter.com/3KXBuLOgMP
と書いたのですが,3つ目の173が怪しいですね…173 = 0x10101101なので,0が一つ足りないような.SCLも観測しておくべきだった…
はてなブログのテーマでレスポンシブが機能しなかった
前の記事に書いたように,レスポンシブなテーマをカスタマイズしていたところ,iPhone5Sでの表示が崩れる問題に遭遇しました.
TL;DR
MINIMというテーマで,レスポンシブにするための記述がiPhone5Sに対応していなかった.
iPhone5Sは横幅360pxなんだけど,何故かテーマではmin-width: 362pxが指定されていて,レスポンシブ指定から外れていた
— tellusium (@tellusium) 2017年3月9日
まずはテーマのバニラ状態で崩れるか確認する
MINIMのサンプルサイトをiPhone5Sで表示させてみたところ,崩れることが確認できました.
PCのブラウザの幅を狭くしてみても,同様の現象が確認できました.
しかも幅を狭くしすぎると崩れることが確認できます.
正常
異常(横にもスクロールできてしまう)
どうやら幅が狭くなりすぎると起こる現象なので,CSSを確認してみます.
CSSの確認
デザインCSSでimportしているリンクへ飛ぶと,CSSの中身が確認できます.
レスポンシブ対応を行なっている部分は@media以降の部分なので,それを探します.
見つかりました.一番下にありました.
@media (max-width: 960px) and (min-width: 362px) {
#content {
margin: 0 auto;
width: 100%;
}
...
あれ…min-widthが362pxになっている…iPhone5Sの横幅は360pxなのに…
はい,これで原因がわかりました.
解決方法
元のCSSを変えるのはできないので,一番手っ取り早い方法として,レスポンシブ対応の部分を丸々デザインCSSにコピペしてきて,min-widthの書式を消去しました.
これでどんなに小さい端末で見てもレスポンシブになるはずです.
余談
なぜmin-width: 362pxにしてあったのかが疑問です.
私はCSS入門者なのでmin-widthを指定する意味がわからないのですが,一定以下に小さくなると,表示が崩れるのでサポート外とする,といった理由でしょうか?
いずれにせよ,360pxという横幅のスマートフォンは少ないはずなので,今現在のほとんどの端末では正しく表示されそうではありますね.
ブログテーマをカスタマイズしてみた
せっかくなので,ブログのデザインをカスタマイズしてみました.
その手順などを簡単にまとめたいと思います.
1. 元のテーマを決める
最初から各パーツのデザインを全て決めるのは難しいので,あるテーマを元に,それをカスタマイズするという方法をとりました.はてなブログのテーマは,次のページにまとまっています.
この中から,自分のイメージに一番近いテーマを選びます.今回私は
を選択しました.
2. CSSの追加
設定 -> デザイン -> カスタマイズ -> デザインCSS から,CSSを追記できます.
この作業については下のサイトなどが参考になりました.
自分のいじりたい要素を探すのには,Chromeのデベロッパーツールなどを使いましたが,少々面倒でした.後になって見つけたのですが,次のサイトにどの要素がどのような名前かがまとまっているので,参考になりそうです.
3. フォントを変える
せっかくここまでカスタマイズしたんですから,フォントもデフォルトでなくカッコ良いものに変えちゃいましょう.
私は次の2つのサービスを使いました.
このブログでは,タイトルにLato,本文にUD新ゴ,見出しにM+を使っています.
(3/16追記:見出しもUD新ゴになりました)
設定方法などは,次のサイトが参考になりました.
おまけ
自分のCSS構成例を置いておきます.基本的には,フォントと色の設定ですね.
最後の@media以下については,iPhone5Sへのレスポンシブ対応のためで,詳細はそのうちまとめる予定です.
/* */
@import "http://hatenablog.com/theme/10328749687194646740.css";
/* */
/* Responsive: yes */
#globalheader-container {
color: #333;
background: #fff;
}
body {
background-color: #fff;
font-family: "UD Shin Go Light";
letter-spacing: 1px;
}
#title {
font-family: "lato",sans-serif;
font-style: normal;
font-weight: 200;
}
.entry {
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,.15);
transition: box-shadow 0.2s;
}
.entry:hover {
box-shadow: 0 0 20px rgba(0,0,0,.15);
}
.hatena-module {
border-radius: 10px;
transition: box-shadow 0.2s;
}
.hatena-module:hover {
box-shadow: 0 0 20px rgba(0,0,0,.1);
}
h1, h2, h3, h4 {
font-weight: normal;
}
a,
a:link,
a:visited,
a span {
color: #660066;
font-style:normal;
text-decoration:none;
}
a:hover,
a:active {
color:#CC00CC;
text-decoration:none;
}
@media (max-width: 960px) {
#content {
margin: 0 auto;
width: 100%;
}
#main {
margin: 0 auto;
max-width: 100%;
width: 100%;
}
#main-inner {
max-width: 95%;
margin: 0 auto;
}
.pager {
margin-left: 10px;
}
#box2 {
max-width: 100%;
width: 100%;
display: block;
}
#box2::after {
content: "";
display: block;
clear: both;
}
#box2-inner {
margin: 0 auto;
width: 95%;
}
}