強化学習の基礎(その4:終)
前回の記事の続きです。
強化学習に必要な環境とエージェントのうち、環境の実装を前回説明しました。 今回は、残りのエージェントと、学習本体の説明をします。
エージェント
エージェントの役割は、「観測結果をもとに、(望ましい)行動をすること」でした。 なので、観測結果を受け取り、そこに何らかの演算を施して、行動を出力できればいいです。 この「何らかの演算」の部分を、普通はニューラルネットワークを用いて実現します。 ここではPyTorchを使った実装を紹介します。
import torch import torch.nn as nn import torch.nn.functional as F class Agent(nn.Module): def __init__(self): self.conv1 = nn.Conv2d(3, 16, 3, padding=1) self.conv2 = nn.Conv2d(16, 16, 3, padding=1) self.conv3 = nn.Conv2d(16, 32, 3, padding=1) self.conv4 = nn.Conv2d(32, 32, 3, padding=1) self.fc1 = nn.Linear(32 * 400 * 225, 1024) self.fc2 = nn.Linear(1024, 7) def forward(self, x): x = F.relu(self.conv1(x)) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv3(x)) x = F.relu(self.conv4(x)) x = F.max_pool2d(x, 2) x = x.view(-1, 32 * 400 * 225) x = F.relu(self.fc1(x)) return F.softmax(self.fc2(x))
CNNに通し、その後全結合層を2つ通す簡単なネットワークです。
forward
メソッドが演算を行う部分となります。
ここらへんの詳しい内容の説明は本筋からそれるので省略します(気が向いたら別記事で書きます)。
学習本体
さて、環境とエージェントが揃ったので、あとはこれらを作用させて学習を行う、学習本体部分を用意すれば完了です。 ここでは、流れ・使用方法が見やすいように抽象的な実装例を紹介します。
import gym from agent import Agent import gym_tetris agent = Agent() env = gym.make('tetris-v0') def do_episode(): obs = env.reset() done = False while not done: action = agent(obs) obs, reward, done, _ = env.step(action) # lossの計算(更新) return loss if __name__ == '__main__': for epoch in range(10000): loss = do_episode() # lossを用いてagentを更新
学習の流れは、以下のようになります。
作成したエージェントと環境を用意する。環境は、
gym.make
メソッドを用います。引数には、gym_tetris/__init__.py
で'id'
にセットした文字列を渡します。適当な回数、「1エピソード実行→得たlossを用いてエージェントを更新」を繰り返す。
ちなみに「エピソード」とは、スタート(reset
呼び出し直後)から、done
がTrue
になるまでを指します。
実装例のdo_episode
メソッドを1回呼び出すのが、1エピソードを実行するのに対応しています。
また、do_episode
メソッド内で、1回行動する毎にエージェントを更新する、という場合もあります。
これは学習アルゴリズムに依ります。
まとめ
これで強化学習の基礎シリーズは完結です。 機械学習・強化学習の基礎と、強化学習に必要な環境・エージェントの実装、そして学習本体の抽象的な実装例を紹介しました。 特に環境の実装は、エージェントの実装に比べて情報が少ないような気がしたので、ちょっと詳しめに書きました。
とはいえ、いくつか実装を放棄した部分もあり、そこが分からんねん!という意見もあるかと思います。 てなわけで、気が向いたらコピペしてそのまま動く実装と、今回のシリーズに基づいた解説も別記事で書きます。
それでは。