· 

Kerasを用いたDQNでFlappyBirdを学習させる

(著)山たー

偉そうなタイトルですが、自分で実装できていません…。そのうち自分で実装して内容を書き換えようと思います。

 

強化学習のシミュレーション環境

 強化学習で大変なのは

①シミュレーション環境の実装(行動空間、報酬設計…etc.)

②学習アルゴリズムの実装

の2点です。シミュレーション環境としてはOpenAI Gymなどがあります。コード例がたくさんあるので、OpenAI Gymで強化学習を動かすだけ動かしてみることは比較的楽にできます(例えばKeras-rl)。しかし、自作の環境を構築しようとすると大きな壁が立ちはだかります。OpenAI Gymのrenderを使って見るも、ゲームを実装できるかと言われると微妙なところ。

 

そこでシミュレーション環境としてPygameを用いてみます。PygameはPythonでゲームを作ることのできるライブラリです。強化学習用の環境としてはPyGame Learning Environmentなんかもあるのですが、よくわからなかったので見送りました。

 

とりあえずやりたいことは、Pygameで自作ゲーム(ゲームとは言わずシミュレーションという方が近いかもしれないが)を実装し、学習アルゴリズムを実装することです。色々さがしたところ、Keras-FlappyBirdというのが近そうだったので、今回はその紹介ということで。

 

Keras-FlappyBird

 Keras-FlappyBirdは、Pygameで実装されたFlappyBirdをKerasを用いたDQNで学習させるという内容です。FlappyBirdって何?という人はこのサイトとかで遊んでみると良いでしょう。実は自分もProcessingでそれっぽいゲームを作ったことがあります。(→ Flappy Birdもどき

要は、鳥の高度を調節して土管の間をくぐるゲームです。

 

動かすにはPygameを導入するため、

pip install pygame 

の後、

git clone https://github.com/yanpanlau/Keras-FlappyBird.git
cd Keras-FlappyBird
python qlearn.py -m "Run"

を実行すればOK。こんな画面が出てくれば成功。

 

学習済みのmodelもあるということで、さぞ軽快に土管の間を飛んでくれるのかと思いきや、土管の根元に向かって上昇し激突する鳥さん…。これってもしかしてちゃんと学習されたモデルではないのか?

 

というわけで

python qlearn.py -m "Train"

として学習させた。

 

TimeStep=3000000の結果は次のようになりました。

 

実装の中身の解説はいずれ更新します。

 

自分で遊んでみる

 同じFlappy Birdを自分で遊ぶには、次のプログラムをqlearn.pyと同じディレクトリにおいて実行すると遊べます。スペースキーでジャンプ、ESCキーで終了です。

import pygame
from pygame.locals import *
import sys
sys.path.append("game/")
import wrapped_flappy_bird as game
import numpy as np

ACTIONS = 2 # number of valid actions

def main():
    # open up a game state to communicate with emulator
    game_state = game.GameState()

    #ループ部分
    while (1):
        action = np.zeros(ACTIONS) #行動の配列(one-hot)
        pressed_key=pygame.key.get_pressed() #すべてのキーの入力を取得
        
        #Spaceキーを押すとジャンプ
        if pressed_key[K_SPACE]:
            action[1] = 1
        if sum(action) != 1:
            action[0] = 1
            
        #ゲーム画面,報酬(reward), 終了key
        x_t, r_t, terminal = game_state.frame_step(action)
    
        #報酬をprint
        print("Reward : "+str("{:.2f}".format(r_t)))
        
        #ESCキーが押されたら終了
        if pressed_key[K_ESCAPE]:
            pygame.quit()
            sys.exit()
            
if __name__ == "__main__":
    main()

コメントをお書きください

コメント: 1
  • #1

    goalken (木曜日, 16 7月 2020 13:00)

    Your share is the great knowledge I have gathered, you are an important person I admire, thank you <a href="https://8balls.io">8 ball</a>