commit 2cf96936246aab67cd5772d6ddc174fcff0a94a6 Author: Koha9 Date: Tue Mar 5 19:11:38 2024 +0900 Source upload diff --git a/scrollball-main.ipynb b/scrollball-main.ipynb new file mode 100644 index 0000000..2e971c7 --- /dev/null +++ b/scrollball-main.ipynb @@ -0,0 +1,510 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 自由課題レポート\n", + "\n", + "## 1 課題概要\n", + " 今度使用するデータセットは自分で作成したゲーム環境が生成したエージェント観測データである。Double DQN(Deep Q-Learning)モデルを使用し、エージェントが観測した環境データによって最善な動作を予測する。\n", + "## 2 ゲーム環境\n", + "### 2.1 ゲーム概要\n", + " Ml-AgentsのサンプルオブジェクトScrollBallを模倣した、ターゲットを追いかけるゲームである。真ん中の球は自機エージェント、正方形はターゲットと設定する。ゲーム開始時にターゲットは自機エージェント以外のゲームエリア内にランダムで生成する。自機は上下左右各方向にコントロールすることができ、リアルにシミュレーションするため、Unityの物理エンジンを使用する。各方向に入力があった場合、直接に一定の速度でその方向に移動するわけではなく、一定な加速度を加えることと設定している。自機エージェントがターゲットと接触するとゲームクリアと判定し、8秒経過もしくはゲームエリアから落ちる場合は失敗判定とする。\n", + "### 2.2 観測情報\n", + " エージェントはターゲットの位置、および自機位置のx,z座標が観測できることとする。その他、自機の水平と垂直xz方向の速度と合わせてステップ毎に合計六つのデータが観測できる。\n", + "### 2.3 Reward設定\n", + " ステップ毎に環境からRewardが返すことになっている。このステップの操作に評価を行うことである。自機がターゲットに前ステップより近づくとその距離値が正のRewardとしてが戻る、逆に前ステップより遠く離れると離れた距離値が負のRewardとして戻ってくる。ゲーム成功時にもらうRewardが10,失敗するときに-10と設定している。\n", + "### 2.4 動作確定\n", + " 2種類の動作が存在する、垂直及び水平になる。垂直では-1,0,1三つの値があり、各自下、静止、上と意味する,水平も-1,0,1三つの値があり、各左、静止、右と意味する。\n", + "## 3 DoubleDQN\n", + "### 3.1 Q-Learning\n", + " Q-Learningはすべての環境状態を十分にサンプリングし、各状態ににQualityが最も高い動作を実行する機械学習手法である。\n", + " Q-Learning試行したすべての環境状態をQ-tableに記録し、その環境状態で試行した動作が環境からもらうRewardをそのQ値として記録する。まだ同様な環境が観測した場合、Q-Tableに記載したQ値が最も高い動作を実行する。だが多くな場合、ゲームの環境状態は無限であり、すべての状況を記録することは難しい、しかもメモリにも大量に消耗する。\n", + "### 3.2 DQN(Deep Q-Learning)\n", + " DQNはQ-Tableの代わりにニューラルネットワークを使用して、観測した環境状態から各動作のQ値を予測する。今回使用するDouble DQNの構造及びコードは以下になる。\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\UCUNI\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\tensorflow_addons\\utils\\ensure_tf_install.py:53: UserWarning: Tensorflow Addons supports using Python ops for all Tensorflow versions above or equal to 2.4.0 and strictly below 2.7.0 (nightly versions are not supported). \n", + " The versions of TensorFlow you are currently using is 2.8.0 and is not supported. \n", + "Some things might work, some things might not.\n", + "If you were to encounter a bug, do not file an issue.\n", + "If you want to make sure you're using a tested and supported configuration, either change the TensorFlow version or the TensorFlow Addons's version. \n", + "You can find the compatibility matrix in TensorFlow Addon's readme:\n", + "https://github.com/tensorflow/addons\n", + " warnings.warn(\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ML-Agents Version : 0.27.0\n", + "TensroFlow Version: 2.8.0\n" + ] + } + ], + "source": [ + "import mlagents_envs\n", + "from mlagents_envs.base_env import ActionTuple\n", + "from mlagents_envs.environment import UnityEnvironment\n", + "\n", + "import tensorflow as tf\n", + "import tensorflow_addons as tfa\n", + "import tensorboard\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import time\n", + "import datetime\n", + "from collections import deque\n", + "from IPython.display import clear_output\n", + "\n", + "print(\"ML-Agents Version :\",mlagents_envs.__version__)\n", + "print(\"TensroFlow Version:\",tf.__version__)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# 割り当てに必要なGPUメモリのみを割り当てようとする\n", + "physical_devices = tf.config.list_physical_devices('GPU')\n", + "tf.config.experimental.set_memory_growth(physical_devices[0], True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "以下環境を実行する際にディレクトリにすべて半角英数字符号となっていることが必要" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ステップ毎に環境観測データ数 6\n", + "ステップ毎に実行可能な動作数 2\n" + ] + } + ], + "source": [ + "# 環境パラメータ\n", + "log_dir = \"ML-logs/\" + datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n", + "tb_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir)\n", + "env_path = './ScrollBall-Build/ML-ScrollBall-Sample'\n", + "brain_name = 'RollerBallBrain'\n", + "\n", + "# ゲーム環境獲得\n", + "env = UnityEnvironment(file_name=env_path, seed=1, side_channels=[])\n", + "env.reset()\n", + "\n", + "# 環境スペック獲得\n", + "tracked_agent = -1\n", + "behavior_specs = env.behavior_specs\n", + "behavior_name = list(behavior_specs)[0]\n", + "spec = behavior_specs[behavior_name]\n", + "observation_specs = spec.observation_specs[0] # 観測spec\n", + "action_spec = spec.action_spec # 動作spec\n", + "\n", + "\n", + "ENV_Discrete_ACTION_SIZE = action_spec.discrete_size# 連続的な動作のSize\n", + "ENV_Continuous_ACTION_SIZE = action_spec.continuous_size# 離散的な動作のSize\n", + "STATE_SIZE = observation_specs.shape[0]# 環境観測データ数\n", + "SAVE_STEPS = 100 # SAVE_STEPS毎にNNを保存する\n", + "ACTION_SIZE = ENV_Discrete_ACTION_SIZE * 3#トータル動作数、一種類の動作に三つの動作が存在するため、*3とする\n", + "MAX_EXP_NUM = 2500 # ExperiencePoolに保存できる最大過去記録数\n", + "\n", + "EPSILON_CUT_STEP = 1300\n", + "EPISODES = 500\n", + "REPLACE_STEPS = 50\n", + "BATCH_SIZE = 256\n", + "LEARNING_RATE = 0.0005\n", + "GAMMA = 0.9\n", + "\n", + "epsilon = 1\n", + "epsilon_min = 0.01\n", + "\n", + "print(\"ステップ毎に環境観測データ数\",STATE_SIZE)\n", + "print(\"ステップ毎に実行可能な動作数\",ENV_Discrete_ACTION_SIZE)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Experience Pool\n", + "class experiencePool:\n", + " def __init__(self):\n", + " self.exp_pool = deque(maxlen=MAX_EXP_NUM)\n", + "\n", + " def add(self, state, action, reward, netx_state, done):\n", + " self.exp_pool.append((state, action, reward, netx_state, done))\n", + "\n", + " def get_random(self, num=1):\n", + " random_index = np.random.choice(len(self.exp_pool), num)\n", + " random_exps = [self.exp_pool[i] for i in random_index]\n", + " return random_exps\n", + "\n", + " def get_len(self):\n", + " return len(self.exp_pool)\n", + "\n", + "# DQNメソッド\n", + "class DQN:\n", + " def __init__(self,load,load_dir):\n", + " self.learning_rate = LEARNING_RATE\n", + " self.epsilon = 1\n", + " self.epsilon_min = 0.01\n", + " self.epsilon_cut = (1-self.epsilon_min)/EPSILON_CUT_STEP\n", + " self.gamma = GAMMA\n", + " \n", + " if load:\n", + " #既存NNデータをローディングする\n", + " self.epsilon = self.epsilon_min\n", + " main_load_dir = load_dir+\"main.h5\"\n", + " target_load_dir = load_dir+\"target.h5\"\n", + " self.main_net,self.target_net = self.loadNN(main_load_dir,target_load_dir)\n", + " else:\n", + " #新規mainとtarget NNを作成する\n", + " self.main_net = self.build_net()\n", + " self.target_net = self.build_net()\n", + " self.exp_pool = experiencePool()\n", + "\n", + " # ---------------------------------------------------------------------------------\n", + " def build_net(self):\n", + " # NNを作成\n", + " rectifiedAdam = tfa.optimizers.RectifiedAdam(learning_rate = self.learning_rate,weight_decay = 0.001)\n", + " #Adam = tf.keras.optimizers.Adam(learning_rate=self.learning_rate)\n", + " neural_net = tf.keras.Sequential()\n", + " neural_net.add(tf.keras.layers.Dense(\n", + " units=128, activation='relu', input_dim=STATE_SIZE))\n", + " neural_net.add(tf.keras.layers.Dense(\n", + " units=256, activation='relu'))\n", + " neural_net.add(tf.keras.layers.Dense(\n", + " units=128, activation='relu'))\n", + " neural_net.add(tf.keras.layers.Dense(\n", + " units=64, activation='relu'))\n", + " neural_net.add(tf.keras.layers.Dense(\n", + " units=ACTION_SIZE, activation='elu'))\n", + "\n", + " neural_net.compile(optimizer=rectifiedAdam, loss='mse', metrics=['accuracy'])\n", + " \n", + " return neural_net\n", + "\n", + " def select_action(self, state):\n", + " # 動作Q値を予測と動作選択\n", + " random_num = np.random.sample()\n", + " \n", + " if random_num > self.epsilon:\n", + " # DQNをベースにし、動作を選択する\n", + " predictResult = self.main_net(state).numpy()[0]\n", + " actionX = np.argmax(predictResult[0:3])-1\n", + " actionZ = np.argmax(predictResult[3:])-1\n", + " action = np.array([actionX, actionZ], dtype=np.float32)\n", + " #print(\"action = \",action)\n", + " else:\n", + " # ランダムで動作を選択\n", + " actionX = np.random.randint(ACTION_SIZE/2)-1\n", + " actionY = np.random.randint(ACTION_SIZE/2)-1\n", + " action = np.array([actionX, actionY], dtype=np.float32)\n", + "\n", + " # 缩小epsilon\n", + " if self.epsilon > self.epsilon_min:\n", + " self.epsilon -= self.epsilon_cut\n", + "\n", + " return action\n", + "\n", + " def training(self):\n", + " # トレーニング開始\n", + " if self.exp_pool.get_len() >= BATCH_SIZE:\n", + " # トレーニング集を獲得\n", + " exp_set = self.exp_pool.get_random(num=BATCH_SIZE)\n", + " exp_state = [data[0] for data in exp_set] # EXP_Poolが記録した当時ラウンドの環境状態\n", + " exp_action = [data[1] for data in exp_set] # そのラウンドで選んだ動作\n", + " exp_reward = [data[2] for data in exp_set] # その動作に応じるreward\n", + " exp_next_state = [data[3] for data in exp_set] # その動作が実行した後の環境状態。\n", + " exp_done = [data[4] for data in exp_set] # 実行後にゲームが終了したか\n", + "\n", + " exp_state = np.asarray(exp_state).squeeze()\n", + " exp_action = np.asarray(exp_action).squeeze()\n", + " exp_next_state = np.asarray(exp_next_state).squeeze()\n", + "\n", + " # 各ネットでQ値予測\n", + " target_net_q = self.target_net(exp_next_state).numpy() # target_NN 未来状況のQ値を予測\n", + " main_net_q = self.main_net(exp_state).numpy() # main_NN 現在状況のQ値を予測\n", + "\n", + " # トレーニング用Q値、目標y、\n", + " y = main_net_q.copy() # (1,6)\n", + " \n", + " # Batch全体インデクス、[0,1,......,BATCH_SIZE]\n", + " batch_index = np.arange(BATCH_SIZE, dtype=np.int32)\n", + " \n", + " # 動作の値(-1,0,1)によってQ値のインデクス(Xは(0,1,2)、Zは(3,4,5),各自Shapeは(1,BATCH_SIZE))を作成\n", + " exp_actionX_index = exp_action[:,0] + 1\n", + " exp_actionZ_index = exp_action[:,1] + 4\n", + " exp_actionX_index = exp_actionX_index.astype(np.int)\n", + " exp_actionZ_index = exp_actionZ_index.astype(np.int)\n", + " \n", + " # target_NNが未来状況によって予測したQ値から 垂直/水平動作各自の最大値Q値を摘出\n", + " fixedX = np.max(target_net_q[:, :3], axis=1) # (batchsize,1)\n", + " fixedZ = np.max(target_net_q[:, -3:], axis=1) # (batchsize,1)\n", + " # そのラウンドで受けたreward+未来最大Q値の和で修正値となる\n", + " fixedX = exp_reward + self.gamma*fixedX \n", + " fixedZ = exp_reward + self.gamma*fixedZ\n", + " # ゲーム終了のラウンドでの修正値は元のreward,ゲーム続行する時の修正値はfixedXとfixedYとする\n", + " y_fixedX = np.where(exp_done,exp_reward,fixedX)\n", + " y_fixedZ = np.where(exp_done,exp_reward,fixedZ)\n", + " \n", + " # 修正値を応用\n", + " y[batch_index, exp_actionX_index] = y_fixedX\n", + " y[batch_index, exp_actionZ_index] = y_fixedZ\n", + "\n", + " # main_netに入れて、フィットする\n", + " self.main_net.fit(exp_state, y, epochs=5, verbose=0,callbacks = [tb_callback])\n", + " \n", + " def saveNN(self):\n", + " # 両NNを保存する\n", + " main_save_dir= \"ML-Model/\" + datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")+\"main.h5\"\n", + " target_save_dir= \"ML-Model/\" + datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")+\"target.h5\"\n", + " self.main_net.save(main_save_dir)\n", + " self.target_net.save(target_save_dir)\n", + " print(\"Model Saved\")\n", + "\n", + " def loadNN(self,main_load_dir,target_load_dir):\n", + " # 両NNをローディングする\n", + " main_net_loaded = tf.keras.models.load_model(main_load_dir)\n", + " target_net_loaded = tf.keras.models.load_model(target_load_dir)\n", + " print(\"Model Loaded\")\n", + " return main_net_loaded,target_net_loaded" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA20AAAI/CAYAAADkwzGCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAABvX0lEQVR4nO3dd5gUVdqG8buGKBgQWkXFiFlRVAyIK1mMYFZUhMIVcRXTbrfpUzHtuphzXAsRAyZQFEWyrhgAswKKCghIaHKGmanvj8EBV0DCDDXh/l0XF9WnqnuewdqBd89b5wRxHCNJkiRJKplykg4gSZIkSVozizZJkiRJKsEs2iRJkiSpBLNokyRJkqQSzKJNkiRJkkowizZJkiRJKsEqJh0AIJVKxbvuumvSMSRJkiQpEaNGjcrGcbzN6s6ViKJt1113ZeTIkUnHkCRJkqREBEEwYU3nbI+UJEmSpBLMok2SJEmSSjCLNkmSJEkqwUrEM22rs3z5ciZNmsSSJUuSjqL1VLVqVerUqUOlSpWSjiJJkiSVeiW2aJs0aRJbbLEFu+66K0EQJB1H6yiOY2bOnMmkSZPYbbfdko4jSZIklXoltj1yyZIl1KpVy4KtlAmCgFq1ajlDKkmSJBWRElu0ARZspZT/3SRJkqSiU6KLtiTNnDmT+vXrU79+fWrXrs2OO+5Y+HrZsmW/u/b+++9n0aJFf/qZTZo0YeTIkTzwwANceeWVheMXX3wxLVq0KHz90EMPcfnllzNy5Eguv/zyDcr46aefrvW9kiRJkkqHEvtMW9Jq1arFF198AUDXrl3ZfPPN+cc//rHaa++//37OP/98qlWrtk6f3ahRI55//vnC119++SV5eXnk5eVRoUIFhg8fTps2bWjQoAENGjTY4IyHH374OuWRJEmSVHI507YeBg0axMEHH0y9evXo2LEjS5cu5cEHH2TKlCk0bdqUpk2bAnDJJZfQoEED9t9/f26++eY/fE79+vX5/vvvWbx4MXPnzmWzzTajfv36fP311wAMHz6cRo0aMXToUE466SSgoCjr2LEjTZo0Yffdd+fBBx9ca9b/fW/79u35y1/+wi677MLrr79OJpOhXr16HHfccSxfvhyAUaNG0bhxYw499FBatWrFr7/+CsCDDz7Ifvvtx4EHHsg555xTNH+YkiRJktaJRds6WrJkCR06dKBXr158/fXX5Obm8thjj3H55Zezww47MGTIEIYMGQLAHXfcwciRI/nqq68YNmwYX3311e8+q2LFihx88MGMGDGCjz/+mCOOOIIjjzyS4cOHM3nyZOI4ZqeddvpDhjFjxtC/f38+/fRTbrnllsJia138+OOPDB48mDfffJPzzz+fpk2b8vXXX7PZZpvx9ttvs3z5crp06cKrr77KqFGj6NixIzfccAMAd955J59//jlfffUVjz/++Eb8KUqSJElaXxZt6ygvL4/ddtuNvfbaC4D27dvz/vvvr/bal19+mUMOOYSDDz6Yb7/9lu++++4P1xx11FEMHz6c4cOH07BhQxo2bFj4+qijjlrt55544olUqVKFVCrFtttuy7Rp09Y5//HHH0+lSpWoV68eeXl5HHfccQDUq1eP8ePHM3bsWL755htatmxJ/fr1uf3225k0aRIABx54IOeddx49e/akYkU7aiVJkqRNqdT8C7zr0K7cMuyWwtcjLxoJQIOnVj7zdXPjm+napCs73LMDvy4oaO07ZPtDGNVpFJ36duKpz54qvHby1ZPZYYsdijznzz//zN13382IESPYeuut6dChw2qXv2/UqBGPP/44S5Ys4dJLL2Wbbbbhu+++Y5tttllj0ValSpXC4woVKpCbm7vOuX57b05ODpUqVSpc4TEnJ4fc3FziOGb//ffno48++sN73377bd5//3369u3LHXfcwddff23xJkmSJG0ipeZf3l2bdKVrk65/GI9vjv8wNuXvU/4w9uTJT/LkyU9u8NevUKEC48ePZ9y4ceyxxx4899xzNG7cGIAtttiC+fPnk0qlmDdvHtWrV2errbZi2rRpvPPOOzRp0uQPn9ewYUM6dOjAjjvuyLbbbgvANttswxtvvMErr7yywTk31N57782MGTP46KOPaNiwIcuXL+f7779n33335ZdffqFp06YcffTRvPTSSyxYsIAaNWps8oySJElSeVRqirakVa1alSiKOPPMM8nNzeWwww6jc+fOAHTq1Injjjuu8Nm2gw8+mH322YeddtqJRo0arfbztt56a7bZZhv233//wrGGDRvy4YcfctBBB22S72lVlStX5tVXX+Xyyy9n7ty55ObmcuWVV7LXXntx/vnnM3fuXOI45vLLL7dgkyRJkjahII7/OFO1qTVo0CAeOXLk78ZGjx7Nvvvum1AibSz/+0mSJEnrLgiCUXEcr3a/rz9diCQIgmeCIJgeBME3q4z1CoLgixW/xgdB8MWK8V2DIFi8yjmXGpQkSZKkjbAu7ZHdgYeBHr8NxHF89m/HQRDcA8xd5fof4ziuX0T5JEmSJKlc+9OiLY7j94Mg2HV154KCJQjPApoVcS5JkiRJEhu/T9tfgGlxHP+wythuQRB8HgTBsCAI/rKRny9JkiRJ5drGrh7ZFnhxlde/AjvHcTwzCIJDgT5BEOwfx/G8/31jEASdgE4AO++880bGkCRJkqSyaYNn2oIgqAicBvT6bSyO46VxHM9ccTwK+BHYa3Xvj+P4yTiOG8Rx3GCbbbbZ0BiSJEmSVKZtTHtkC2BMHMeTfhsIgmCbIAgqrDjeHdgT+GnjIiZj5syZ1K9fn/r161O7dm123HHHwtfLli373bX3338/ixYt+tPPbNKkCb9tbbDrrrtSr169ws8cPnz4Gt93wgknMGfOHAA233zz1V7ToUMHXn31VU499VTq16/PHnvswVZbbfW7zz/qqKPW8buXJEmSyobs119z19FHk+3QgWyHDtx14olks9mkY62XP22PDILgRaAJkAqCYBJwcxzH/wHO4fetkQDHALcGQbAcyAc6x3E8q2gjbxq1atXiiy++AKBr165svvnm/OMf/1jttffffz/nn38+1apVW6+vMWTIEFKp1J9e169fv3X+zN69ewMwdOhQ7r77bt56663Cc2srDCVJkqQyZ8IEoiZNyMyaBdtuC0CmXz+IItLpdMLh1t26rB7Zdg3jHVYz9hrw2sbHKpkGDRrEP/7xD3JzcznssMN47LHHeOKJJ5gyZQpNmzYllUoxZMgQLrnkEkaMGMHixYs544wzuOWWW9bp80855RR++eUXlixZwhVXXEGnTp2Aglm5kSNH/q7Ai+OYLl26MGDAAHbaaScqV678p5+/+eabs2DBAoYOHcrNN99MjRo1+PrrrznrrLOoV68eDzzwAIsXL6ZPnz7UrVuXGTNm0LlzZyZOnAgUFKeNGjVi2LBhXHHFFQAEQcD777/PFltssb5/nJIkSVLx+fFHaN6c8OqroXJlwjAsGG/YcOVxKbGxC5GUG0uWLKFDhw4MGjSIvfbaiwsuuIDHHnuMK6+8knvvvfd3s2Z33HEHNWvWJC8vj+bNm/PVV19x4IEH/uEzmzZtSoUKFahSpQqffPIJzzzzDDVr1mTx4sUcdthhnH766dSqVWu1eXr37s3YsWP57rvvmDZtGvvttx8dO3Zc5+/nyy+/ZPTo0dSsWZPdd9+dv/71r3z66ac88MADPPTQQ9x///1cccUVXHXVVRx99NFMnDiRVq1aMXr0aO6++24eeeQRGjVqxIIFC6hateqG/aFKkiRJRST75ZdEbdsSbr01ANFXXxHefDOpf/yDVefUStMM2282dsn/EiWbzXLXXXcVS49qXl4eu+22G3vtVbCuSvv27Xn//fdXe+3LL7/MIYccwsEHH8y3337Ld999t9rrhgwZwhdffMEnn3wCwIMPPshBBx3EkUceyS+//MIPP/yw2vcBvP/++7Rt25YKFSqwww470KzZ+m2Vd9hhh7H99ttTpUoV6taty7HHHgtAvXr1GD9+PAADBw7ksssuo379+rRu3Zp58+axYMECGjVqxNVXX82DDz7InDlzqFjR2l+SJEkJ+vlnoqZNyYweTVSvHlG9emQWLCCK46STFYnS86/tIPjTSyIgA5DJsE71czH8R/z555+5++67GTFiBFtvvTUdOnRgyZIlf/q+oUOHMnDgQD766COqVatGkyZN1ul9G6pKlSqFxzk5OYWvc3JyyM3NBSA/P5+PP/74DzNp1157LSeeeCL9+vWjUaNG9O/fn3322afYskqSJElr9MMP0KIF4TXXQE7OytbHunVLXRvkmpSembY4/tNf4YwZdOvWjXDGjHW6fn1UqFCB8ePHM27cOACee+45GjduDMAWW2zB/PnzAZg3bx7Vq1dnq622Ytq0abzzzjvr9Plz585l6623plq1aowZM4aPP/54rdcfc8wx9OrVi7y8PH799VeGDBmyXt/Pujj22GN56KGHCl//tjDLjz/+SL169bjmmms47LDDGDNmTJF/bUmSJGm1Jkwge+CB3LX55mS32YZs/frcddhhcOGFpNNpUqkUqVSq8LgsKD0zbevgt/84xaFq1apEUcSZZ55ZuBBJ586dAejUqRPHHXccO+ywA0OGDOHggw9mn332YaeddqJRo0br9PnHHXccjz/+OPvuuy977703Rx555FqvP/XUUxk8eDD77bcfO++8Mw0bNtzo7/F/Pfjgg1x66aUceOCB5Obmcswxx/D4449z//33M2TIEHJycth///05/vjji/xrS5IkSX+wYnGR6MADyXz9NVx9NVSs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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Episode 261 done,Reward = 10.0 mean steps = 13.049618320610687 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n", + "\n", + "Episode 262 done,Reward = -10.0 mean steps = 13.049429657794677 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n", + "target_net replaced\n", + "\n", + "Episode 263 done,Reward = -10.0 mean steps = 13.151515151515152 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n", + "\n", + "Episode 264 done,Reward = 10.0 mean steps = 13.124528301886793 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n", + "\n", + "Episode 265 done,Reward = 10.0 mean steps = 13.135338345864662 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n", + "target_net replaced\n", + "Model Saved\n", + "\n", + "Episode 266 done,Reward = 10.0 mean steps = 13.142322097378278 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n", + "\n", + "Episode 267 done,Reward = -10.0 mean steps = 13.156716417910447 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n", + "\n", + "Episode 268 done,Reward = 10.0 mean steps = 13.118959107806692 exp_num = 2500 \n", + "epsilon = 0.009999999999982863\n" + ] + }, + { + "ename": "UnityCommunicatorStoppedException", + "evalue": "Communicator has exited.", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mUnityCommunicatorStoppedException\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_13628/1299734337.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 51\u001b[0m \u001b[1;31m# 動作をゲーム環境に渡す。\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 52\u001b[0m \u001b[0menv\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_actions\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbehavior_name\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mbehavior_name\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0maction\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0maction_Tuple\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m \u001b[0menv\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 54\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 55\u001b[0m \u001b[1;31m# 環境が動作を実行し、次の環境状態を返す。\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\mlagents_envs\\timers.py\u001b[0m in \u001b[0;36mwrapped\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 303\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mwrapped\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 304\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mhierarchical_timer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__qualname__\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 305\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 306\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 307\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mwrapped\u001b[0m \u001b[1;31m# type: ignore\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m~\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\mlagents_envs\\environment.py\u001b[0m in \u001b[0;36mstep\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 333\u001b[0m \u001b[0moutputs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_communicator\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mexchange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstep_input\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_poll_process\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 334\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0moutputs\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 335\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mUnityCommunicatorStoppedException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Communicator has exited.\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 336\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_update_behavior_specs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moutputs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 337\u001b[0m \u001b[0mrl_output\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0moutputs\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrl_output\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mUnityCommunicatorStoppedException\u001b[0m: Communicator has exited." + ] + } + ], + "source": [ + "# エージェント作成\n", + "agent = DQN(load = False,load_dir=\"ML-Model/\" + \"20220205-051103\")\n", + "# トレーニング済みNNをローディングするにはこちらのコードを使用↓\n", + "#agent = DQN(load = True,load_dir=\"ML-Model/\" + \"FinalNN-\")\n", + "\n", + "total_steps = 0 \n", + "steps_list = []\n", + "successTimes = 0\n", + "failTimes = 0\n", + "successTimes_his = []\n", + "failTimes_his = []\n", + "this10TimesWin = 0\n", + "MeanWinPerin10Times = []\n", + "\n", + "for episode in range(EPISODES):\n", + " # episode 開始 \n", + " done = False #ゲーム終了状態をFalse\n", + " steps = 0 \n", + " # 環境初期状態を獲得\n", + " env.reset()\n", + " decision_steps, terminal_steps = env.get_steps(behavior_name)\n", + " state = decision_steps.obs[0]\n", + " state = np.reshape(state, [1, STATE_SIZE])\n", + " \n", + " # ゲームスタート\n", + " while True:\n", + " reward = 0\n", + " steps+=1\n", + " total_steps += 1\n", + " # エージェントナンバーをトラックする\n", + " if tracked_agent == -1 and len(decision_steps) >= 1:\n", + " tracked_agent = decision_steps.agent_id[0]\n", + " \n", + " # REPLACE_STEPS毎でtarget_net にmain_netで入れ替える\n", + " if total_steps % REPLACE_STEPS == 0 and total_steps !=0:\n", + " agent.target_net.set_weights(agent.main_net.get_weights())\n", + " print('target_net replaced')\n", + " \n", + " # SAVE_STEPS毎でNNを保存する\n", + " if total_steps % SAVE_STEPS ==0 and total_steps !=0:\n", + " agent.saveNN()\n", + " \n", + " # main_netで動作選択\n", + " action = agent.select_action(state=state)\n", + " continuous_actions = np.array([[0]], dtype=np.float)\n", + " discrete_actions = np.expand_dims(action,axis=0)\n", + " # 動作をML-Agentsが認識可能なActionTuple型に変換\n", + " action_Tuple = ActionTuple(\n", + " continuous=continuous_actions, discrete=discrete_actions)\n", + "\n", + " # 動作をゲーム環境に渡す。\n", + " env.set_actions(behavior_name=behavior_name, action=action_Tuple)\n", + " env.step()\n", + " \n", + " # 環境が動作を実行し、次の環境状態を返す。\n", + " decision_steps, terminal_steps = env.get_steps(behavior_name)\n", + " if tracked_agent in decision_steps: # ゲーム終了していない場合、環境状態がdecision_stepsに保存される\n", + " next_state = decision_steps[tracked_agent].obs[0]\n", + " next_state = np.reshape(next_state,[1,STATE_SIZE])\n", + " reward = decision_steps[tracked_agent].reward\n", + " if tracked_agent in terminal_steps: # ゲーム終了した場合、環境状態がterminal_stepsに保存される\n", + " next_state = terminal_steps[tracked_agent].obs[0]\n", + " next_state = np.reshape(next_state,[1,STATE_SIZE])\n", + " reward = terminal_steps[tracked_agent].reward\n", + " done = True\n", + " \n", + " # Experience_poolに保存\n", + " agent.exp_pool.add(state,action,reward,next_state,done)\n", + " #print(\"Reward = \",reward)\n", + " # 環境状態を次状態に変更。\n", + " state = next_state\n", + " \n", + " # ゲーム終了後処理\n", + " if done:\n", + " mean_steps = total_steps/(episode+1)\n", + " print(\"\\nEpisode\",episode,\"done,Reward =\",reward,\"mean steps =\",mean_steps,\"exp_num =\",agent.exp_pool.get_len(),\"\\nepsilon =\",agent.epsilon)\n", + " agent.training()\n", + " if(reward >=10):\n", + " successTimes+=1\n", + " this10TimesWin+=1\n", + " else:\n", + " failTimes+=1\n", + " successTimes_his.append(successTimes)\n", + " failTimes_his.append(failTimes)\n", + " if episode % 10 ==0 and episode !=0:\n", + " clear_output()\n", + " this10TimesWinPer = float(this10TimesWin/10)\n", + " this10TimesWin = 0\n", + " MeanWinPerin10Times.append(this10TimesWinPer)\n", + " # 合計成功数(緑)、合計失敗数(赤)を図で表示する\n", + " plt.figure(figsize = (15,10))\n", + " plt.plot(range(len(successTimes_his)), successTimes_his,color='green',linestyle='--', linewidth=1, label='TotalWinTimes')\n", + " plt.plot(range(len(successTimes_his)), failTimes_his,color='red', linewidth=1,marker='o', markersize=1, markerfacecolor='black',markeredgecolor='black',label='TotalFaildTimes')\n", + " # plt.savefig('output.jpg')\n", + " plt.legend()\n", + " plt.savefig(\"wintimes.png\")\n", + " plt.show()\n", + " \n", + " #10回実行した後の成功確率を図で表示する\n", + " plt.figure(figsize=(15,10))\n", + " plt.plot(MeanWinPerin10Times)\n", + " plt.savefig(\"steps.png\")\n", + " plt.show()\n", + " break\n", + "env.close()\n", + "print(\"Finished~\")" + ] + } + ], + "metadata": { + "interpreter": { + "hash": "c62a1b52b24525839a95f7ca2b53f501cc329096d80c6be9aea5c814c594ecdd" + }, + "kernelspec": { + "display_name": "Python 3.9.7 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "undefined.undefined.undefined" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/scrollball-main.py b/scrollball-main.py new file mode 100644 index 0000000..ad52ec3 --- /dev/null +++ b/scrollball-main.py @@ -0,0 +1,314 @@ +import mlagents_envs +from mlagents_envs.base_env import ActionTuple +from mlagents_envs.environment import UnityEnvironment + +import argparse +import tensorflow as tf +import tensorflow_addons as tfa +import tensorboard +import numpy as np +import matplotlib.pyplot as plt +import time +import datetime +from collections import deque +from IPython.display import clear_output + +print("ML-Agents Version :",mlagents_envs.__version__) +print("TensroFlow Version:",tf.__version__) + +# 環境パラメータ +log_dir = "ML-logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") +tb_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir) +env_path = './ScrollBall-Build/ML-ScrollBall-Sample' +brain_name = 'RollerBallBrain' + +parser = argparse.ArgumentParser() +parser.add_argument("--env_path", default=env_path) +parser.add_argument("-train", action="store_true",default=False) +parser.add_argument("-silent", action="store_true",default=False) + +args = parser.parse_args() + +# ゲーム環境獲得 +env = UnityEnvironment(file_name=args.env_path, seed=1, side_channels=[]) +env.reset() + +# 環境スペック獲得 +tracked_agent = -1 +behavior_specs = env.behavior_specs +behavior_name = list(behavior_specs)[0] +spec = behavior_specs[behavior_name] +observation_specs = spec.observation_specs[0] # 観測spec +action_spec = spec.action_spec # 動作spec + +ENV_Discrete_ACTION_SIZE = action_spec.discrete_size# 連続的な動作のSize +ENV_Continuous_ACTION_SIZE = action_spec.continuous_size# 離散的な動作のSize +STATE_SIZE = observation_specs.shape[0]# 環境観測データ数 +SAVE_STEPS = 100 # SAVE_STEPS毎にNNを保存する +ACTION_SIZE = ENV_Discrete_ACTION_SIZE * 3#トータル動作数、一種類の動作に三つの動作が存在するため、*3とする +MAX_EXP_NUM = 2500 # ExperiencePoolに保存できる最大過去記録数 + +EPSILON_CUT_STEP = 1300 +EPISODES = 500 +REPLACE_STEPS = 50 +BATCH_SIZE = 256 +LEARNING_RATE = 0.0005 +GAMMA = 0.9 + +epsilon = 1 +epsilon_min = 0.01 + +print("ステップ毎に環境観測データ数",STATE_SIZE) +print("ステップ毎に実行可能な動作数",ENV_Discrete_ACTION_SIZE) + +# Experience Pool +class experiencePool: + def __init__(self): + self.exp_pool = deque(maxlen=MAX_EXP_NUM) + + def add(self, state, action, reward, netx_state, done): + self.exp_pool.append((state, action, reward, netx_state, done)) + + def get_random(self, num=1): + random_index = np.random.choice(len(self.exp_pool), num) + random_exps = [self.exp_pool[i] for i in random_index] + return random_exps + + def get_len(self): + return len(self.exp_pool) + +# DQNメソッド +class DQN: + def __init__(self,load,load_dir): + self.learning_rate = LEARNING_RATE + self.epsilon = 1 + self.epsilon_min = 0.01 + self.epsilon_cut = (1-self.epsilon_min)/EPSILON_CUT_STEP + self.gamma = GAMMA + + if load: + #既存NNデータをローディングする + self.epsilon = self.epsilon_min + main_load_dir = load_dir+"main.h5" + target_load_dir = load_dir+"target.h5" + self.main_net,self.target_net = self.loadNN(main_load_dir,target_load_dir) + else: + #新規mainとtarget NNを作成する + self.main_net = self.build_net() + self.target_net = self.build_net() + self.exp_pool = experiencePool() + + # --------------------------------------------------------------------------------- + def build_net(self): + # NNを作成 + rectifiedAdam = tfa.optimizers.RectifiedAdam(learning_rate = self.learning_rate,weight_decay = 0.001) + #Adam = tf.keras.optimizers.Adam(learning_rate=self.learning_rate) + neural_net = tf.keras.Sequential() + neural_net.add(tf.keras.layers.Dense( + units=128, activation='relu', input_dim=STATE_SIZE)) + neural_net.add(tf.keras.layers.Dense( + units=256, activation='relu')) + neural_net.add(tf.keras.layers.Dense( + units=128, activation='relu')) + neural_net.add(tf.keras.layers.Dense( + units=64, activation='relu')) + neural_net.add(tf.keras.layers.Dense( + units=ACTION_SIZE, activation='elu')) + + neural_net.compile(optimizer=rectifiedAdam, loss='mse', metrics=['accuracy']) + + return neural_net + + def select_action(self, state): + # 動作Q値を予測と動作選択 + random_num = np.random.sample() + + if random_num > self.epsilon: + # DQNをベースにし、動作を選択する + predictResult = self.main_net(state).numpy()[0] + actionX = np.argmax(predictResult[0:3])-1 + actionZ = np.argmax(predictResult[3:])-1 + action = np.array([actionX, actionZ], dtype=np.float32) + #print("action = ",action) + else: + # ランダムで動作を選択 + actionX = np.random.randint(ACTION_SIZE/2)-1 + actionY = np.random.randint(ACTION_SIZE/2)-1 + action = np.array([actionX, actionY], dtype=np.float32) + + # 缩小epsilon + if self.epsilon > self.epsilon_min: + self.epsilon -= self.epsilon_cut + + return action + + def training(self): + # トレーニング開始 + if self.exp_pool.get_len() >= BATCH_SIZE: + # トレーニング集を獲得 + exp_set = self.exp_pool.get_random(num=BATCH_SIZE) + exp_state = [data[0] for data in exp_set] # EXP_Poolが記録した当時ラウンドの環境状態 + exp_action = [data[1] for data in exp_set] # そのラウンドで選んだ動作 + exp_reward = [data[2] for data in exp_set] # その動作に応じるreward + exp_next_state = [data[3] for data in exp_set] # その動作が実行した後の環境状態。 + exp_done = [data[4] for data in exp_set] # 実行後にゲームが終了したか + + exp_state = np.asarray(exp_state).squeeze() + exp_action = np.asarray(exp_action).squeeze() + exp_next_state = np.asarray(exp_next_state).squeeze() + + # 各ネットでQ値予測 + target_net_q = self.target_net(exp_next_state).numpy() # target_NN 未来状況のQ値を予測 + main_net_q = self.main_net(exp_state).numpy() # main_NN 現在状況のQ値を予測 + + # トレーニング用Q値、目標y、 + y = main_net_q.copy() # (1,6) + + # Batch全体インデクス、[0,1,......,BATCH_SIZE] + batch_index = np.arange(BATCH_SIZE, dtype=np.int32) + + # 動作の値(-1,0,1)によってQ値のインデクス(Xは(0,1,2)、Zは(3,4,5),各自Shapeは(1,BATCH_SIZE))を作成 + exp_actionX_index = exp_action[:,0] + 1 + exp_actionZ_index = exp_action[:,1] + 4 + exp_actionX_index = exp_actionX_index.astype(np.int) + exp_actionZ_index = exp_actionZ_index.astype(np.int) + + # target_NNが未来状況によって予測したQ値から 垂直/水平動作各自の最大値Q値を摘出 + fixedX = np.max(target_net_q[:, :3], axis=1) # (batchsize,1) + fixedZ = np.max(target_net_q[:, -3:], axis=1) # (batchsize,1) + # そのラウンドで受けたreward+未来最大Q値の和で修正値となる + fixedX = exp_reward + self.gamma*fixedX + fixedZ = exp_reward + self.gamma*fixedZ + # ゲーム終了のラウンドでの修正値は元のreward,ゲーム続行する時の修正値はfixedXとfixedYとする + y_fixedX = np.where(exp_done,exp_reward,fixedX) + y_fixedZ = np.where(exp_done,exp_reward,fixedZ) + + # 修正値を応用 + y[batch_index, exp_actionX_index] = y_fixedX + y[batch_index, exp_actionZ_index] = y_fixedZ + + # main_netに入れて、フィットする + self.main_net.fit(exp_state, y, epochs=5, verbose=0,callbacks = [tb_callback]) + + def saveNN(self): + # 両NNを保存する + main_save_dir= "ML-Model/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")+"main.h5" + target_save_dir= "ML-Model/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")+"target.h5" + self.main_net.save(main_save_dir) + self.target_net.save(target_save_dir) + print("Model Saved") + + def loadNN(self,main_load_dir,target_load_dir): + # 両NNをローディングする + main_net_loaded = tf.keras.models.load_model(main_load_dir) + target_net_loaded = tf.keras.models.load_model(target_load_dir) + print("Model Loaded") + return main_net_loaded,target_net_loaded + +if not args.train: + agent = DQN(load = True,load_dir="ML-Model/" + "FinalNN-") +else: + agent = DQN(load = False,load_dir="ML-Model/" + "20220205-051103") + +total_steps = 0 +steps_list = [] +successTimes = 0 +failTimes = 0 +successTimes_his = [] +failTimes_his = [] +this10TimesWin = 0 +MeanWinPerin10Times = [] + +for episode in range(EPISODES): + # episode 開始 + done = False #ゲーム終了状態をFalse + steps = 0 + # 環境初期状態を獲得 + env.reset() + decision_steps, terminal_steps = env.get_steps(behavior_name) + state = decision_steps.obs[0] + state = np.reshape(state, [1, STATE_SIZE]) + + # ゲームスタート + while True: + reward = 0 + steps+=1 + total_steps += 1 + # エージェントナンバーをトラックする + if tracked_agent == -1 and len(decision_steps) >= 1: + tracked_agent = decision_steps.agent_id[0] + + # REPLACE_STEPS毎でtarget_net にmain_netで入れ替える + if total_steps % REPLACE_STEPS == 0 and total_steps !=0: + agent.target_net.set_weights(agent.main_net.get_weights()) + print('target_net replaced') + + # SAVE_STEPS毎でNNを保存する + if total_steps % SAVE_STEPS ==0 and total_steps !=0: + agent.saveNN() + + # main_netで動作選択 + action = agent.select_action(state=state) + continuous_actions = np.array([[0]], dtype=np.float) + discrete_actions = np.expand_dims(action,axis=0) + # 動作をML-Agentsが認識可能なActionTuple型に変換 + action_Tuple = ActionTuple( + continuous=continuous_actions, discrete=discrete_actions) + + # 動作をゲーム環境に渡す。 + env.set_actions(behavior_name=behavior_name, action=action_Tuple) + env.step() + + # 環境が動作を実行し、次の環境状態を返す。 + decision_steps, terminal_steps = env.get_steps(behavior_name) + if tracked_agent in decision_steps: # ゲーム終了していない場合、環境状態がdecision_stepsに保存される + next_state = decision_steps[tracked_agent].obs[0] + next_state = np.reshape(next_state,[1,STATE_SIZE]) + reward = decision_steps[tracked_agent].reward + if tracked_agent in terminal_steps: # ゲーム終了した場合、環境状態がterminal_stepsに保存される + next_state = terminal_steps[tracked_agent].obs[0] + next_state = np.reshape(next_state,[1,STATE_SIZE]) + reward = terminal_steps[tracked_agent].reward + done = True + + # Experience_poolに保存 + agent.exp_pool.add(state,action,reward,next_state,done) + #print("Reward = ",reward) + # 環境状態を次状態に変更。 + state = next_state + + # ゲーム終了後処理 + if done: + mean_steps = total_steps/(episode+1) + print("\nEpisode",episode,"done,Reward =",reward,"mean steps =",mean_steps,"exp_num =",agent.exp_pool.get_len(),"\nepsilon =",agent.epsilon) + agent.training() + if(reward >=10): + successTimes+=1 + this10TimesWin+=1 + else: + failTimes+=1 + successTimes_his.append(successTimes) + failTimes_his.append(failTimes) + if episode % 10 ==0 and episode !=0: + clear_output() + this10TimesWinPer = float(this10TimesWin/10) + this10TimesWin = 0 + MeanWinPerin10Times.append(this10TimesWinPer) + # 合計成功数(緑)、合計失敗数(赤)を図で表示する + if not args.silent: + plt.figure(figsize = (15,10)) + plt.plot(range(len(successTimes_his)), successTimes_his,color='green',linestyle='--', linewidth=1, label='TotalWinTimes') + plt.plot(range(len(successTimes_his)), failTimes_his,color='red', linewidth=1,marker='o', markersize=1, markerfacecolor='black',markeredgecolor='black',label='TotalFaildTimes') + # plt.savefig('output.jpg') + plt.legend() + plt.savefig("wintimes.png") + plt.show() + + #10回実行した後の成功確率を図で表示する + plt.figure(figsize=(15,10)) + plt.plot(MeanWinPerin10Times) + plt.savefig("steps.png") + plt.show() + break +env.close() +print("Finished~") \ No newline at end of file