11
11

More than 5 years have passed since last update.

クリスマスだから、強化学習でAIにブロック崩しをさせてみた(v 0.6.0)

Last updated at Posted at 2018-12-22

はじめに

こんにちは、アドベントカレンダーのラストを飾らせていただく皆川です。
クリスマスということなのでブロックをリア充に見立ててAIに崩してもらおうと思いました。

強化学習とはなんぞや

機械学習という言葉をよく耳にすると思うのですが、機械学習とは教師あり学習・教師なし学習・強化学習の三つから構成されています。下記の画像を参考にいただくとわかりやすいです。

Qiita

出典:教師あり学習と教師なし学習(https://goo.gl/images/Yti2zX

強化学習とは「環境に置かれたエージェントが環境に対して行動し得られる報酬が最大化されるような方策を求める手法」です。

よくわからないですよね、、、、簡単に説明すると

まず設計者(人間)はエージェント(AI)に対して何をしたらいくつ報酬をあげるのかということを設定します。(例:ボールをゴールに入れたら1.0の報酬、逆に決められたら−1.0の報酬)

次にエージェントが知るべき環境を与えてあげます(例:ボールの速度、ボールとエージェントの相対距離)

あとは、エージェントに何回もゲームに挑戦させます。そうすると、エージェントは得られる報酬を最大化させようと行動を調整します。(例:報酬を最大化させるためにボールに近づきボールをゴールの中に入れようとする)

ML-Agents

この強化学習をするために、UnityではML-Agentsというライブラリが用意されています。発表されてから早1年が経ち、日々アップデートされ使いやすくなっています。

ゲームにおいて、AIの作成をするのはとても骨の折れる作業です。しかし、このML-Agentsを使えば簡単に時間がかからずAIにゲームの仕組みを理解させ、優秀なNPCを作成することができます。

以下の動画をご覧いただければイメージがつきやすいと思います

参考にしたもの

実際、自分が作る時に参考になったものをご紹介いたします

GitHub

https://github.com/Unity-Technologies/ml-agents
まあこれをみれば他のものはいらないのですが、初めてだと若干きついかもしれません

書籍

Unityではじめる機械学習・強化学習 Unity ML-Agents実践ゲームプログラミング
ML-Agents唯一の書籍。2018/8/3に発売されたものなのですが、v0.3(この記事投稿時はv0.6)なのでほとんど役に立たないのですが、初めてやる人はこれで全体の大枠をつかんでからやるのもオススメです。

※1/8 追記

メールが届きまして、https://www.borndigital.co.jp/book/6702.html
こちらのサイトにv0.6改訂の内容が記載されました。

UnityBlog

https://blogs.unity3d.com/jp/2018/12/17/ml-agents-toolkit-v0-6-improved-usability-of-brains-and-imitation-learning/
MLはバージョンアップが激しいので、UnityBlogで追うことが大切です

UnityConnect

https://connect.unity.com
お学びグループ、Forrum、PublicChannel(Unity MachineLearning)ここで質問ができるのでオススメです。

記事

@kai_kou さん MacでUnity ML-Agentsの環境を構築する(v0.5.0対応)
https://qiita.com/kai_kou/items/6478fa686ce1af5939d8

環境構築

ML-Agents(v0.6.0)ではUnity2017.4以降で、pythonは3.6です(ターミナル,アナコンダどちらでも大丈夫です)。

以下の手順に沿って進めていきます

1.まずはml-agents-masterをクローンします
git clone https://github.com/Unity-Technologies/ml-agents.git

2.そしたらcdをml-agentsにしてパッケージをインストールします
pip3 install -e .

3.適当なUnityProjectを作成します

4.先ほどダウンロードしたUnitySDKを作成したプロジェクトにインポートします

5.Edit > Project Settings > Player > Other Settings > Scripting Runtime Version > Experimental (.NET 4.6 Equivalent or .NET 4.x Equivalent)
*ここで一度プロジェクトの再ダウンロードを要求されるのであらかじめシーンを保存しておきます

6.TensorFlowSharp Pluginをプロジェクトにインポートします

7.Edit > Project Settings > Player > Other Settings >Scripting Define Symbols > ENABLE_TENSORFLOW

ここまでが全プロジェクト共通の設定です。

ブロック崩し

まず基本となる簡単なブロック崩しゲームを作ります

Image from Gyazo

球を弾き返してブロックを壊せば点数が入る簡単なゲームです。

今回はこのプレイヤーが操作している棒をAgentとして強化学習させていきます

ブロック崩しにML-Agentを適用させる

ML-Agentで学習させるには、AgentとBrainとAcademyが必要になります。

Agent

BreakOutAgent.cs
using UnityEngine;
using MLAgents;

public class BreakOutAgent : Agent
{

    [SerializeField] private GameObject[] _blocks;
    [SerializeField] private GameObject _ball;
    private Rigidbody _rigidbody;
    private Rigidbody _ballRigidBody;

//Agentの初期化時に呼ばれるStart関数のようなもの(Start関数は使えない)
    public override void InitializeAgent()
    {
        _rigidbody = gameObject.GetComponent<Rigidbody>();
        _ballRigidBody = _ball.GetComponent<Rigidbody>();
    }

//ここではBrainに環境の情報を与えます、情報を与えすぎると学習に時間がかかってしまうので必要なものだけ選びます。(今回だと、ボールとプレイヤーの相対位置とボールのベクトル)また、ブロックの情報なども与えたいので本来はVisualObservationの方が好ましいと思います。

    public override void CollectObservations()
    {
        AddVectorObs(_ball.transform.position - gameObject.transform.position);
        AddVectorObs(_ballRigidBody.velocity);
    }

//フレーム毎に呼ばれます
    public override void AgentAction(float[] vectorAction, string textAction)
    {

//プレイヤー上に報酬の表示
        Monitor.verticalOffset = -4;
        Monitor.Log("Reward", "" + GetCumulativeReward(), gameObject.transform);

//エピソード完了
        if (GameManager._score == 210 || GameManager._life == 0)
        {
            Done();
            return;
        }

//0~2で行動を決める
        var _movement = (int) vectorAction[0];
        switch (_movement)
        {
            case 1:
                _rigidbody.AddForce(transform.right * -50, ForceMode.Impulse);
                AddReward(-0.01f);
                break;
            case 2:
                _rigidbody.AddForce(transform.right * 50, ForceMode.Impulse);
                AddReward(-0.01f);
                break;
        }
    }
//Agentがボールに当たったら報酬を受け取るようにする   
    private void OnCollisionEnter(Collision other)
    {
        if (other.gameObject.tag == "Ball")
        {
            AddReward(0.1f);
        }
    }

    private void OnGUI()
    {
        GUI.skin.label.normal.textColor = Color.white;
    }

//エピソード完了時に呼ばれる
    public override void AgentReset()
    {
        GameManager._life = 3;
        GameManager._score = 0;
        gameObject.transform.position = new Vector3(0, 0, 0);

        foreach (var _block in _blocks)
        {
            _block.SetActive(true);
        }

        _ball.transform.position = new Vector3(0f, 0.6f, -7f);
        _ball.SetActive(true);
    }
}

Image from Gyazo
推論時と学習時で以下に紹介するBrainの指定を変えます。

Brain

Agentを操る脳です。ScriptableObjectとして用意されているのでProjectビューから作成できます。
Image from Gyazo

PlayerBrain

プレイヤー(人間)が操る場合ではこちらを使用します。模倣学習や、学習前の実験で使用します。
VectorObservationはボールの速度ベクトル(x,y,z)とプレイヤーとボールの相対位置(x,y,z)の情報を与えるので6に設定してあります。branchは(0~2)を指定して、1の際は左、2の際は右へプレイヤーが移動するように指定しています。
Image from Gyazo

LearningBrain

学習・推論時に使用します。設定はPlayerと同じで、Modelには学習終了後の.byteファイルを指定します。学習前はmodelは空にしておきます。
Image from Gyazo

HeuristicBrain

手書きスクリプトでActionを決定する場合はこちらを使用します。

Academy

学習時のBrainの指定や学習についての設定を行います。名前の通りに学校です。

BreakOutAcademy.cs
using MLAgents;

public class BreakOutAcademy : Academy {

    //環境のリセット時に呼ばれる
    public override void AcademyReset()
    {

    }

    //ステップごとに呼ばれる
    public override void AcademyStep()
    {

    }
}

ステップとはupdateと同じようなもので、ステップ数を指定して何ステップ毎にBrainがActionを決定するかを決めたりします。
Image from Gyazo
学習時にはBroadcasthubにLearningBrainを指定してControlにチェックを入れます。その他はとりあえず既定値のままにしておきます。

学習の実行

上記で紹介している以外のものがたくさんあるのですが、以上で基本的な設定は終わります。

次に学習を実行します。AgentとAcademyのBrainがLearningであることをしっかりと確認したらターミナルへいきます。

ターミナルのディレクトリがml-agentsであることを確認したら以下のコマンドを実行します

mlagents-learn ../config/trainer_config.yaml --run-id=firstRun --train

trainer_config.yamlはconfigの中にあるのでターミナルに直接ドラッグしてパスを指定してください。
--run-id はmodelファイルを作成するときの名前なのでなんでも大丈夫です。
Image from Gyazo
Editorの再生ボタンを押すように要求されるので押すと学習が開始します
Image from Gyazo
カクカクしてますがとりあえず動いて感動です
Image from Gyazo
終わるとml-agents > models > firstRun ができているのでプロジェクトにインポートして、BreakOutLearning.bytesをBreakOutLearningのModelに指定してあげます。
Image from Gyazo
最後にAgentのBrainをBreakOutLearningにしてプロジェクトを実行します(推論)

最後に

思った以上に簡単に作れることがわかっていただけたでしょうか?自分はこれを作成している途中でgithubから再ダウンロードしたら、バージョンが変わってて全然わかんなくなった(締め切り近い)という地獄のような経験をしました。

多分日本語記事で最新版のML-Agentsに関する記事はあんまりないと思うので是非参考にしていただければ嬉しいです。

ML-Agentsはそんなに機械学習に関する知識がないひとでも作れるようになっているので、ぜひまずは手始めに公式サンプルの3DBallをやってみてはいかがでしょうか!

ここを直した方がいいなどいろんなご意見いただけると嬉しいです。

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11