From 6a830b44ae0c084b7b93df44905ed818226b522f Mon Sep 17 00:00:00 2001 From: Vadim Liventsev Date: Fri, 16 Feb 2024 13:03:57 +0100 Subject: [PATCH] Upgraded from gym to Gymnasium --- colab/Colab_UnityEnvironment_1_Run.ipynb | 366 +++++++++--------- ...olab_UnityEnvironment_4_SB3VectorEnv.ipynb | 4 +- docs/Installation-Anaconda-Windows.md | 2 +- docs/Python-Gym-API.md | 2 +- .../KR/docs/Installation-Anaconda-Windows.md | 2 +- localized_docs/KR/docs/Installation.md | 2 +- ...20\275\320\276\320\262\320\272\320\260.md" | 2 +- localized_docs/TR/docs/Installation.md | 2 +- .../mlagents_envs/envs/unity_gym_env.py | 52 ++- 9 files changed, 214 insertions(+), 220 deletions(-) diff --git a/colab/Colab_UnityEnvironment_1_Run.ipynb b/colab/Colab_UnityEnvironment_1_Run.ipynb index 8d9dc53638..04cd03a51d 100644 --- a/colab/Colab_UnityEnvironment_1_Run.ipynb +++ b/colab/Colab_UnityEnvironment_1_Run.ipynb @@ -1,29 +1,4 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "Colab-UnityEnvironment-1-Run.ipynb", - "private_outputs": true, - "provenance": [], - "collapsed_sections": [], - "toc_visible": true - }, - "kernelspec": { - "name": "python3", - "language": "python", - "display_name": "Python 3" - }, - "pycharm": { - "stem_cell": { - "cell_type": "raw", - "source": [], - "metadata": { - "collapsed": false - } - } - } - }, "cells": [ { "cell_type": "markdown", @@ -46,9 +21,11 @@ }, { "cell_type": "code", + "execution_count": null, "metadata": { "id": "htb-p1hSNX7D" }, + "outputs": [], "source": [ "#@title Install Rendering Dependencies { display-mode: \"form\" }\n", "#@markdown (You only need to run this code when using Colab's hosted runtime)\n", @@ -122,9 +99,7 @@ " !bash frame-buffer start\n", " os.environ[\"DISPLAY\"] = \":1\"\n", "pro_bar.update(progress(100, 100))" - ], - "execution_count": null, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -137,22 +112,14 @@ }, { "cell_type": "code", + "execution_count": 1, "metadata": { - "id": "N8yfQqkbebQ5", "ExecuteTime": { - "start_time": "2023-10-04T12:52:21.641839Z", - "end_time": "2023-10-04T12:52:21.642251Z" - } + "end_time": "2023-10-04T12:52:21.642251Z", + "start_time": "2023-10-04T12:52:21.641839Z" + }, + "id": "N8yfQqkbebQ5" }, - "source": [ - "try:\n", - " import mlagents\n", - " print(\"ml-agents already installed\")\n", - "except ImportError:\n", - " !python -m pip install -q mlagents==1.0.0\n", - " print(\"Installed ml-agents\")" - ], - "execution_count": 1, "outputs": [ { "name": "stdout", @@ -161,6 +128,14 @@ "ml-agents already installed\n" ] } + ], + "source": [ + "try:\n", + " import mlagents\n", + " print(\"ml-agents already installed\")\n", + "except ImportError:\n", + " !python -m pip install -q mlagents==1.0.0\n", + " print(\"Installed ml-agents\")" ] }, { @@ -174,19 +149,19 @@ }, { "cell_type": "code", + "execution_count": 2, "metadata": { - "id": "DpZPbRvRuLZv", "ExecuteTime": { - "start_time": "2023-10-04T12:52:23.330185Z", - "end_time": "2023-10-04T12:52:23.339236Z" - } + "end_time": "2023-10-04T12:52:23.339236Z", + "start_time": "2023-10-04T12:52:23.330185Z" + }, + "id": "DpZPbRvRuLZv" }, + "outputs": [], "source": [ "#@title Select Environment { display-mode: \"form\" }\n", "env_id = \"GridWorld\" #@param ['Basic', '3DBall', '3DBallHard', 'GridWorld', 'Hallway', 'VisualHallway', 'CrawlerDynamicTarget', 'CrawlerStaticTarget', 'Bouncer', 'SoccerTwos', 'PushBlock', 'VisualPushBlock', 'WallJump', 'Tennis', 'Reacher', 'Pyramids', 'VisualPyramids', 'Walker', 'FoodCollector', 'VisualFoodCollector', 'StrikersVsGoalie', 'WormStaticTarget', 'WormDynamicTarget']\n" - ], - "execution_count": 2, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -199,27 +174,14 @@ }, { "cell_type": "code", + "execution_count": 3, "metadata": { - "id": "YSf-WhxbqtLw", "ExecuteTime": { - "start_time": "2023-10-04T12:52:25.056933Z", - "end_time": "2023-10-04T12:52:26.115543Z" - } + "end_time": "2023-10-04T12:52:26.115543Z", + "start_time": "2023-10-04T12:52:25.056933Z" + }, + "id": "YSf-WhxbqtLw" }, - "source": [ - "# -----------------\n", - "# This code is used to close an env that might not have been closed before\n", - "try:\n", - " env.close()\n", - "except:\n", - " pass\n", - "# -----------------\n", - "\n", - "from mlagents_envs.registry import default_registry\n", - "\n", - "env = default_registry[env_id].make()" - ], - "execution_count": 3, "outputs": [ { "name": "stdout", @@ -257,6 +219,19 @@ " \"memorysetup-temp-allocator-size-gfx=262144\"\n" ] } + ], + "source": [ + "# -----------------\n", + "# This code is used to close an env that might not have been closed before\n", + "try:\n", + " env.close()\n", + "except:\n", + " pass\n", + "# -----------------\n", + "\n", + "from mlagents_envs.registry import default_registry\n", + "\n", + "env = default_registry[env_id].make()" ] }, { @@ -271,18 +246,18 @@ }, { "cell_type": "code", + "execution_count": 4, "metadata": { - "id": "dhtl0mpeqxYi", "ExecuteTime": { - "start_time": "2023-10-04T12:52:40.819560Z", - "end_time": "2023-10-04T12:52:41.038983Z" - } + "end_time": "2023-10-04T12:52:41.038983Z", + "start_time": "2023-10-04T12:52:40.819560Z" + }, + "id": "dhtl0mpeqxYi" }, + "outputs": [], "source": [ "env.reset()" - ], - "execution_count": 4, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -304,20 +279,14 @@ }, { "cell_type": "code", + "execution_count": 5, "metadata": { - "id": "a7KatdThq7OV", "ExecuteTime": { - "start_time": "2023-10-04T12:52:47.812858Z", - "end_time": "2023-10-04T12:52:47.820527Z" - } + "end_time": "2023-10-04T12:52:47.820527Z", + "start_time": "2023-10-04T12:52:47.812858Z" + }, + "id": "a7KatdThq7OV" }, - "source": [ - "# We will only consider the first Behavior\n", - "behavior_name = list(env.behavior_specs)[0]\n", - "print(f\"Name of the behavior : {behavior_name}\")\n", - "spec = env.behavior_specs[behavior_name]" - ], - "execution_count": 5, "outputs": [ { "name": "stdout", @@ -326,6 +295,12 @@ "Name of the behavior : GridWorld?team=0\n" ] } + ], + "source": [ + "# We will only consider the first Behavior\n", + "behavior_name = list(env.behavior_specs)[0]\n", + "print(f\"Name of the behavior : {behavior_name}\")\n", + "spec = env.behavior_specs[behavior_name]" ] }, { @@ -339,23 +314,14 @@ }, { "cell_type": "code", + "execution_count": 6, "metadata": { - "id": "PqDTV5mSrJF5", "ExecuteTime": { - "start_time": "2023-10-04T12:52:50.586284Z", - "end_time": "2023-10-04T12:52:50.596936Z" - } + "end_time": "2023-10-04T12:52:50.596936Z", + "start_time": "2023-10-04T12:52:50.586284Z" + }, + "id": "PqDTV5mSrJF5" }, - "source": [ - "# Examine the number of observations per Agent\n", - "print(\"Number of observations : \", len(spec.observation_specs))\n", - "\n", - "# Is there a visual observation ?\n", - "# Visual observation have 3 dimensions: Height, Width and number of channels\n", - "vis_obs = any(len(spec.shape) == 3 for spec in spec.observation_specs)\n", - "print(\"Is there a visual observation ?\", vis_obs)" - ], - "execution_count": 6, "outputs": [ { "name": "stdout", @@ -365,6 +331,15 @@ "Is there a visual observation ? True\n" ] } + ], + "source": [ + "# Examine the number of observations per Agent\n", + "print(\"Number of observations : \", len(spec.observation_specs))\n", + "\n", + "# Is there a visual observation ?\n", + "# Visual observation have 3 dimensions: Height, Width and number of channels\n", + "vis_obs = any(len(spec.shape) == 3 for spec in spec.observation_specs)\n", + "print(\"Is there a visual observation ?\", vis_obs)" ] }, { @@ -378,13 +353,24 @@ }, { "cell_type": "code", + "execution_count": 7, "metadata": { - "id": "M9zk1-az1L-G", "ExecuteTime": { - "start_time": "2023-10-04T12:52:52.411887Z", - "end_time": "2023-10-04T12:52:52.456259Z" - } + "end_time": "2023-10-04T12:52:52.456259Z", + "start_time": "2023-10-04T12:52:52.411887Z" + }, + "id": "M9zk1-az1L-G" }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "There are 1 discrete actions\n", + "Action number 0 has 5 different options\n" + ] + } + ], "source": [ "# Is the Action continuous or multi-discrete ?\n", "if spec.action_spec.continuous_size > 0:\n", @@ -401,17 +387,6 @@ " for action, branch_size in enumerate(spec.action_spec.discrete_branches):\n", " print(f\"Action number {action} has {branch_size} different options\")\n", "\n" - ], - "execution_count": 7, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "There are 1 discrete actions\n", - "Action number 0 has 5 different options\n" - ] - } ] }, { @@ -436,18 +411,18 @@ }, { "cell_type": "code", + "execution_count": 8, "metadata": { - "id": "ePZtcHXUrjyf", "ExecuteTime": { - "start_time": "2023-10-04T12:52:55.105403Z", - "end_time": "2023-10-04T12:52:55.111994Z" - } + "end_time": "2023-10-04T12:52:55.111994Z", + "start_time": "2023-10-04T12:52:55.105403Z" + }, + "id": "ePZtcHXUrjyf" }, + "outputs": [], "source": [ "decision_steps, terminal_steps = env.get_steps(behavior_name)" - ], - "execution_count": 8, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -461,18 +436,18 @@ }, { "cell_type": "code", + "execution_count": 9, "metadata": { - "id": "KB-nxfbw337g", "ExecuteTime": { - "start_time": "2023-10-04T12:52:56.360968Z", - "end_time": "2023-10-04T12:52:56.368561Z" - } + "end_time": "2023-10-04T12:52:56.368561Z", + "start_time": "2023-10-04T12:52:56.360968Z" + }, + "id": "KB-nxfbw337g" }, + "outputs": [], "source": [ "env.set_actions(behavior_name, spec.action_spec.empty_action(len(decision_steps)))" - ], - "execution_count": 9, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -486,18 +461,18 @@ }, { "cell_type": "code", + "execution_count": 10, "metadata": { - "id": "nl3K40ZR4bh2", "ExecuteTime": { - "start_time": "2023-10-04T12:52:57.609971Z", - "end_time": "2023-10-04T12:52:57.664885Z" - } + "end_time": "2023-10-04T12:52:57.664885Z", + "start_time": "2023-10-04T12:52:57.609971Z" + }, + "id": "nl3K40ZR4bh2" }, + "outputs": [], "source": [ "env.step()" - ], - "execution_count": 10, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -521,29 +496,14 @@ }, { "cell_type": "code", + "execution_count": 11, "metadata": { - "id": "OJpta61TsBiO", "ExecuteTime": { - "start_time": "2023-10-04T12:53:00.550680Z", - "end_time": "2023-10-04T12:53:00.862654Z" - } + "end_time": "2023-10-04T12:53:00.862654Z", + "start_time": "2023-10-04T12:53:00.550680Z" + }, + "id": "OJpta61TsBiO" }, - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "%matplotlib inline\n", - "\n", - "for index, obs_spec in enumerate(spec.observation_specs):\n", - " if len(obs_spec.shape) == 3:\n", - " print(\"Here is the first visual observation\")\n", - " plt.imshow(np.moveaxis(decision_steps.obs[index][0, :, :, :], 0, -1))\n", - " plt.show()\n", - "\n", - "for index, obs_spec in enumerate(spec.observation_specs):\n", - " if len(obs_spec.shape) == 1:\n", - " print(\"First vector observations : \", decision_steps.obs[index][0,:])" - ], - "execution_count": 11, "outputs": [ { "name": "stdout", @@ -554,8 +514,10 @@ }, { "data": { - "text/plain": "
", - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhQAAAGfCAYAAAAH5UtjAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAk3ElEQVR4nO3df3BU1f3/8dduyG6iwEZQNkQSjD+DP6AYNKxgWzEtQx0rhVq12OKP6mgD8sNWiQpoq8bqVPFHxGox1FGaEUdQbIXaKOFrGxAiqGgbUalEYYPWZgMomww53z/8uOPCXuXmbNzN5vmYuTPm3LMn75OLm1fu3nOvxxhjBAAAYMGb6gIAAEDPR6AAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADW+nTXwNXV1brrrrsUDoc1YsQI3X///Tr99NO/9nWdnZ3avn27+vXrJ4/H013lAQCAr2GM0a5du1RQUCCv92vOQZhuUFtba3w+n3n00UfNm2++aa644gqTl5dnWlpavva1zc3NRhIbGxsbGxtbmmzNzc1f+/vbY0zyHw5WVlam0047TQ888ICkz886FBYWavr06ZozZ85XvjYSiSgvL08Xnz9Rvuzs/fYmvVQAABAT/8lAe0eHHl+6XK2trQoEAl/5yqR/5NHe3q7GxkZVVlbG2rxer8rLy9XQ0HBA/2g0qmg0Gvt6165dkiRfdrZ8PgIFAADfnMSXGhzMJQhJvyjz448/1r59+xQMBuPag8GgwuHwAf2rqqoUCARiW2FhYbJLAgAA3SzlqzwqKysViURiW3Nzc6pLAgAALiX9I4/DDz9cWVlZamlpiWtvaWlRfn7+Af39fr/8fn+Ckb64FgQAAHwz9v+9e/C/h5N+hsLn86m0tFR1dXWxts7OTtXV1SkUCiX72wEAgDTQLfehmD17tqZOnapRo0bp9NNP14IFC7Rnzx5deuml3fHtAABAinVLoLjgggv00Ucfad68eQqHw/rWt76llStXHnChJgAAyAzddqfMadOmadq0ad01PAAASCMpX+UBAAB6PgIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYM11oFizZo3OPfdcFRQUyOPxaPny5XH7jTGaN2+eBg8erNzcXJWXl2vLli3JqhcAAKQh14Fiz549GjFihKqrqxPuv/POO3XffffpoYce0rp163TooYdq/Pjx2rt3r3WxAAAgPfVx+4IJEyZowoQJCfcZY7RgwQLddNNNOu+88yRJjz32mILBoJYvX64LL7zwgNdEo1FFo9HY121tbW5LAgAAKZbUayi2bt2qcDis8vLyWFsgEFBZWZkaGhoSvqaqqkqBQCC2FRYWJrMkAADwDUhqoAiHw5KkYDAY1x4MBmP79ldZWalIJBLbmpubk1kSAAD4Brj+yCPZ/H6//H5/qssAAAAWknqGIj8/X5LU0tIS197S0hLbBwAAMk9SA0VxcbHy8/NVV1cXa2tra9O6desUCoWS+a0AAEAacf2Rx+7du/XOO+/Evt66das2bdqkAQMGqKioSDNnztStt96q4447TsXFxZo7d64KCgo0ceLEZNYNAADSiOtAsWHDBp111lmxr2fPni1Jmjp1qhYvXqzrrrtOe/bs0ZVXXqnW1laNHTtWK1euVE5OTvKqBgAAacVjjDGpLuLL2traFAgEdNlPfyyfLzvV5QAA0Gu1t3fo0SVPKRKJqH///l/Zl2d5AAAAawQKAABgjUABAACsESgAAIA1AgUAALBGoAAAANYIFAAAwBqBAgAAWCNQAAAAawQKAABgjUABAACsESgAAIA1AgUAALBGoAAAANYIFAAAwBqBAgAAWCNQAAAAawQKAABgjUABAACsESgAAIA1AgUAALBGoAAAANYIFAAAwFqfVBcA9DR9g0cnbPckaDMux040RrcP7jBOombH+hx4sxL/zeLxuB0p4SjWvZNTR3J88kFTqksArHCGAgAAWCNQAAAAawQKAABgjUABAACsESgAAIA1VnkALrlcLJEUxsXgjvU5juG048CRnHp6vU5/mzhUk5QflsMgTj8Az4E1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du0yGzduNBs3bjSSzN133202btxo3n//fWPM58t88vLyzDPPPGNef/11c9555/W4JVtXX321CQQCZvXq1XFLtz799NNYn6uuusoUFRWZF1980WzYsMGEQiETCoVSWLV7c+bMMfX19Wbr1q3m9ddfN3PmzDEej8f87W9/M8ZkxhwT+fIqD2MyY57XXnutWb16tdm6dav5xz/+YcrLy83hhx9udu7caYzJjDka8/nS3z59+pjbbrvNbNmyxTzxxBPmkEMOMY8//nisTya8Bxnz+arAoqIic/311x+wLxOO59SpU82RRx4ZWzb69NNPm8MPP9xcd911sT6pOJZpGyiMMeb+++83RUVFxufzmdNPP92sXbs21SVZeemll4ykA7apU6caYz5f6jN37lwTDAaN3+83Z599tmlqakpt0S4lmp8kU1NTE+vz2WefmV/+8pfmsMMOM4cccoj50Y9+ZHbs2JG6orvgsssuM0OHDjU+n88cccQR5uyzz46FCWMyY46J7B8oMmGeF1xwgRk8eLDx+XzmyCOPNBdccEHcvRkyYY5fWLFihTn55JON3+83JSUl5uGHH47bnwnvQcYYs2rVKiMpYe2ZcDzb2trMjBkzTFFRkcnJyTFHH320ufHGG000Go31ScWx9BjzpVtrAQAAdEFaXkMBAAB6FgIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADW/j+eh66m08pdXQAAAABJRU5ErkJggg==" + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhQAAAGfCAYAAAAH5UtjAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAk3ElEQVR4nO3df3BU1f3/8dduyG6iwEZQNkQSjD+DP6AYNKxgWzEtQx0rhVq12OKP6mgD8sNWiQpoq8bqVPFHxGox1FGaEUdQbIXaKOFrGxAiqGgbUalEYYPWZgMomww53z/8uOPCXuXmbNzN5vmYuTPm3LMn75OLm1fu3nOvxxhjBAAAYMGb6gIAAEDPR6AAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADW+nTXwNXV1brrrrsUDoc1YsQI3X///Tr99NO/9nWdnZ3avn27+vXrJ4/H013lAQCAr2GM0a5du1RQUCCv92vOQZhuUFtba3w+n3n00UfNm2++aa644gqTl5dnWlpavva1zc3NRhIbGxsbGxtbmmzNzc1f+/vbY0zyHw5WVlam0047TQ888ICkz886FBYWavr06ZozZ85XvjYSiSgvL08Xnz9Rvuzs/fYmvVQAABAT/8lAe0eHHl+6XK2trQoEAl/5yqR/5NHe3q7GxkZVVlbG2rxer8rLy9XQ0HBA/2g0qmg0Gvt6165dkiRfdrZ8PgIFAADfnMSXGhzMJQhJvyjz448/1r59+xQMBuPag8GgwuHwAf2rqqoUCARiW2FhYbJLAgAA3SzlqzwqKysViURiW3Nzc6pLAgAALiX9I4/DDz9cWVlZamlpiWtvaWlRfn7+Af39fr/8fn+Ckb64FgQAAHwz9v+9e/C/h5N+hsLn86m0tFR1dXWxts7OTtXV1SkUCiX72wEAgDTQLfehmD17tqZOnapRo0bp9NNP14IFC7Rnzx5deuml3fHtAABAinVLoLjgggv00Ucfad68eQqHw/rWt76llStXHnChJgAAyAzddqfMadOmadq0ad01PAAASCMpX+UBAAB6PgIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYM11oFizZo3OPfdcFRQUyOPxaPny5XH7jTGaN2+eBg8erNzcXJWXl2vLli3JqhcAAKQh14Fiz549GjFihKqrqxPuv/POO3XffffpoYce0rp163TooYdq/Pjx2rt3r3WxAAAgPfVx+4IJEyZowoQJCfcZY7RgwQLddNNNOu+88yRJjz32mILBoJYvX64LL7zwgNdEo1FFo9HY121tbW5LAgAAKZbUayi2bt2qcDis8vLyWFsgEFBZWZkaGhoSvqaqqkqBQCC2FRYWJrMkAADwDUhqoAiHw5KkYDAY1x4MBmP79ldZWalIJBLbmpubk1kSAAD4Brj+yCPZ/H6//H5/qssAAAAWknqGIj8/X5LU0tIS197S0hLbBwAAMk9SA0VxcbHy8/NVV1cXa2tra9O6desUCoWS+a0AAEAacf2Rx+7du/XOO+/Evt66das2bdqkAQMGqKioSDNnztStt96q4447TsXFxZo7d64KCgo0ceLEZNYNAADSiOtAsWHDBp111lmxr2fPni1Jmjp1qhYvXqzrrrtOe/bs0ZVXXqnW1laNHTtWK1euVE5OTvKqBgAAacVjjDGpLuLL2traFAgEdNlPfyyfLzvV5QAA0Gu1t3fo0SVPKRKJqH///l/Zl2d5AAAAawQKAABgjUABAACsESgAAIA1AgUAALBGoAAAANYIFAAAwBqBAgAAWCNQAAAAawQKAABgjUABAACsESgAAIA1AgUAALBGoAAAANYIFAAAwBqBAgAAWCNQAAAAawQKAABgjUABAACsESgAAIA1AgUAALBGoAAAANYIFAAAwFqfVBcA9DR9g0cnbPckaDMux040RrcP7jBOombH+hx4sxL/zeLxuB0p4SjWvZNTR3J88kFTqksArHCGAgAAWCNQAAAAawQKAABgjUABAACsESgAAIA1VnkALrlcLJEUxsXgjvU5juG048CRnHp6vU5/mzhUk5QflsMgTj8Az4E1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du0yGzduNBs3bjSSzN133202btxo3n//fWPM58t88vLyzDPPPGNef/11c9555/W4JVtXX321CQQCZvXq1XFLtz799NNYn6uuusoUFRWZF1980WzYsMGEQiETCoVSWLV7c+bMMfX19Wbr1q3m9ddfN3PmzDEej8f87W9/M8ZkxhwT+fIqD2MyY57XXnutWb16tdm6dav5xz/+YcrLy83hhx9udu7caYzJjDka8/nS3z59+pjbbrvNbNmyxTzxxBPmkEMOMY8//nisTya8Bxnz+arAoqIic/311x+wLxOO59SpU82RRx4ZWzb69NNPm8MPP9xcd911sT6pOJZpGyiMMeb+++83RUVFxufzmdNPP92sXbs21SVZeemll4ykA7apU6caYz5f6jN37lwTDAaN3+83Z599tmlqakpt0S4lmp8kU1NTE+vz2WefmV/+8pfmsMMOM4cccoj50Y9+ZHbs2JG6orvgsssuM0OHDjU+n88cccQR5uyzz46FCWMyY46J7B8oMmGeF1xwgRk8eLDx+XzmyCOPNBdccEHcvRkyYY5fWLFihTn55JON3+83JSUl5uGHH47bnwnvQcYYs2rVKiMpYe2ZcDzb2trMjBkzTFFRkcnJyTFHH320ufHGG000Go31ScWx9BjzpVtrAQAAdEFaXkMBAAB6FgIFAACwRqAAAADWCBQAAMAagQIAAFgjUAAAAGsECgAAYI1AAQAArBEoAACANQIFAACwRqAAAADW/j+eh66m08pdXQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] }, "metadata": {}, "output_type": "display_data" @@ -567,6 +529,21 @@ "First vector observations : [1. 0.]\n" ] } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "%matplotlib inline\n", + "\n", + "for index, obs_spec in enumerate(spec.observation_specs):\n", + " if len(obs_spec.shape) == 3:\n", + " print(\"Here is the first visual observation\")\n", + " plt.imshow(np.moveaxis(decision_steps.obs[index][0, :, :, :], 0, -1))\n", + " plt.show()\n", + "\n", + "for index, obs_spec in enumerate(spec.observation_specs):\n", + " if len(obs_spec.shape) == 1:\n", + " print(\"First vector observations : \", decision_steps.obs[index][0,:])" ] }, { @@ -580,13 +557,25 @@ }, { "cell_type": "code", + "execution_count": 12, "metadata": { - "id": "a2uQUsoMtIUK", "ExecuteTime": { - "start_time": "2023-10-04T12:53:02.785602Z", - "end_time": "2023-10-04T12:53:04.145406Z" - } + "end_time": "2023-10-04T12:53:04.145406Z", + "start_time": "2023-10-04T12:53:02.785602Z" + }, + "id": "a2uQUsoMtIUK" }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total rewards for episode 0 is -1.1499999966472387\n", + "Total rewards for episode 1 is -1.5599999874830246\n", + "Total rewards for episode 2 is -1.049999998882413\n" + ] + } + ], "source": [ "for episode in range(3):\n", " env.reset()\n", @@ -617,18 +606,6 @@ " episode_rewards += terminal_steps[tracked_agent].reward\n", " done = True\n", " print(f\"Total rewards for episode {episode} is {episode_rewards}\")\n" - ], - "execution_count": 12, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Total rewards for episode 0 is -1.1499999966472387\n", - "Total rewards for episode 1 is -1.5599999874830246\n", - "Total rewards for episode 2 is -1.049999998882413\n" - ] - } ] }, { @@ -642,18 +619,14 @@ }, { "cell_type": "code", + "execution_count": 13, "metadata": { - "id": "vdWG6_SqtNtv", "ExecuteTime": { - "start_time": "2023-10-04T12:53:06.093669Z", - "end_time": "2023-10-04T12:53:06.416573Z" - } + "end_time": "2023-10-04T12:53:06.416573Z", + "start_time": "2023-10-04T12:53:06.093669Z" + }, + "id": "vdWG6_SqtNtv" }, - "source": [ - "env.close()\n", - "print(\"Closed environment\")\n" - ], - "execution_count": 13, "outputs": [ { "name": "stdout", @@ -662,7 +635,36 @@ "Closed environment\n" ] } + ], + "source": [ + "env.close()\n", + "print(\"Closed environment\")\n" ] } - ] + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Colab-UnityEnvironment-1-Run.ipynb", + "private_outputs": true, + "provenance": [], + "toc_visible": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "pycharm": { + "stem_cell": { + "cell_type": "raw", + "metadata": { + "collapsed": false + }, + "source": [] + } + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/colab/Colab_UnityEnvironment_4_SB3VectorEnv.ipynb b/colab/Colab_UnityEnvironment_4_SB3VectorEnv.ipynb index 59fa645884..9d53d20a2d 100644 --- a/colab/Colab_UnityEnvironment_4_SB3VectorEnv.ipynb +++ b/colab/Colab_UnityEnvironment_4_SB3VectorEnv.ipynb @@ -161,8 +161,8 @@ "from pathlib import Path\n", "from typing import Callable, Any\n", "\n", - "import gym\n", - "from gym import Env\n", + "import gymnasium as gym\n", + "from gymnasium import Env\n", "\n", "from stable_baselines3 import PPO\n", "from stable_baselines3.common.vec_env import VecMonitor, VecEnv, SubprocVecEnv\n", diff --git a/docs/Installation-Anaconda-Windows.md b/docs/Installation-Anaconda-Windows.md index ef5053f6e3..9935240441 100644 --- a/docs/Installation-Anaconda-Windows.md +++ b/docs/Installation-Anaconda-Windows.md @@ -144,7 +144,7 @@ reinforcement learning trainers to use with Unity environments. The `ml-agents-envs` subdirectory contains a Python API to interface with Unity, which the `ml-agents` package depends on. -The `gym-unity` subdirectory contains a package to interface with OpenAI Gym. +The `gym-unity` subdirectory contains a package to interface with Gymnasium. Keep in mind where the files were downloaded, as you will need the trainer config files in this directory when running `mlagents-learn`. Make sure you are diff --git a/docs/Python-Gym-API.md b/docs/Python-Gym-API.md index 50051195ed..c29255262c 100644 --- a/docs/Python-Gym-API.md +++ b/docs/Python-Gym-API.md @@ -93,7 +93,7 @@ observation, a single discrete action and a single Agent in the scene. Add the following code to the `train_unity.py` file: ```python -import gym +import gymnasium as gym from baselines import deepq from baselines import logger diff --git a/localized_docs/KR/docs/Installation-Anaconda-Windows.md b/localized_docs/KR/docs/Installation-Anaconda-Windows.md index ffe801ad77..b3230718e0 100644 --- a/localized_docs/KR/docs/Installation-Anaconda-Windows.md +++ b/localized_docs/KR/docs/Installation-Anaconda-Windows.md @@ -112,7 +112,7 @@ git clone https://github.com/Unity-Technologies/ml-agents.git `ml-agents-envs` ���� ���丮���� `ml-agents` ��Ű���� ���ӵǴ� ����Ƽ�� �������̽��� ���� ���̽� API�� ���ԵǾ� �ֽ��ϴ�. -`gym-unity` ���� ���丮���� OpenAI Gym�� �������̽��� ���� ��Ű���� ���ԵǾ� �ֽ��ϴ�. +`gym-unity` ���� ���丮���� Gymnasium�� �������̽��� ���� ��Ű���� ���ԵǾ� �ֽ��ϴ�. `mlagents-learn`�� ������ �� Ʈ���̳��� ȯ�� ���� ������ �� ���丮 �ȿ� �ʿ��ϹǷ�, ������ �ٿ�ε� �� ���丮�� ��ġ�� ����Ͻʽÿ�. ���ͳ��� ����Ǿ����� Ȯ���ϰ� Anaconda ������Ʈ���� ���� ��ɾ Ÿ���� �Ͻʽÿ�t: diff --git a/localized_docs/KR/docs/Installation.md b/localized_docs/KR/docs/Installation.md index dc525b1f1f..64d4460ba3 100644 --- a/localized_docs/KR/docs/Installation.md +++ b/localized_docs/KR/docs/Installation.md @@ -36,7 +36,7 @@ git clone https://github.com/Unity-Technologies/ml-agents.git `ml-agents-envs` 하위 디렉토리에는 `ml-agents` 패키지에 종속되는 유니티의 인터페이스를 위한 파이썬 API가 포함되어 있습니다. -`gym-unity` 하위 디렉토리에는 OpenAI Gym의 인터페이스를 위한 패키지가 포함되어 있습니다. +`gym-unity` 하위 디렉토리에는 Gymnasium의 인터페이스를 위한 패키지가 포함되어 있습니다. ### 파이썬과 mlagents 패키지 설치 diff --git "a/localized_docs/RU/docs/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260.md" "b/localized_docs/RU/docs/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260.md" index eaeaa1a7ed..6b2b7948d6 100644 --- "a/localized_docs/RU/docs/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260.md" +++ "b/localized_docs/RU/docs/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\320\272\320\260.md" @@ -12,7 +12,7 @@ ML-Agents Toolkit состоит из нескольких компоненто API для взаимодействия с Unity сценой. Этот пакет управляет передачей данных между Unity сценой и алгоритмами машинного обучения, реализованных на Python. Пакет mlagents зависит от mlagents_envs. - ([`gym_unity`](https://github.com/Unity-Technologies/ml-agents/tree/main/gym-unity)) - позволяет обернуть вашу сцену - в Unity в среду OpenAI Gym. + в Unity в среду Gymnasium. - Unity [Project](https://github.com/Unity-Technologies/ml-agents/tree/main/Project), содержащий [примеры сцены](https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Learning-Environment-Examples.md), где реализованы различные возможности ML-Agents для наглядности. diff --git a/localized_docs/TR/docs/Installation.md b/localized_docs/TR/docs/Installation.md index 1fb8f5660a..675b090ca2 100644 --- a/localized_docs/TR/docs/Installation.md +++ b/localized_docs/TR/docs/Installation.md @@ -7,7 +7,7 @@ ML-Agents Araç Seti birkaç bileşen içermektedir: - [`mlagents`](https://github.com/Unity-Technologies/ml-agents/tree/release_7_docs/ml-agents) Unity sahnenizdeki davranışları eğitmenizi sağlayan makine öğrenimi algoritmalarını içerir. Bu nedenle `mlagents` paketini kurmanız gerekecek. - [`mlagents_envs`](https://github.com/Unity-Technologies/ml-agents/tree/release_7_docs/ml-agents-envs) Unity sahnesiyle etkileşime girmek için Python API içermektedir. Unity sahnesi ile Python makine öğrenimi algoritmaları arasında veri mesajlaşmasını kolaylaştıran temel bir katmandır. Sonuç olarak, `mlagents,` `mlagents_envs` apisine bağımlıdır. - - [`gym_unity`](https://github.com/Unity-Technologies/ml-agents/tree/release_7_docs/gym-unity) OpenAI Gym arayüzünü destekleyen Unity sahneniz için bir Python kapsayıcı sağlar. + - [`gym_unity`](https://github.com/Unity-Technologies/ml-agents/tree/release_7_docs/gym-unity) Gymnasium arayüzünü destekleyen Unity sahneniz için bir Python kapsayıcı sağlar. - Unity [Project](../Project/) klasörü [örnek ortamlar](Learning-Environment-Examples.md) ile başlamanıza yardımcı olacak araç setinin çeşitli özelliklerini vurgulayan sahneler içermektedir. diff --git a/ml-agents-envs/mlagents_envs/envs/unity_gym_env.py b/ml-agents-envs/mlagents_envs/envs/unity_gym_env.py index df29a95c9a..14c40ceb8d 100644 --- a/ml-agents-envs/mlagents_envs/envs/unity_gym_env.py +++ b/ml-agents-envs/mlagents_envs/envs/unity_gym_env.py @@ -1,10 +1,16 @@ +""" +An adapter between Unity ml-agents BaseEnv and Gymnasium Env. + +Remixed from https://github.com/Unity-Technologies/ml-agents/blob/develop/ml-agents-envs/mlagents_envs/envs/unity_gym_env.py +""" + import itertools import numpy as np from typing import Any, Dict, List, Optional, Tuple, Union -import gym -from gym import error, spaces +import gymnasium as gym +from gymnasium import error, spaces from mlagents_envs.base_env import ActionTuple, BaseEnv from mlagents_envs.base_env import DecisionSteps, TerminalSteps @@ -20,7 +26,7 @@ class UnityGymException(error.Error): logger = logging_util.get_logger(__name__) -GymStepResult = Tuple[np.ndarray, float, bool, Dict] +GymStepResult = Tuple[np.ndarray, float, bool, bool, Dict] class UnityToGymWrapper(gym.Env): @@ -107,13 +113,13 @@ def __init__( self.action_size = self.group_spec.action_spec.discrete_size branches = self.group_spec.action_spec.discrete_branches if self.group_spec.action_spec.discrete_size == 1: - self._action_space = spaces.Discrete(branches[0]) + self.action_space = spaces.Discrete(branches[0]) else: if flatten_branched: self._flattener = ActionFlattener(branches) - self._action_space = self._flattener.action_space + self.action_space = self._flattener.action_space else: - self._action_space = spaces.MultiDiscrete(branches) + self.action_space = spaces.MultiDiscrete(branches) elif self.group_spec.action_spec.is_continuous(): if flatten_branched: @@ -124,7 +130,7 @@ def __init__( self.action_size = self.group_spec.action_spec.continuous_size high = np.array([1] * self.group_spec.action_spec.continuous_size) - self._action_space = spaces.Box(-high, high, dtype=np.float32) + self.action_space = spaces.Box(-high, high, dtype=np.float32) else: raise UnityGymException( "The gym wrapper does not provide explicit support for both discrete " @@ -132,7 +138,7 @@ def __init__( ) if action_space_seed is not None: - self._action_space.seed(action_space_seed) + self.action_space.seed(action_space_seed) # Set observations space list_spaces: List[gym.Space] = [] @@ -147,11 +153,11 @@ def __init__( high = np.array([np.inf] * self._get_vec_obs_size()) list_spaces.append(spaces.Box(-high, high, dtype=np.float32)) if self._allow_multiple_obs: - self._observation_space = spaces.Tuple(list_spaces) + self.observation_space = spaces.Tuple(list_spaces) else: - self._observation_space = list_spaces[0] # only return the first one + self.observation_space = list_spaces[0] # only return the first one - def reset(self) -> Union[List[np.ndarray], np.ndarray]: + def reset(self) -> Tuple[Union[List[np.ndarray], np.ndarray], Dict]: """Resets the state of the environment and returns an initial observation. Returns: observation (object/list): the initial observation of the space. @@ -163,7 +169,7 @@ def reset(self) -> Union[List[np.ndarray], np.ndarray]: self.game_over = False res: GymStepResult = self._single_step(decision_step) - return res[0] + return res[0], {} def step(self, action: List[Any]) -> GymStepResult: """Run one timestep of the environment's dynamics. When end of @@ -229,7 +235,7 @@ def _single_step(self, info: Union[DecisionSteps, TerminalSteps]) -> GymStepResu done = isinstance(info, TerminalSteps) - return (default_observation, info.reward[0], done, {"step": info}) + return (default_observation, info.reward[0], done, False, {"step": info}) def _preprocess_single(self, single_visual_obs: np.ndarray) -> np.ndarray: if self.uint8_visual: @@ -303,23 +309,9 @@ def _check_agents(n_agents: int) -> None: raise UnityGymException( f"There can only be one Agent in the environment but {n_agents} were detected." ) - - @property - def metadata(self): - return {"render.modes": ["rgb_array"]} - - @property - def reward_range(self) -> Tuple[float, float]: - return -float("inf"), float("inf") - - @property - def action_space(self) -> gym.Space: - return self._action_space - - @property - def observation_space(self): - return self._observation_space - + + metadata = {"render.modes": ["rgb_array"]} + reward_range = (-float("inf"), float("inf")) class ActionFlattener: """