はてなブログで数式を書く時の疑問点
[tex: e^{i\pi} + 1 = 0]
とかくと,
と表示されます.
また,冒頭に
<p style="display: none;">[tex: ]</p>
と書いておけば,
\begin{align} e^{i\pi} + 1 = 0 \end{align}
と書いても
\begin{align}
e^{i\pi} + 1 = 0
\end{align}
と表示されます.
ですが,
[tex: \sigma]
は,
となりますが,
\begin{align} \sigma \end{align}
は,
\begin{align}
\sigma
\end{align}
となります.
なんで?
\begin{align} \delta \end{align}
は,
\begin{align}
\delta
\end{align}
なのに.
論文:Reward function and initial values : Better choices for accelerated Goal-directed Reinforcement Learning
hal.archives-ouvertes.fr
強化学習において,報酬と初期値の決め方大事だよね,という話.
2値報酬&一様初期値の場合
ゴール状態の報酬が,それ以外の報酬がのとき,もしであれば,
\begin{align} \forall s \forall a Q^*(s,a) = Q_\infty = \frac{r_\infty}{1-\gamma} \end{align}
となりますが,これはでも,が十分遠ければ成り立ちます.
このとき,だと学習できませんよね,とここまでは当たり前の話.
次に学習時ですが,Q値の更新式は,初期値をとすると,
\begin{array}
Q Q\left(s,a\right) &\leftarrow& Q_i + \alpha[r_\infty + (\gamma - 1)Q_i]\\ &\leftarrow& Q_i + \alpha(1-\gamma)(Q_\infty - Q_i)
\end{array}
と書け,ここから,
- なら,未訪状態を探索しやすくなり,学習初期の探索が進みやすい
- だと,探索済みの状態を選びやすいため学習が進みにくく避けた方が良い
ということが分かります.
言われてみれば確かにな,という感じなのですが,特に各状態で得られる報酬のばらつきが大きく,事前にその予測が難しい場合に,になっていないかということは,あまり今まで気にしていなかったので勉強になりました.
実験では,Gridworldにおいて,としたときに,とするよりもとした方が,学習初期の成績が良いよ,ということを言っているのですが,当然前記設定だと,いつまでも探索を続けることになり,学習後期のスコアはのときの方が断然よく,う~んという感じ.
連続値報酬&非一様初期値の場合
Progress estimatorという考え方が提案されていて,例えばGridworldのケースでは,状態との距離をとしたときに,
\begin{align}
r(s, a, s') = -d^2(s', s_g)
\end{align}
とする方法が提案されていますが,これは袋小路から抜け出せなくなりやすいため良くない,代わりに
とするのが良いと提案しています,が正直う~ん.
このケースではそりゃ良くなるでしょうけど,どの程度一般化できるのか疑問なのと,そもそもこんな風に適切な報酬を設定できるケースが現実の問題においてどのくらいあるのでしょう.
初期値の与え方についても同様に,Goal biasと称して
を提案していますが,上記と同じ疑問が残ります.
なんか誤読しているのでしょうか...
scikit-learnのStratifiedKFoldの結果が0.19とそれ以前で変わる件
scikit-learnのStratifiedKFoldが0.18.2から0.19.0への変更で、実行結果が異なるようになりました。
それも、shuffle=Trueとしたときだけです。
StratifiedKFoldは識別の際にラベルの数の偏りを考慮した分割をするため有用ですが、
このことを覚えておいた方がよさそうです。
0.18.1 | 0.18.2 | 0.19.0 | |
---|---|---|---|
KFold | 0.96 | 0.96 | 0.96 |
KFold(shuffle) | 0.9533333 | 0.9533333 | 0.9533333 |
cross_val_score | 0.9599673 | 0.9599673 | 0.9599673 |
StratifiedKFold | 0.9599673 | 0.9599673 | 0.9599673 |
StratifiedKFold(shuffle) | 0.9603758 | 0.9603758 | 0.9665033 |
検証用コードはこちら
from sklearn.utils import shuffle from sklearn.datasets import load_iris from sklearn.svm import LinearSVC from sklearn.model_selection import cross_val_score from sklearn.model_selection import KFold, StratifiedKFold iris = load_iris() X, y = shuffle(iris.data, iris.target, random_state=0) clf = LinearSVC(random_state=0) score = cross_val_score(clf, X, y, cv=KFold()).mean() print('KFold: {s}'.format(s=score)) score = cross_val_score(clf, X, y, cv=KFold(shuffle=True, random_state=0)).mean() print('KFold (shuffle): {s}'.format(s=score)) score = cross_val_score(clf, X, y).mean() print('cross_val_score: {s}'.format(s=score)) score = cross_val_score(clf, X, y, cv=StratifiedKFold()).mean() print('StratifiedKFold: {s}'.format(s=score)) score = cross_val_score(clf, X, y, cv=StratifiedKFold(shuffle=True, random_state=0)).mean() print('StratifiedKFold (shuffle): {s}'.format(s=score))
論文:Simple Nearest Neighbor Policy Method for Continuous Control Tasks
サマリー
ICLR 2018に投稿されてdouble-bline review中の論文。
Nearest Neighbor Policy Method
強化学習に最近傍法を適用した、パラメータ推定が不要な2種類の手法を提案
定式化
- :トラジェクトリ(状態、行動、報酬の系列)の集合
- :全トラジェクトリ集合のうちバッファに保存されるもの
- :初期状態
- :距離関数
- :報酬の閾値
NN-1
- エピソード開始時に、初期状態の最近傍となるトラジェクトリをバッファから探す
- 得られたトラジェクトリの行動にノイズを加えたものを行動とする
- テスト時にはノイズを付与しない
- エピソード終了時、得られた報酬の和が閾値を超えていたら、そのトラジェクトリをバッファに加える
NN-2
- NN-1と異なり、時刻tの状態と行動と累積報酬和のタプルを保存する
- 各状態で最近傍のタプルを検索し行動を決める
- NN-1同様、行動にはノイズを付与し、テスト時には付与しない
- エピソード終了時、得られた報酬の和が閾値を超えていたら、すべてのタプルをバッファに加える
Trainable NN Plicy
本論文の趣旨とは異なるが、提案手法は、距離関数と閾値を学習させる余地がある。
Experiment Settings
Environments
- タスクはSparse Reachre、Sparse Half-Cheetah、Sparse Cartpole Swingup、Sparse Double Pendulum、Sparse Mountain Car
- Sparseとは、報酬を、成功したときだけ1とし、それ以外は0にするということ。タスクを難しくしている。
Evaluation Metrics
Results and Analysis
Performances of the NN-1 and NN-2 Policies
- Sparse Mountain Carは全然ダメだった。これはタスクが難しいと考えられる
- Sparse ReacherとSparse Double PendulumはNN-1,2ともに成功率9割を超えた。Sparse Cart PoleはNN-2でframe skip=4にしたら成功率ほぼ100%になった。難しいといわれるSparse Half CheetahもNN-1,2ともに成功率70%を超えた。
Perceived Quality of the Nearest Neighbor Policies
- 最適化ありの手法では、行動の自然さを制約に加えることができるが、提案手法では難しい。そのためタスクは達成できてもおかしな挙動をする場合がある
- 最適化ありの手法で、行動のノルムを明示的に正則項として加えた場合と比較すると、提案手法は行動のノルムが大きい(ただし比較対象はスパースではない報酬系)
- 行動の自然さを明示的に制約に加えない場合、最適化ありの手法でも提案手法でも、行動のノルムの大きさは大して変わらない
強化学習の教科書はSuttonの本や、「これからの強化学習」、「速習 強化学習」が有名ですが、私はこちらがお薦めです。説明が理解しやすく、サンプルコードはOctaveですが、別言語への再実装も容易だと思います。
「ゼロから作るDeep Learning」を読んだ
評判に違わずとても良い本でした。
副題に「Pythonで学ぶディープラーニングの理論と実装」とあるように実装を重視しており、単純パーセプトロンから多層パーセプトロン、畳み込みニューラルネットワークまで、丁寧な解説で実装方法を理解することができます。
本書の特徴の一つは、ニューラルネットワークの学習方法である誤差逆伝搬法を、一般的な合成関数の微分の連鎖律として数式ベースで説明するのではなく、「計算グラフ」という考え方で説明している点だと思います。
計算グラフは、下図のように計算の過程をノードとエッジで表したものです。詳細は本を読んでいただきたいのですが、計算グラフを用いることで、誤差逆伝搬法の仕組みとその実装イメージを理解しやすくなっています。
その他にも本書では、ソフトマックス関数実装時のオーバーフロー対策、重みの初期値はどうするのが良いか、CNNのプーリングのウィンドウサイズとストライドは同じ値にするのが一般的、など理論だけでなく、実装し使う上で役に立つ情報が満載です。
ただ、後半のディープラーニングの話にいくほど、紙面上での実装の説明は少なくなっていくので、Githubにあるソースコードを追う必要があります。欲を言えば、その分コードのコメントをもう少し充実させてほしいと思うかもしれません。
少し気になったのは、4章で、従来の機械学習は、人の考えた特徴量(SIFTやHOGなど)をSVMなどの入力としていたのに対し、ディープラーニングでは人の特徴量設計が不要で、人のアイディアが介在しない、という記述があることです。
画像認識の場合、SIFTやHOGのような特徴量を用いずに、ピクセルの値をそのまま入力として、従来に比べて高い精度を達成できたというのは事実ですが、それをもって、ディープラーニングが「特徴量の生成が不要」、「人のアイディアが介在しない」と言ってしまうのは適切ではない、ということも既に色々なところで言われていることであり、本書を読んだ初学者がそのような認識をもってしまわないか心配です。
もう1点、6章で過学習について述べており、過学習対策をしなかった場合、訓練データに対する認識精度はほぼ100%なのに対し、テストデータの認識精度は隔たりがある(70%強)が、Weidht decayを用いることで、訓練データの認識精度が100%にならず、テストデータの認識精度との隔たりが小さくなったと言っています。しかし、このときのテストデータの認識精度をみると70%強で、過学習対策をしなかったときとほとんど変わりません。
これでは、なぜ過学習がいけないのか、が十分に伝わらないのではないでしょうか。
とは言っても、自分でいろいろパラメータをいじってみると分かるのですが、本書で例題として取り上げているMNISTという手書き数字認識問題は、問題が簡単すぎて「過学習してしまうことにより、テストデータに対する認識精度が悪化してしまう」状態を作り出すのが難しいという問題があります。
と細かな点を挙げましたが、本書はディープラーニングの基礎を実装できるレベルで理解したい方に最適だと思います。
軽量ノートPC LG gramのメモリ増強
長いこと持ち運び用のノートPC(1kg以下)を探していたのですが,気がついたらAmazonでLGのgramが安くなっていたので買ってしまいました.
このPCはメモリ4GBということで購入を躊躇していたのですが,以下の記事をみるとメモリの積み増しができそうだということで,メモリ(8GB)も合わせて購入.
togetter.com
結果としてメモリ増設上手くいきましたので,他の人の参考になればと思い分解,メモリ増設の記録を共有します.
(当然ですが作業は自己責任でお願いします)
こちらが購入品です.
早速裏面を開けます.使うものはマイナスの精密ドライバー.最初もう少し大きい普通のドライバーを使おうとしたところ,上手くいかず塗装が少し剥げてしまったので,慌てて100円ショップに行って精密ドライバーを購入しました.
精密ドライバーを使って滑り止めのゴムを外していきます.奥まで差し込んでほじくるようにするとボロンと外れます.ゴムの裏面は糊のようなものでベタついているので,元に戻せば再びくっついてくれそうです.
四隅ではなく中央部のゴムも同様に外します.
5箇所の滑り止めのゴムを外したら,次は3箇所ある目隠しシールを剥がします.ここはマイナスドライバーではなく,カッターナイフを使うのが良いと思います.隙間にカッターの歯を少し潜らせると切れに剥がすことができると思います.
この目隠しシールもはがした後も粘着性が残っているので,綺麗に戻すことができました.
すべてのネジ穴が見えている状態です.
プラスドライバーでネジを外していきます.100円ショップで購入した精密ドライバーでは上手く外すことができず,ネジ山をバカにしてしまいそうだったため,手持ちのもう少し良さそうなプラスドライバーを利用しました.
すべてのネジを外したら,手前側から隙間にマイナスドライバーを差し込んで,少しずつ蓋を外していきます.何箇所かあるフックを外していく感じです.
ヒンジ側はこのように開きます.
蓋が開きました.中央部に空いているメモリスロットが見えます.
メモリスロットに拡大図です.
ここに,このメモリを増設します.
しました.切り欠きがあるので,特に悩むことはないと思います.
蓋を閉じるまでに起動してメモリが増えていることを確認します.
4GB+8GB=12GBになっていることが確認できました.
LG gramの13インチモデル,840gと軽量でメモリを増設しても10万円以下とコストパフォーマンス高いと思います.
皆様の参考になれば幸いです.