diff --git "a/Copy_of_unit5.ipynb" "b/Copy_of_unit5.ipynb" new file mode 100644--- /dev/null +++ "b/Copy_of_unit5.ipynb" @@ -0,0 +1,2236 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "2D3NL_e4crQv" + }, + "source": [ + "# Unit 5: An Introduction to ML-Agents\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "97ZiytXEgqIz" + }, + "source": [ + "\"Thumbnail\"/\n", + "\n", + "In this notebook, you'll learn about ML-Agents and train two agents.\n", + "\n", + "- The first one will learn to **shoot snowballs onto spawning targets**.\n", + "- The second need to press a button to spawn a pyramid, then navigate to the pyramid, knock it over, **and move to the gold brick at the top**. To do that, it will need to explore its environment, and we will use a technique called curiosity.\n", + "\n", + "After that, you'll be able **to watch your agents playing directly on your browser**.\n", + "\n", + "For more information about the certification process, check this section 👉 https://huggingface.co/deep-rl-course/en/unit0/introduction#certification-process" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FMYrDriDujzX" + }, + "source": [ + "⬇️ Here is an example of what **you will achieve at the end of this unit.** ⬇️\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cBmFlh8suma-" + }, + "source": [ + "\"Pyramids\"/\n", + "\n", + "\"SnowballTarget\"/" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A-cYE0K5iL-w" + }, + "source": [ + "### 🎮 Environments:\n", + "\n", + "- [Pyramids](https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Learning-Environment-Examples.md#pyramids)\n", + "- SnowballTarget\n", + "\n", + "### 📚 RL-Library:\n", + "\n", + "- [ML-Agents](https://github.com/Unity-Technologies/ml-agents)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qEhtaFh9i31S" + }, + "source": [ + "We're constantly trying to improve our tutorials, so **if you find some issues in this notebook**, please [open an issue on the GitHub Repo](https://github.com/huggingface/deep-rl-class/issues)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "j7f63r3Yi5vE" + }, + "source": [ + "## Objectives of this notebook 🏆\n", + "\n", + "At the end of the notebook, you will:\n", + "\n", + "- Understand how works **ML-Agents**, the environment library.\n", + "- Be able to **train agents in Unity Environments**.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "viNzVbVaYvY3" + }, + "source": [ + "## This notebook is from the Deep Reinforcement Learning Course\n", + "\"Deep" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "6p5HnEefISCB" + }, + "source": [ + "In this free course, you will:\n", + "\n", + "- 📖 Study Deep Reinforcement Learning in **theory and practice**.\n", + "- 🧑‍💻 Learn to **use famous Deep RL libraries** such as Stable Baselines3, RL Baselines3 Zoo, CleanRL and Sample Factory 2.0.\n", + "- 🤖 Train **agents in unique environments**\n", + "\n", + "And more check 📚 the syllabus 👉 https://huggingface.co/deep-rl-course/communication/publishing-schedule\n", + "\n", + "Don’t forget to **sign up to the course** (we are collecting your email to be able to **send you the links when each Unit is published and give you information about the challenges and updates).**\n", + "\n", + "\n", + "The best way to keep in touch is to join our discord server to exchange with the community and with us 👉🏻 https://discord.gg/ydHrjt3WP5" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Y-mo_6rXIjRi" + }, + "source": [ + "## Prerequisites 🏗️\n", + "Before diving into the notebook, you need to:\n", + "\n", + "🔲 📚 **Study [what is ML-Agents and how it works by reading Unit 5](https://huggingface.co/deep-rl-course/unit5/introduction)** 🤗 " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xYO1uD5Ujgdh" + }, + "source": [ + "# Let's train our agents 🚀\n", + "\n", + "**To validate this hands-on for the certification process, you just need to push your trained models to the Hub**. There’s no results to attain to validate this one. But if you want to get nice results you can try to attain:\n", + "\n", + "- For `Pyramids` : Mean Reward = 1.75\n", + "- For `SnowballTarget` : Mean Reward = 15 or 30 targets hit in an episode.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "DssdIjk_8vZE" + }, + "source": [ + "## Set the GPU 💪\n", + "- To **accelerate the agent's training, we'll use a GPU**. To do that, go to `Runtime > Change Runtime type`\n", + "\n", + "\"GPU" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sTfCXHy68xBv" + }, + "source": [ + "- `Hardware Accelerator > GPU`\n", + "\n", + "\"GPU" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2neXRzPKhP8r" + }, + "source": [ + "## Clone the repository 🔽\n", + "\n", + "- We need to clone the repository, that contains **ML-Agents.**" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "PDzOFtT9hP8r" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# Clone the repository (can take 3min)\n", + "!git clone --depth 1 https://github.com/Unity-Technologies/ml-agents" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zerrfAA3hP8r" + }, + "source": [ + "## Setup the Virtual Environment 🔽\n", + "- In order for the **ML-Agents** to run successfully in Colab, Colab's Python version must meet the library's Python requirements.\n", + "\n", + "- We can check for the supported Python version under the `python_requires` parameter in the `setup.py` files. These files are required to set up the **ML-Agents** library for use and can be found in the following locations:\n", + " - `/content/ml-agents/ml-agents/setup.py`\n", + " - `/content/ml-agents/ml-agents-envs/setup.py`\n", + "\n", + "- Colab's Current Python version(can be checked using `!python --version`) doesn't match the library's `python_requires` parameter, as a result installation may silently fail and lead to errors like these, when executing the same commands later:\n", + " - `/bin/bash: line 1: mlagents-learn: command not found`\n", + " - `/bin/bash: line 1: mlagents-push-to-hf: command not found`\n", + "\n", + "- To resolve this, we'll create a virtual environment with a Python version compatible with the **ML-Agents** library.\n", + "\n", + "`Note:` *For future compatibility, always check the `python_requires` parameter in the installation files and set your virtual environment to the maximum supported Python version in the given below script if the Colab's Python version is not compatible*" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "ACPLuUjHhP8r", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "59a16bef-3c5b-43f0-b39b-996f8efbab5a" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Python 3.11.12\n" + ] + } + ], + "source": [ + "# Colab's Current Python Version (Incompatible with ML-Agents)\n", + "!python --version" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "oYrUzNVkhP8r", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "c3b80174-8a9a-49b2-c1d6-fc3cf8d12c06" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Collecting virtualenv\n", + " Downloading virtualenv-20.30.0-py3-none-any.whl.metadata (4.5 kB)\n", + "Collecting distlib<1,>=0.3.7 (from virtualenv)\n", + " Downloading distlib-0.3.9-py2.py3-none-any.whl.metadata (5.2 kB)\n", + "Requirement already satisfied: filelock<4,>=3.12.2 in /usr/local/lib/python3.11/dist-packages (from virtualenv) (3.18.0)\n", + "Requirement already satisfied: platformdirs<5,>=3.9.1 in /usr/local/lib/python3.11/dist-packages (from virtualenv) (4.3.7)\n", + "Downloading virtualenv-20.30.0-py3-none-any.whl (4.3 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.3/4.3 MB\u001b[0m \u001b[31m41.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading distlib-0.3.9-py2.py3-none-any.whl (468 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m469.0/469.0 kB\u001b[0m \u001b[31m32.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hInstalling collected packages: distlib, virtualenv\n", + "Successfully installed distlib-0.3.9 virtualenv-20.30.0\n", + "created virtual environment CPython3.11.12.final.0-64 in 1060ms\n", + " creator CPython3Posix(dest=/content/myenv, clear=False, no_vcs_ignore=False, global=False)\n", + " seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)\n", + " added seed packages: pip==25.0.1, setuptools==78.1.0, wheel==0.45.1\n", + " activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator\n", + "--2025-04-25 06:21:52-- https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh\n", + "Resolving repo.anaconda.com (repo.anaconda.com)... 104.16.32.241, 104.16.191.158, 2606:4700::6810:20f1, ...\n", + "Connecting to repo.anaconda.com (repo.anaconda.com)|104.16.32.241|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 154615621 (147M) [application/octet-stream]\n", + "Saving to: ‘Miniconda3-latest-Linux-x86_64.sh’\n", + "\n", + "Miniconda3-latest-L 100%[===================>] 147.45M 284MB/s in 0.5s \n", + "\n", + "2025-04-25 06:21:53 (284 MB/s) - ‘Miniconda3-latest-Linux-x86_64.sh’ saved [154615621/154615621]\n", + "\n", + "PREFIX=/usr/local\n", + "Unpacking payload ...\n", + "\n", + "Installing base environment...\n", + "\n", + "Preparing transaction: ...working... done\n", + "Executing transaction: ...working... done\n", + "installation finished.\n", + "WARNING:\n", + " You currently have a PYTHONPATH environment variable set. This may cause\n", + " unexpected behavior when running the Python interpreter in Miniconda3.\n", + " For best results, please verify that your PYTHONPATH only points to\n", + " directories of packages that are compatible with the Python interpreter\n", + " in Miniconda3: /usr/local\n", + "Channels:\n", + " - defaults\n", + "Platform: linux-64\n", + "Collecting package metadata (repodata.json): ...working... done\n", + "Solving environment: ...working... done\n", + "\n", + "## Package Plan ##\n", + "\n", + " environment location: /usr/local\n", + "\n", + " added / updated specs:\n", + " - python=3.10.12\n", + " - ujson\n", + "\n", + "\n", + "The following packages will be downloaded:\n", + "\n", + " package | build\n", + " ---------------------------|-----------------\n", + " anaconda-anon-usage-0.7.0 |py310hfc0e8ea_101 29 KB\n", + " annotated-types-0.6.0 | py310h06a4308_0 22 KB\n", + " boltons-24.1.0 | py310h06a4308_0 425 KB\n", + " brotli-python-1.0.9 | py310h6a678d5_9 356 KB\n", + " ca-certificates-2025.2.25 | h06a4308_0 129 KB\n", + " certifi-2025.1.31 | py310h06a4308_0 162 KB\n", + " cffi-1.17.1 | py310h1fdaa30_1 251 KB\n", + " conda-25.3.1 | py310h06a4308_0 923 KB\n", + " conda-anaconda-telemetry-0.1.2| py310h06a4308_1 13 KB\n", + " conda-anaconda-tos-0.1.3 | py310h06a4308_0 36 KB\n", + " conda-content-trust-0.2.0 | py310h06a4308_1 51 KB\n", + " conda-package-handling-2.4.0| py310h06a4308_0 272 KB\n", + " conda-package-streaming-0.11.0| py310h06a4308_0 30 KB\n", + " cryptography-44.0.1 | py310h7825ff9_0 1.5 MB\n", + " distro-1.9.0 | py310h06a4308_0 31 KB\n", + " frozendict-2.4.2 | py310h5eee18b_0 55 KB\n", + " idna-3.7 | py310h06a4308_0 130 KB\n", + " jsonpatch-1.33 | py310h06a4308_1 31 KB\n", + " libmambapy-2.0.5 | py310hdb19cb5_1 671 KB\n", + " markdown-it-py-2.2.0 | py310h06a4308_1 114 KB\n", + " mdurl-0.1.0 | py310h06a4308_0 18 KB\n", + " menuinst-2.2.0 | py310h06a4308_1 224 KB\n", + " openssl-3.0.16 | h5eee18b_0 5.2 MB\n", + " packaging-24.2 | py310h06a4308_0 174 KB\n", + " pip-25.0 | py310h06a4308_0 2.3 MB\n", + " platformdirs-4.3.7 | py310h06a4308_0 37 KB\n", + " pluggy-1.5.0 | py310h06a4308_0 37 KB\n", + " pybind11-abi-4 | hd3eb1b0_1 14 KB\n", + " pycosat-0.6.6 | py310h5eee18b_2 88 KB\n", + " pydantic-2.10.3 | py310h06a4308_0 655 KB\n", + " pydantic-core-2.27.1 | py310h4aa5aa6_0 1.5 MB\n", + " pygments-2.19.1 | py310h06a4308_0 1.9 MB\n", + " pysocks-1.7.1 | py310h06a4308_0 28 KB\n", + " python-3.10.12 | h955ad1f_0 26.8 MB\n", + " requests-2.32.3 | py310h06a4308_1 101 KB\n", + " rich-13.9.4 | py310h06a4308_0 502 KB\n", + " ruamel.yaml-0.18.6 | py310h5eee18b_0 206 KB\n", + " ruamel.yaml.clib-0.2.8 | py310h5eee18b_0 157 KB\n", + " setuptools-75.8.0 | py310h06a4308_0 1.6 MB\n", + " tqdm-4.67.1 | py310h2f386ee_0 134 KB\n", + " truststore-0.10.0 | py310h06a4308_0 40 KB\n", + " typing-extensions-4.12.2 | py310h06a4308_0 9 KB\n", + " typing_extensions-4.12.2 | py310h06a4308_0 65 KB\n", + " ujson-5.10.0 | py310h6a678d5_1 141 KB\n", + " urllib3-2.3.0 | py310h06a4308_0 190 KB\n", + " wheel-0.45.1 | py310h06a4308_0 115 KB\n", + " zstandard-0.23.0 | py310h2c38b39_1 431 KB\n", + " ------------------------------------------------------------\n", + " Total: 47.8 MB\n", + "\n", + "The following NEW packages will be INSTALLED:\n", + "\n", + " ujson pkgs/main/linux-64::ujson-5.10.0-py310h6a678d5_1 \n", + "\n", + "The following packages will be REMOVED:\n", + "\n", + " expat-2.6.4-h6a678d5_0\n", + "\n", + "The following packages will be UPDATED:\n", + "\n", + " anaconda-anon-usa~ 0.5.0-py312hfc0e8ea_100 --> 0.7.0-py310hfc0e8ea_101 \n", + " ca-certificates 2024.12.31-h06a4308_0 --> 2025.2.25-h06a4308_0 \n", + " conda 25.1.1-py312h06a4308_0 --> 25.3.1-py310h06a4308_0 \n", + " conda-anaconda-te~ 0.1.2-py312h06a4308_0 --> 0.1.2-py310h06a4308_1 \n", + " conda-anaconda-tos 0.1.2-py312h06a4308_0 --> 0.1.3-py310h06a4308_0 \n", + " cryptography 43.0.3-py312h7825ff9_1 --> 44.0.1-py310h7825ff9_0 \n", + " openssl 3.0.15-h5eee18b_0 --> 3.0.16-h5eee18b_0 \n", + " platformdirs 3.10.0-py312h06a4308_0 --> 4.3.7-py310h06a4308_0 \n", + " pygments 2.15.1-py312h06a4308_1 --> 2.19.1-py310h06a4308_0 \n", + "\n", + "The following packages will be DOWNGRADED:\n", + "\n", + " annotated-types 0.6.0-py312h06a4308_0 --> 0.6.0-py310h06a4308_0 \n", + " boltons 24.1.0-py312h06a4308_0 --> 24.1.0-py310h06a4308_0 \n", + " brotli-python 1.0.9-py312h6a678d5_9 --> 1.0.9-py310h6a678d5_9 \n", + " certifi 2025.1.31-py312h06a4308_0 --> 2025.1.31-py310h06a4308_0 \n", + " cffi 1.17.1-py312h1fdaa30_1 --> 1.17.1-py310h1fdaa30_1 \n", + " conda-content-tru~ 0.2.0-py312h06a4308_1 --> 0.2.0-py310h06a4308_1 \n", + " conda-package-han~ 2.4.0-py312h06a4308_0 --> 2.4.0-py310h06a4308_0 \n", + " conda-package-str~ 0.11.0-py312h06a4308_0 --> 0.11.0-py310h06a4308_0 \n", + " distro 1.9.0-py312h06a4308_0 --> 1.9.0-py310h06a4308_0 \n", + " frozendict 2.4.2-py312h06a4308_0 --> 2.4.2-py310h5eee18b_0 \n", + " idna 3.7-py312h06a4308_0 --> 3.7-py310h06a4308_0 \n", + " jsonpatch 1.33-py312h06a4308_1 --> 1.33-py310h06a4308_1 \n", + " libmambapy 2.0.5-py312hdb19cb5_1 --> 2.0.5-py310hdb19cb5_1 \n", + " markdown-it-py 2.2.0-py312h06a4308_1 --> 2.2.0-py310h06a4308_1 \n", + " mdurl 0.1.0-py312h06a4308_0 --> 0.1.0-py310h06a4308_0 \n", + " menuinst 2.2.0-py312h06a4308_1 --> 2.2.0-py310h06a4308_1 \n", + " packaging 24.2-py312h06a4308_0 --> 24.2-py310h06a4308_0 \n", + " pip 25.0-py312h06a4308_0 --> 25.0-py310h06a4308_0 \n", + " pluggy 1.5.0-py312h06a4308_0 --> 1.5.0-py310h06a4308_0 \n", + " pybind11-abi 5-hd3eb1b0_0 --> 4-hd3eb1b0_1 \n", + " pycosat 0.6.6-py312h5eee18b_2 --> 0.6.6-py310h5eee18b_2 \n", + " pydantic 2.10.3-py312h06a4308_0 --> 2.10.3-py310h06a4308_0 \n", + " pydantic-core 2.27.1-py312h4aa5aa6_0 --> 2.27.1-py310h4aa5aa6_0 \n", + " pysocks 1.7.1-py312h06a4308_0 --> 1.7.1-py310h06a4308_0 \n", + " python 3.12.9-h5148396_0 --> 3.10.12-h955ad1f_0 \n", + " requests 2.32.3-py312h06a4308_1 --> 2.32.3-py310h06a4308_1 \n", + " rich 13.9.4-py312h06a4308_0 --> 13.9.4-py310h06a4308_0 \n", + " ruamel.yaml 0.18.6-py312h5eee18b_0 --> 0.18.6-py310h5eee18b_0 \n", + " ruamel.yaml.clib 0.2.8-py312h5eee18b_0 --> 0.2.8-py310h5eee18b_0 \n", + " setuptools 75.8.0-py312h06a4308_0 --> 75.8.0-py310h06a4308_0 \n", + " tqdm 4.67.1-py312he106c6f_0 --> 4.67.1-py310h2f386ee_0 \n", + " truststore 0.10.0-py312h06a4308_0 --> 0.10.0-py310h06a4308_0 \n", + " typing-extensions 4.12.2-py312h06a4308_0 --> 4.12.2-py310h06a4308_0 \n", + " typing_extensions 4.12.2-py312h06a4308_0 --> 4.12.2-py310h06a4308_0 \n", + " urllib3 2.3.0-py312h06a4308_0 --> 2.3.0-py310h06a4308_0 \n", + " wheel 0.45.1-py312h06a4308_0 --> 0.45.1-py310h06a4308_0 \n", + " zstandard 0.23.0-py312h2c38b39_1 --> 0.23.0-py310h2c38b39_1 \n", + "\n", + "\n", + "Preparing transaction: ...working... done\n", + "Verifying transaction: ...working... done\n", + "Executing transaction: ...working... Removed 2 cache files.\n", + "Removed 0 Terms of Service files.\n", + "\n", + "done\n" + ] + } + ], + "source": [ + "# Install virtualenv and create a virtual environment\n", + "!pip install virtualenv\n", + "!virtualenv myenv\n", + "\n", + "# Download and install Miniconda\n", + "!wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh\n", + "!chmod +x Miniconda3-latest-Linux-x86_64.sh\n", + "!./Miniconda3-latest-Linux-x86_64.sh -b -f -p /usr/local\n", + "\n", + "# Activate Miniconda and install Python ver 3.10.12\n", + "!source /usr/local/bin/activate\n", + "!conda install -q -y --prefix /usr/local python=3.10.12 ujson # Specify the version here\n", + "\n", + "# Set environment variables for Python and conda paths\n", + "!export PYTHONPATH=/usr/local/lib/python3.10/site-packages/\n", + "!export CONDA_PREFIX=/usr/local/envs/myenv" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "LW_GbzKvhP8r", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "d5074158-220f-4d25-bbbc-e3f27c3c4f76" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Python 3.10.12\n" + ] + } + ], + "source": [ + "# Python Version in New Virtual Environment (Compatible with ML-Agents)\n", + "!python --version" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s_4UBsYGhP8r" + }, + "source": [ + "## Installing the dependencies 🔽" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "_rQ4hFoWhP8r" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# Go inside the repository and install the package (can take 3min)\n", + "%cd ml-agents\n", + "!pip3 install -e ./ml-agents-envs\n", + "!pip3 install -e ./ml-agents" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "R5_7Ptd_kEcG" + }, + "source": [ + "## SnowballTarget ⛄\n", + "\n", + "If you need a refresher on how this environments work check this section 👉\n", + "https://huggingface.co/deep-rl-course/unit5/snowball-target" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "HRY5ufKUKfhI" + }, + "source": [ + "### Download and move the environment zip file in `./training-envs-executables/linux/`\n", + "- Our environment executable is in a zip file.\n", + "- We need to download it and place it to `./training-envs-executables/linux/`\n", + "- We use a linux executable because we use colab, and colab machines OS is Ubuntu (linux)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "C9Ls6_6eOKiA" + }, + "outputs": [], + "source": [ + "# Here, we create training-envs-executables and linux\n", + "!mkdir ./training-envs-executables\n", + "!mkdir ./training-envs-executables/linux" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ekSh8LWawkB5" + }, + "source": [ + "We downloaded the file SnowballTarget.zip from https://github.com/huggingface/Snowball-Target using `wget`" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "6LosWO50wa77", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "9de0d6d8-9982-41ef-c024-b50c1d3dcc10" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "--2025-04-25 06:25:07-- https://github.com/huggingface/Snowball-Target/raw/main/SnowballTarget.zip\n", + "Resolving github.com (github.com)... 140.82.116.4\n", + "Connecting to github.com (github.com)|140.82.116.4|:443... connected.\n", + "HTTP request sent, awaiting response... 302 Found\n", + "Location: https://media.githubusercontent.com/media/huggingface/Snowball-Target/main/SnowballTarget.zip [following]\n", + "--2025-04-25 06:25:07-- https://media.githubusercontent.com/media/huggingface/Snowball-Target/main/SnowballTarget.zip\n", + "Resolving media.githubusercontent.com (media.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to media.githubusercontent.com (media.githubusercontent.com)|185.199.108.133|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 35134213 (34M) [application/zip]\n", + "Saving to: ‘./training-envs-executables/linux/SnowballTarget.zip’\n", + "\n", + "./training-envs-exe 100%[===================>] 33.51M 171MB/s in 0.2s \n", + "\n", + "2025-04-25 06:25:08 (171 MB/s) - ‘./training-envs-executables/linux/SnowballTarget.zip’ saved [35134213/35134213]\n", + "\n" + ] + } + ], + "source": [ + "!wget \"https://github.com/huggingface/Snowball-Target/raw/main/SnowballTarget.zip\" -O ./training-envs-executables/linux/SnowballTarget.zip" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_LLVaEEK3ayi" + }, + "source": [ + "We unzip the executable.zip file" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "id": "8FPx0an9IAwO" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!unzip -d ./training-envs-executables/linux/ ./training-envs-executables/linux/SnowballTarget.zip" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "nyumV5XfPKzu" + }, + "source": [ + "Make sure your file is accessible" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "id": "EdFsLJ11JvQf" + }, + "outputs": [], + "source": [ + "!chmod -R 755 ./training-envs-executables/linux/SnowballTarget" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NAuEq32Mwvtz" + }, + "source": [ + "### Define the SnowballTarget config file\n", + "- In ML-Agents, you define the **training hyperparameters into config.yaml files.**\n", + "\n", + "There are multiple hyperparameters. To know them better, you should check for each explanation with [the documentation](https://github.com/Unity-Technologies/ml-agents/blob/release_20_docs/docs/Training-Configuration-File.md)\n", + "\n", + "\n", + "So you need to create a `SnowballTarget.yaml` config file in ./content/ml-agents/config/ppo/\n", + "\n", + "We'll give you here a first version of this config (to copy and paste into your `SnowballTarget.yaml file`), **but you should modify it**.\n", + "\n", + "```\n", + "behaviors:\n", + " SnowballTarget:\n", + " trainer_type: ppo\n", + " summary_freq: 10000\n", + " keep_checkpoints: 10\n", + " checkpoint_interval: 50000\n", + " max_steps: 200000\n", + " time_horizon: 64\n", + " threaded: false\n", + " hyperparameters:\n", + " learning_rate: 0.0003\n", + " learning_rate_schedule: linear\n", + " batch_size: 128\n", + " buffer_size: 2048\n", + " beta: 0.005\n", + " epsilon: 0.2\n", + " lambd: 0.95\n", + " num_epoch: 3\n", + " network_settings:\n", + " normalize: false\n", + " hidden_units: 256\n", + " num_layers: 2\n", + " vis_encode_type: simple\n", + " reward_signals:\n", + " extrinsic:\n", + " gamma: 0.99\n", + " strength: 1.0\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "4U3sRH4N4h_l" + }, + "source": [ + "\"Config\n", + "\"Config" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "JJJdo_5AyoGo" + }, + "source": [ + "As an experimentation, you should also try to modify some other hyperparameters. Unity provides very [good documentation explaining each of them here](https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Training-Configuration-File.md).\n", + "\n", + "Now that you've created the config file and understand what most hyperparameters do, we're ready to train our agent 🔥." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "f9fI555bO12v" + }, + "source": [ + "### Train the agent\n", + "\n", + "To train our agent, we just need to **launch mlagents-learn and select the executable containing the environment.**\n", + "\n", + "We define four parameters:\n", + "\n", + "1. `mlagents-learn `: the path where the hyperparameter config file is.\n", + "2. `--env`: where the environment executable is.\n", + "3. `--run_id`: the name you want to give to your training run id.\n", + "4. `--no-graphics`: to not launch the visualization during the training.\n", + "\n", + "\"MlAgents\n", + "\n", + "Train the model and use the `--resume` flag to continue training in case of interruption.\n", + "\n", + "> It will fail first time if and when you use `--resume`, try running the block again to bypass the error.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "lN32oWF8zPjs" + }, + "source": [ + "The training will take 10 to 35min depending on your config, go take a ☕️you deserve it 🤗." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "id": "bS-Yh1UdHfzy", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "a9cada39-18da-422f-8b7e-2956026d6127" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + " ┐ ╖\n", + " ╓╖╬│╡ ││╬╖╖\n", + " ╓╖╬│││││┘ ╬│││││╬╖\n", + " ╖╬│││││╬╜ ╙╬│││││╖╖ ╗╗╗\n", + " ╬╬╬╬╖││╦╖ ╖╬││╗╣╣╣╬ ╟╣╣╬ ╟╣╣╣ ╜╜╜ ╟╣╣\n", + " ╬╬╬╬╬╬╬╬╖│╬╖╖╓╬╪│╓╣╣╣╣╣╣╣╬ ╟╣╣╬ ╟╣╣╣ ╒╣╣╖╗╣╣╣╗ ╣╣╣ ╣╣╣╣╣╣ ╟╣╣╖ ╣╣╣\n", + " ╬╬╬╬┐ ╙╬╬╬╬│╓╣╣╣╝╜ ╫╣╣╣╬ ╟╣╣╬ ╟╣╣╣ ╟╣╣╣╙ ╙╣╣╣ ╣╣╣ ╙╟╣╣╜╙ ╫╣╣ ╟╣╣\n", + " ╬��╬╬┐ ╙╬╬╣╣ ╫╣╣╣╬ ╟╣╣╬ ╟╣╣╣ ╟╣╣╬ ╣╣╣ ╣╣╣ ╟╣╣ ╣╣╣┌╣╣╜\n", + " ╬╬╬╜ ╬╬╣╣ ╙╝╣╣╬ ╙╣╣╣╗╖╓╗╣╣╣╜ ╟╣╣╬ ╣╣╣ ╣╣╣ ╟╣╣╦╓ ╣╣╣╣╣\n", + " ╙ ╓╦╖ ╬╬╣╣ ╓╗╗╖ ╙╝╣╣╣╣╝╜ ╘╝╝╜ ╝╝╝ ╝╝╝ ╙╣╣╣ ╟╣╣╣\n", + " ╩╬╬╬╬╬╬╦╦╬╬╣╣╗╣╣╣╣╣╣╣╝ ╫╣╣╣╣\n", + " ╙╬╬╬╬╬╬╬╣╣╣╣╣╣╝╜\n", + " ╙╬╬╬╣╣╣╜\n", + " ╙\n", + " \n", + " Version information:\n", + " ml-agents: 1.2.0.dev0,\n", + " ml-agents-envs: 1.2.0.dev0,\n", + " Communicator API: 1.5.0,\n", + " PyTorch: 2.7.0+cu126\n", + "[INFO] Connected to Unity environment with package version 2.1.0-exp.1 and communication version 1.5.0\n", + "[INFO] Connected new brain: SnowballTarget?team=0\n", + "[INFO] Hyperparameters for behavior name SnowballTarget: \n", + "\ttrainer_type:\tppo\n", + "\thyperparameters:\t\n", + "\t batch_size:\t128\n", + "\t buffer_size:\t2048\n", + "\t learning_rate:\t0.0003\n", + "\t beta:\t0.005\n", + "\t epsilon:\t0.2\n", + "\t lambd:\t0.95\n", + "\t num_epoch:\t3\n", + "\t shared_critic:\tFalse\n", + "\t learning_rate_schedule:\tlinear\n", + "\t beta_schedule:\tlinear\n", + "\t epsilon_schedule:\tlinear\n", + "\tcheckpoint_interval:\t10000\n", + "\tnetwork_settings:\t\n", + "\t normalize:\tFalse\n", + "\t hidden_units:\t256\n", + "\t num_layers:\t2\n", + "\t vis_encode_type:\tsimple\n", + "\t memory:\tNone\n", + "\t goal_conditioning_type:\thyper\n", + "\t deterministic:\tFalse\n", + "\treward_signals:\t\n", + "\t extrinsic:\t\n", + "\t gamma:\t0.99\n", + "\t strength:\t1.0\n", + "\t network_settings:\t\n", + "\t normalize:\tFalse\n", + "\t hidden_units:\t128\n", + "\t num_layers:\t2\n", + "\t vis_encode_type:\tsimple\n", + "\t memory:\tNone\n", + "\t goal_conditioning_type:\thyper\n", + "\t deterministic:\tFalse\n", + "\tinit_path:\tNone\n", + "\tkeep_checkpoints:\t10\n", + "\teven_checkpoints:\tFalse\n", + "\tmax_steps:\t200000\n", + "\ttime_horizon:\t64\n", + "\tsummary_freq:\t10000\n", + "\tthreaded:\tFalse\n", + "\tself_play:\tNone\n", + "\tbehavioral_cloning:\tNone\n", + "[INFO] SnowballTarget. Step: 10000. Time Elapsed: 24.080 s. Mean Reward: 3.068. Std of Reward: 1.982. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-9952.onnx\n", + "[INFO] SnowballTarget. Step: 20000. Time Elapsed: 46.037 s. Mean Reward: 5.855. Std of Reward: 2.838. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-19992.onnx\n", + "[INFO] SnowballTarget. Step: 30000. Time Elapsed: 65.453 s. Mean Reward: 9.409. Std of Reward: 2.782. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-29944.onnx\n", + "[INFO] SnowballTarget. Step: 40000. Time Elapsed: 87.109 s. Mean Reward: 11.600. Std of Reward: 2.694. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-39984.onnx\n", + "[INFO] SnowballTarget. Step: 50000. Time Elapsed: 108.006 s. Mean Reward: 13.409. Std of Reward: 2.480. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-49936.onnx\n", + "[INFO] SnowballTarget. Step: 60000. Time Elapsed: 128.236 s. Mean Reward: 16.291. Std of Reward: 2.535. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-59976.onnx\n", + "[INFO] SnowballTarget. Step: 70000. Time Elapsed: 148.612 s. Mean Reward: 17.227. Std of Reward: 2.770. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-69992.onnx\n", + "[INFO] SnowballTarget. Step: 80000. Time Elapsed: 170.653 s. Mean Reward: 19.364. Std of Reward: 3.204. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-79968.onnx\n", + "[INFO] SnowballTarget. Step: 90000. Time Elapsed: 189.386 s. Mean Reward: 21.205. Std of Reward: 2.616. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-89984.onnx\n", + "[INFO] SnowballTarget. Step: 100000. Time Elapsed: 211.025 s. Mean Reward: 22.145. Std of Reward: 2.561. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-99960.onnx\n", + "[INFO] SnowballTarget. Step: 110000. Time Elapsed: 231.675 s. Mean Reward: 23.556. Std of Reward: 2.608. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-109992.onnx\n", + "[INFO] SnowballTarget. Step: 120000. Time Elapsed: 252.154 s. Mean Reward: 24.644. Std of Reward: 2.282. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-119952.onnx\n", + "[INFO] SnowballTarget. Step: 130000. Time Elapsed: 273.694 s. Mean Reward: 24.600. Std of Reward: 2.356. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-129992.onnx\n", + "[INFO] SnowballTarget. Step: 140000. Time Elapsed: 292.726 s. Mean Reward: 25.182. Std of Reward: 2.733. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-139944.onnx\n", + "[INFO] SnowballTarget. Step: 150000. Time Elapsed: 314.498 s. Mean Reward: 24.345. Std of Reward: 2.002. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-149984.onnx\n", + "[INFO] SnowballTarget. Step: 160000. Time Elapsed: 335.089 s. Mean Reward: 24.909. Std of Reward: 2.618. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-159936.onnx\n", + "[INFO] SnowballTarget. Step: 170000. Time Elapsed: 355.200 s. Mean Reward: 25.473. Std of Reward: 1.999. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-169976.onnx\n", + "[INFO] SnowballTarget. Step: 180000. Time Elapsed: 376.018 s. Mean Reward: 25.159. Std of Reward: 2.066. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-179992.onnx\n", + "[INFO] SnowballTarget. Step: 190000. Time Elapsed: 397.822 s. Mean Reward: 26.000. Std of Reward: 2.098. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-189968.onnx\n", + "[INFO] SnowballTarget. Step: 200000. Time Elapsed: 416.901 s. Mean Reward: 26.068. Std of Reward: 2.126. Training.\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-199984.onnx\n", + "[INFO] Exported results/SnowballTarget1/SnowballTarget/SnowballTarget-200112.onnx\n", + "[INFO] Copied results/SnowballTarget1/SnowballTarget/SnowballTarget-200112.onnx to results/SnowballTarget1/SnowballTarget.onnx.\n" + ] + } + ], + "source": [ + "!mlagents-learn ./config/ppo/SnowballTarget.yaml --env=./training-envs-executables/linux/SnowballTarget/SnowballTarget --run-id=\"SnowballTarget1\" --no-graphics" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "5Vue94AzPy1t" + }, + "source": [ + "### Push the agent to the 🤗 Hub\n", + "\n", + "- Now that we trained our agent, we’re **ready to push it to the Hub to be able to visualize it playing on your browser🔥.**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "izT6FpgNzZ6R" + }, + "source": [ + "To be able to share your model with the community there are three more steps to follow:\n", + "\n", + "1️⃣ (If it's not already done) create an account to HF ➡ https://huggingface.co/join\n", + "\n", + "2️⃣ Sign in and then, you need to store your authentication token from the Hugging Face website.\n", + "- Create a new token (https://huggingface.co/settings/tokens) **with write role**\n", + "\n", + "\"Create\n", + "\n", + "- Copy the token\n", + "- Run the cell below and paste the token" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "id": "rKt2vsYoK56o", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 17, + "referenced_widgets": [ + "cf2e80dc498d4493b576a45baa9a849b", + "5e3b528ad250460fa6158d0d032716c0", + "e37c0704832f420b8668bd6e21270603", + "600aeaf6fe7d4b0a96fa6894db71aea9", + "d433ed981934444eb13554f4c5704a58", + "b8390b69f50845a686ce0997fe0492bd", + "2df449be1d564def908b737f21ff872b", + "a1ed6b536500448cb6e5ae1e083fb691", + "0099cd26eea841f0a894c9232f8fc22c", + "0e2c518c2e1244bcaf9072b0fdff1762", + "c4db06dcc587486b8b0af1a507a69c4b", + "942698b3d61548d0bfc89efde15d3265", + "fd71862c428f4b74b9e63f01b3fa4b49", + "fc3631e43c0443b5b6264f980dc5083a", + "b0cd3262611a48baa76d17457862440a", + "5242f42d28924c43bd32d3f03168b580", + "1371b2f7777741579693d52f568b195a", + "da203dfb9d1c4f63aeb27d285124d1e1", + "ab7285415e8f40be8f40cf00914a4438", + "438a3cc35e5b4d9cb62c6160f962a199" + ] + }, + "outputId": "24a928a0-c9bc-40dd-b42f-f3ef7fa44c65" + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "VBox(children=(HTML(value='
, so in my case results/First Training.\n", + "3. `--repo-id`: the name of the Hugging Face repo you want to create or update. It’s always /\n", + "If the repo does not exist **it will be created automatically**\n", + "4. `--commit-message`: since HF repos are git repository you need to define a commit message.\n", + "\n", + "\"Push\n", + "\n", + "For instance:\n", + "\n", + "`!mlagents-push-to-hf --run-id=\"SnowballTarget1\" --local-dir=\"./results/SnowballTarget1\" --repo-id=\"ThomasSimonini/ppo-SnowballTarget\" --commit-message=\"First Push\"`" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "id": "kAFzVB7OYj_H", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "ed4e8c68-1805-4c10-fda9-9e0ec6763589" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[INFO] This function will create a model card and upload your SnowballTarget1 into HuggingFace Hub. This is a work in progress: If you encounter a bug, please send open an issue\n", + "[INFO] Pushing repo SnowballTarget1 to the Hugging Face Hub\n", + "Upload 23 LFS files: 0% 0/23 [00:00" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Djs8c5rR0Z8a" + }, + "source": [ + "1. In step 1, type your username (your username is case sensitive: for instance, my username is ThomasSimonini not thomassimonini or ThOmasImoNInI) and click on the search button.\n", + "\n", + "2. In step 2, select your model repository.\n", + "\n", + "3. In step 3, **choose which model you want to replay**:\n", + " - I have multiple ones, since we saved a model every 500000 timesteps.\n", + " - But since I want the more recent, I choose `SnowballTarget.onnx`\n", + "\n", + "👉 What’s nice **is to try with different models step to see the improvement of the agent.**\n", + "\n", + "And don't hesitate to share the best score your agent gets on discord in #rl-i-made-this channel 🔥\n", + "\n", + "Let's now try a harder environment called Pyramids..." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rVMwRi4y_tmx" + }, + "source": [ + "## Pyramids 🏆\n", + "\n", + "### Download and move the environment zip file in `./training-envs-executables/linux/`\n", + "- Our environment executable is in a zip file.\n", + "- We need to download it and place it to `./training-envs-executables/linux/`\n", + "- We use a linux executable because we use colab, and colab machines OS is Ubuntu (linux)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "x2C48SGZjZYw" + }, + "source": [ + "We downloaded the file Pyramids.zip from from https://huggingface.co/spaces/unity/ML-Agents-Pyramids/resolve/main/Pyramids.zip using `wget`" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "id": "eWh8Pl3sjZY2", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "6246f952-4c46-4966-d0f0-832d0f79cb3f" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "--2025-04-25 06:45:00-- https://huggingface.co/spaces/unity/ML-Agents-Pyramids/resolve/main/Pyramids.zip\n", + "Resolving huggingface.co (huggingface.co)... 3.163.189.37, 3.163.189.114, 3.163.189.90, ...\n", + "Connecting to huggingface.co (huggingface.co)|3.163.189.37|:443... connected.\n", + "HTTP request sent, awaiting response... 302 Found\n", + "Location: https://cdn-lfs.hf.co/repos/f2/c7/f2c7eed6c9ed94477803abde6483db87a56a1f82597e00780698db5998afdcda/1e0f1cfa88a380b42644d974525a7dbfe144089883a401526b8341c5441f7cae?response-content-disposition=inline%3B+filename*%3DUTF-8%27%27Pyramids.zip%3B+filename%3D%22Pyramids.zip%22%3B&response-content-type=application%2Fzip&Expires=1745567100&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc0NTU2NzEwMH19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5oZi5jby9yZXBvcy9mMi9jNy9mMmM3ZWVkNmM5ZWQ5NDQ3NzgwM2FiZGU2NDgzZGI4N2E1NmExZjgyNTk3ZTAwNzgwNjk4ZGI1OTk4YWZkY2RhLzFlMGYxY2ZhODhhMzgwYjQyNjQ0ZDk3NDUyNWE3ZGJmZTE0NDA4OTg4M2E0MDE1MjZiODM0MWM1NDQxZjdjYWU%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qJnJlc3BvbnNlLWNvbnRlbnQtdHlwZT0qIn1dfQ__&Signature=dCT0g8hmi0-dpt7uNVNU%7Ey9ooXzVn7ry0Na4NA02ev1VkVahNM4LrsnoIOYFmKyQmgdGxesUK24mmzgUohU9YHzowbEJz4giuAbV5LH7EtEgJhqnRP6XTrwfaFG78FHGvZUEfvFewDAENmtGu3A5bNGXCznV5Yq2gtAWxNdNee3u2NXVem%7Etfq4CP38uJXMQAKyYeiN3NF4FntpQ2FW8suGPkTm5FwtJW08ZdMcCZEJm72NF0O9XVsZ-II9TLRObHJgjYhU8LRAjkSQOWoOGlLYUCLqkWJQWW3e4lFiysaqHRCJhzSvuVpqGq4Qch4wrxL6Q-%7EdLBj8blmI56IhqOA__&Key-Pair-Id=K3RPWS32NSSJCE [following]\n", + "--2025-04-25 06:45:00-- https://cdn-lfs.hf.co/repos/f2/c7/f2c7eed6c9ed94477803abde6483db87a56a1f82597e00780698db5998afdcda/1e0f1cfa88a380b42644d974525a7dbfe144089883a401526b8341c5441f7cae?response-content-disposition=inline%3B+filename*%3DUTF-8%27%27Pyramids.zip%3B+filename%3D%22Pyramids.zip%22%3B&response-content-type=application%2Fzip&Expires=1745567100&Policy=eyJTdGF0ZW1lbnQiOlt7IkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc0NTU2NzEwMH19LCJSZXNvdXJjZSI6Imh0dHBzOi8vY2RuLWxmcy5oZi5jby9yZXBvcy9mMi9jNy9mMmM3ZWVkNmM5ZWQ5NDQ3NzgwM2FiZGU2NDgzZGI4N2E1NmExZjgyNTk3ZTAwNzgwNjk4ZGI1OTk4YWZkY2RhLzFlMGYxY2ZhODhhMzgwYjQyNjQ0ZDk3NDUyNWE3ZGJmZTE0NDA4OTg4M2E0MDE1MjZiODM0MWM1NDQxZjdjYWU%7EcmVzcG9uc2UtY29udGVudC1kaXNwb3NpdGlvbj0qJnJlc3BvbnNlLWNvbnRlbnQtdHlwZT0qIn1dfQ__&Signature=dCT0g8hmi0-dpt7uNVNU%7Ey9ooXzVn7ry0Na4NA02ev1VkVahNM4LrsnoIOYFmKyQmgdGxesUK24mmzgUohU9YHzowbEJz4giuAbV5LH7EtEgJhqnRP6XTrwfaFG78FHGvZUEfvFewDAENmtGu3A5bNGXCznV5Yq2gtAWxNdNee3u2NXVem%7Etfq4CP38uJXMQAKyYeiN3NF4FntpQ2FW8suGPkTm5FwtJW08ZdMcCZEJm72NF0O9XVsZ-II9TLRObHJgjYhU8LRAjkSQOWoOGlLYUCLqkWJQWW3e4lFiysaqHRCJhzSvuVpqGq4Qch4wrxL6Q-%7EdLBj8blmI56IhqOA__&Key-Pair-Id=K3RPWS32NSSJCE\n", + "Resolving cdn-lfs.hf.co (cdn-lfs.hf.co)... 18.238.238.115, 18.238.238.89, 18.238.238.41, ...\n", + "Connecting to cdn-lfs.hf.co (cdn-lfs.hf.co)|18.238.238.115|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 42907187 (41M) [application/zip]\n", + "Saving to: ‘./training-envs-executables/linux/Pyramids.zip’\n", + "\n", + "./training-envs-exe 100%[===================>] 40.92M 132MB/s in 0.3s \n", + "\n", + "2025-04-25 06:45:00 (132 MB/s) - ‘./training-envs-executables/linux/Pyramids.zip’ saved [42907187/42907187]\n", + "\n" + ] + } + ], + "source": [ + "!wget \"https://huggingface.co/spaces/unity/ML-Agents-Pyramids/resolve/main/Pyramids.zip\" -O ./training-envs-executables/linux/Pyramids.zip" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "V5LXPOPujZY3" + }, + "source": [ + "We unzip the executable.zip file" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "id": "SmNgFdXhjZY3" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!unzip -d ./training-envs-executables/linux/ ./training-envs-executables/linux/Pyramids.zip" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "T1jxwhrJjZY3" + }, + "source": [ + "Make sure your file is accessible" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "id": "6fDd03btjZY3" + }, + "outputs": [], + "source": [ + "!chmod -R 755 ./training-envs-executables/linux/Pyramids/Pyramids" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fqceIATXAgih" + }, + "source": [ + "### Modify the PyramidsRND config file\n", + "- Contrary to the first environment which was a custom one, **Pyramids was made by the Unity team**.\n", + "- So the PyramidsRND config file already exists and is in ./content/ml-agents/config/ppo/PyramidsRND.yaml\n", + "- You might asked why \"RND\" in PyramidsRND. RND stands for *random network distillation* it's a way to generate curiosity rewards. If you want to know more on that we wrote an article explaning this technique: https://medium.com/data-from-the-trenches/curiosity-driven-learning-through-random-network-distillation-488ffd8e5938\n", + "\n", + "For this training, we’ll modify one thing:\n", + "- The total training steps hyperparameter is too high since we can hit the benchmark (mean reward = 1.75) in only 1M training steps.\n", + "👉 To do that, we go to config/ppo/PyramidsRND.yaml,**and modify these to max_steps to 1000000.**\n", + "\n", + "\"Pyramids" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RI-5aPL7BWVk" + }, + "source": [ + "As an experimentation, you should also try to modify some other hyperparameters, Unity provides a very [good documentation explaining each of them here](https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Training-Configuration-File.md).\n", + "\n", + "We’re now ready to train our agent 🔥." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "s5hr1rvIBdZH" + }, + "source": [ + "### Train the agent\n", + "\n", + "The training will take 30 to 45min depending on your machine, go take a ☕️you deserve it 🤗." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "id": "fXi4-IaHBhqD", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "e92680fb-d0f8-449d-d2f8-506c23d59e01" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + " ┐ ╖\n", + " ╓╖╬│╡ ││╬╖╖\n", + " ╓╖╬│││││┘ ╬│││││╬╖\n", + " ╖╬│││││╬╜ ╙╬│││││╖╖ ╗╗╗\n", + " ╬╬╬╬╖││╦╖ ╖╬││╗╣╣╣╬ ╟╣╣╬ ╟╣╣╣ ╜╜╜ ╟╣╣\n", + " ╬╬╬╬╬╬╬╬╖│╬╖╖╓╬╪│╓╣╣╣╣╣╣╣╬ ╟╣╣╬ ╟╣╣╣ ╒╣╣╖╗╣╣╣╗ ╣╣╣ ╣╣╣╣╣╣ ╟╣╣╖ ╣╣╣\n", + " ╬╬╬╬┐ ╙╬╬╬╬│╓╣╣╣╝╜ ╫╣╣╣╬ ╟╣╣╬ ╟╣╣╣ ╟╣╣╣╙ ╙╣╣╣ ╣╣╣ ╙╟╣╣╜╙ ╫╣╣ ╟╣╣\n", + " ╬╬╬╬┐ ╙╬╬╣╣ ╫╣╣╣╬ ���╣╣╬ ╟╣╣╣ ╟╣╣╬ ╣╣╣ ╣╣╣ ╟╣╣ ╣╣╣┌╣╣╜\n", + " ╬╬╬╜ ╬╬╣╣ ╙╝╣╣╬ ╙╣╣╣╗╖╓╗╣╣╣╜ ╟╣╣╬ ╣╣╣ ╣╣╣ ╟╣╣╦╓ ╣╣╣╣╣\n", + " ╙ ╓╦╖ ╬╬╣╣ ╓╗╗╖ ╙╝╣╣╣╣╝╜ ╘╝╝╜ ╝╝╝ ╝╝╝ ╙╣╣╣ ╟╣╣╣\n", + " ╩╬╬╬╬╬╬╦╦╬╬╣╣╗╣╣╣╣╣╣╣╝ ╫╣╣╣╣\n", + " ╙╬╬╬╬╬╬╬╣╣╣╣╣╣╝╜\n", + " ╙╬╬╬╣╣╣╜\n", + " ╙\n", + " \n", + " Version information:\n", + " ml-agents: 1.2.0.dev0,\n", + " ml-agents-envs: 1.2.0.dev0,\n", + " Communicator API: 1.5.0,\n", + " PyTorch: 2.7.0+cu126\n", + "[INFO] Connected to Unity environment with package version 2.2.1-exp.1 and communication version 1.5.0\n", + "[INFO] Connected new brain: Pyramids?team=0\n", + "[INFO] Hyperparameters for behavior name Pyramids: \n", + "\ttrainer_type:\tppo\n", + "\thyperparameters:\t\n", + "\t batch_size:\t128\n", + "\t buffer_size:\t2048\n", + "\t learning_rate:\t0.0003\n", + "\t beta:\t0.01\n", + "\t epsilon:\t0.2\n", + "\t lambd:\t0.95\n", + "\t num_epoch:\t3\n", + "\t shared_critic:\tFalse\n", + "\t learning_rate_schedule:\tlinear\n", + "\t beta_schedule:\tlinear\n", + "\t epsilon_schedule:\tlinear\n", + "\tcheckpoint_interval:\t500000\n", + "\tnetwork_settings:\t\n", + "\t normalize:\tFalse\n", + "\t hidden_units:\t512\n", + "\t num_layers:\t2\n", + "\t vis_encode_type:\tsimple\n", + "\t memory:\tNone\n", + "\t goal_conditioning_type:\thyper\n", + "\t deterministic:\tFalse\n", + "\treward_signals:\t\n", + "\t extrinsic:\t\n", + "\t gamma:\t0.99\n", + "\t strength:\t1.0\n", + "\t network_settings:\t\n", + "\t normalize:\tFalse\n", + "\t hidden_units:\t128\n", + "\t num_layers:\t2\n", + "\t vis_encode_type:\tsimple\n", + "\t memory:\tNone\n", + "\t goal_conditioning_type:\thyper\n", + "\t deterministic:\tFalse\n", + "\t rnd:\t\n", + "\t gamma:\t0.99\n", + "\t strength:\t0.01\n", + "\t network_settings:\t\n", + "\t normalize:\tFalse\n", + "\t hidden_units:\t64\n", + "\t num_layers:\t3\n", + "\t vis_encode_type:\tsimple\n", + "\t memory:\tNone\n", + "\t goal_conditioning_type:\thyper\n", + "\t deterministic:\tFalse\n", + "\t learning_rate:\t0.0001\n", + "\t encoding_size:\tNone\n", + "\tinit_path:\tNone\n", + "\tkeep_checkpoints:\t5\n", + "\teven_checkpoints:\tFalse\n", + "\tmax_steps:\t1000000\n", + "\ttime_horizon:\t128\n", + "\tsummary_freq:\t30000\n", + "\tthreaded:\tFalse\n", + "\tself_play:\tNone\n", + "\tbehavioral_cloning:\tNone\n", + "[INFO] Pyramids. Step: 30000. Time Elapsed: 53.979 s. Mean Reward: -1.000. Std of Reward: 0.000. Training.\n", + "[INFO] Pyramids. Step: 60000. Time Elapsed: 109.651 s. Mean Reward: -0.923. Std of Reward: 0.436. Training.\n", + "[INFO] Pyramids. Step: 90000. Time Elapsed: 166.075 s. Mean Reward: -1.000. Std of Reward: 0.000. Training.\n", + "[INFO] Pyramids. Step: 120000. Time Elapsed: 221.482 s. Mean Reward: -1.000. Std of Reward: 0.000. Training.\n", + "[INFO] Pyramids. Step: 150000. Time Elapsed: 279.101 s. Mean Reward: -0.860. Std of Reward: 0.532. Training.\n", + "[INFO] Pyramids. Step: 180000. Time Elapsed: 337.486 s. Mean Reward: -0.790. Std of Reward: 0.658. Training.\n", + "[INFO] Pyramids. Step: 210000. Time Elapsed: 396.923 s. Mean Reward: -1.000. Std of Reward: 0.000. Training.\n", + "[INFO] Pyramids. Step: 240000. Time Elapsed: 453.105 s. Mean Reward: -0.859. Std of Reward: 0.555. Training.\n", + "[INFO] Pyramids. Step: 270000. Time Elapsed: 508.875 s. Mean Reward: -0.499. Std of Reward: 0.953. Training.\n", + "[INFO] Pyramids. Step: 300000. Time Elapsed: 566.591 s. Mean Reward: -0.497. Std of Reward: 0.958. Training.\n", + "[INFO] Pyramids. Step: 330000. Time Elapsed: 623.433 s. Mean Reward: -0.854. Std of Reward: 0.557. Training.\n", + "[INFO] Pyramids. Step: 360000. Time Elapsed: 684.751 s. Mean Reward: -0.855. Std of Reward: 0.559. Training.\n", + "[INFO] Pyramids. Step: 390000. Time Elapsed: 744.153 s. Mean Reward: -1.000. Std of Reward: 0.000. Training.\n", + "[INFO] Pyramids. Step: 420000. Time Elapsed: 803.956 s. Mean Reward: -0.646. Std of Reward: 0.843. Training.\n", + "[INFO] Pyramids. Step: 450000. Time Elapsed: 863.349 s. Mean Reward: -0.535. Std of Reward: 0.973. Training.\n", + "[INFO] Pyramids. Step: 480000. Time Elapsed: 921.001 s. Mean Reward: -0.535. Std of Reward: 0.972. Training.\n", + "[INFO] Exported results/Pyramids Training/Pyramids/Pyramids-499944.onnx\n", + "[INFO] Pyramids. Step: 510000. Time Elapsed: 979.158 s. Mean Reward: -0.535. Std of Reward: 0.973. Training.\n", + "[INFO] Pyramids. Step: 540000. Time Elapsed: 1038.612 s. Mean Reward: -0.699. Std of Reward: 0.783. Training.\n", + "[INFO] Pyramids. Step: 570000. Time Elapsed: 1097.540 s. Mean Reward: -0.013. Std of Reward: 1.117. Training.\n", + "[INFO] Pyramids. Step: 600000. Time Elapsed: 1154.583 s. Mean Reward: -0.310. Std of Reward: 1.099. Training.\n", + "[INFO] Pyramids. Step: 630000. Time Elapsed: 1218.477 s. Mean Reward: 0.377. Std of Reward: 1.215. Training.\n", + "[INFO] Pyramids. Step: 660000. Time Elapsed: 1279.782 s. Mean Reward: 0.597. Std of Reward: 1.194. Training.\n", + "[INFO] Pyramids. Step: 690000. Time Elapsed: 1339.417 s. Mean Reward: 0.583. Std of Reward: 1.151. Training.\n", + "[INFO] Pyramids. Step: 720000. Time Elapsed: 1402.384 s. Mean Reward: 0.824. Std of Reward: 1.146. Training.\n", + "[INFO] Pyramids. Step: 750000. Time Elapsed: 1465.694 s. Mean Reward: 0.807. Std of Reward: 1.109. Training.\n", + "[INFO] Pyramids. Step: 780000. Time Elapsed: 1532.055 s. Mean Reward: 1.100. Std of Reward: 0.960. Training.\n", + "[INFO] Pyramids. Step: 810000. Time Elapsed: 1597.690 s. Mean Reward: 1.283. Std of Reward: 0.837. Training.\n", + "[INFO] Pyramids. Step: 840000. Time Elapsed: 1664.329 s. Mean Reward: 1.371. Std of Reward: 0.831. Training.\n", + "[INFO] Pyramids. Step: 870000. Time Elapsed: 1732.872 s. Mean Reward: 1.214. Std of Reward: 0.884. Training.\n", + "[INFO] Pyramids. Step: 900000. Time Elapsed: 1802.467 s. Mean Reward: 1.464. Std of Reward: 0.698. Training.\n", + "[INFO] Pyramids. Step: 930000. Time Elapsed: 1868.391 s. Mean Reward: 1.388. Std of Reward: 0.742. Training.\n", + "[INFO] Pyramids. Step: 960000. Time Elapsed: 1938.144 s. Mean Reward: 1.496. Std of Reward: 0.615. Training.\n", + "[INFO] Pyramids. Step: 990000. Time Elapsed: 2011.035 s. Mean Reward: 1.510. Std of Reward: 0.551. Training.\n", + "[INFO] Exported results/Pyramids Training/Pyramids/Pyramids-999897.onnx\n", + "[INFO] Exported results/Pyramids Training/Pyramids/Pyramids-1000025.onnx\n", + "[INFO] Copied results/Pyramids Training/Pyramids/Pyramids-1000025.onnx to results/Pyramids Training/Pyramids.onnx.\n" + ] + } + ], + "source": [ + "!mlagents-learn ./config/ppo/PyramidsRND.yaml --env=./training-envs-executables/linux/Pyramids/Pyramids --run-id=\"Pyramids Training\" --no-graphics" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "txonKxuSByut" + }, + "source": [ + "### Push the agent to the 🤗 Hub\n", + "\n", + "- Now that we trained our agent, we’re **ready to push it to the Hub to be able to visualize it playing on your browser🔥.**" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "id": "yiEQbv7rB4mU", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "0551736d-abb6-4bad-a809-ac54824d4a13" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[INFO] This function will create a model card and upload your Pyramids Training into HuggingFace Hub. This is a work in progress: If you encounter a bug, please send open an issue\n", + "[INFO] Pushing repo Pyramids Training to the Hugging Face Hub\n", + "Upload 9 LFS files: 0% 0/9 [00:00
Copy a token from your Hugging Face\ntokens page and paste it below.
Immediately click login after copying\nyour token or it might be stored in plain text in this notebook file.
" + } + }, + "e37c0704832f420b8668bd6e21270603": { + "model_module": "@jupyter-widgets/controls", + "model_name": "PasswordModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "PasswordModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "PasswordView", + "continuous_update": true, + "description": "Token:", + "description_tooltip": null, + "disabled": false, + "layout": "IPY_MODEL_0e2c518c2e1244bcaf9072b0fdff1762", + "placeholder": "​", + "style": "IPY_MODEL_c4db06dcc587486b8b0af1a507a69c4b", + "value": "" + } + }, + "600aeaf6fe7d4b0a96fa6894db71aea9": { + "model_module": "@jupyter-widgets/controls", + "model_name": "CheckboxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "CheckboxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "CheckboxView", + "description": "Add token as git credential?", + "description_tooltip": null, + "disabled": false, + "indent": true, + "layout": "IPY_MODEL_942698b3d61548d0bfc89efde15d3265", + "style": "IPY_MODEL_fd71862c428f4b74b9e63f01b3fa4b49", + "value": true + } + }, + "d433ed981934444eb13554f4c5704a58": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ButtonModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ButtonModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ButtonView", + "button_style": "", + "description": "Login", + "disabled": false, + "icon": "", + "layout": "IPY_MODEL_fc3631e43c0443b5b6264f980dc5083a", + "style": "IPY_MODEL_b0cd3262611a48baa76d17457862440a", + "tooltip": "" + } + }, + "b8390b69f50845a686ce0997fe0492bd": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5242f42d28924c43bd32d3f03168b580", + "placeholder": "​", + "style": "IPY_MODEL_1371b2f7777741579693d52f568b195a", + "value": "\nPro Tip: If you don't already have one, you can create a dedicated\n'notebooks' token with 'write' access, that you can then easily reuse for all\nnotebooks. " + } + }, + "2df449be1d564def908b737f21ff872b": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": "center", + "align_self": null, + "border": null, + "bottom": null, + "display": "flex", + "flex": null, + "flex_flow": "column", + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": "50%" + } + }, + "a1ed6b536500448cb6e5ae1e083fb691": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "0099cd26eea841f0a894c9232f8fc22c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "0e2c518c2e1244bcaf9072b0fdff1762": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c4db06dcc587486b8b0af1a507a69c4b": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "942698b3d61548d0bfc89efde15d3265": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "fd71862c428f4b74b9e63f01b3fa4b49": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "fc3631e43c0443b5b6264f980dc5083a": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "b0cd3262611a48baa76d17457862440a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ButtonStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ButtonStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "button_color": null, + "font_weight": "" + } + }, + "5242f42d28924c43bd32d3f03168b580": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "1371b2f7777741579693d52f568b195a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "da203dfb9d1c4f63aeb27d285124d1e1": { + "model_module": "@jupyter-widgets/controls", + "model_name": "LabelModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "LabelModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "LabelView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_ab7285415e8f40be8f40cf00914a4438", + "placeholder": "​", + "style": "IPY_MODEL_438a3cc35e5b4d9cb62c6160f962a199", + "value": "Connecting..." + } + }, + "ab7285415e8f40be8f40cf00914a4438": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "438a3cc35e5b4d9cb62c6160f962a199": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + } + } + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file