# 【苦しみながら理解するReinforcement Learning】チュートリアル その4-0

ようやく手を動かせそうなところに来た。

Reinforcement Learning with Tensorflowをやってく！

## 概要

Instead of starting with a complex and unwieldy deep neural network, we will begin by implementing a simple lookup-table version of the algorithm, and then show how to implement a neural-network equivalent using Tensorflow.

Unlike policy gradient methods, which attempt to learn functions which directly map an observation to an action, Q-Learning attempts to learn the value of being in a given state, and taking a specific action there.

うーん、Q-Learningとはなんだったか？

方策オフ型TD制御

方策オフ型：挙動を生成するために使われる挙動方策(behavior policy)と呼ばれる方策は、実際のところ、評価され改善される推定方策(estimation policy)と呼ばれる方策とは関連付けられていない。
TD制御：Temporal Difference Learning


ここで言いたかったのは、行動からマッピングする関数を学習する方策オン型とは異なり、Q-Learningは状態から価値を学習し、行動を取るということだったのだろう…

アタリのゲームもQ-Learningですよと。

このチュートリアルではOpenAI gymFrozenLakeを解く。

The FrozenLake environment consists of a 4×4 grid of blocks, each one either being the start block, the goal block, a safe frozen block, or a dangerous hole. The objective is to have an agent learn to navigate from the start to the goal without moving onto a hole.

In it’s simplest implementation, Q-Learning is a table of values for every state (row) and action (column) possible in the environment.

we have 16 possible states (one for each block), and 4 possible actions (the four directions of movement), giving us a 16×4 table of Q-values.

Bellman equationでテーブルをアップデートする。

これは、長期的な状態の価値と、直近の価値に次に最善の行動をとったときの価値を加えたものが等しいとしている。

この方法だとテーブル(Q-table)を将来の価値を予測するために再利用できる（どういう意味だ？）

This says that the Q-value for a given state (s) and action (a) should represent the current reward (r) plus the maximum discounted (γ) future reward expected according to our own table for the next state (s’) we would end up in.

The discount variable allows us to decide how important the possible future rewards are compared to the present reward.

## コード例

gymのdocumentationは見ておいた方がよいですね！
というか、gymってこうやって使えるの簡単…

env = gym.make('FrozenLake-v0')


もちろんその前にはpip install gymをしておきましょう！

FrozenLakeの説明も載せておきます！

The FrozenLake environment consists of a 4×4 grid of blocks, each one either being the start block, the goal block, a safe frozen block, or a dangerous hole. The objective is to have an agent learn to navigate from the start to the goal without moving onto a hole. At any given time the agent can choose to move either up, down, left, or right. The catch is that there is a wind which occasionally blows the agent onto a space they didn’t choose. As such, perfect performance every time is impossible, but learning to avoid the holes and reach the goal are certainly still doable. The reward at every step is 0, except for entering the goal, which provides a reward of 1. Thus, we will need an algorithm that learns long-term expected rewards. This is exactly what Q-Learning is designed to provide.

ここでenvは、env.observation_space.nenv.action_space.n
コンソールでやってみると、

> import gym
> env = gym.make('FrozenLake-v0')
> env.observation_space.n
#=> 16
> env.action_space.n
#=> 4


となるので、observation_spaceは状態の数、action_spaceは行動の数を返すんでしょう、おそらく。

なので、

Q = np.zeros([env.observation_space.n,env.action_space.n])


は、

Q = np.zeros([16,4])


となるので、16x4の二次元行列を作成しています。
パラメータは以下の通り

lr = .8　：Γ
y = .95　：yの初期値
num_episodes = 2000　：エピソードの数
rList = []　：報酬のlist

s = env.reset()　：はじめの状態に戻す（env.reset()すると0が入る）
rAll = 0　：バッチ内の報酬の合計
d = False　：完了したかどうか（doneの意味だと思う）
j = 0　：繰り返しのカウント（なぜ繰り返しは99回なのかはわからない...）


Qテーブル内からノイズを含めた（グリーディな）選択を行う。

a = np.argmax(Q[s,:] + np.random.randn(1, env.action_space.n)*(1./(i+1)))


これだと、エピソードのカウントが増える度にノイズ部分が小さくなるようにしている(1./(i+1))のは、徐々にグリーディでなくならせようとしているのか…な…？

ここで再度エピソードとステップをしっかり把握！

しかし、このやり方だとaが少数にならないかな？

numpyのargmaxは最も高かったindexを返すので、少数にはならないんだよ！

そして

s1,r,d,_ = env.step(a)


step関数がめちゃ便利。
step関数はactionを入れることで、以下の4つを返す。

* observation (object): an environment-specific object representing your observation of the environment. For example, pixel data from a camera, joint angles and joint velocities of a robot, or the board state in a board game.
* reward (float): amount of reward achieved by the previous action. The scale varies between environments, but the goal is always to increase your total reward.
* done (boolean): whether it’s time to reset the environment again. Most (but not all) tasks are divided up into well-defined episodes, and done being True indicates the episode has terminated. (For example, perhaps the pole tipped too far, or you lost your last life.)
* info (dict): diagnostic information useful for debugging. It can sometimes be useful for learning (for example, it might contain the raw probabilities behind the environment’s last state change). However, official evaluations of your agent are not allowed to use this for learning.


Q[s,a] = Q[s,a] + lr*(r + y*np.max(Q[s1,:]) - Q[s,a])


ここで、Q関数のアップデートをする。

rAll += r
s = s1


rAllで全部報酬を足して、sを次にアップデートをする。
で、これでループ回して

print "Score over time: " +  str(sum(rList)/num_episodes)


なんかわかってきましたよね！w