File size: 47,254 Bytes
f386f57 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | {
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "52a17104",
"metadata": {},
"outputs": [],
"source": [
"import importlib\n",
"import Game2 \n",
"import numpy as np\n",
"\n",
"importlib.reload(Game2) \n",
"game_runner = Game2.RocketLandingGameRunner(width=800, height=600, render=False)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f0ad93a0",
"metadata": {},
"outputs": [],
"source": [
"MEMORY_SIZE = 100_000 \n",
"GAMMA = 0.995 \n",
"ALPHA = 1e-3 \n",
"NUM_STEPS_FOR_UPDATE = 4 \n",
"MINIBATCH_SIZE = 64 \n",
"E_DECAY = 0.995 \n",
"E_MIN = 0.001 "
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "663d87d0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5 4\n"
]
}
],
"source": [
"state_space_size=len(game_runner.state_space)\n",
"action_space_size=len(game_runner.action_space)\n",
"print(state_space_size,action_space_size)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "a8102d63",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[400. 300. 0. 0. 0.]\n"
]
}
],
"source": [
"inital_state = game_runner.reset()\n",
"print(inital_state)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "c1032039",
"metadata": {},
"outputs": [],
"source": [
"from collections import deque,namedtuple\n",
"import tensorflow as tf\n",
"q_network = tf.keras.Sequential([\n",
" tf.keras.layers.Input(shape=(state_space_size,)),\n",
" tf.keras.layers.Dense(64, activation='relu'),\n",
" tf.keras.layers.Dense(64, activation='relu'),\n",
" tf.keras.layers.Dense(64, activation='relu'),\n",
" tf.keras.layers.Dense(action_space_size, activation='linear')\n",
"])\n",
"target_network = tf.keras.Sequential([\n",
" tf.keras.layers.Input(shape=(state_space_size,)),\n",
" tf.keras.layers.Dense(64, activation='relu'),\n",
" tf.keras.layers.Dense(64, activation='relu'),\n",
" tf.keras.layers.Dense(64, activation='relu'),\n",
" tf.keras.layers.Dense(action_space_size, activation='linear')\n",
"])\n",
"optimizer = tf.keras.optimizers.Adam(learning_rate=ALPHA)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "d52372ee",
"metadata": {},
"outputs": [],
"source": [
"Experience = namedtuple(\"Experience\", field_names=[\"state\", \"action\", \"reward\", \"next_state\", \"done\"])"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "b4aa9676",
"metadata": {},
"outputs": [],
"source": [
"def compute_loss(experience,GAMMA,q_network,target_network):\n",
" states, actions, rewards, next_states, done_vals = experience\n",
" max_q=tf.reduce_max(target_network(next_states), axis=1)\n",
" target_q = rewards + (1 - done_vals) * GAMMA * max_q\n",
" q_values = q_network(states)\n",
" q_values = tf.gather_nd(q_values, tf.stack([tf.range(q_values.shape[0]),\n",
" tf.cast(actions, tf.int32)], axis=1))\n",
" loss=tf.keras.losses.MSE(target_q, q_values)\n",
" return loss"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "2131a447",
"metadata": {},
"outputs": [],
"source": [
"@tf.function\n",
"def Learning(experience,GAMMA):\n",
" with tf.GradientTape() as tape:\n",
" loss = compute_loss(experience, GAMMA, q_network, target_network)\n",
" gradients = tape.gradient(loss, q_network.trainable_variables)\n",
" optimizer.apply_gradients(zip(gradients, q_network.trainable_variables))\n",
" tau = 0.1\n",
" for target_param, q_param in zip(target_network.trainable_variables, q_network.trainable_variables):\n",
" target_param.assign(tau * q_param + (1.0 - tau) * target_param)\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "01f4f57a",
"metadata": {},
"outputs": [],
"source": [
"import random\n",
"def get_action(q_values, epsilon=0.01): \n",
" if random.random() > epsilon:\n",
" return np.argmax(q_values.numpy()[0])\n",
" else:\n",
" return random.choice(np.arange(4))"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "133eaed1",
"metadata": {},
"outputs": [],
"source": [
"def check_update_conditions(t, num_steps_upd, memory_buffer):\n",
" if (t + 1) % num_steps_upd == 0 and len(memory_buffer) > MINIBATCH_SIZE:\n",
" return True\n",
" else:\n",
" return False"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "c98ea751",
"metadata": {},
"outputs": [],
"source": [
"def get_experiences(memory_buffer):\n",
" experiences = random.sample(memory_buffer, k=MINIBATCH_SIZE)\n",
" states = tf.convert_to_tensor(np.array([e.state for e in experiences if e is not None]),dtype=tf.float32)\n",
" actions = tf.convert_to_tensor(np.array([e.action for e in experiences if e is not None]), dtype=tf.float32)\n",
" rewards = tf.convert_to_tensor(np.array([e.reward for e in experiences if e is not None]), dtype=tf.float32)\n",
" next_states = tf.convert_to_tensor(np.array([e.next_state for e in experiences if e is not None]),dtype=tf.float32)\n",
" done_vals = tf.convert_to_tensor(np.array([e.done for e in experiences if e is not None]).astype(np.uint8),\n",
" dtype=tf.float32)\n",
" return (states, actions, rewards, next_states, done_vals)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "bd6921de",
"metadata": {},
"outputs": [],
"source": [
"def get_new_eps(epsilon):\n",
" return max(E_MIN, E_DECAY*epsilon)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b1085588",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Episode 100 | Total point average of the last 100 episodes: 11.81\n",
"Episode 136 | Total point average of the last 100 episodes: 29.85"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Episode 137 | Total point average of the last 100 episodes: 30.15\n",
"\n",
"Environment solved in 137 episodes!\n",
"\n",
"Total Runtime: 138.98 s (2.32 min)\n"
]
}
],
"source": [
"import time\n",
"start = time.time()\n",
"num_episodes = 2000\n",
"max_num_timesteps = 1000\n",
"\n",
"total_point_history = []\n",
"\n",
"num_p_av = 100 \n",
"epsilon = 1.0 \n",
"\n",
"memory_buffer = deque(maxlen=MEMORY_SIZE)\n",
"target_network.set_weights(q_network.get_weights())\n",
"for i in range(num_episodes):\n",
" state=game_runner.reset()\n",
" total_points=0\n",
" for t in range(max_num_timesteps):\n",
" state_qn = np.expand_dims(state, axis=0) \n",
" q_values = q_network(state_qn)\n",
" action = get_action(q_values, epsilon)\n",
" next_state, reward, done = game_runner.step(action)\n",
" memory_buffer.append(Experience(state, action, reward, next_state, done))\n",
" update=check_update_conditions(t, NUM_STEPS_FOR_UPDATE, memory_buffer)\n",
" if update:\n",
" experience = get_experiences(memory_buffer)\n",
" Learning(experience, GAMMA)\n",
"\n",
" state = next_state.copy()\n",
" total_points += reward\n",
" if done:\n",
" break\n",
" total_point_history.append(total_points)\n",
" av_latest_points = np.mean(total_point_history[-num_p_av:])\n",
" epsilon = get_new_eps(epsilon)\n",
" \n",
"\n",
" print(f\"\\rEpisode {i+1} | Total point average of the last {num_p_av} episodes: {av_latest_points:.2f}\", end=\"\")\n",
"\n",
" if (i+1) % num_p_av == 0:\n",
" print(f\"\\rEpisode {i+1} | Total point average of the last {num_p_av} episodes: {av_latest_points:.2f}\")\n",
"\n",
" if av_latest_points >= 30.0:\n",
" print(f\"\\n\\nEnvironment solved in {i+1} episodes!\")\n",
" q_network.save('rocket_simulation.h5')\n",
" break\n",
" \n",
"tot_time = time.time() - start\n",
"\n",
"print(f\"\\nTotal Runtime: {tot_time:.2f} s ({(tot_time/60):.2f} min)\")\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "4e110ec2",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:absl:No training configuration found in the save file, so the model was *not* compiled. Compile it manually.\n"
]
}
],
"source": [
"from tensorflow.keras.models import load_model\n",
"\n",
"importlib.reload(Game2) \n",
"game_runner = Game2.RocketLandingGameRunner(width=800, height=600, render=False)\n",
"# Load the saved model\n",
"q_network = load_model('rocketsimulation.h5')\n",
"\n",
"game_runner2=Game2.RocketLandingGameRunner(width=800, height=600, render=True)\n",
"game_runner2.run(q_network)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "bb53647c",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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EREREZEJgyMiIiIiEwZHRERERCYMjoiIiIhMGBwRkU9Mnz7d5ezjaa1MmTLy/vvvSyA6cOCAZMqUyThtAhFlHAZHROQTjzzyiOzevdvXs0FE5CKr611EROkve/bs6kIZC2d9x0mviSh5zBwRUarOnj1u3Dh1VnUEOLVq1ZIffvjBeHzZsmWqSeiPP/6QmjVrSlhYmNx1112yffv2ZJvV/v77b7n33nslV65c6szaOEP5hg0bjMd//PFHqVatmoSGhqrmsnfffddpnnB27vvvv1/ND+brm2++cZnvCxcuyJNPPikFCxZU79GiRQv1vrdq2vrpp5/UvIWHh6vPGhkZaUwzatQoqV27ttPz0JSHedR69+4tnTp1krfeeksKFy6sPveYMWMkNjZWhg4dKvny5ZMSJUrItGnTXOZh165d0rhxY7UMq1evLsuXL3d6HMu0Xbt2kjNnTvXaPXv2lDNnzhiPN2/eXJ577jkZOHCgFChQQNq0aZPs5yWiBAyOiMhrCIy+/PJLmTp1quzYsUMGDRokjz32mMuOGzt+BDHr169XAQmCl5s3b7p9zUcffVQFCJh248aNMmzYMMmWLZt6DLcffvhh6datm2zbtk0FJK+//roKsMwByOHDh2Xp0qUqUJsyZYoKmMweeughdd+8efPUa9atW1datmwp586dS/Hzvvrqq/LSSy+p+p877rhDunfvrgIbbyxZskSOHTsmK1askIkTJ8rIkSOlQ4cOkjdvXlm7dq30799fnn76aTly5IjLMhwyZIhs3rxZGjVqpJbh2bNnjWAPAV6dOnVUIDl//nw5efKkWlZmM2bMUNmiv/76S31nRHQLaXL6WiKyjevXr6uzha9evdrp/r59+zq6d++u/l+6dKk62/rMmTONx8+ePavOnv3999+r2zgTe0REhPF4rly5HNOnT3f7nj169HDcd999TvfhLN1Vq1ZV/0dFRan3W7dunfH4zp071X3vvfeeur1y5UpH7ty51fyblS9f3vHJJ5+4fd/9+/er1/j888+N+3bs2KHuw+vDyJEjHbVq1XJ6Ht4TZxzXevXqpW7HxcUZ91WqVMnRpEkT43ZsbKwjR44cju+++87pvcePH29MgzOOlyhRwvHf//5X3R47dqyjdevWTu99+PBh9TwsE2jWrJmjTp06bj8fEbnHmiMi8sqePXvk6tWrct9997nUsiCDYYZMh4amo0qVKsnOnTvdvu7gwYNVk9dXX30lrVq1Ulme8uXLq8fwnI4dOzpNf/fdd6vmq7i4OPV41qxZVVOcVrlyZZdmu8uXL0v+/PmdXufatWuyd+/eFD8zmga1okWLqmtkoPAenkKTYObMScl6NIGhmUzLkiWLmjdrtsu8DPEZ69evbyxDfCZkytCkZoXPhCwXmJcLEd0agyMi8goCDEA9UfHixZ0eQz1QaqGprEePHup10eyFZqeZM2dK586dJa3mG4EN6qGsbjWkgG7eA9Qg6borQMDjcCBZk8Rd06H5NfTruLtPv66nnwnNbP/9739dHtNBHOTIkcPj1yQiBkdE5KWqVauqIOjQoUPSrFmzFKdds2aNlCpVSv1//vx51XW/SpUqyU6PTAcuqGFCXQ8KlBEc4TmolzHDbUyLjAsyOKgBQh3RnXfeqR6PiopSNTka6otOnDihsi/mYunbhVoqvC4CJB04peXYRFiGTZs2Vf/rz4gCa/2ZUKiOz4PPRURpgwXZROQV9CZDcTICGBT6ovlm06ZN8tFHH6nbZuiRtXjxYtWjCgXT6C2FXltWaNrCDh9ZnYMHD6rAB4XZOpBCQTJeZ+zYsSrAwvtMmjRJzQegua5t27aqoBnFzQgg0ERnHioATXVoosL7L1iwQPVEW716tSq2NveK8xZ6g50+fVomTJiglsXkyZNV5iut4PXmzJmjeq0NGDBABZlPPPGEegy3UUyOQBLLC+//559/Sp8+fVRzIxGlDoMjIvIaghT0FkOvNQQwCEzQHIYu9Gbjx4+XF198UdW8ILvy22+/uR1jB9kf9MB6/PHHVTYIva3QPX306NFGhmTWrFmqmQ11OiNGjFCBFwIuDVmmYsWKqWxWly5dpF+/flKoUCHjcWR15s6dq7IwCB7wPuj9hmAM9T+phc+PnnEIYtDNf926dUbQlhawDHHBa69atUp+/fVXFWQCPi8CSQRCrVu3lho1aqgu+2gmNNc3EZF3MqEq28vnEBGlCBkgjAuELEd6nyKEiCit8dCCiIiIyITBEREREZEJm9WIiIiITJg5IiIiIjJhcERERERkwuCIiIiIyITBEREREZEJgyMiIiIiEwZHRERERCYMjoiIiIhMGBwRERERmTA4IiIiIpIk/w83A+V+x/+FAAAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib as plt\n",
"plt.pyplot.plot(list(range(1,len(total_point_history)+1)),total_point_history)\n",
"plt.pyplot.title('Total Points per Episode')\n",
"plt.pyplot.xlabel('episode number')\n",
"plt.pyplot.ylabel('total points')\n",
"plt.pyplot.show()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "93a47de7",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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": "3.11.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
|