{ "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": [ "
" ] }, "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 }