【AI + pygame】pygameで作るインベーダー風ゲーム 第6回 強化学習編その3(任意のパラメータから学習させる)

2019年05月16日

(2019年5月16日更新)

エンジニアのMです。
pygame によるインベーダー風ゲームの改造記事の第6回です。
ひとまず予定していた連載はこれで最後ですが、ネタがあれば続きがあるかもしれません。

今回のコードはこちらからダウンロードできます。
-> pygame_invader_6.zip

前回は画像を入力として学習させましたが、今回はこちらで必要そうなパラメータを渡して学習させることにします。

スタンダードなNNモデル

今回の入力は Flatten() で展開済みの1次元データです。
普通の3層ニューラルネットワークモデルを適用します。
学習用コードとネットワーク構造は以下の通りです。

from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.optimizers import Adam
from keras.regularizers import l2

from rl.agents.dqn import DQNAgent
from rl.policy import EpsGreedyQPolicy
from rl.memory import SequentialMemory
import invader07_part4

env = invader07_part4.Invader(step=True, image=False)
nb_actions = 3

hidden_size = 1024

model = Sequential()
model.add(Flatten(input_shape=(1, ) + env.observation_space.shape))
model.add(Dense(hidden_size, kernel_initializer='he_normal', activation='relu',
                kernel_regularizer=l2(0.01)))
model.add(Dense(hidden_size, kernel_initializer='he_normal', activation='relu',
                kernel_regularizer=l2(0.01)))
model.add(Dense(hidden_size, kernel_initializer='he_normal', activation='relu',
                kernel_regularizer=l2(0.01)))
model.add(Dense(nb_actions, activation='linear'))
print(model.summary())

memory = SequentialMemory(limit=200000, window_length=1)
policy = EpsGreedyQPolicy(eps=0.001)

dqn = DQNAgent(model=model, nb_actions=nb_actions,gamma=0.99, memory=memory, nb_steps_warmup=100,
               target_model_update=1e-2, policy=policy)

dqn.compile(Adam(lr=1e-3), metrics=['mae'])

fname = "invader_model_1024_d3.bin"
try:
    dqn.load_weights(fname)
    print("Weights are loaded.")
except:
    print("Weights are NOT loaded.")

history = dqn.fit(env, nb_steps=200000, verbose=2)

dqn.save_weights(fname, overwrite=True)

dqn.test(env, nb_episodes=20)

前回も使ったL2正則化を使います。
パラメータ数は300万ほどで前回より遥かに多いですが、構造が単純なので計算は高速に行われます。
環境構築も前回で終わっているので、すぐに学習させられるはずです。

前回よりやっていることは単純なはずなのですが、dqn.test() での挙動が怪しい問題を最後までクリアできませんでした。
dqn.fit() ではまあまあ避けつつたまにクリアしてくれるのに対して、dqn.test() では弾の位置と関係なく毎回同じように動いてほとんどクリアできていないという状態です。

dqn.fit() で学習が進行した状態でのクリア率は 30~35% 程度で、学習そのものがうまく行っていない訳では無さそうなのが余計に分からないところです。
おそらくは、observation_space の設定に問題があるのだと思うのですが、今はこれ以上突っ込まないことにします。
解決策が見つかったら第7回で報告するかもしれません。

一部問題はありましたが、今回もプレイ動画を用意しました。
test() がうまく動かなかったので、このプレイ動画は fit() の途中を抜き出したものです。
モデルデータは容量の都合で割愛します。

まとめ

人手で設定したパラメータを元に学習させようとしてみましたが、微妙な結果に終わってしまいました。
人間が設定すると、調整すべきパラメータが多くなるので、かえって面倒になる例と言えるかもしれません。
環境を整えたあとは機械にお任せしたほうが、お互いにとって良い結果となるでしょう。

この記事が気に入ったら
いいね ! しよう

Twitter で
フォームズ編集部
オフィスで働く方、ネットショップやホームページを運営されている皆様へ、ネットを使った仕事の効率化、Webマーケティングなど役立つ情報をお送りしています。