浏览代码

Merge pull request #884 from Unity-Technologies/release-v0.4

Release v0.4
/hotfix-v0.9.2a
GitHub 7 年前
当前提交
bf858cd6
共有 517 个文件被更改,包括 5858 次插入6137 次删除
  1. 2
      .gitattributes
  2. 2
      .gitignore
  3. 3
      Dockerfile
  4. 15
      README.md
  5. 16
      docs/Feature-Monitor.md
  6. 117
      docs/Getting-Started-with-Balance-Ball.md
  7. 71
      docs/Installation-Windows.md
  8. 14
      docs/Installation.md
  9. 4
      docs/Learning-Environment-Best-Practices.md
  10. 25
      docs/Learning-Environment-Create-New.md
  11. 6
      docs/Learning-Environment-Design-Agents.md
  12. 1
      docs/Learning-Environment-Design-Heuristic-Brains.md
  13. 120
      docs/Learning-Environment-Examples.md
  14. 7
      docs/ML-Agents-Overview.md
  15. 22
      docs/Python-API.md
  16. 16
      docs/Readme.md
  17. 11
      docs/Training-Curriculum-Learning.md
  18. 15
      docs/Training-Imitation-Learning.md
  19. 20
      docs/Training-ML-Agents.md
  20. 22
      docs/Training-PPO.md
  21. 196
      docs/Training-on-Amazon-Web-Service.md
  22. 14
      docs/Using-Docker.md
  23. 12
      docs/Using-TensorFlow-Sharp-in-Unity.md
  24. 11
      docs/Using-Tensorboard.md
  25. 2
      docs/dox-ml-agents.conf
  26. 999
      docs/images/crawler.png
  27. 577
      docs/images/cuDNN_membership_required.png
  28. 181
      docs/images/cuda_toolkit_directory.PNG
  29. 178
      docs/images/cudnn_zip_files.PNG
  30. 649
      docs/images/mlagents-TensorBoard.png
  31. 218
      docs/images/new_system_variable.PNG
  32. 127
      docs/images/path_variables.PNG
  33. 47
      docs/images/system_variable_name_value.PNG
  34. 2
      docs/localized/zh-CN/README.md
  35. 6
      docs/localized/zh-CN/docs/Getting-Started-with-Balance-Ball.md
  36. 2
      docs/localized/zh-CN/docs/Installation.md
  37. 10
      docs/localized/zh-CN/docs/ML-Agents-Overview.md
  38. 6
      docs/localized/zh-CN/docs/Readme.md
  39. 9
      python/curricula/wall.json
  40. 26
      python/learn.py
  41. 4
      python/requirements.txt
  42. 164
      python/tests/test_bc.py
  43. 344
      python/tests/test_ppo.py
  44. 218
      python/tests/test_unityagents.py
  45. 113
      python/tests/test_unitytrainers.py
  46. 76
      python/trainer_config.yaml
  47. 549
      python/unityagents/environment.py
  48. 14
      python/unitytrainers/bc/models.py
  49. 60
      python/unitytrainers/bc/trainer.py
  50. 14
      python/unitytrainers/buffer.py
  51. 236
      python/unitytrainers/models.py
  52. 138
      python/unitytrainers/ppo/models.py
  53. 373
      python/unitytrainers/ppo/trainer.py
  54. 39
      python/unitytrainers/trainer.py
  55. 45
      python/unitytrainers/trainer_controller.py
  56. 130
      unity-environment/Assets/ML-Agents/Editor/AgentEditor.cs
  57. 159
      unity-environment/Assets/ML-Agents/Editor/BrainEditor.cs
  58. 2
      unity-environment/Assets/ML-Agents/Editor/MLAgentsEditModeTest.cs
  59. 199
      unity-environment/Assets/ML-Agents/Editor/ResetParameterDrawer.cs
  60. 3
      unity-environment/Assets/ML-Agents/Examples.meta
  61. 1
      unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAcademy.cs
  62. 42
      unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs
  63. 1
      unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DDecision.cs
  64. 42
      unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs
  65. 955
      unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBall.bytes
  66. 2
      unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBall.bytes.meta
  67. 959
      unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBallHard.bytes
  68. 2
      unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBallHard.bytes.meta
  69. 10
      unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Prefabs/RLArea.prefab
  70. 63
      unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Prefabs/TeachingArea.prefab
  71. 1
      unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaAcademy.cs
  72. 65
      unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaAgent.cs
  73. 1
      unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaArea.cs
  74. 986
      unity-environment/Assets/ML-Agents/Examples/BananaCollectors/TFModels/Banana.bytes
  75. 1
      unity-environment/Assets/ML-Agents/Examples/Basic/Scripts/BasicAcademy.cs
  76. 18
      unity-environment/Assets/ML-Agents/Examples/Basic/Scripts/BasicAgent.cs
  77. 1
      unity-environment/Assets/ML-Agents/Examples/Basic/Scripts/BasicDecision.cs
  78. 1
      unity-environment/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAcademy.cs
  79. 42
      unity-environment/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs
  80. 14
      unity-environment/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerBanana.cs
  81. 340
      unity-environment/Assets/ML-Agents/Examples/Bouncer/TFModels/Bouncer.bytes
  82. 2
      unity-environment/Assets/ML-Agents/Examples/Bouncer/TFModels/Bouncer.bytes.meta
  83. 5
      unity-environment/Assets/ML-Agents/Examples/Crawler.meta
  84. 2
      unity-environment/Assets/ML-Agents/Examples/Crawler/Prefabs.meta
  85. 881
      unity-environment/Assets/ML-Agents/Examples/Crawler/Prefabs/Crawler.prefab
  86. 5
      unity-environment/Assets/ML-Agents/Examples/Crawler/Prefabs/Crawler.prefab.meta
  87. 2
      unity-environment/Assets/ML-Agents/Examples/Crawler/Scripts.meta
  88. 9
      unity-environment/Assets/ML-Agents/Examples/Crawler/Scripts/CrawlerAcademy.cs
  89. 5
      unity-environment/Assets/ML-Agents/Examples/Crawler/Scripts/CrawlerAcademy.cs.meta
  90. 5
      unity-environment/Assets/ML-Agents/Examples/Crawler/TFModels.meta
  91. 1
      unity-environment/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAcademy.cs
  92. 11
      unity-environment/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs
  93. 1
      unity-environment/Assets/ML-Agents/Examples/Hallway/Prefabs/HallwayArea.prefab
  94. 33
      unity-environment/Assets/ML-Agents/Examples/Hallway/Scenes/Hallway.unity
  95. 1
      unity-environment/Assets/ML-Agents/Examples/Hallway/Scripts/HallwayAcademy.cs
  96. 16
      unity-environment/Assets/ML-Agents/Examples/Hallway/Scripts/HallwayAgent.cs
  97. 427
      unity-environment/Assets/ML-Agents/Examples/PushBlock/Prefabs/PushBlockArea.prefab
  98. 361
      unity-environment/Assets/ML-Agents/Examples/PushBlock/Scenes/PushBlock.unity
  99. 19
      unity-environment/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs
  100. 1
      unity-environment/Assets/ML-Agents/Examples/PushBlock/Scripts/PushBlockAcademy.cs

2
.gitattributes


*.unity binary
*.prefab binary
*.meta binary
*/CommunicatorObjects/* binary
*/communicator_objects/* binary
*.md text

2
.gitignore


/unity-environment/[Pp]ackages/
/unity-environment/[Uu]nity[Pp]ackage[Mm]anager/
/unity-environment/Assets/AssetStoreTools*
/unity-environment/Assets/Plugins*
/unity-environment/Assets/Gizmos*
# Tensorflow Model Info
/models

3
Dockerfile


WORKDIR /execute
COPY python /execute/python
# port 5005 is the port used in in Editor training.
EXPOSE 5005
ENTRYPOINT ["python", "python/learn.py"]

15
README.md


* Visualizing network outputs within the environment
* Simplified set-up with Docker
## Documentation and References
## Documentation
* For more information, in addition to installation and usage
instructions, see our [documentation home](docs/Readme.md).
* If you have
used a version of ML-Agents prior to v0.4, we strongly recommend
our [guide on migrating from earlier versions](docs/Migrating.md).
**For more information, in addition to installation and usage
instructions, see our [documentation home](docs/Readme.md).** If you have
used a version of ML-Agents prior to v0.3, we strongly recommend
our [guide on migrating to v0.3](docs/Migrating-v0.3.md).
## References
We have also published a series of blog posts that are relevant for ML-Agents:
We have published a series of blog posts that are relevant for ML-Agents:
- Overviewing reinforcement learning concepts
([multi-armed bandit](https://blogs.unity3d.com/2017/06/26/unity-ai-themed-blog-entries/)
and [Q-learning](https://blogs.unity3d.com/2017/08/22/unity-ai-reinforcement-learning-with-q-learning/))

16
docs/Feature-Monitor.md


The monitor allows visualizing information related to the agents or training process within a Unity scene.
You can track many different things both related and unrelated to the agents themselves. To use the Monitor, call the Log function anywhere in your code :
Monitor.Log(key, value, displayType , target)
Monitor.Log(key, value, target)
* *`value`* is the information you want to display.
* *`displayType`* is a MonitorType that can be either `text`, `slider`, `bar` or `hist`.
* `text` will convert `value` into a string and display it. It can be useful for displaying error messages!
* `slider` is used to display a single float between -1 and 1. Note that value must be a float if you want to use a slider. If the value is positive, the slider will be green, if the value is negative, the slider will be red.
* `hist` is used to display multiple floats. Note that value must be a list or array of floats. The Histogram will be a sequence of vertical sliders.
* `bar` is used to see the proportions. Note that value must be a list or array of positive floats. For each float in values, a rectangle of width of value divided by the sum of all values will be show. It is best for visualizing values that sum to 1.
* *`value`* is the information you want to display. *`value`* can have different types :
* *`string`* - The Monitor will display the string next to the key. It can be useful for displaying error messages.
* *`float`* - The Monitor will display a slider. Note that the values must be between -1 and 1. If the value is positive, the slider will be green, if the value is negative, the slider will be red.
* *`float[]`* - The Monitor Log call can take an additional argument called `displayType` that can be either `INDEPENDENT` (default) or `PROPORTIONAL` :
* *`INDEPENDENT`* is used to display multiple independent floats as a histogram. The histogram will be a sequence of vertical sliders.
* *`PROPORTION`* is used to see the proportions between numbers. For each float in values, a rectangle of width of value divided by the sum of all values will be show. It is best for visualizing values that sum to 1.
* *`target`* is the transform to which you want to attach information. If the transform is `null` the information will be attached to the global monitor.

117
docs/Getting-Started-with-Balance-Ball.md


drops the ball so that it will reset with a new ball for the next simulation
step.
## Building the Environment
The first step is to open the Unity scene containing the 3D Balance Ball
environment:
1. Launch Unity.
2. On the Projects dialog, choose the **Open** option at the top of the window.
3. Using the file dialog that opens, locate the `unity-environment` folder
within the ML-Agents project and click **Open**.
4. In the `Project` window, navigate to the folder
`Assets/ML-Agents/Examples/3DBall/`.
5. Double-click the `Scene` file to load the scene containing the Balance
Ball environment.
![3DBall Scene](images/mlagents-Open3DBall.png)
Since we are going to build this environment to conduct training, we need to
set the brain used by the agents to **External**. This allows the agents to
communicate with the external training process when making their decisions.
1. In the **Scene** window, click the triangle icon next to the Ball3DAcademy
object.
2. Select its child object `Ball3DBrain`.
3. In the Inspector window, set **Brain Type** to `External`.
![Set Brain to External](images/mlagents-SetExternalBrain.png)
Next, we want the set up scene to play correctly when the training process
launches our environment executable. This means:
* The environment application runs in the background
* No dialogs require interaction
* The correct scene loads automatically
1. Open Player Settings (menu: **Edit** > **Project Settings** > **Player**).
2. Under **Resolution and Presentation**:
- Ensure that **Run in Background** is Checked.
- Ensure that **Display Resolution Dialog** is set to Disabled.
3. Open the Build Settings window (menu:**File** > **Build Settings**).
4. Choose your target platform.
- (optional) Select “Development Build” to
[log debug messages](https://docs.unity3d.com/Manual/LogFiles.html).
5. If any scenes are shown in the **Scenes in Build** list, make sure that
the 3DBall Scene is the only one checked. (If the list is empty, than only the
current scene is included in the build).
6. Click *Build*:
a. In the File dialog, navigate to the `python` folder in your ML-Agents
directory.
b. Assign a file name and click **Save**.
![Build Window](images/mlagents-BuildWindow.png)
Now that we have a Unity executable containing the simulation environment, we
can perform the training. To first ensure that your environment and the Python
API work as expected, you can use the `python/Basics`
[Jupyter notebook](Background-Jupyter.md).
This notebook contains a simple walkthrough of the functionality of the API.
Within `Basics`, be sure to set `env_name` to the name of the environment file
you built earlier.
Now that we have an environment, we can perform the training.
### Training with PPO

To train the agents within the Ball Balance environment, we will be using the python
package. We have provided a convenient Python wrapper script called `learn.py` which accepts arguments used to configure both training and inference phases.
We will pass to this script the path of the environment executable that we just built. (Optionally) We can
use `run_id` to identify the experiment and create a folder where the model and summary statistics are stored. When
using TensorBoard to observe the training statistics, it helps to set this to a sequential value
We can use `run_id` to identify the experiment and create a folder where the model and summary statistics are stored. When using TensorBoard to observe the training statistics, it helps to set this to a sequential value
To summarize, go to your command line, enter the `ml-agents` directory and type:
To summarize, go to your command line, enter the `ml-agents/python` directory and type:
python3 python/learn.py <env_file_path> --run-id=<run-identifier> --train
python3 learn.py --run-id=<run-identifier> --train
When the message _"Start training by pressing the Play button in the Unity Editor"_ is displayed on the screen, you can press the :arrow_forward: button in Unity to start training in the Editor.
The `--train` flag tells ML-Agents to run in training mode. `env_file_path` should be the path to the Unity executable that was just created.
The `--train` flag tells ML-Agents to run in training mode.
**Note**: You can train using an executable rather than the Editor. To do so, follow the intructions in
[Using an Execuatble](Learning-Environment-Executable.md).
Once you start training using `learn.py` in the way described in the previous section, the `ml-agents` folder will
Once you start training using `learn.py` in the way described in the previous section, the `ml-agents/python` folder will
in more detail, you can use TensorBoard. From the command line run:
in more detail, you can use TensorBoard. From the command line navigate to `ml-agents/python` folder and run:
Then navigate to `localhost:6006`.
Then navigate to `localhost:6006` in your browser.
From TensorBoard, you will see the summary statistics:

default. In order to enable it, you must follow these steps. Please note that
the `Internal` Brain mode will only be available once completing these steps.
1. Make sure the TensorFlowSharp plugin is in your `Assets` folder. A Plugins
folder which includes TF# can be downloaded
[here](https://s3.amazonaws.com/unity-ml-agents/0.3/TFSharpPlugin.unitypackage).
Double click and import it once downloaded. You can see if this was
successfully installed by checking the TensorFlow files in the Project tab
under `Assets` -> `ML-Agents` -> `Plugins` -> `Computer`
2. Go to `Edit` -> `Project Settings` -> `Player`
3. For each of the platforms you target
(**`PC, Mac and Linux Standalone`**, **`iOS`** or **`Android`**):
1. Go into `Other Settings`.
2. Select `Scripting Runtime Version` to
`Experimental (.NET 4.6 Equivalent)`
3. In `Scripting Defined Symbols`, add the flag `ENABLE_TENSORFLOW`.
After typing in, press Enter.
4. Go to `File` -> `Save Project`
5. Restart the Unity Editor.
To set up the TensorFlowSharp Support, follow [Setting up ML-Agents within Unity](Basic-Guide.md#setting-up-ml-agents-within-unity) section.
of the Basic Guide page.
1. The trained model is stored in `models/<run-identifier>` in the `ml-agents` folder. Once the
training is complete, there will be a `<env_name>.bytes` file in that location where `<env_name>` is the name
of the executable used during training.
2. Move `<env_name>.bytes` from `python/models/ppo/` into
`unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/`.
3. Open the Unity Editor, and select the `3DBall` scene as described above.
4. Select the `Ball3DBrain` object from the Scene hierarchy.
5. Change the `Type of Brain` to `Internal`.
6. Drag the `<env_name>.bytes` file from the Project window of the Editor
to the `Graph Model` placeholder in the `3DBallBrain` inspector window.
7. Press the Play button at the top of the editor.
If you followed these steps correctly, you should now see the trained model
being used to control the behavior of the balance ball within the Editor
itself. From here you can re-build the Unity binary, and run it standalone
with your agent's new learned behavior built right in.
To embed the trained model into Unity, follow the later part of [Training the Brain with Reinforcement Learning](Basic-Guide.md#training-the-brain-with-reinforcement-learning) section of the Basic Buides page.

71
docs/Installation-Windows.md


ML-Agents supports Windows 10. While it might be possible to run ML-Agents using other versions of Windows, it has not been tested on other versions. Furthermore, ML-Agents has not been tested on a Windows VM such as Bootcamp or Parallels.
To use ML-Agents, you install Python and the required Python packages as outlined below. This guide also covers how set up GPU-based training (for advanced users). GPU-based training is not required for the v0.3 release of ML-Agents. However, training on a GPU might be required by future versions and features.
To use ML-Agents, you install Python and the required Python packages as outlined below. This guide also covers how set up GPU-based training (for advanced users). GPU-based training is not required for the v0.4 release of ML-Agents. However, training on a GPU might be required by future versions and features.
[Download](https://www.anaconda.com/download/#windows) and install Anaconda for Windows. By using Anaconda, you can manage separate environments for different distributions of Python. Python 3 is required as we no longer support Python 2. In this guide, we are using Python version 3.5 (Anaconda comes with Python 3.6, we will create an environment with python 3.5) and Anaconda version 5.1 ([64-bit](https://repo.continuum.io/archive/Anaconda3-5.1.0-Windows-x86_64.exe) or [32-bit](https://repo.continuum.io/archive/Anaconda3-5.1.0-Windows-x86.exe) direct links).
[Download](https://www.anaconda.com/download/#windows) and install Anaconda for Windows. By using Anaconda, you can manage separate environments for different distributions of Python. Python 3 is required as we no longer support Python 2. In this guide, we are using Python version 3.6 and Anaconda version 5.1 ([64-bit](https://repo.continuum.io/archive/Anaconda3-5.1.0-Windows-x86_64.exe) or [32-bit](https://repo.continuum.io/archive/Anaconda3-5.1.0-Windows-x86.exe) direct links).
<p align="center">
<img src="images/anaconda_install.PNG"

</p>
After installation, you must open __Anaconda Navigator__ to finish the setup. From the Windows search bar, type _anaconda navigator_. You can close Anaconda Navigator after it opens.
If environment variables were not created, or if you see the error "conda is not recognized as internal or external command", in System Variables, "Path" add the following new paths:
If environment variables were not created, you will see error "conda is not recognized as internal or external command" when you type `conda` into the command line. To solve this you will need to set the environment variable correctly.
Type `environment variables` in the search bar (this can be reached by hitting the Windows key or the bottom left Windows button). You should see an option called __Edit the system environment variables__.
<p align="center">
<img src="images/edit_env_var.png"
alt="edit env variables"
width="250" border="10" />
</p>
From here, click the __Environment Variables__ button.
Double click "Path" under __System variable__ to edit the "Path" variable, click __New__ to add the following new paths.
C:\ProgramData\Anaconda3\Scripts
C:\ProgramData\Anaconda3\Scripts\conda.exe
C:\ProgramData\Anaconda3
C:\ProgramData\Anaconda3\python.exe
%UserProfile%\Anaconda3\Scripts
%UserProfile%\Anaconda3\Scripts\conda.exe
%UserProfile%\Anaconda3
%UserProfile%\Anaconda3\python.exe
## Step 2: Setup and Activate a New Conda Environment
You will create a new [Conda environment](https://conda.io/docs/) to be used with ML-Agents. This means that all the packages that you install are localized to just this environment. It will not affect any other installation of Python or other environments. Whenever you want to run ML-Agents, you will need activate this Conda environment.

```
conda create -n ml-agents python=3.5
conda create -n ml-agents python=3.6
```
You may be asked to install new packages. Type `y` and press enter _(make sure you are connected to the internet)_. You must install these required packages. The new Conda environment is called ml-agents and uses Python version 3.6.

To use this environment, you must activate it. _(To use this environment In the future, you can run the same command)_. In the same Anaconda Prompt, type in the following command:
```
conda activate ml-agents
activate ml-agents
```
You should see `(ml-agents)` prepended on the last line.

```
pip install tensorflow==1.4.0
pip install tensorflow==1.7.1
```
## Step 3: Install Required Python Packages

If you haven't already, clone the ML-Agents Github repository to your local computer. You can do this using Git ([download here](https://git-scm.com/download/win)) and running the following commands in an Anaconda Prompt _(if you open a new prompt, be sure to activate the ml-agents Conda environment by typing `activate ml-agents`)_:
```
git clone git@github.com:Unity-Technologies/ml-agents.git
git clone https://github.com/Unity-Technologies/ml-agents.git
```
If you don't want to use Git, you can always directly download all the files [here](https://github.com/Unity-Technologies/ml-agents/archive/master.zip).

```
This will complete the installation of all the required Python packages to run ML-Agents.
This will complete the installation of all the required Python packages to run ML-Agents.
Not required to use v0.3 for ML-Agents. This is a guide for advanced users who want to train using GPUs. Additionally, you will need to check if your GPU is CUDA compatible. Please check Nvidia's page [here](https://developer.nvidia.com/cuda-gpus).
GPU is not required for ML-Agents and won't speed up the PPO algorithm a lot during training(but something in the future will benefit from GPU). This is a guide for advanced users who want to train using GPUs. Additionally, you will need to check if your GPU is CUDA compatible. Please check Nvidia's page [here](https://developer.nvidia.com/cuda-gpus).
As of ML-Agents v0.3, only CUDA 8 and cuDNN 6 is supported.
As of ML-Agents v0.4, only CUDA v9.0 and cuDNN v7.0.5 is supported.
[Download](https://developer.nvidia.com/cuda-toolkit-archive) and install the CUDA toolkit from Nvidia's archive. The toolkit includes GPU-accelerated libraries, debugging and optimization tools, a C/C++ (Step Visual Studio 2015) compiler and a runtime library and is needed to run ML-Agents. In this guide, we are using version 8.0.61 ([direct link](https://developer.nvidia.com/compute/cuda/8.0/Prod2/network_installers/cuda_8.0.61_win10_network-exe)).
[Download](https://developer.nvidia.com/cuda-toolkit-archive) and install the CUDA toolkit 9.0 from Nvidia's archive. The toolkit includes GPU-accelerated libraries, debugging and optimization tools, a C/C++ (Step Visual Studio 2017) compiler and a runtime library and is needed to run ML-Agents. In this guide, we are using version 9.0.176 (https://developer.nvidia.com/compute/cuda/9.0/Prod/network_installers/cuda_9.0.176_win10_network-exe)).
Run the installer and select the Express option. Note the directory where you installed the CUDA toolkit. In this guide, we installed in the directory `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0`
Run the installer and select the Express option. Note the directory where you installed the CUDA toolkit. In this guide, we installed in the directory `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0`
[Download](https://developer.nvidia.com/cudnn) and install the cuDNN library from Nvidia. cuDNN is is a GPU-accelerated library of primitives for deep neural networks. Before you can download, you will need to sign up for free to the Nvidia Developer Program.
[Download](https://developer.nvidia.com/cudnn) and install the cuDNN library from Nvidia. cuDNN is a GPU-accelerated library of primitives for deep neural networks. Before you can download, you will need to sign up for free to the Nvidia Developer Program.
<p align="center">
<img src="images/cuDNN_membership_required.png"

Once you've signed up, go back to the cuDNN [downloads page](https://developer.nvidia.com/cudnn). You may or may not be asked to fill out a short survey. When you get to the list cuDNN releases, __make sure you are downloading the right version for the CUDA toolkit you installed in Step 1.__ In this guide, we are using version 6.0 for CUDA toolkit version 8.0 ([direct link](https://developer.nvidia.com/compute/machine-learning/cudnn/secure/v6/prod/8.0_20170307/cudnn-8.0-windows10-x64-v6.0-zip)).
Once you've signed up, go back to the cuDNN [downloads page](https://developer.nvidia.com/cudnn). You may or may not be asked to fill out a short survey. When you get to the list cuDNN releases, __make sure you are downloading the right version for the CUDA toolkit you installed in Step 1.__ In this guide, we are using version 7.0.5 for CUDA toolkit version 9.0 ([direct link](https://developer.nvidia.com/compute/machine-learning/cudnn/secure/v7.0.5/prod/9.0_20171129/cudnn-9.0-windows10-x64-v7)).
After you have downloaded the cuDNN files, you will need to extract the files into the CUDA toolkit directory. In the cuDNN zip file, there are three folders called `bin`, `include`, and `lib`.

width="500" border="10" />
</p>
Copy these three folders into the CUDA toolkit directory. The CUDA toolkit directory is located at `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0`
Copy these three folders into the CUDA toolkit directory. The CUDA toolkit directory is located at `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0`
<p align="center">
<img src="images/cuda_toolkit_directory.PNG"

width="500" border="10" />
</p>
For __Variable Name__, enter `CUDA_HOME`. For the variable value, put the directory location for the CUDA toolkit. In this guide, the directory location is `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0`. Press __OK__ once.
For __Variable Name__, enter `CUDA_HOME`. For the variable value, put the directory location for the CUDA toolkit. In this guide, the directory location is `C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0`. Press __OK__ once.
<p align="center">
<img src="images/system_variable_name_value.PNG"

To set the two path variables, inside the same __Environment Variables__ window and under the second box called __System Variables__, find a variable called `PATH` and click __Edit__. You will add two directories to the list. For this guide, the two entries would look like:
To set the two path variables, inside the same __Environment Variables__ window and under the second box called __System Variables__, find a variable called `Path` and click __Edit__. You will add two directories to the list. For this guide, the two entries would look like:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\extras\CUPTI\libx64
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\lib\x64
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\extras\CUPTI\libx64
Make sure to replace the relevant directory location with the one you have installed. _Please note that case sensitivity matters_.

</p>
### Install TensorFlow GPU
Next, install `tensorflow-gpu` using `pip`. You'll need version 1.4.0 as newer versions require CUDA 9 which is not yet supported. In an Anaconda Prompt with the Conda environment ml-agents activated, type in the following command _(make sure you are connected to the internet)_:
Next, install `tensorflow-gpu` using `pip`. You'll need version 1.7.1. In an Anaconda Prompt with the Conda environment ml-agents activated, type in the following command to uninstall the tensorflow for cpu and install the tensorflow for gpu _(make sure you are connected to the internet)_:
pip install tensorflow-gpu==1.4.0
pip uninstall tensorflow
pip install tensorflow-gpu==1.7.1
```
Lastly, you should test to see if everything installed properly and that TensorFlow can identify your GPU. In the same Anaconda Prompt, type in the following command:

```
Found device 0 with properties ...
```
Step Visual Studio 2015: CUDA 8.0 is not compatible with Visual Studio 2017, so you will need an older version. Uninstall Visual Studio 2017 that comes with Unity, download Visual Studio Enterprise 2015 and install it with the Windows SDK. If you don't want/ can't install Visual Studio Enterprise 2015, you will need:
[Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145),
[Visual Studio Community 2015](https://www.visualstudio.com/vs/older-downloads/) + [Windows SDK](https://msdn.microsoft.com/en-us/library/mt683786.aspx).
## Acknowledgements

14
docs/Installation.md


# Installation & Set-up
# Installation
To install and use ML-Agents, you need install Unity, clone this repository
and install Python with additional dependencies. Each of the subsections

Once installed, you will want to clone the ML-Agents GitHub repository.
git clone git@github.com:Unity-Technologies/ml-agents.git
git clone https://github.com/Unity-Technologies/ml-agents.git
The `unity-environment` directory in this repository contains the Unity Assets
to add to your projects. The `python` directory contains the training code.

[instructions](https://packaging.python.org/guides/installing-using-linux-tools/#installing-pip-setuptools-wheel-with-linux-package-managers)
on installing it.
To install dependencies, go into the `python` subdirectory of the repository,
To install dependencies, **go into the `python` subdirectory** of the repository,
and run from the command line:
pip3 install .

If you'd like to use Docker for ML-Agents, please follow
[this guide](Using-Docker.md).
## Unity Packages
## Next Steps
You can download the [TensorFlowSharp](Background-TensorFlow.md#tensorflowsharp) plugin as a Unity package [here](https://s3.amazonaws.com/unity-ml-agents/0.3/TFSharpPlugin.unitypackage).
The [Basic Guide](Basic-Guide.md) page contains several short
tutorials on setting up ML-Agents within Unity, running a pre-trained model, in
addition to building and training environments.
If you run into any problems installing ML-Agents,
If you run into any problems regarding ML-Agents, refer to our [FAQ](FAQ.md) and our [Limitations](Limitations.md) pages. If you can't find anything please
[submit an issue](https://github.com/Unity-Technologies/ml-agents/issues) and
make sure to cite relevant information on OS, Python version, and exact error
message (whenever possible).

4
docs/Learning-Environment-Best-Practices.md


## Vector Observations
* Vector Observations should include all variables relevant to allowing the agent to take the optimally informed decision.
* In cases where Vector Observations need to be remembered or compared over time, increase the `Stacked Vectors` value to allow the agent to keep track of multiple observations into the past.
* Categorical variables such as type of object (Sword, Shield, Bow) should be encoded in one-hot fashion (i.e. `3` -> `0, 0, 1`).
* Categorical variables such as type of object (Sword, Shield, Bow) should be encoded in one-hot fashion (i.e. `3` > `0, 0, 1`).
* Besides encoding non-numeric values, all inputs should be normalized to be in the range 0 to +1 (or -1 to 1). For example, the `x` position information of an agent where the maximum possible value is `maxValue` should be recorded as `AddVectorObs(transform.position.x / maxValue);` rather than `AddVectorObs(transform.position.x);`. See the equation below for one approach of normalization.
* Positional information of relevant GameObjects should be encoded in relative coordinates wherever possible. This is often relative to the agent position.

* When using continuous control, action values should be clipped to an appropriate range.
* When using continuous control, action values should be clipped to an appropriate range. The provided PPO model automatically clips these values between -1 and 1, but third party training systems may not do so.
* Be sure to set the Vector Action's Space Size to the number of used Vector Actions, and not greater, as doing the latter can interfere with the efficiency of the training process.

25
docs/Learning-Environment-Create-New.md


In such a basic scene, we don't need the Academy to initialize, reset, or otherwise control any objects in the environment so we have the simplest possible Academy implementation:
```csharp
using MLAgents;
public class RollerAcademy : Academy { }
```

```csharp
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class RollerAgent : Agent
{

**Actions**
The decision of the Brain comes in the form of an action array passed to the `AgentAction()` function. The number of elements in this array is determined by the `Vector Action Space Type` and `Vector Action Space Size` settings of the agent's Brain. The RollerAgent uses the continuous vector action space and needs two continuous control signals from the brain. Thus, we will set the Brain `Vector Action Size` to 2. The first element,`action[0]` determines the force applied along the x axis; `action[1]` determines the force applied along the z axis. (If we allowed the agent to move in three dimensions, then we would need to set `Vector Action Size` to 3. Note the Brain really has no idea what the values in the action array mean. The training process just adjusts the action values in response to the observation input and then sees what kind of rewards it gets as a result.
The decision of the Brain comes in the form of an action array passed to the `AgentAction()` function. The number of elements in this array is determined by the `Vector Action Space Type` and `Vector Action Space Size` settings of the agent's Brain. The RollerAgent uses the continuous vector action space and needs two continuous control signals from the brain. Thus, we will set the Brain `Vector Action Size` to 2. The first element,`action[0]` determines the force applied along the x axis; `action[1]` determines the force applied along the z axis. (If we allowed the agent to move in three dimensions, then we would need to set `Vector Action Size` to 3. Each of these values returned by the network are between `-1` and `1.` Note the Brain really has no idea what the values in the action array mean. The training process just adjusts the action values in response to the observation input and then sees what kind of rewards it gets as a result.
controlSignal.x = Mathf.Clamp(action[0], -1, 1);
controlSignal.z = Mathf.Clamp(action[1], -1, 1);
controlSignal.x = action[0];
controlSignal.z = action[1];
The agent clamps the action values to the range [-1,1] for two reasons. First, the learning algorithm has less incentive to try very large values (since there won't be any affect on agent behavior), which can avoid numeric instability in the neural network calculations. Second, nothing prevents the neural network from returning excessively large values, so we want to limit them to reasonable ranges in any case.
**Rewards**

// Reached target
if (distanceToTarget < 1.42f)
{
Done();
Done();
**Note:** When you mark an agent as done, it stops its activity until it is reset. You can have the agent reset immediately, by setting the Agent.ResetOnDone property in the inspector or you can wait for the Academy to reset the environment. This RollerBall environment relies on the `ResetOnDone` mechanism and doesn't set a `Max Steps` limit for the Academy (so it never resets the environment).
**Note:** When you mark an agent as done, it stops its activity until it is reset. You can have the agent reset immediately, by setting the Agent.ResetOnDone property to true in the inspector or you can wait for the Academy to reset the environment. This RollerBall environment relies on the `ResetOnDone` mechanism and doesn't set a `Max Steps` limit for the Academy (so it never resets the environment).
To encourage the agent along, we also reward it for getting closer to the target (saving the previous distance measurement between steps):

// Fell off platform
if (this.transform.position.y < -1.0)
{
Done();
Done();
}
```

// Reached target
if (distanceToTarget < 1.42f)
{
Done();
Done();
}
// Getting closer

// Fell off platform
if (this.transform.position.y < -1.0)
{
Done();
Done();
controlSignal.x = Mathf.Clamp(vectorAction[0], -1, 1);
controlSignal.z = Mathf.Clamp(vectorAction[1], -1, 1);
controlSignal.x = vectorAction[0];
controlSignal.z = vectorAction[1];
rBody.AddForce(controlSignal * speed);
}
```

6
docs/Learning-Environment-Design-Agents.md


### Multiple Visual Observations
Camera observations use rendered textures from one or more cameras in a scene. The brain vectorizes the textures and feeds them into a neural network. You can use camera observations and either continuous feature vector or discrete state observations at the same time.
Camera observations use rendered textures from one or more cameras in a scene. The brain vectorizes the textures into a 3D Tensor which can be fed into a convolutional neural network (CNN). For more information on CNNs, see [this guide](http://cs231n.github.io/convolutional-networks/). You can use camera observations and either continuous feature vector or discrete state observations at the same time.
Agents using camera images can capture state of arbitrary complexity and are useful when the state is difficult to describe numerically. However, they are also typically less efficient and slower to train, and sometimes don't succeed at all.

In addition, make sure that the Agent's Brain expects a visual observation. In the Brain inspector, under `Brain Parameters` -> `Visual Observations`, specify the number of Cameras the agent is using for its visual observations. For each visual observation, set the width and height of the image (in pixels) and whether or not the observation is color or grayscale (when `Black And White` is checked).
In addition, make sure that the Agent's Brain expects a visual observation. In the Brain inspector, under **Brain Parameters** > **Visual Observations**, specify the number of Cameras the agent is using for its visual observations. For each visual observation, set the width and height of the image (in pixels) and whether or not the observation is color or grayscale (when `Black And White` is checked).
### Discrete Vector Observation Space: Table Lookup

}
```
You should clamp continuous action values to a reasonable value (typically [-1,1]) to avoid introducing instability while training the agent with the PPO algorithm. As shown above, you can scale the control values as needed after clamping them.
By default the output from our provided PPO algorithm pre-clamps the values of `vectorAction` into the [-1, 1] range. It is a best practice to manually clip these as well, if you plan to use a 3rd party algorithm with your environment. As shown above, you can scale the control values as needed after clamping them.
### Discrete Action Space

1
docs/Learning-Environment-Design-Heuristic-Brains.md


```csharp
using UnityEngine;
using MLAgents;
public class HeuristicLogic : MonoBehaviour, Decision
{

120
docs/Learning-Environment-Examples.md


[Making a New Learning Environment](Learning-Environment-Create-New.md)
page.
Note: Environment scenes marked as _optional_ do not have accompanying pre-trained model files, and are designed to serve as challenges for researchers.
If you would like to contribute environments, please see our
[contribution guidelines](../CONTRIBUTING.md) page.

* Brains: One brain with the following observation/action space.
* Vector Observation space: (Discrete) One variable corresponding to current state.
* Vector Action space: (Discrete) Two possible actions (Move left, move right).
* Visual Observations: 0
* Visual Observations: None.
* Benchmark Mean Reward: 0.94
## 3DBall: 3D Balance Ball
## [3DBall: 3D Balance Ball](https://youtu.be/dheeCO29-EI)
![3D Balance Ball](images/balance.png)

* Vector Observation space: (Continuous) 8 variables corresponding to rotation of platform, and position, rotation, and velocity of ball.
* Vector Observation space (Hard Version): (Continuous) 5 variables corresponding to rotation of platform and position and rotation of ball.
* Vector Action space: (Continuous) Size of 2, with one value corresponding to X-rotation, and the other to Z-rotation.
* Visual Observations: 0
* Visual Observations: None.
* Benchmark Mean Reward: 100
## GridWorld
## [GridWorld](https://youtu.be/gu8HE9WKEVI)
![GridWorld](images/gridworld.png)

* Vector Action space: (Discrete) Size of 4, corresponding to movement in cardinal directions.
* Visual Observations: One corresponding to top-down view of GridWorld.
* Reset Parameters: Three, corresponding to grid size, number of obstacles, and number of goals.
* Benchmark Mean Reward: 0.8
## Tennis
## [Tennis](https://youtu.be/RDaIh7JX6RI)
![Tennis](images/tennis.png)

* Brains: One brain with the following observation/action space.
* Vector Observation space: (Continuous) 8 variables corresponding to position and velocity of ball and racket.
* Vector Action space: (Continuous) Size of 2, corresponding to movement toward net or away from net, and jumping.
* Visual Observations: None
* Visual Observations: None.
* Benchmark Mean Reward: 2.5
* Optional Imitation Learning scene: `TennisIL`.
## Push Block
## [Push Block](https://youtu.be/jKdw216ZgoE)
![Push](images/push.png)

* Brains: One brain with the following observation/action space.
* Vector Observation space: (Continuous) 15 variables corresponding to position and velocities of agent, block, and goal.
* Vector Action space: (Continuous) Size of 2, corresponding to movement in X and Z directions.
* Visual Observations: None.
* Visual Observations (Optional): One first-person camera. Use `VisualPushBlock` scene.
* Benchmark Mean Reward: 4.5
* Optional Imitation Learning scene: `PushBlockIL`.
## Wall Jump
## [Wall Jump](https://youtu.be/NITLug2DIWQ)
![Wall](images/wall.png)

* Vector Action space: (Discrete) Size of 74, corresponding to 14 raycasts each detecting 4 possible objects. plus the global position of the agent and whether or not the agent is grounded.
* Visual Observations: None.
* Reset Parameters: 4, corresponding to the height of the possible walls.
* Benchmark Mean Reward (Big & Small Wall Brain): 0.8
## Reacher
## [Reacher](https://youtu.be/2N9EoF6pQyE)
![Tennis](images/reacher.png)
![Reacher](images/reacher.png)
* Agents: The environment contains 32 agent linked to a single brain.
* Agents: The environment contains 10 agent linked to a single brain.
* Visual Observations: None
* Visual Observations: None.
* Benchmark Mean Reward: 30
## Crawler
## [Crawler](https://youtu.be/ftLliaeooYI)
* Goal: The agents must move its body along the x axis without falling.
* Goal: The agents must move its body toward the goal direction without falling.
* `CrawlerStaticTarget` - Goal direction is always forward.
* `CrawlerDynamicTarget`- Goal direction is randomized.
* +1 times velocity in the x direction
* -1 for falling.
* -0.01 times the action squared
* -0.05 times y position change
* -0.05 times velocity in the z direction
* +0.03 times body velocity in the goal direction.
* +0.01 times body direction alignment with goal direction.
* Vector Action space: (Continuous) Size of 12, corresponding to torque applicable to 12 joints.
* Visual Observations: None
* Vector Action space: (Continuous) Size of 20, corresponding to target rotations for joints.
* Visual Observations: None.
* Benchmark Mean Reward: 2000
## Banana Collector
## [Banana Collector](https://youtu.be/heVMs3t9qSk)
![Banana](images/banana.png)

* Brains: One brain with the following observation/action space.
* Vector Observation space: (Continuous) 53 corresponding to velocity of agent (2), whether agent is frozen and/or shot its laser (2), plus ray-based perception of objects around agent's forward direction (49; 7 raycast angles with 7 measurements for each).
* Vector Action space: (Continuous) Size of 3, corresponding to forward movement, y-axis rotation, and whether to use laser to disable other agents.
* Visual Observations (Optional; None by default): First-person view for each agent.
* Reset Parameters: None
* Visual Observations (Optional): First-person camera per-agent. Use `VisualBanana` scene.
* Reset Parameters: None.
* Benchmark Mean Reward: 10
* Optional Imitation Learning scene: `BananaIL`.
## Hallway
## [Hallway](https://youtu.be/53GyfpPQRUQ)
![Hallway](images/hallway.png)

* Brains: One brain with the following observation/action space:
* Vector Observation space: (Continuous) 30 corresponding to local ray-casts detecting objects, goals, and walls.
* Vector Action space: (Discrete) 4 corresponding to agent rotation and forward/backward movement.
* Visual Observations (Optional): First-person view for the agent.
* Reset Parameters: None
* Visual Observations (Optional): First-person view for the agent. Use `VisualHallway` scene.
* Reset Parameters: None.
* Benchmark Mean Reward: 0.7
* Optional Imitation Learning scene: `HallwayIL`.
## Bouncer
## [Bouncer](https://youtu.be/Tkv-c-b1b2I)
![Bouncer](images/bouncer.png)

* Brains: One brain with the following observation/action space:
* Vector Observation space: (Continuous) 6 corresponding to local position of agent and banana.
* Vector Action space: (Continuous) 3 corresponding to agent force applied for the jump.
* Visual Observations: None
* Reset Parameters: None
* Visual Observations: None.
* Reset Parameters: None.
* Benchmark Mean Reward: 2.5
## Soccer Twos
## [Soccer Twos](https://youtu.be/Hg3nmYD3DjQ)
![SoccerTwos](images/soccer.png)

* Vector Action space: (Discrete)
* Striker: 6 corresponding to forward, backward, sideways movement, as well as rotation.
* Goalie: 4 corresponding to forward, backward, sideways movement.
* Visual Observations: None
* Visual Observations: None.
* Benchmark Mean Reward (Striker & Goalie Brain): 0 (the means will be inverse of each other and criss crosses during training)
## Walker
![Walker](images/walker.png)
* Set-up: Physics-based Humanoids agents with 26 degrees of freedom. These DOFs correspond to articulation of the following body-parts: hips, chest, spine, head, thighs, shins, feets, arms, forearms and hands.
* Goal: The agents must move its body toward the goal direction as quickly as possible without falling.
* Agents: The environment contains 11 independent agent linked to a single brain.
* Agent Reward Function (independent):
* +0.03 times body velocity in the goal direction.
* +0.01 times head y position.
* +0.01 times body direction alignment with goal direction.
* -0.01 times head velocity difference from body velocity.
* Brains: One brain with the following observation/action space.
* Vector Observation space: (Continuous) 215 variables corresponding to position, rotation, velocity, and angular velocities of each limb, along with goal direction.
* Vector Action space: (Continuous) Size of 39, corresponding to target rotations applicable to the joints.
* Visual Observations: None.
* Reset Parameters: None.
* Benchmark Mean Reward: 1000
## Pyramids
![Pyramids](images/pyramids.png)
* Set-up: Environment where the agent needs 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.
* Goal: Move to the golden brick on top of the spawned pyramid.
* Agents: The environment contains one agent linked to a single brain.
* Agent Reward Function (independent):
* +2 For moving to golden brick (minus 0.001 per step).
* Brains: One brain with the following observation/action space:
* Vector Observation space: (Continuous) 148 corresponding to local ray-casts detecting switch, bricks, golden brick, and walls, plus variable indicating switch state.
* Vector Action space: (Discrete) 4 corresponding to agent rotation and forward/backward movement.
* Visual Observations (Optional): First-person camera per-agent. Use `VisualPyramids` scene.
* Reset Parameters: None.
* Optional Imitation Learning scene: `PyramidsIL`.
* Benchmark Mean Reward: 1.75

7
docs/ML-Agents-Overview.md


actions performed with the controller (in addition to the agent observations)
will be recorded and sent to the Python API. The imitation learning algorithm
will then use these pairs of observations and actions from the human player
to learn a policy.
to learn a policy. [Video Link](https://youtu.be/kpb8ZkMBFYs).
The [Training with Imitation Learning](Training-Imitation-Learning.md) tutorial covers this
training mode with the **Banana Collector** sample environment.

[guide](Training-on-Amazon-Web-Service.md)
on how to set-up EC2 instances in addition to a public pre-configured Amazon
Machine Image (AMI).
* **Cloud Training on Microsoft Azure** - To facilitate using ML-Agents on
Azure machines, we provide a
[guide](Training-on-Microsoft-Azure.md)
on how to set-up virtual machine instances in addition to a pre-configured data science image.
## Summary and Next Steps

22
docs/Python-API.md


To communicate with an agent in a Unity environment from a Python program, the agent must either use an **External** brain or use a brain that is broadcasting (has its **Broadcast** property set to true). Your code is expected to return actions for agents with external brains, but can only observe broadcasting brains (the information you receive for an agent is the same in both cases). See [Using the Broadcast Feature](Learning-Environment-Design-Brains.md#using-the-broadcast-feature).
For a simple example of using the Python API to interact with a Unity environment, see the Basic [Jupyter](Background-Jupyter.md) notebook, which opens an environment, runs a few simulation steps taking random actions, and closes the environment.
For a simple example of using the Python API to interact with a Unity environment, see the Basic [Jupyter](Background-Jupyter.md) notebook (`python/Basics.ipynb`), which opens an environment, runs a few simulation steps taking random actions, and closes the environment.
_Notice: Currently communication between Unity and Python takes place over an open socket without authentication. As such, please make sure that the network where training takes place is secure. This will be addressed in a future release._

* `file_name` is the name of the environment binary (located in the root directory of the python project).
* `worker_id` indicates which port to use for communication with the environment. For use in parallel training regimes such as A3C.
* `seed` indicates the seed to use when generating random numbers during the training process. In environments which do not involve physics calculations, setting the seed enables reproducible experimentation by ensuring that the environment and trainers utilize the same random seed.
If you want to directly interact with the Editor, you need to use `file_name=None`, then press the :arrow_forward: button in the Editor when the message _"Start training by pressing the Play button in the Unity Editor"_ is displayed on the screen
## Interacting with a Unity Environment

- `memory` is an optional input that can be used to send a list of floats per agents to be retrieved at the next step.
- `text_action` is an optional input that be used to send a single string per agent.
Note that if you have more than one external brain in the environment, you must provide dictionaries from brain names to arrays for `action`, `memory` and `value`. For example: If you have two external brains named `brain1` and `brain2` each with one agent taking two continuous actions, then you can have:
```python
action = {'brain1':[1.0, 2.0], 'brain2':[3.0,4.0]}
```
Returns a dictionary mapping brain names to BrainInfo objects.
For example, to access the BrainInfo belonging to a brain called 'brain_name', and the BrainInfo field 'vector_observations':
```python
info = env.step()
brainInfo = info['brain_name']
observations = brainInfo.vector_observations
```
Note that if you have more than one external brain in the environment, you must provide dictionaries from brain names to arrays for `action`, `memory` and `value`. For example: If you have two external brains named `brain1` and `brain2` each with one agent taking two continuous actions, then you can have:
```python
action = {'brain1':[1.0, 2.0], 'brain2':[3.0,4.0]}
```

16
docs/Readme.md


# Unity ML-Agents Documentation
## Installation & Set-up
* [Installation](Installation.md)
* [Background: Jupyter Notebooks](Background-Jupyter.md)
* [Docker Set-up](Using-Docker.md)
* [Basic Guide](Basic-Guide.md)
* [Installation & Set-up](Installation.md)
* [Background: Jupyter Notebooks](Background-Jupyter.md)
* [Docker Set-up](Using-Docker.md)
* [Getting Started with the 3D Balance Ball Environment](Getting-Started-with-Balance-Ball.md)
* [Example Environments](Learning-Environment-Examples.md)

* [Brains](Learning-Environment-Design-Brains.md): [Player](Learning-Environment-Design-Player-Brains.md), [Heuristic](Learning-Environment-Design-Heuristic-Brains.md), [Internal & External](Learning-Environment-Design-External-Internal-Brains.md)
* [Learning Environment Best Practices](Learning-Environment-Best-Practices.md)
* [Using the Monitor](Feature-Monitor.md)
* [Using an Executable Environment](Learning-Environment-Executable.md)
* [TensorFlowSharp in Unity (Experimental)](Using-TensorFlow-Sharp-in-Unity.md)
## Training

* [Training with Imitation Learning](Training-Imitation-Learning.md)
* [Training with LSTM](Feature-Memory.md)
* [Training on the Cloud with Amazon Web Services](Training-on-Amazon-Web-Service.md)
* [Training on the Cloud with Microsoft Azure](Training-on-Microsoft-Azure.md)
* [Migrating to ML-Agents v0.3](Migrating-v0.3.md)
* [Migrating from earlier versions of ML-Agents](Migrating.md)
* [Frequently Asked Questions](FAQ.md)
* [Limitations & Common Issues](Limitations-and-Common-Issues.md)
* [Limitations](Limitations.md)
## API Docs
* [API Reference](API-Reference.md)

11
docs/Training-Curriculum-Learning.md


accomplish the task. From there, we can slowly add to the difficulty of the task by
increasing the size of the wall, until the agent can complete the initially
near-impossible task of scaling the wall. We are including just such an environment with
ML-Agents 0.2, called Wall Area.
ML-Agents 0.2, called Wall Jump.
![Wall](images/curriculum.png)

```json
{
"measure" : "reward",
"thresholds" : [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5],
"measure" : "progress",
"thresholds" : [0.1, 0.3, 0.5],
"min_wall_height" : [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5],
"max_wall_height" : [1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0]
"big_wall_min_height" : [0.0, 4.0, 6.0, 8.0],
"big_wall_max_height" : [4.0, 7.0, 8.0, 8.0],
"small_wall_height" : [1.5, 2.0, 2.5, 4.0]
}
}
```

15
docs/Training-Imitation-Learning.md


# Imitation Learning
It is often more intuitive to simply demonstrate the behavior we want an agent to perform, rather than attempting to have it learn via trial-and-error methods. Consider our [running example](ML-Agents-Overview.md#running-example-training-npc-behaviors) of training a medic NPC : instead of indirectly training a medic with the help of a reward function, we can give the medic real world examples of observations from the game and actions from a game controller to guide the medic's behavior. More specifically, in this mode, the Brain type during training is set to Player and all the actions performed with the controller (in addition to the agent observations) will be recorded and sent to the Python API. The imitation learning algorithm will then use these pairs of observations and actions from the human player to learn a policy.
It is often more intuitive to simply demonstrate the behavior we want an agent to perform, rather than attempting to have it learn via trial-and-error methods. Consider our [running example](ML-Agents-Overview.md#running-example-training-npc-behaviors) of training a medic NPC : instead of indirectly training a medic with the help of a reward function, we can give the medic real world examples of observations from the game and actions from a game controller to guide the medic's behavior. More specifically, in this mode, the Brain type during training is set to Player and all the actions performed with the controller (in addition to the agent observations) will be recorded and sent to the Python API. The imitation learning algorithm will then use these pairs of observations and actions from the human player to learn a policy. [Video Link](https://youtu.be/kpb8ZkMBFYs).
## Using Behavioral Cloning

2. Set the "Teacher" brain to Player mode, and properly configure the inputs to map to the corresponding actions. **Ensure that "Broadcast" is checked within the Brain inspector window.**
3. Set the "Student" brain to External mode.
4. Link the brains to the desired agents (one agent as the teacher and at least one agent as a student).
5. Build the Unity executable for your desired platform.
6. In `trainer_config.yaml`, add an entry for the "Student" brain. Set the `trainer` parameter of this entry to `imitation`, and the `brain_to_imitate` parameter to the name of the teacher brain: "Teacher". Additionally, set `batches_per_epoch`, which controls how much training to do each moment. Increase the `max_steps` option if you'd like to keep training the agents for a longer period of time.
7. Launch the training process with `python3 python/learn.py <env_name> --train --slow`, where `<env_name>` is the path to your built Unity executable.
8. From the Unity window, control the agent with the Teacher brain by providing "teacher demonstrations" of the behavior you would like to see.
9. Watch as the agent(s) with the student brain attached begin to behave similarly to the demonstrations.
10. Once the Student agents are exhibiting the desired behavior, end the training process with `CTL+C` from the command line.
11. Move the resulting `*.bytes` file into the `TFModels` subdirectory of the Assets folder (or a subdirectory within Assets of your choosing) , and use with `Internal` brain.
5. In `trainer_config.yaml`, add an entry for the "Student" brain. Set the `trainer` parameter of this entry to `imitation`, and the `brain_to_imitate` parameter to the name of the teacher brain: "Teacher". Additionally, set `batches_per_epoch`, which controls how much training to do each moment. Increase the `max_steps` option if you'd like to keep training the agents for a longer period of time.
6. Launch the training process with `python3 python/learn.py --train --slow`, and press the :arrow_forward: button in Unity when the message _"Start training by pressing the Play button in the Unity Editor"_ is displayed on the screen
7. From the Unity window, control the agent with the Teacher brain by providing "teacher demonstrations" of the behavior you would like to see.
8. Watch as the agent(s) with the student brain attached begin to behave similarly to the demonstrations.
9. Once the Student agents are exhibiting the desired behavior, end the training process with `CTL+C` from the command line.
10. Move the resulting `*.bytes` file into the `TFModels` subdirectory of the Assets folder (or a subdirectory within Assets of your choosing) , and use with `Internal` brain.
### BC Teacher Helper

20
docs/Training-ML-Agents.md


For a broader overview of reinforcement learning, imitation learning and the ML-Agents training process, see [ML-Agents Overview](ML-Agents-Overview.md).
## Training with Learn.py
## Training with learn.py
Use the Python `Learn.py` program to train agents. `Learn.py` supports training with [reinforcement learning](Background-Machine-Learning.md#reinforcement-learning), [curriculum learning](Training-Curriculum-Learning.md), and [behavioral cloning imitation learning](Training-Imitation-Learning.md).
Use the Python `learn.py` program to train agents. `learn.py` supports training with [reinforcement learning](Background-Machine-Learning.md#reinforcement-learning), [curriculum learning](Training-Curriculum-Learning.md), and [behavioral cloning imitation learning](Training-Imitation-Learning.md).
Run `Learn.py` from the command line to launch the training process. Use the command line patterns and the `trainer_config.yaml` file to control training options.
Run `learn.py` from the command line to launch the training process. Use the command line patterns and the `trainer_config.yaml` file to control training options.
python3 learn.py <env_file_path> --run-id=<run-identifier> --train
python3 learn.py <env_name> --run-id=<run-identifier> --train
where `<env_file_path>` is the path to your Unity executable containing the agents to be trained and `<run-identifier>` is an optional identifier you can use to identify the results of individual training runs.
where
* `<env_name>`__(Optional)__ is the name (including path) of your Unity executable containing the agents to be trained. If `<env_name>` is not passed, the training will happen in the Editor. Press the :arrow_forward: button in Unity when the message _"Start training by pressing the Play button in the Unity Editor"_ is displayed on the screen.
* `<run-identifier>` is an optional identifier you can use to identify the results of individual training runs.
1. Build the project, making sure that you only include the training scene.
1. [Build the project](Learning-Environment-Executable.md), making sure that you only include the training scene.
2. Open a terminal or console window.
3. Navigate to the ml-agents `python` folder.
4. Run the following to launch the training process using the path to the Unity environment you built in step 1:

* `--train` – Specifies whether to train model or only run in inference mode. When training, **always** use the `--train` option.
* `--worker-id=<n>` – When you are running more than one training environment at the same time, assign each a unique worker-id number. The worker-id is added to the communication port opened between the current instance of learn.py and the ExternalCommunicator object in the Unity environment. Defaults to 0.
* `--docker-target-name=<dt>` – The Docker Volume on which to store curriculum, executable and model files. See [Using Docker](Using-Docker.md).
* `--no-graphics` - Specify this option to run the Unity executable in `-batchmode` and doesn't initialize the graphics driver. Use this only if your training doesn't involve visual observations (reading from Pixels). See [here](https://docs.unity3d.com/Manual/CommandLineArguments.html) for more details.
### Training config file

| batch_size | The number of experiences in each iteration of gradient descent.| PPO, BC |
| batches_per_epoch | In imitation learning, the number of batches of training examples to collect before training the model.| BC |
| beta | The strength of entropy regularization.| PPO, BC |
| brain_to_imitate | For imitation learning, the name of the GameObject containing the Brain component to imitate. | BC |
| brain\_to\_imitate | For imitation learning, the name of the GameObject containing the Brain component to imitate. | BC |
| curiosity\_enc\_size | The size of the encoding to use in the forward and inverse models in the Curioity module. | PPO |
| curiosity_strength | Magnitude of intrinsic reward generated by Intrinsic Curiosity Module. | PPO |
| epsilon | Influences how rapidly the policy can evolve during training.| PPO, BC |
| gamma | The reward discount rate for the Generalized Advantage Estimator (GAE). | PPO |
| hidden_units | The number of units in the hidden layers of the neural network. | PPO, BC |

| summary_freq | How often, in steps, to save training statistics. This determines the number of data points shown by TensorBoard. | PPO, BC |
| time_horizon | How many steps of experience to collect per-agent before adding it to the experience buffer. | PPO, BC |
| trainer | The type of training to perform: "ppo" or "imitation".| PPO, BC |
| use_curiosity | Train using an additional intrinsic reward signal generated from Intrinsic Curiosity Module. | PPO |
| use_recurrent | Train using a recurrent neural network. See [Using Recurrent Neural Networks](Feature-Memory.md).| PPO, BC |
|| PPO = Proximal Policy Optimization, BC = Behavioral Cloning (Imitation)) ||

22
docs/Training-PPO.md


Typical Range: `64` - `512`
### (Optional) Intrinsic Curiosity Module Hyperparameters
The below hyperparameters are only used when `use_curiosity` is set to true.
#### Curioisty Encoding Size
`curiosity_enc_size` corresponds to the size of the hidden layer used to encode the observations within the intrinsic curiosity module. This value should be small enough to encourage the curiosity module to compress the original observation, but also not too small to prevent it from learning the dynamics of the environment.
Typical Range: `64` - `256`
#### Curiosity Strength
`curiosity_strength` corresponds to the magnitude of the intrinsic reward generated by the intrinsic curiosity module. This should be scaled in order to ensure it is large enough to not be overwhelmed by extrnisic reward signals in the environment. Likewise it should not be too large to overwhelm the extrinsic reward signal.
Typical Range: `0.1` - `0.001`
## Training Statistics
To view training statistics, use TensorBoard. For information on launching and using TensorBoard, see [here](./Getting-Started-with-Balance-Ball.md#observing-training-progress).

#### Policy Loss
These values will oscillate with training.
These values will oscillate during training. Generally they should be less than 1.0.
These values should increase with the reward. They corresponds to how much future reward the agent predicts itself receiving at any given point.
These values should increase as the cumulative reward increases. They correspond to how much future reward the agent predicts itself receiving at any given point.
These values will increase as the reward increases, and should decrease when reward becomes stable.
These values will increase as the reward increases, and then should decrease once reward becomes stable.

196
docs/Training-on-Amazon-Web-Service.md


# Training on Amazon Web Service
This page contains instructions for setting up an EC2 instance on Amazon Web Service for training ML-Agents environments. You can run "headless" training if none of the agents in the environment use visual observations.
This page contains instructions for setting up an EC2 instance on Amazon Web Service for training ML-Agents environments.
## Pre-Configured AMI
A public pre-configured AMI is available with the ID: `ami-30ec184a` in the `us-east-1` region. It was created as a modification of the Amazon Deep Learning [AMI](https://aws.amazon.com/marketplace/pp/B01M0AXXQB).
## Preconfigured AMI
## Configuring your own Instance
We've prepared an preconfigured AMI for you with the ID: `ami-6880c317` in the `us-east-1` region. It was created as a modification of [Deep Learning AMI (Ubuntu)](https://aws.amazon.com/marketplace/pp/B077GCH38C). If you want to do training without the headless mode, you need to enable X Server on it. After launching your EC2 instance using the ami and ssh into it, run the following commands to enable it:
1. To begin with, you will need an EC2 instance which contains the latest Nvidia drivers, CUDA8, and cuDNN. There are a number of external tutorials which describe this, such as:
* [Getting CUDA 8 to Work With openAI Gym on AWS and Compiling TensorFlow for CUDA 8 Compatibility](https://davidsanwald.github.io/2016/11/13/building-tensorflow-with-gpu-support.html)
* [Installing TensorFlow on an AWS EC2 P2 GPU Instance](http://expressionflow.com/2016/10/09/installing-tensorflow-on-an-aws-ec2-p2-gpu-instance/)
* [Updating Nvidia CUDA to 8.0.x in Ubuntu 16.04 – EC2 Gx instance](https://aichamp.wordpress.com/2016/11/09/updating-nvidia-cuda-to-8-0-x-in-ubuntu-16-04-ec2-gx-instance/)
```
//Start the X Server, press Enter to come to the command line
sudo /usr/bin/X :0 &
## Installing ML-Agents
//Check if Xorg process is running
//You will have a list of processes running on the GPU, Xorg should be in the list, as shown below
nvidia-smi
/*
* Thu Jun 14 20:27:26 2018
* +-----------------------------------------------------------------------------+
* | NVIDIA-SMI 390.67 Driver Version: 390.67 |
* |-------------------------------+----------------------+----------------------+
* | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
* | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
* |===============================+======================+======================|
* | 0 Tesla K80 On | 00000000:00:1E.0 Off | 0 |
* | N/A 35C P8 31W / 149W | 9MiB / 11441MiB | 0% Default |
* +-------------------------------+----------------------+----------------------+
*
* +-----------------------------------------------------------------------------+
* | Processes: GPU Memory |
* | GPU PID Type Process name Usage |
* |=============================================================================|
* | 0 2331 G /usr/lib/xorg/Xorg 8MiB |
* +-----------------------------------------------------------------------------+
*/
2. Move `python` sub-folder of this ml-agents repo to the remote ECS instance, and set it as the working directory.
2. Install the required packages with `pip3 install .`.
//Make the ubuntu use X Server for display
export DISPLAY=:0
```
## Testing
## Configuring your own Instance
To verify that all steps worked correctly:
You could also choose to configure your own instance. To begin with, you will need an EC2 instance which contains the latest Nvidia drivers, CUDA9, and cuDNN. In this tutorial we used the [Deep Learning AMI (Ubuntu)](https://aws.amazon.com/marketplace/pp/B077GCH38C) listed under AWS Marketplace with a p2.xlarge instance.
1. In the Unity Editor, load a project containing an ML-Agents environment (you can use one of the example environments if you have not created your own).
2. Open the Build Settings window (menu: File > Build Settings).
3. Select Linux as the Target Platform, and x86_64 as the target architecture.
4. Check Headless Mode (unless you have enabled a virtual screen following the instructions below).
5. Click Build to build the Unity environment executable.
6. Upload the executable to your EC2 instance.
7. Test the instance setup from Python using:
### Installing ML-Agents on the instance
After launching your EC2 instance using the ami and ssh into it:
1. Activate the python3 environment
```
source activate python3
```
```python
from unityagents import UnityEnvironment
2. Clone the ML-Agents repo and install the required python packages
env = UnityEnvironment(<your_env>)
```
Where `<your_env>` corresponds to the path to your environment executable.
You should receive a message confirming that the environment was loaded successfully.
```
git clone https://github.com/Unity-Technologies/ml-agents.git
cd ml-agents/python
pip3 install .
```
## (Optional) Enabling a virtual screen
### Setting up X Server (optional)
_Instructions here are adapted from this [Medium post](https://medium.com/towards-data-science/how-to-run-unity-on-amazon-cloud-or-without-monitor-3c10ce022639) on running general Unity applications in the cloud._
X Server setup is only necessary if you want to do training that requires visual observation input. _Instructions here are adapted from this [Medium post](https://medium.com/towards-data-science/how-to-run-unity-on-amazon-cloud-or-without-monitor-3c10ce022639) on running general Unity applications in the cloud._
1. Run the following commands to install Xorg:
1. Install and setup Xorg:
//Install Xorg
//Get the BusID information
nvidia-xconfig --query-gpu-info
//Add the BusID information to your /etc/X11/xorg.conf file
sudo sed -i 's/ BoardName "Tesla K80"/ BoardName "Tesla K80"\n BusID "0:30:0"/g' /etc/X11/xorg.conf
//Remove the Section "Files" from the /etc/X11/xorg.conf file
sudo vim /etc/X11/xorg.conf //And remove two lines that contain Section "Files" and EndSection
2. Restart the EC2 instance.
2. Update and setup Nvidia driver:
3. Make sure there are no Xorg processes running. To kill the Xorg processes, run `sudo killall Xorg`.
Note that you might have to run this command multiple times depending on how Xorg is configured.
If you run `nvidia-smi`, you will have a list of processes running on the GPU, Xorg should not be in the list.
```
//Download and install the latest Nvidia driver for ubuntu
wget http://download.nvidia.com/XFree86/Linux-x86_64/390.67/NVIDIA-Linux-x86_64-390.67.run
sudo /bin/bash ./NVIDIA-Linux-x86_64-390.67.run --accept-license --no-questions --ui=none
4. Run:
//Disable Nouveau as it will clash with the Nvidia driver
sudo echo 'blacklist nouveau' | sudo tee -a /etc/modprobe.d/blacklist.conf
sudo echo 'options nouveau modeset=0' | sudo tee -a /etc/modprobe.d/blacklist.conf
sudo echo options nouveau modeset=0 | sudo tee -a /etc/modprobe.d/nouveau-kms.conf
sudo update-initramfs -u
```
2. Restart the EC2 instance:
```
sudo reboot now
```
3. Make sure there are no Xorg processes running:
```
//Kill any possible running Xorg processes
//Note that you might have to run this command multiple times depending on how Xorg is configured.
sudo killall Xorg
//Check if there is any Xorg process left
//You will have a list of processes running on the GPU, Xorg should not be in the list, as shown below.
nvidia-smi
/*
* Thu Jun 14 20:21:11 2018
* +-----------------------------------------------------------------------------+
* | NVIDIA-SMI 390.67 Driver Version: 390.67 |
* |-------------------------------+----------------------+----------------------+
* | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
* | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
* |===============================+======================+======================|
* | 0 Tesla K80 On | 00000000:00:1E.0 Off | 0 |
* | N/A 37C P8 31W / 149W | 0MiB / 11441MiB | 0% Default |
* +-------------------------------+----------------------+----------------------+
*
* +-----------------------------------------------------------------------------+
* | Processes: GPU Memory |
* | GPU PID Type Process name Usage |
* |=============================================================================|
* | No running processes found |
* +-----------------------------------------------------------------------------+
*/
```
4. Start X Server and make the ubuntu use X Server for display:
//Start the X Server, press Enter to come to the command line
//Check if Xorg process is running
//You will have a list of processes running on the GPU, Xorg should be in the list.
nvidia-smi
//Make the ubuntu use X Server for display
5. To ensure the installation was successful, run `glxgears`. If there are no errors, then Xorg is correctly configured.
5. Ensure the Xorg is correctly configured:
```
//For more information on glxgears, see ftp://www.x.org/pub/X11R6.8.1/doc/glxgears.1.html.
glxgears
//If Xorg is configured correctly, you should see the following message
/*
* Running synchronized to the vertical refresh. The framerate should be
* approximately the same as the monitor refresh rate.
* 137296 frames in 5.0 seconds = 27459.053 FPS
* 141674 frames in 5.0 seconds = 28334.779 FPS
* 141490 frames in 5.0 seconds = 28297.875 FPS
*/
```
## Training on EC2 instance
1. In the Unity Editor, load a project containing an ML-Agents environment (you can use one of the example environments if you have not created your own).
2. Open the Build Settings window (menu: File > Build Settings).
3. Select Linux as the Target Platform, and x86_64 as the target architecture.
4. Check Headless Mode (If you haven't setup the X Server).
5. Click Build to build the Unity environment executable.
6. Upload the executable to your EC2 instance within `ml-agents/python` folder.
7. Test the instance setup from Python using:
```python
from unityagents import UnityEnvironment
env = UnityEnvironment(<your_env>)
```
Where `<your_env>` corresponds to the path to your environment executable.
You should receive a message confirming that the environment was loaded successfully.
8. Train the executable
```
//cd into your ml-agents/python folder
chmod +x <your_env>.x86_64
python learn.py <your_env> --train
```

14
docs/Using-Docker.md


Using Docker for ML-Agents involves three steps: building the Unity environment with specific flags, building a Docker container and, finally, running the container. If you are not familiar with building a Unity environment for ML-Agents, please read through our [Getting Started with the 3D Balance Ball Example](Getting-Started-with-Balance-Ball.md) guide first.
### Build the Environment
### Build the Environment (Optional)
_If you want to used the Editor to perform training, you can skip this step._
Since Docker typically runs a container sharing a (linux) kernel with the host machine, the
Unity environment **has** to be built for the **linux platform**. When building a Unity environment, please select the following options from the the Build Settings window:

### Build the Docker Container
First, make sure the Docker engine is running on your machine. Then build the Docker container by calling the following command at the top-level of the repository:
**Note** if you modify hyperparameters in `trainer_config.yaml` you will have to build a new Docker Container before running.
-p 5005:5005 \
<image-name>:latest <environment-name> \
--docker-target-name=unity-volume \
--train \

Notes on argument values:
- `<container-name>` is used to identify the container (in case you want to interrupt and terminate it). This is optional and Docker will generate a random name if this is not set. _Note that this must be unique for every run of a Docker image._
- `<image-name>` and `<environment-name>`: References the image and environment names, respectively.
- `<image-name>` references the image name used when building the container.
- `<environemnt-name>` __(Optional)__: If you are training with a linux executable, this is the name of the executable. If you are training in the Editor, do not pass a `<environemnt-name>` argument and press the :arrow_forward: button in Unity when the message _"Start training by pressing the Play button in the Unity Editor"_ is displayed on the screen.
For the `3DBall` environment, for example this would be:
To train with a `3DBall` environment executable, the command would be:
-p 5005:5005 \
balance.ball.v0.1:latest 3DBall \
--docker-target-name=unity-volume \
--train \

12
docs/Using-TensorFlow-Sharp-in-Unity.md


## Requirements
* Unity 2017.1 or above
* Unity TensorFlow Plugin ([Download here](https://s3.amazonaws.com/unity-ml-agents/0.3/TFSharpPlugin.unitypackage))
* Unity TensorFlow Plugin ([Download here](https://s3.amazonaws.com/unity-ml-agents/0.4/TFSharpPlugin.unitypackage))
# Using TensorFlowSharp with ML-Agents

# iOS additional instructions for building
* Once you build for iOS in the editor, Xcode will launch.
* In `General` -> `Linked Frameworks and Libraries`:
* Add a framework called `Accelerate.framework`
* Remove the library `libtensorflow-core.a`
* In `Build Settings`->`Linking`->`Other Linker Flags`:
* Once you build the project for iOS in the editor, open the .xcodeproj file within the project folder using Xcode.
* Set up your ios account following the [iOS Account setup page](https://docs.unity3d.com/Manual/iphone-accountsetup.html).
* In **Build Settings** > **Linking** > **Other Linker Flags**:
* Drag the library `libtensorflow-core.a` from the `Project Navigator` on the left under `Libraries/ML-Agents/Plugins/iOS` into the flag list, after `-force_load`.
* Drag the library `libtensorflow-core.a` from the **Project Navigator** on the left under `Libraries/ML-Agents/Plugins/iOS` into the flag list, after `-force_load`.
# Using TensorFlowSharp without ML-Agents

11
docs/Using-Tensorboard.md


* Learning Rate - How large a step the training algorithm takes as it searches
for the optimal policy. Should decrease over time.
* Policy Loss - The mean loss of the policy function update. Correlates to how
* Policy Loss - The mean magnitude of policy loss function. Correlates to how
much the policy (process for deciding actions) is changing. The magnitude of
this should decrease during a successful training session.

* Value Loss - The mean loss of the value function update. Correlates to how
well the model is able to predict the value of each state. This should decrease
during a successful training session.
well the model is able to predict the value of each state. This should increase
while the agent is learning, and then decrease once the reward stabilizes.
* _(Curiosity-Specific)_ Intrinsic Reward - This corresponds to the mean cumulative intrinsic reward generated per-episode.
* _(Curiosity-Specific)_ Forward Loss - The mean magnitude of the inverse model loss function. Corresponds to how well the model is able to predict the new observation encoding.
* _(Curiosity-Specific)_ Inverse Loss - The mean magnitude of the forward model loss function. Corresponds to how well the model is able to predict the action taken between two observations.

2
docs/dox-ml-agents.conf


# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v0.3
PROJECT_NUMBER = v0.4
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

999
docs/images/crawler.png
文件差异内容过多而无法显示
查看文件

577
docs/images/cuDNN_membership_required.png

之前 之后
宽度: 789  |  高度: 649  |  大小: 79 KiB

181
docs/images/cuda_toolkit_directory.PNG

之前 之后
宽度: 878  |  高度: 346  |  大小: 30 KiB

178
docs/images/cudnn_zip_files.PNG

之前 之后
宽度: 547  |  高度: 353  |  大小: 20 KiB

649
docs/images/mlagents-TensorBoard.png

之前 之后
宽度: 1395  |  高度: 548  |  大小: 138 KiB

218
docs/images/new_system_variable.PNG
文件差异内容过多而无法显示
查看文件

127
docs/images/path_variables.PNG

之前 之后
宽度: 527  |  高度: 501  |  大小: 19 KiB

47
docs/images/system_variable_name_value.PNG

之前 之后
宽度: 653  |  高度: 165  |  大小: 6.2 KiB

2
docs/localized/zh-CN/README.md


**除了安装和使用说明外,如需更多信息,
请参阅我们的[文档主页](docs/Readme.md)。**如果您使用的
是 v0.3 之前的 ML-Agents 版本,强烈建议您参考
我们的[关于迁移到 v0.3 的指南](/docs/Migrating-v0.3.md)。
我们的[关于迁移到 v0.3 的指南](/docs/Migrating.md)。
我们还发布了一系列与 ML-Agents 相关的博客文章:
- reinforcement learning(强化学习)概念概述

6
docs/localized/zh-CN/docs/Getting-Started-with-Balance-Ball.md


总之,转到命令行,进入 `ml-agents` 目录并输入:
```python
python3 python/learn.py <env_file_path> --run-id=<run-identifier> --train
```
python3 python/learn.py <env_name> --run-id=<run-identifier> --train
`--train` 标志告诉 ML-Agents 以训练模式运行。`env_file_path` 应该是刚才创建的 Unity 可执行文件的路径
`--train` 标志告诉 ML-Agents 以训练模式运行。`env_name` 应该是刚才创建的 Unity 可执行文件的名字
### 观测训练进度

2
docs/localized/zh-CN/docs/Installation.md


## Unity 包
您可以通过 Unity 包的形式下载TensorflowSharp 插件([AWS S3链接](https://s3.amazonaws.com/unity-ml-agents/0.3/TFSharpPlugin.unitypackage),[百度盘链接](https://pan.baidu.com/s/1s0mJN8lvuxTcYbs2kL2FqA))
您可以通过 Unity 包的形式下载TensorFlowSharp 插件([AWS S3链接](https://s3.amazonaws.com/unity-ml-agents/0.3/TFSharpPlugin.unitypackage),[百度盘链接](https://pan.baidu.com/s/1s0mJN8lvuxTcYbs2kL2FqA))
## 帮助

10
docs/localized/zh-CN/docs/ML-Agents-Overview.md


让您了解如何设置 EC2 实例以及公共的预配置 Amazon
Machine Image (AMI)。
* **Microsoft Azure 上的云训练** - 为了便于在 Microsoft Azure
机器上使用 ML-Agents,我们提供了一份
[指南](/docs/Training-on-Microsoft-Azure.md)
让您了解如何设置 virtual machine instance 实例以及公共的预配置 Data Science VM。
* **Cloud Training on Microsoft Azure** - To facilitate using ML-Agents on
Azure machines, we provide a
[guide](Training-on-Microsoft-Azure.md)
on how to set-up virtual machine instances in addition to a pre-configured data science image.
## 总结和后续步骤
简要总结一下:ML-Agents 使 Unity 中构建的游戏和模拟环境

6
docs/localized/zh-CN/docs/Readme.md


* [Imitation Learning(模仿学习)训练要点](/docs/Training-Imitation-Learning.md)
* [LSTM 训练要点](/docs/Feature-Memory.md)
* [如何使用 Amazon Web Services 进行云端训练](/docs/Training-on-Amazon-Web-Service.md)
* [如何使用 Microsoft Azure 进行云端训练](/docs/Training-on-Microsoft-Azure.md)
* [如何从老版本升级到 ML-Agents v0.3](/docs/Migrating-v0.3.md)
* [如何从老版本升级到 ML-Agents v0.3](/docs/Migrating.md)
* [常见问题](/docs/FAQ.md)
* [ML-Agents 尚未实现功能以及常见问题](/docs/Limitations-and-Common-Issues.md)
* [ML-Agents 尚未实现功能](/docs/Limitations.md)
## API 文档
* [API 参考](/docs/API-Reference.md)

9
python/curricula/wall.json


{
"measure" : "reward",
"thresholds" : [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5],
"measure" : "progress",
"thresholds" : [0.1, 0.3, 0.5],
"min_wall_height" : [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5],
"max_wall_height" : [1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0]
"big_wall_min_height" : [0.0, 4.0, 6.0, 8.0],
"big_wall_max_height" : [4.0, 7.0, 8.0, 8.0],
"small_wall_height" : [1.5, 2.0, 2.5, 4.0]
}
}

26
python/learn.py


from unitytrainers.trainer_controller import TrainerController
print('''
,m' ,▓▓▓▀▓▓▄ ▓▓▓ ▓▓▌
' ▄▓▓▀ ▓▓▓ ▄▄ ▄▄ ,▄▄ ▄▄▄▄ ,▄▄ ▄▓▓▌▄ ▄▄▄ ,▄▄
^
^ `
'▀▓▓▓▄ ^▓▓▓ ▓▓▓ └▀▀▀▀ ▀▀ ^▀▀ `▀▀ `▀▀ '
,
`
¬`
''')
learn [options]
learn --help
Options:

--slow Whether to run the game at training speed [default: False].
--train Whether to train model, or only run inference [default: False].
--worker-id=<n> Number to add to communication port (5005). Used for multi-environment [default: 0].
--docker-target-name=<dt> Docker Volume to store curriculum, executable and model files [default: Empty].
--docker-target-name=<dt> Docker Volume to store curriculum, executable and model files [default: Empty].
--no-graphics Whether to run the Unity simulator in no-graphics mode [default: False].
'''
options = docopt(_USAGE)

curriculum_file = None
lesson = int(options['--lesson'])
fast_simulation = not bool(options['--slow'])
no_graphics = options['--no-graphics']
# Constants
# Assumption that this yaml is present in same dir as this file

tc = TrainerController(env_path, run_id, save_freq, curriculum_file, fast_simulation, load_model, train_model,
worker_id, keep_checkpoints, lesson, seed, docker_target_name, TRAINER_CONFIG_PATH)
worker_id, keep_checkpoints, lesson, seed, docker_target_name, TRAINER_CONFIG_PATH,
no_graphics)
tc.start_learning()

4
python/requirements.txt


tensorflow==1.4.0
tensorflow==1.7.1
Pillow>=4.2.1
matplotlib
numpy>=1.11.0

pyyaml
protobuf==3.5.2
grpcio==1.11.0

164
python/tests/test_bc.py


from unitytrainers.bc.models import BehavioralCloningModel
from unityagents import UnityEnvironment
from .mock_communicator import MockCommunicator
def test_cc_bc_model():
c_action_c_state_start = '''{
"AcademyName": "RealFakeAcademy",
"resetParameters": {},
"brainNames": ["RealFakeBrain"],
"externalBrainNames": ["RealFakeBrain"],
"logPath":"RealFakePath",
"apiNumber":"API-3",
"brainParameters": [{
"vectorObservationSize": 3,
"numStackedVectorObservations": 2,
"vectorActionSize": 2,
"memorySize": 0,
"cameraResolutions": [],
"vectorActionDescriptions": ["",""],
"vectorActionSpaceType": 1,
"vectorObservationSpaceType": 1
}]
}'''.encode()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_cc_bc_model(mock_communicator, mock_launcher):
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
# End of mock
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = c_action_c_state_start
env = UnityEnvironment(' ')
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=0)
env = UnityEnvironment(' ')
model = BehavioralCloningModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
model = BehavioralCloningModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.sample_action, model.policy]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
run_list = [model.sample_action, model.policy]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_dc_bc_model(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=0)
env = UnityEnvironment(' ')
model = BehavioralCloningModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
def test_dc_bc_model():
d_action_c_state_start = '''{
"AcademyName": "RealFakeAcademy",
"resetParameters": {},
"brainNames": ["RealFakeBrain"],
"externalBrainNames": ["RealFakeBrain"],
"logPath":"RealFakePath",
"apiNumber":"API-3",
"brainParameters": [{
"vectorObservationSize": 3,
"numStackedVectorObservations": 2,
"vectorActionSize": 2,
"memorySize": 0,
"cameraResolutions": [{"width":30,"height":40,"blackAndWhite":false}],
"vectorActionDescriptions": ["",""],
"vectorActionSpaceType": 0,
"vectorObservationSpaceType": 1
}]
}'''.encode()
run_list = [model.sample_action, model.policy]
feed_dict = {model.batch_size: 2,
model.dropout_rate: 1.0,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_visual_dc_bc_model(mock_communicator, mock_launcher):
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = d_action_c_state_start
env = UnityEnvironment(' ')
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=2)
env = UnityEnvironment(' ')
model = BehavioralCloningModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
model = BehavioralCloningModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.sample_action, model.policy]
feed_dict = {model.batch_size: 2,
model.dropout_rate: 1.0,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.visual_in[0]: np.ones([2, 40, 30, 3]),
model.visual_in[1]: np.ones([2, 40, 30, 3])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
run_list = [model.sample_action, model.policy]
feed_dict = {model.batch_size: 2,
model.dropout_rate: 1.0,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.visual_in[0]: np.ones([2, 40, 30, 3])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_visual_cc_bc_model(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=2)
env = UnityEnvironment(' ')
model = BehavioralCloningModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.sample_action, model.policy]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.visual_in[0]: np.ones([2, 40, 30, 3]),
model.visual_in[1]: np.ones([2, 40, 30, 3])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
if __name__ == '__main__':

344
python/tests/test_ppo.py


import tensorflow as tf
from unitytrainers.ppo.models import PPOModel
from unitytrainers.ppo.trainer import discount_rewards
from .mock_communicator import MockCommunicator
def test_ppo_model_continuous():
c_action_c_state_start = '''{
"AcademyName": "RealFakeAcademy",
"resetParameters": {},
"brainNames": ["RealFakeBrain"],
"externalBrainNames": ["RealFakeBrain"],
"logPath":"RealFakePath",
"apiNumber":"API-3",
"brainParameters": [{
"vectorObservationSize": 3,
"numStackedVectorObservations": 2,
"vectorActionSize": 2,
"memorySize": 0,
"cameraResolutions": [],
"vectorActionDescriptions": ["",""],
"vectorActionSpaceType": 1,
"vectorObservationSpaceType": 1
}]
}'''.encode()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_cc_vector(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=0)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.probs, model.value, model.entropy,
model.learning_rate]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_cc_visual(mock_communicator, mock_launcher):
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
# End of mock
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = c_action_c_state_start
env = UnityEnvironment(' ')
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=2)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
model = PPOModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.probs, model.value, model.entropy,
model.learning_rate]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
run_list = [model.output, model.probs, model.value, model.entropy,
model.learning_rate]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.visual_in[0]: np.ones([2, 40, 30, 3]),
model.visual_in[1]: np.ones([2, 40, 30, 3])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
def test_ppo_model_discrete():
d_action_c_state_start = '''{
"AcademyName": "RealFakeAcademy",
"resetParameters": {},
"brainNames": ["RealFakeBrain"],
"externalBrainNames": ["RealFakeBrain"],
"logPath":"RealFakePath",
"apiNumber":"API-3",
"brainParameters": [{
"vectorObservationSize": 3,
"numStackedVectorObservations": 2,
"vectorActionSize": 2,
"memorySize": 0,
"cameraResolutions": [{"width":30,"height":40,"blackAndWhite":false}],
"vectorActionDescriptions": ["",""],
"vectorActionSpaceType": 0,
"vectorObservationSpaceType": 1
}]
}'''.encode()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_dc_visual(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=2)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.visual_in[0]: np.ones([2, 40, 30, 3]),
model.visual_in[1]: np.ones([2, 40, 30, 3])
}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_dc_vector(mock_communicator, mock_launcher):
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
# End of mock
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = d_action_c_state_start
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=0)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"])
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.visual_in[0]: np.ones([2, 40, 30, 3])
}
sess.run(run_list, feed_dict=feed_dict)
env.close()
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_dc_vector_rnn(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=0)
env = UnityEnvironment(' ')
memory_size = 128
model = PPOModel(env.brains["RealFakeBrain"], use_recurrent=True, m_size=memory_size)
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate, model.memory_out]
feed_dict = {model.batch_size: 1,
model.sequence_length: 2,
model.prev_action: [0, 0],
model.memory_in: np.zeros((1, memory_size)),
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_cc_vector_rnn(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=0)
env = UnityEnvironment(' ')
memory_size = 128
model = PPOModel(env.brains["RealFakeBrain"], use_recurrent=True, m_size=memory_size)
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate, model.memory_out]
feed_dict = {model.batch_size: 1,
model.sequence_length: 2,
model.memory_in: np.zeros((1, memory_size)),
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]])}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_dc_vector_curio(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=0)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"], use_curiosity=True)
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate, model.intrinsic_reward]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.next_vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.action_holder: [0, 0]}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_cc_vector_curio(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=0)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"], use_curiosity=True)
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate, model.intrinsic_reward]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.next_vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.output: [[0.0, 0.0], [0.0, 0.0]]}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_dc_visual_curio(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=2)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"], use_curiosity=True)
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate, model.intrinsic_reward]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.next_vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.action_holder: [0, 0],
model.visual_in[0]: np.ones([2, 40, 30, 3]),
model.visual_in[1]: np.ones([2, 40, 30, 3]),
model.next_visual_in[0]: np.ones([2, 40, 30, 3]),
model.next_visual_in[1]: np.ones([2, 40, 30, 3])
}
sess.run(run_list, feed_dict=feed_dict)
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_ppo_model_cc_visual_curio(mock_communicator, mock_launcher):
tf.reset_default_graph()
with tf.Session() as sess:
with tf.variable_scope("FakeGraphScope"):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=2)
env = UnityEnvironment(' ')
model = PPOModel(env.brains["RealFakeBrain"], use_curiosity=True)
init = tf.global_variables_initializer()
sess.run(init)
run_list = [model.output, model.all_probs, model.value, model.entropy,
model.learning_rate, model.intrinsic_reward]
feed_dict = {model.batch_size: 2,
model.sequence_length: 1,
model.vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.next_vector_in: np.array([[1, 2, 3, 1, 2, 3],
[3, 4, 5, 3, 4, 5]]),
model.output: [[0.0, 0.0], [0.0, 0.0]],
model.visual_in[0]: np.ones([2, 40, 30, 3]),
model.visual_in[1]: np.ones([2, 40, 30, 3]),
model.next_visual_in[0]: np.ones([2, 40, 30, 3]),
model.next_visual_in[1]: np.ones([2, 40, 30, 3])
}
sess.run(run_list, feed_dict=feed_dict)
env.close()
def test_rl_functions():
rewards = np.array([0.0, 0.0, 0.0, 1.0])
gamma = 0.9
returns = discount_rewards(rewards, gamma, 0.0)
np.testing.assert_array_almost_equal(returns, np.array([0.729, 0.81, 0.9, 1.0]))
if __name__ == '__main__':

218
python/tests/test_unityagents.py


from unityagents import UnityEnvironment, UnityEnvironmentException, UnityActionException, \
BrainInfo, Curriculum
from .mock_communicator import MockCommunicator
def append_length(partial_string):
return struct.pack("I", len(partial_string.encode())) + partial_string.encode()
dummy_start = '''{
"AcademyName": "RealFakeAcademy",
"resetParameters": {},
"brainNames": ["RealFakeBrain"],
"externalBrainNames": ["RealFakeBrain"],
"logPath":"RealFakePath",
"apiNumber":"API-3",
"brainParameters": [{
"vectorObservationSize": 3,
"numStackedVectorObservations": 2,
"vectorActionSize": 2,
"memorySize": 0,
"cameraResolutions": [],
"vectorActionDescriptions": ["",""],
"vectorActionSpaceType": 1,
"vectorObservationSpaceType": 1
}]
}'''.encode()
dummy_reset = [
'CONFIG_REQUEST'.encode(),
append_length(
'''
{
"brain_name": "RealFakeBrain",
"agents": [1,2],
"vectorObservations": [1,2,3,4,5,6,1,2,3,4,5,6],
"rewards": [1,2],
"previousVectorActions": [1,2,3,4],
"previousTextActions":["",""],
"memories": [],
"dones": [false, false],
"maxes": [false, false],
"textObservations" :[" "," "]
}'''),
append_length('END_OF_MESSAGE:False')]
dummy_step = ['actions'.encode(),
append_length('''
{
"brain_name": "RealFakeBrain",
"agents": [1,2,3],
"vectorObservations": [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9],
"rewards": [1,2,3],
"previousVectorActions": [1,2,3,4,5,6],
"previousTextActions":["","",""],
"memories": [],
"dones": [false, false, false],
"maxes": [false, false, false],
"textObservations" :[" "," ", " "]
}'''),
append_length('END_OF_MESSAGE:False'),
'actions'.encode(),
append_length('''
{
"brain_name": "RealFakeBrain",
"agents": [1,2,3],
"vectorObservations": [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9],
"rewards": [1,2,3],
"previousVectorActions": [1,2,3,4,5,6],
"previousTextActions":["","",""],
"memories": [],
"dones": [false, false, true],
"maxes": [false, false, false],
"textObservations" :[" "," ", " "]
}'''),
append_length('END_OF_MESSAGE:True')]
dummy_curriculum = json.loads('''{
"measure" : "reward",

UnityEnvironment(' ')
def test_initialization():
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = dummy_start
env = UnityEnvironment(' ')
with pytest.raises(UnityActionException):
env.step([0])
assert env.brain_names[0] == 'RealFakeBrain'
env.close()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_initialization(mock_communicator, mock_launcher):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=0)
env = UnityEnvironment(' ')
with pytest.raises(UnityActionException):
env.step([0])
assert env.brain_names[0] == 'RealFakeBrain'
env.close()
def test_reset():
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = dummy_start
env = UnityEnvironment(' ')
brain = env.brains['RealFakeBrain']
mock_socket.recv.side_effect = dummy_reset
brain_info = env.reset()
env.close()
assert not env.global_done
assert isinstance(brain_info, dict)
assert isinstance(brain_info['RealFakeBrain'], BrainInfo)
assert isinstance(brain_info['RealFakeBrain'].visual_observations, list)
assert isinstance(brain_info['RealFakeBrain'].vector_observations, np.ndarray)
assert len(brain_info['RealFakeBrain'].visual_observations) == brain.number_visual_observations
assert brain_info['RealFakeBrain'].vector_observations.shape[0] == \
len(brain_info['RealFakeBrain'].agents)
assert brain_info['RealFakeBrain'].vector_observations.shape[1] == \
brain.vector_observation_space_size * brain.num_stacked_vector_observations
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_reset(mock_communicator, mock_launcher):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=0)
env = UnityEnvironment(' ')
brain = env.brains['RealFakeBrain']
brain_info = env.reset()
env.close()
assert not env.global_done
assert isinstance(brain_info, dict)
assert isinstance(brain_info['RealFakeBrain'], BrainInfo)
assert isinstance(brain_info['RealFakeBrain'].visual_observations, list)
assert isinstance(brain_info['RealFakeBrain'].vector_observations, np.ndarray)
assert len(brain_info['RealFakeBrain'].visual_observations) == brain.number_visual_observations
assert brain_info['RealFakeBrain'].vector_observations.shape[0] == \
len(brain_info['RealFakeBrain'].agents)
assert brain_info['RealFakeBrain'].vector_observations.shape[1] == \
brain.vector_observation_space_size * brain.num_stacked_vector_observations
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_step(mock_communicator, mock_launcher):
mock_communicator.return_value = MockCommunicator(
discrete_action=False, visual_inputs=0)
env = UnityEnvironment(' ')
brain = env.brains['RealFakeBrain']
brain_info = env.reset()
brain_info = env.step([0] * brain.vector_action_space_size * len(brain_info['RealFakeBrain'].agents))
with pytest.raises(UnityActionException):
env.step([0])
brain_info = env.step([-1] * brain.vector_action_space_size * len(brain_info['RealFakeBrain'].agents))
with pytest.raises(UnityActionException):
env.step([0] * brain.vector_action_space_size * len(brain_info['RealFakeBrain'].agents))
env.close()
assert env.global_done
assert isinstance(brain_info, dict)
assert isinstance(brain_info['RealFakeBrain'], BrainInfo)
assert isinstance(brain_info['RealFakeBrain'].visual_observations, list)
assert isinstance(brain_info['RealFakeBrain'].vector_observations, np.ndarray)
assert len(brain_info['RealFakeBrain'].visual_observations) == brain.number_visual_observations
assert brain_info['RealFakeBrain'].vector_observations.shape[0] == \
len(brain_info['RealFakeBrain'].agents)
assert brain_info['RealFakeBrain'].vector_observations.shape[1] == \
brain.vector_observation_space_size * brain.num_stacked_vector_observations
def test_step():
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = dummy_start
env = UnityEnvironment(' ')
brain = env.brains['RealFakeBrain']
mock_socket.recv.side_effect = dummy_reset
brain_info = env.reset()
mock_socket.recv.side_effect = dummy_step
brain_info = env.step([0] * brain.vector_action_space_size * len(brain_info['RealFakeBrain'].agents))
with pytest.raises(UnityActionException):
env.step([0])
brain_info = env.step([0] * brain.vector_action_space_size * len(brain_info['RealFakeBrain'].agents))
with pytest.raises(UnityActionException):
env.step([0] * brain.vector_action_space_size * len(brain_info['RealFakeBrain'].agents))
env.close()
assert env.global_done
assert isinstance(brain_info, dict)
assert isinstance(brain_info['RealFakeBrain'], BrainInfo)
assert isinstance(brain_info['RealFakeBrain'].visual_observations, list)
assert isinstance(brain_info['RealFakeBrain'].vector_observations, np.ndarray)
assert len(brain_info['RealFakeBrain'].visual_observations) == brain.number_visual_observations
assert brain_info['RealFakeBrain'].vector_observations.shape[0] == \
len(brain_info['RealFakeBrain'].agents)
assert brain_info['RealFakeBrain'].vector_observations.shape[1] == \
brain.vector_observation_space_size * brain.num_stacked_vector_observations
assert not brain_info['RealFakeBrain'].local_done[0]
assert brain_info['RealFakeBrain'].local_done[2]
print("\n\n\n\n\n\n\n" + str(brain_info['RealFakeBrain'].local_done))
assert not brain_info['RealFakeBrain'].local_done[0]
assert brain_info['RealFakeBrain'].local_done[2]
def test_close():
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = dummy_start
env = UnityEnvironment(' ')
assert env._loaded
env.close()
assert not env._loaded
mock_socket.close.assert_called_once()
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_close(mock_communicator, mock_launcher):
comm = MockCommunicator(
discrete_action=False, visual_inputs=0)
mock_communicator.return_value = comm
env = UnityEnvironment(' ')
assert env._loaded
env.close()
assert not env._loaded
assert comm.has_been_closed
def test_curriculum():

113
python/tests/test_unitytrainers.py


from unitytrainers.ppo.trainer import PPOTrainer
from unitytrainers.bc.trainer import BehavioralCloningTrainer
from unityagents import UnityEnvironmentException
from .mock_communicator import MockCommunicator
dummy_start = '''{
"AcademyName": "RealFakeAcademy",

summary_freq: 1000
use_recurrent: false
memory_size: 8
use_curiosity: false
curiosity_strength: 0.0
curiosity_enc_size: 1
''')
dummy_bc_config = yaml.load('''

summary_freq: 1000
use_recurrent: false
memory_size: 8
use_curiosity: false
curiosity_strength: 0.0
curiosity_enc_size: 1
''')
dummy_bad_config = yaml.load('''

''')
def test_initialization():
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = dummy_start
tc = TrainerController(' ', ' ', 1, None, True, True, False, 1,
1, 1, 1, '', "tests/test_unitytrainers.py")
assert(tc.env.brain_names[0] == 'RealFakeBrain')
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_initialization(mock_communicator, mock_launcher):
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=1)
tc = TrainerController(' ', ' ', 1, None, True, True, False, 1,
1, 1, 1, '', "tests/test_unitytrainers.py", False)
assert(tc.env.brain_names[0] == 'RealFakeBrain')
def test_load_config():
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_load_config(mock_communicator, mock_launcher):
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
mock_load.return_value = dummy_config
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = dummy_start
mock_load.return_value = dummy_config
tc = TrainerController(' ', ' ', 1, None, True, True, False, 1,
1, 1, 1, '','')
config = tc._load_config()
assert(len(config) == 1)
assert(config['default']['trainer'] == "ppo")
mock_load.return_value = dummy_config
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=1)
mock_load.return_value = dummy_config
tc = TrainerController(' ', ' ', 1, None, True, True, False, 1,
1, 1, 1, '','', False)
config = tc._load_config()
assert(len(config) == 1)
assert(config['default']['trainer'] == "ppo")
def test_initialize_trainers():
@mock.patch('unityagents.UnityEnvironment.executable_launcher')
@mock.patch('unityagents.UnityEnvironment.get_communicator')
def test_initialize_trainers(mock_communicator, mock_launcher):
with mock.patch('subprocess.Popen'):
with mock.patch('socket.socket') as mock_socket:
with mock.patch('glob.glob') as mock_glob:
mock_glob.return_value = ['FakeLaunchPath']
mock_socket.return_value.accept.return_value = (mock_socket, 0)
mock_socket.recv.return_value.decode.return_value = dummy_start
tc = TrainerController(' ', ' ', 1, None, True, True, False, 1,
1, 1, 1, '', "tests/test_unitytrainers.py")
mock_communicator.return_value = MockCommunicator(
discrete_action=True, visual_inputs=1)
tc = TrainerController(' ', ' ', 1, None, True, True, False, 1,
1, 1, 1, '', "tests/test_unitytrainers.py", False)
# Test for PPO trainer
mock_load.return_value = dummy_config
config = tc._load_config()
tf.reset_default_graph()
with tf.Session() as sess:
tc._initialize_trainers(config, sess)
assert(len(tc.trainers) == 1)
assert(isinstance(tc.trainers['RealFakeBrain'], PPOTrainer))
# Test for PPO trainer
mock_load.return_value = dummy_config
config = tc._load_config()
tf.reset_default_graph()
with tf.Session() as sess:
tc._initialize_trainers(config, sess)
assert(len(tc.trainers) == 1)
assert(isinstance(tc.trainers['RealFakeBrain'], PPOTrainer))
# Test for Behavior Cloning Trainer
mock_load.return_value = dummy_bc_config
config = tc._load_config()
tf.reset_default_graph()
with tf.Session() as sess:
tc._initialize_trainers(config, sess)
assert(isinstance(tc.trainers['RealFakeBrain'], BehavioralCloningTrainer))
# Test for Behavior Cloning Trainer
mock_load.return_value = dummy_bc_config
config = tc._load_config()
tf.reset_default_graph()
with tf.Session() as sess:
tc._initialize_trainers(config, sess)
assert(isinstance(tc.trainers['RealFakeBrain'], BehavioralCloningTrainer))
# Test for proper exception when trainer name is incorrect
mock_load.return_value = dummy_bad_config
config = tc._load_config()
tf.reset_default_graph()
with tf.Session() as sess:
with pytest.raises(UnityEnvironmentException):
tc._initialize_trainers(config, sess)
# Test for proper exception when trainer name is incorrect
mock_load.return_value = dummy_bad_config
config = tc._load_config()
tf.reset_default_graph()
with tf.Session() as sess:
with pytest.raises(UnityEnvironmentException):
tc._initialize_trainers(config, sess)
def assert_array(a, b):

)
b[fake_agent_id]['action'].append([100 * fake_agent_id + 10 * step + 4,
100 * fake_agent_id + 10 * step + 5])
a = b[1]['vector_observation'].get_batch(batch_size=2, training_length=None, sequential=True)
a = b[1]['vector_observation'].get_batch(batch_size=2, training_length=1, sequential=True)
assert_array(a, np.array([[171, 172, 173], [181, 182, 183]]))
a = b[2]['vector_observation'].get_batch(batch_size=2, training_length=3, sequential=True)
assert_array(a, np.array([

76
python/trainer_config.yaml


sequence_length: 64
summary_freq: 1000
use_recurrent: false
use_curiosity: false
curiosity_strength: 0.01
curiosity_enc_size: 128
BananaBrain:
normalize: false

BouncerBrain:
normalize: true
max_steps: 5.0e5
num_layers: 2
hidden_units: 64
PushBlockBrain:
max_steps: 5.0e4

num_layers: 2
normalize: false
PyramidBrain:
use_curiosity: true
summary_freq: 2000
curiosity_strength: 0.01
curiosity_enc_size: 256
time_horizon: 128
batch_size: 128
buffer_size: 2048
hidden_units: 512
num_layers: 2
beta: 1.0e-2
max_steps: 2.0e5
num_epoch: 3
VisualPyramidBrain:
use_curiosity: true
time_horizon: 128
batch_size: 32
buffer_size: 1024
hidden_units: 256
num_layers: 2
beta: 1.0e-2
max_steps: 5.0e5
num_epoch: 3
Ball3DBrain:
normalize: true
batch_size: 1200

gamma: 0.995
beta: 0.001
BouncerBrain:
Ball3DHardBrain:
max_steps: 5.0e5
num_layers: 2
hidden_units: 56
batch_size: 1200
buffer_size: 12000
summary_freq: 1000
time_horizon: 1000
gamma: 0.995
beta: 0.001
TennisBrain:
normalize: true
CrawlerBrain:
normalize: true

gamma: 0.995
max_steps: 1e6
summary_freq: 3000
num_layers: 3
hidden_units: 512
WalkerBrain:
normalize: true
num_epoch: 3
time_horizon: 1000
batch_size: 2048
buffer_size: 20480
gamma: 0.995
max_steps: 2e6
summary_freq: 3000
num_layers: 3
hidden_units: 512
ReacherBrain:
normalize: true

batches_per_epoch: 5
num_layers: 4
hidden_units: 64
use_recurrent: false
StudentRecurrentBrain:
trainer: imitation
max_steps: 10000
summary_freq: 1000
brain_to_imitate: TeacherBrain
batch_size: 16
batches_per_epoch: 5
num_layers: 4
hidden_units: 64
use_recurrent: true
sequence_length: 32
buffer_size: 128

549
python/unityagents/environment.py


import atexit
import io
import json
import io
import socket
import struct
from PIL import Image
from communicator_objects import UnityRLInput, UnityRLOutput, AgentActionProto,\
EnvironmentParametersProto, UnityRLInitializationInput, UnityRLInitializationOutput,\
UnityInput, UnityOutput
from .rpc_communicator import RpcCommunicator
from .socket_communicator import SocketCommunicator
from PIL import Image
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("unityagents")

def __init__(self, file_name, worker_id=0,
def __init__(self, file_name=None, worker_id=0,
seed=0, docker_training=False):
seed=0, docker_training=False, no_graphics=False):
"""
Starts a new unity environment and establishes a connection with the environment.
Notice: Currently communication between Unity and Python takes place over an open socket without authentication.

:int base_port: Baseline port number to connect to Unity environment over. worker_id increments over this.
:int worker_id: Number to add to communication port (5005) [0]. Used for asynchronous agent scenarios.
:param docker_training: Informs this class whether the process is being run within a container.
:param no_graphics: Whether to run the Unity simulator in no-graphics mode
atexit.register(self.close)
atexit.register(self._close)
self._version_ = "API-3"
self._loaded = False
self._open_socket = False
self._version_ = "API-4"
self._loaded = False # If true, this means the environment was successfully loaded
self.proc1 = None # The process that is started. If None, no process was started
self.communicator = self.get_communicator(worker_id, base_port)
# If the environment name is 'editor', a new environment will not be launched
# and the communicator will directly try to connect to an existing unity environment.
if file_name is not None:
self.executable_launcher(file_name, docker_training, no_graphics)
else:
logger.info("Start training by pressing the Play button in the Unity Editor.")
self._loaded = True
rl_init_parameters_in = UnityRLInitializationInput(
seed=seed
)
# Establish communication socket
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.bind(("localhost", self.port))
self._open_socket = True
except socket.error:
self._open_socket = True
self.close()
raise socket.error("Couldn't launch new environment because worker number {} is still in use. "
"You may need to manually close a previously opened environment "
"or use a different worker number.".format(str(worker_id)))
aca_params = self.send_academy_parameters(rl_init_parameters_in)
except UnityTimeOutException:
self._close()
raise
# TODO : think of a better way to expose the academyParameters
self._unity_version = aca_params.version
if self._unity_version != self._version_:
raise UnityEnvironmentException(
"The API number is not compatible between Unity and python. Python API : {0}, Unity API : "
"{1}.\nPlease go to https://github.com/Unity-Technologies/ml-agents to download the latest version "
"of ML-Agents.".format(self._version_, self._unity_version))
self._n_agents = {}
self._global_done = None
self._academy_name = aca_params.name
self._log_path = aca_params.log_path
self._brains = {}
self._brain_names = []
self._external_brain_names = []
for brain_param in aca_params.brain_parameters:
self._brain_names += [brain_param.brain_name]
resolution = [{
"height": x.height,
"width": x.width,
"blackAndWhite": x.gray_scale
} for x in brain_param.camera_resolutions]
self._brains[brain_param.brain_name] = \
BrainParameters(brain_param.brain_name, {
"vectorObservationSize": brain_param.vector_observation_size,
"numStackedVectorObservations": brain_param.num_stacked_vector_observations,
"cameraResolutions": resolution,
"vectorActionSize": brain_param.vector_action_size,
"vectorActionDescriptions": brain_param.vector_action_descriptions,
"vectorActionSpaceType": brain_param.vector_action_space_type,
"vectorObservationSpaceType": brain_param.vector_observation_space_type
})
if brain_param.brain_type == 2:
self._external_brain_names += [brain_param.brain_name]
self._num_brains = len(self._brain_names)
self._num_external_brains = len(self._external_brain_names)
self._resetParameters = dict(aca_params.environment_parameters.float_parameters) # TODO
self._curriculum = Curriculum(curriculum, self._resetParameters)
logger.info("\n'{0}' started successfully!\n{1}".format(self._academy_name, str(self)))
if self._num_external_brains == 0:
logger.warning(" No External Brains found in the Unity Environment. "
"You will not be able to pass actions to your agent(s).")
@property
def curriculum(self):
return self._curriculum
@property
def logfile_path(self):
return self._log_path
@property
def brains(self):
return self._brains
@property
def global_done(self):
return self._global_done
@property
def academy_name(self):
return self._academy_name
@property
def number_brains(self):
return self._num_brains
@property
def number_external_brains(self):
return self._num_external_brains
@property
def brain_names(self):
return self._brain_names
@property
def external_brain_names(self):
return self._external_brain_names
def executable_launcher(self, file_name, docker_training, no_graphics):
cwd = os.getcwd()
file_name = (file_name.strip()
.replace('.app', '').replace('.exe', '').replace('.x86_64', '').replace('.x86', ''))

if len(candidates) > 0:
launch_string = candidates[0]
if launch_string is None:
self.close()
self._close()
raise UnityEnvironmentException("Couldn't launch the {0} environment. "
"Provided filename does not match any environments."
.format(true_filename))

if docker_training == False:
proc1 = subprocess.Popen(
[launch_string,
'--port', str(self.port),
'--seed', str(seed)])
if not docker_training:
if no_graphics:
self.proc1 = subprocess.Popen(
[launch_string,'-nographics', '-batchmode',
'--port', str(self.port)])
else:
self.proc1 = subprocess.Popen(
[launch_string, '--port', str(self.port)])
else:
"""
Comments for future maintenance:

"""
docker_ls = ("exec xvfb-run --auto-servernum"
" --server-args='-screen 0 640x480x24'"
" {0} --port {1} --seed {2}").format(launch_string,
str(self.port),
str(seed))
proc1 = subprocess.Popen(docker_ls,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
self._socket.settimeout(30)
try:
try:
self._socket.listen(1)
self._conn, _ = self._socket.accept()
self._conn.settimeout(30)
p = self._conn.recv(self._buffer_size).decode('utf-8')
p = json.loads(p)
except socket.timeout as e:
raise UnityTimeOutException(
"The Unity environment took too long to respond. Make sure {} does not need user interaction to "
"launch and that the Academy and the external Brain(s) are attached to objects in the Scene."
.format(str(file_name)))
" {0} --port {1}").format(launch_string, str(self.port))
self.proc1 = subprocess.Popen(docker_ls,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
if "apiNumber" not in p:
self._unity_version = "API-1"
else:
self._unity_version = p["apiNumber"]
if self._unity_version != self._version_:
raise UnityEnvironmentException(
"The API number is not compatible between Unity and python. Python API : {0}, Unity API : "
"{1}.\nPlease go to https://github.com/Unity-Technologies/ml-agents to download the latest version "
"of ML-Agents.".format(self._version_, self._unity_version))
self._data = {}
self._global_done = None
self._academy_name = p["AcademyName"]
self._log_path = p["logPath"]
# Need to instantiate new AllBrainInfo
self._brains = {}
self._brain_names = p["brainNames"]
self._external_brain_names = p["externalBrainNames"]
self._external_brain_names = [] if self._external_brain_names is None else self._external_brain_names
self._num_brains = len(self._brain_names)
self._num_external_brains = len(self._external_brain_names)
self._resetParameters = p["resetParameters"]
self._curriculum = Curriculum(curriculum, self._resetParameters)
for i in range(self._num_brains):
self._brains[self._brain_names[i]] = BrainParameters(self._brain_names[i], p["brainParameters"][i])
self._loaded = True
logger.info("\n'{0}' started successfully!\n{1}".format(self._academy_name, str(self)))
if self._num_external_brains == 0:
logger.warning(" No External Brains found in the Unity Environment. "
"You will not be able to pass actions to your agent(s).")
except UnityEnvironmentException:
proc1.kill()
self.close()
raise
@property
def curriculum(self):
return self._curriculum
@property
def logfile_path(self):
return self._log_path
@property
def brains(self):
return self._brains
@property
def global_done(self):
return self._global_done
@property
def academy_name(self):
return self._academy_name
@property
def number_brains(self):
return self._num_brains
@property
def number_external_brains(self):
return self._num_external_brains
@property
def brain_names(self):
return self._brain_names
@property
def external_brain_names(self):
return self._external_brain_names
@staticmethod
def _process_pixels(image_bytes=None, bw=False):
"""
Converts byte array observation image into numpy array, re-sizes it, and optionally converts it to grey scale
:param image_bytes: input byte array corresponding to image
:return: processed numpy array of observation from environment
"""
s = bytearray(image_bytes)
image = Image.open(io.BytesIO(s))
s = np.array(image) / 255.0
if bw:
s = np.mean(s, axis=2)
s = np.reshape(s, [s.shape[0], s.shape[1], 1])
return s
def get_communicator(self, worker_id, base_port):
return RpcCommunicator(worker_id, base_port)
# return SocketCommunicator(worker_id, base_port)
def __str__(self):
_new_reset_param = self._curriculum.get_config()

for k in self._resetParameters])) + '\n' + \
'\n'.join([str(self._brains[b]) for b in self._brains])
def _recv_bytes(self):
try:
s = self._conn.recv(self._buffer_size)
message_length = struct.unpack("I", bytearray(s[:4]))[0]
s = s[4:]
while len(s) != message_length:
s += self._conn.recv(self._buffer_size)
except socket.timeout as e:
raise UnityTimeOutException("The environment took too long to respond.", self._log_path)
return s
def _get_state_image(self, bw):
"""
Receives observation from socket, and confirms.
:param bw:
:return:
"""
s = self._recv_bytes()
s = self._process_pixels(image_bytes=s, bw=bw)
self._conn.send(b"RECEIVED")
return s
def _get_state_dict(self):
"""
Receives dictionary of state information from socket, and confirms.
:return:
"""
state = self._recv_bytes().decode('utf-8')
if state[:14] == "END_OF_MESSAGE":
return {}, state[15:] == 'True'
self._conn.send(b"RECEIVED")
state_dict = json.loads(state)
return state_dict, None
def reset(self, train_mode=True, config=None, lesson=None) -> AllBrainInfo:
"""
Sends a signal to reset the unity environment.

raise UnityEnvironmentException("The parameter '{0}' is not a valid parameter.".format(k))
if self._loaded:
self._conn.send(b"RESET")
try:
self._conn.recv(self._buffer_size)
except socket.timeout as e:
raise UnityTimeOutException("The environment took too long to respond.", self._log_path)
self._conn.send(json.dumps({"train_model": train_mode, "parameters": config}).encode('utf-8'))
return self._get_state()
outputs = self.communicator.exchange(
self._generate_reset_input(train_mode, config)
)
if outputs is None:
raise KeyboardInterrupt
rl_output = outputs.rl_output
s = self._get_state(rl_output)
self._global_done = s[1]
for _b in self._external_brain_names:
self._n_agents[_b] = len(s[0][_b].agents)
return s[0]
def _get_state(self) -> AllBrainInfo:
"""
Collects experience information from all external brains in environment at current step.
:return: a dictionary of BrainInfo objects.
"""
self._data = {}
while True:
state_dict, end_of_message = self._get_state_dict()
if end_of_message is not None:
self._global_done = end_of_message
for _b in self._brain_names:
if _b not in self._data:
self._data[_b] = BrainInfo([], np.array([]), [], np.array([]),
[], [], [], np.array([]), [], max_reached=[])
return self._data
b = state_dict["brain_name"]
n_agent = len(state_dict["agents"])
try:
if self._brains[b].vector_observation_space_type == "continuous":
vector_obs = np.array(state_dict["vectorObservations"]).reshape(
(n_agent, self._brains[b].vector_observation_space_size
* self._brains[b].num_stacked_vector_observations))
else:
vector_obs = np.array(state_dict["vectorObservations"]).reshape(
(n_agent, self._brains[b].num_stacked_vector_observations))
except UnityActionException:
raise UnityActionException("Brain {0} has an invalid vector observation. "
"Expecting {1} {2} vector observations but received {3}."
.format(b, n_agent if self._brains[b].vector_observation_space_type == "discrete"
else str(self._brains[b].vector_observation_space_size * n_agent
* self._brains[b].num_stacked_vector_observations),
self._brains[b].vector_observation_space_type,
len(state_dict["vectorObservations"])))
memories = np.array(state_dict["memories"]).reshape((n_agent, -1))
text_obs = state_dict["textObservations"]
rewards = state_dict["rewards"]
dones = state_dict["dones"]
agents = state_dict["agents"]
maxes = state_dict["maxes"]
if n_agent > 0:
vector_actions = np.array(state_dict["previousVectorActions"]).reshape((n_agent, -1))
text_actions = state_dict["previousTextActions"]
else:
vector_actions = np.array([])
text_actions = []
observations = []
for o in range(self._brains[b].number_visual_observations):
obs_n = []
for a in range(n_agent):
obs_n.append(self._get_state_image(self._brains[b].camera_resolutions[o]['blackAndWhite']))
observations.append(np.array(obs_n))
self._data[b] = BrainInfo(observations, vector_obs, text_obs, memories, rewards,
agents, dones, vector_actions, text_actions, max_reached=maxes)
def _send_action(self, vector_action ,memory, text_action):
"""
Send dictionary of actions, memories, and value estimates over socket.
:param vector_action: a dictionary of lists of vector actions.
:param memory: a dictionary of lists of of memories.
:param text_action: a dictionary of lists of text actions.
"""
try:
self._conn.recv(self._buffer_size)
except socket.timeout as e:
raise UnityTimeOutException("The environment took too long to respond.", self._log_path)
action_message = {"vector_action": vector_action, "memory": memory, "text_action": text_action}
self._conn.send(self._append_length(json.dumps(action_message).encode('utf-8')))
@staticmethod
def _append_length(message):
return struct.pack("I", len(message)) + message
@staticmethod
def _flatten(arr):
"""
Converts dictionary of arrays to list for transmission over socket.
:param arr: numpy vector.
:return: flattened list.
"""
if isinstance(arr, (int, np.int_, float, np.float_)):
arr = [float(arr)]
if isinstance(arr, np.ndarray):
arr = arr.tolist()
if len(arr) == 0:
return arr
if isinstance(arr[0], np.ndarray):
arr = [item for sublist in arr for item in sublist.tolist()]
if isinstance(arr[0], list):
arr = [item for sublist in arr for item in sublist]
arr = [float(x) for x in arr]
return arr
def step(self, vector_action=None, memory=None, text_action=None) -> AllBrainInfo:
"""
Provides the environment with an action, moves the environment dynamics forward accordingly, and returns

"in the environment".format(brain_name))
for b in self._external_brain_names:
n_agent = len(self._data[b].agents)
n_agent = self._n_agents[b]
if b not in vector_action:
# raise UnityActionException("You need to input an action for the brain {0}".format(b))
if self._brains[b].vector_action_space_type == "discrete":

text_action[b] = [""] * n_agent
else:
if text_action[b] is None:
text_action[b] = []
text_action[b] = [""] * n_agent
if isinstance(text_action[b], str):
text_action[b] = [text_action[b]] * n_agent
if not ((len(text_action[b]) == n_agent) or len(text_action[b]) == 0):

self._brains[b].vector_action_space_type,
str(vector_action[b])))
self._conn.send(b"STEP")
self._send_action(vector_action, memory, text_action)
return self._get_state()
outputs = self.communicator.exchange(
self._generate_step_input(vector_action, memory, text_action)
)
if outputs is None:
raise KeyboardInterrupt
rl_output = outputs.rl_output
s = self._get_state(rl_output)
self._global_done = s[1]
for _b in self._external_brain_names:
self._n_agents[_b] = len(s[0][_b].agents)
return s[0]
elif not self._loaded:
raise UnityEnvironmentException("No Unity environment is loaded.")
elif self._global_done:

"""
Sends a shutdown signal to the unity environment, and closes the socket connection.
"""
if self._loaded & self._open_socket:
self._conn.send(b"EXIT")
self._conn.close()
if self._open_socket:
self._socket.close()
self._loaded = False
if self._loaded:
self._close()
def _close(self):
self._loaded = False
self.communicator.close()
if self.proc1 is not None:
self.proc1.kill()
@staticmethod
def _flatten(arr):
"""
Converts arrays to list.
:param arr: numpy vector.
:return: flattened list.
"""
if isinstance(arr, (int, np.int_, float, np.float_)):
arr = [float(arr)]
if isinstance(arr, np.ndarray):
arr = arr.tolist()
if len(arr) == 0:
return arr
if isinstance(arr[0], np.ndarray):
arr = [item for sublist in arr for item in sublist.tolist()]
if isinstance(arr[0], list):
arr = [item for sublist in arr for item in sublist]
arr = [float(x) for x in arr]
return arr
@staticmethod
def _process_pixels(image_bytes, gray_scale):
"""
Converts byte array observation image into numpy array, re-sizes it, and optionally converts it to grey scale
:param image_bytes: input byte array corresponding to image
:return: processed numpy array of observation from environment
"""
s = bytearray(image_bytes)
image = Image.open(io.BytesIO(s))
s = np.array(image) / 255.0
if gray_scale:
s = np.mean(s, axis=2)
s = np.reshape(s, [s.shape[0], s.shape[1], 1])
return s
def _get_state(self, output: UnityRLOutput) -> (AllBrainInfo, bool):
"""
Collects experience information from all external brains in environment at current step.
:return: a dictionary of BrainInfo objects.
"""
_data = {}
global_done = output.global_done
for b in output.agentInfos:
agent_info_list = output.agentInfos[b].value
vis_obs = []
for i in range(self.brains[b].number_visual_observations):
obs = [self._process_pixels(x.visual_observations[i],
self.brains[b].camera_resolutions[i]['blackAndWhite'])
for x in agent_info_list]
vis_obs += [np.array(obs)]
if len(agent_info_list) == 0:
memory_size = 0
else:
memory_size = max([len(x.memories) for x in agent_info_list])
if memory_size == 0:
memory = np.zeros((0, 0))
else:
[x.memories.extend([0] * (memory_size - len(x.memories))) for x in agent_info_list]
memory = np.array([x.memories for x in agent_info_list])
_data[b] = BrainInfo(
visual_observation=vis_obs,
vector_observation=np.array([x.stacked_vector_observation for x in agent_info_list]),
text_observations=[x.text_observation for x in agent_info_list],
memory=memory,
reward=[x.reward for x in agent_info_list],
agents=[x.id for x in agent_info_list],
local_done=[x.done for x in agent_info_list],
vector_action=np.array([x.stored_vector_actions for x in agent_info_list]),
text_action=[x.stored_text_actions for x in agent_info_list],
max_reached=[x.max_step_reached for x in agent_info_list]
)
return _data, global_done
def _generate_step_input(self, vector_action, memory, text_action) -> UnityRLInput:
rl_in = UnityRLInput()
for b in vector_action:
n_agents = self._n_agents[b]
if n_agents == 0:
continue
_a_s = len(vector_action[b]) // n_agents
_m_s = len(memory[b]) // n_agents
for i in range(n_agents):
action = AgentActionProto(
vector_actions=vector_action[b][i*_a_s: (i+1)*_a_s],
memories=memory[b][i*_m_s: (i+1)*_m_s],
text_actions=text_action[b][i]
)
rl_in.agent_actions[b].value.extend([action])
rl_in.command = 0
return self.wrap_unity_input(rl_in)
def _generate_reset_input(self, training, config) -> UnityRLInput:
rl_in = UnityRLInput()
rl_in.is_training = training
rl_in.environment_parameters.CopyFrom(EnvironmentParametersProto())
for key in config:
rl_in.environment_parameters.float_parameters[key] = config[key]
rl_in.command = 1
return self.wrap_unity_input(rl_in)
def send_academy_parameters(self, init_parameters: UnityRLInitializationInput) -> UnityRLInitializationOutput:
inputs = UnityInput()
inputs.rl_initialization_input.CopyFrom(init_parameters)
return self.communicator.initialize(inputs).rl_initialization_output
def wrap_unity_input(self, rl_input: UnityRLInput) -> UnityOutput:
result = UnityInput()
result.rl_input.CopyFrom(rl_input)
return result

14
python/unitytrainers/bc/models.py


LearningModel.__init__(self, m_size, normalize, use_recurrent, brain)
num_streams = 1
hidden_streams = self.create_new_obs(num_streams, h_size, n_layers)
hidden_streams = self.create_observation_streams(num_streams, h_size, n_layers)
tf.Variable(self.m_size, name="memory_size", trainable=False, dtype=tf.int32)
hidden_reg, self.memory_out = self.create_recurrent_encoder(hidden_reg, self.memory_in)
hidden_reg, self.memory_out = self.create_recurrent_encoder(hidden_reg, self.memory_in,
self.sequence_length)
self.policy = tf.layers.dense(hidden_reg, self.a_size, activation=None, use_bias=False,
self.policy = tf.layers.dense(hidden_reg, self.a_size, activation=None, use_bias=False, name='pre_action',
kernel_initializer=c_layers.variance_scaling_initializer(factor=0.01))
if brain.vector_action_space_type == "discrete":

self.action_percent = tf.reduce_mean(tf.cast(
tf.equal(tf.cast(tf.argmax(self.action_probs, axis=1), tf.int32), self.sample_action), tf.float32))
else:
self.sample_action = tf.identity(self.policy, name="action")
self.clipped_sample_action = tf.clip_by_value(self.policy, -1, 1)
self.sample_action = tf.identity(self.clipped_sample_action, name="action")
self.loss = tf.reduce_sum(tf.squared_difference(self.true_action, self.sample_action))
self.clipped_true_action = tf.clip_by_value(self.true_action, -1, 1)
self.loss = tf.reduce_sum(tf.squared_difference(self.clipped_true_action, self.sample_action))
optimizer = tf.train.AdamOptimizer(learning_rate=lr)
self.update = optimizer.minimize(self.loss)

60
python/unitytrainers/bc/trainer.py


self.brain_to_imitate = trainer_parameters['brain_to_imitate']
self.batches_per_epoch = trainer_parameters['batches_per_epoch']
self.use_recurrent = trainer_parameters['use_recurrent']
self.step = 0
self.sequence_length = 1
self.m_size = None
if self.use_recurrent:

normalize=False,
use_recurrent=trainer_parameters['use_recurrent'],
brain=self.brain)
self.inference_run_list = [self.model.sample_action]
if self.use_recurrent:
self.inference_run_list += [self.model.memory_out]
def __str__(self):

Returns the number of steps the trainer has performed
:return: the step count of the trainer
"""
return self.step
return self.sess.run(self.model.global_step)
@property
def get_last_reward(self):

else:
return 0
def increment_step(self):
def increment_step_and_update_last_reward(self):
Increment the step count of the trainer
"""
self.step += 1
def update_last_reward(self):
"""
Updates the last reward
Increment the step count of the trainer and Updates the last reward
self.sess.run(self.model.increment_step)
return
def take_action(self, all_brain_info: AllBrainInfo):

agent_brain = all_brain_info[self.brain_name]
feed_dict = {self.model.dropout_rate: 1.0, self.model.sequence_length: 1}
run_list = [self.model.sample_action]
if self.use_observations:
for i, _ in enumerate(agent_brain.visual_observations):
feed_dict[self.model.visual_in[i]] = agent_brain.visual_observations[i]

if agent_brain.memories.shape[1] == 0:
agent_brain.memories = np.zeros((len(agent_brain.agents), self.m_size))
feed_dict[self.model.memory_in] = agent_brain.memories
run_list += [self.model.memory_out]
agent_action, memories = self.sess.run(run_list, feed_dict)
agent_action, memories = self.sess.run(self.inference_run_list, feed_dict)
agent_action = self.sess.run(run_list, feed_dict)
agent_action = self.sess.run(self.inference_run_list, feed_dict)
return agent_action, None, None, None
def add_experiences(self, curr_info: AllBrainInfo, next_info: AllBrainInfo, take_action_outputs):

if stored_info_student is None:
continue
else:
idx = stored_info_student.agents.index(agent_id)
if not stored_info_student.local_done[idx]:
if agent_id not in self.cumulative_rewards:
self.cumulative_rewards[agent_id] = 0
self.cumulative_rewards[agent_id] += next_info_student.rewards[next_idx]
if agent_id not in self.cumulative_rewards:
self.cumulative_rewards[agent_id] = 0
self.cumulative_rewards[agent_id] += next_info_student.rewards[next_idx]
if not next_info_student.local_done[next_idx]:
if agent_id not in self.episode_steps:
self.episode_steps[agent_id] = 0
self.episode_steps[agent_id] += 1

for l in range(len(info_student.agents)):
if info_student.local_done[l]:
agent_id = info_student.agents[l]
self.stats['cumulative_reward'].append(self.cumulative_rewards[agent_id])
self.stats['episode_length'].append(self.episode_steps[agent_id])
self.stats['cumulative_reward'].append(
self.cumulative_rewards.get(agent_id, 0))
self.stats['episode_length'].append(
self.episode_steps.get(agent_id, 0))
self.cumulative_rewards[agent_id] = 0
self.episode_steps[agent_id] = 0

else:
self.stats['losses'].append(0)
def write_summary(self, lesson_number):
"""
Saves training statistics to Tensorboard.
:param lesson_number: The lesson the trainer is at.
"""
if (self.get_step % self.trainer_parameters['summary_freq'] == 0 and self.get_step != 0 and
self.is_training and self.get_step <= self.get_max_steps):
steps = self.get_step
if len(self.stats['cumulative_reward']) > 0:
mean_reward = np.mean(self.stats['cumulative_reward'])
logger.info("{0} : Step: {1}. Mean Reward: {2}. Std of Reward: {3}."
.format(self.brain_name, steps, mean_reward, np.std(self.stats['cumulative_reward'])))
summary = tf.Summary()
for key in self.stats:
if len(self.stats[key]) > 0:
stat_mean = float(np.mean(self.stats[key]))
summary.value.add(tag='Info/{}'.format(key), simple_value=stat_mean)
self.stats[key] = []
summary.value.add(tag='Info/Lesson', simple_value=lesson_number)
self.summary_writer.add_summary(summary, steps)
self.summary_writer.flush()

14
python/unitytrainers/buffer.py


class AgentBufferField(list):
"""
AgentBufferField is a list of numpy arrays. When an agent collects a field, you can add it to his
AgentBufferField is a list of numpy arrays. When an agent collects a field, you can add it to his
AgentBufferField with the append method.
"""

self[:] = []
self[:] = list(np.array(data))
def get_batch(self, batch_size=None, training_length=None, sequential=True):
def get_batch(self, batch_size=None, training_length=1, sequential=True):
:param batch_size: The number of elements to retrieve. If None:
:param batch_size: The number of elements to retrieve. If None:
:param sequential: If true and training_length is not None: the elements
:param sequential: If true and training_length is not None: the elements
if training_length is None:
# When the training length is None, the method returns a list of elements,
if training_length == 1:
# When the training length is 1, the method returns a list of elements,
# not a list of sequences of elements.
if batch_size is None:
# If batch_size is None : All the elements of the AgentBufferField are returned.

def check_length(self, key_list):
"""
Some methods will require that some fields have the same length.
check_length will return true if the fields in key_list
check_length will return true if the fields in key_list
have the same length.
:param key_list: The fields which length will be compared
"""

236
python/unitytrainers/models.py


self.visual_in = []
self.batch_size = tf.placeholder(shape=None, dtype=tf.int32, name='batch_size')
self.sequence_length = tf.placeholder(shape=None, dtype=tf.int32, name='sequence_length')
self.mask_input = tf.placeholder(shape=[None], dtype=tf.float32, name='masks')
self.mask = tf.cast(self.mask_input, tf.int32)
self.o_size = brain.vector_observation_space_size * brain.num_stacked_vector_observations
self.v_size = brain.number_visual_observations
@staticmethod
def create_global_steps():

return tf.multiply(input_activation, tf.nn.sigmoid(input_activation))
@staticmethod
def create_visual_input(o_size_h, o_size_w, bw, name):
def create_visual_input(camera_parameters, name):
"""
Creates image input op.
:param camera_parameters: Parameters for visual observation from BrainInfo.
:param name: Desired name of input op.
:return: input op.
"""
o_size_h = camera_parameters['height']
o_size_w = camera_parameters['width']
bw = camera_parameters['blackAndWhite']
if bw:
c_channels = 1
else:

return visual_in
def create_vector_input(self, s_size):
def create_vector_input(self, name='vector_observation'):
"""
Creates ops for vector observation input.
:param name: Name of the placeholder op.
:param o_size: Size of stacked vector observation.
:return:
"""
self.vector_in = tf.placeholder(shape=[None, s_size], dtype=tf.float32, name='vector_observation')
self.vector_in = tf.placeholder(shape=[None, self.o_size], dtype=tf.float32, name=name)
self.running_mean = tf.get_variable("running_mean", [s_size], trainable=False, dtype=tf.float32,
self.running_mean = tf.get_variable("running_mean", [self.o_size], trainable=False, dtype=tf.float32,
self.running_variance = tf.get_variable("running_variance", [s_size], trainable=False, dtype=tf.float32,
initializer=tf.ones_initializer())
self.new_mean = tf.placeholder(shape=[s_size], dtype=tf.float32, name='new_mean')
self.new_variance = tf.placeholder(shape=[s_size], dtype=tf.float32, name='new_variance')
self.update_mean = tf.assign(self.running_mean, self.new_mean)
self.update_variance = tf.assign(self.running_variance, self.new_variance)
self.running_variance = tf.get_variable("running_variance", [self.o_size], trainable=False,
dtype=tf.float32, initializer=tf.ones_initializer())
self.update_mean, self.update_variance = self.create_normalizer_update(self.vector_in)
return self.normalized_state
self.normalized_state = self.vector_in
return self.vector_in
return self.vector_in
def create_continuous_state_encoder(self, h_size, activation, num_layers):
def create_normalizer_update(self, vector_input):
mean_current_observation = tf.reduce_mean(vector_input, axis=0)
new_mean = self.running_mean + (mean_current_observation - self.running_mean) / \
tf.cast(self.global_step + 1, tf.float32)
new_variance = self.running_variance + (mean_current_observation - new_mean) * \
(mean_current_observation - self.running_mean)
update_mean = tf.assign(self.running_mean, new_mean)
update_variance = tf.assign(self.running_variance, new_variance)
return update_mean, update_variance
@staticmethod
def create_continuous_observation_encoder(observation_input, h_size, activation, num_layers, scope, reuse):
:param reuse: Whether to re-use the weights within the same scope.
:param scope: Graph scope for the encoder ops.
:param observation_input: Input vector.
hidden = self.normalized_state
for j in range(num_layers):
hidden = tf.layers.dense(hidden, h_size, activation=activation,
kernel_initializer=c_layers.variance_scaling_initializer(1.0))
with tf.variable_scope(scope):
hidden = observation_input
for i in range(num_layers):
hidden = tf.layers.dense(hidden, h_size, activation=activation, reuse=reuse, name="hidden_{}".format(i),
kernel_initializer=c_layers.variance_scaling_initializer(1.0))
def create_visual_encoder(self, image_input, h_size, activation, num_layers):
def create_visual_observation_encoder(self, image_input, h_size, activation, num_layers, scope, reuse):
:param reuse: Whether to re-use the weights within the same scope.
:param scope: The scope of the graph within which to create the ops.
:param image_input: The placeholder for the image input to use.
:param h_size: Hidden layer size.
:param activation: What type of activation function to use for layers.

conv1 = tf.layers.conv2d(image_input, 16, kernel_size=[8, 8], strides=[4, 4],
activation=tf.nn.elu)
conv2 = tf.layers.conv2d(conv1, 32, kernel_size=[4, 4], strides=[2, 2],
activation=tf.nn.elu)
hidden = c_layers.flatten(conv2)
with tf.variable_scope(scope):
conv1 = tf.layers.conv2d(image_input, 16, kernel_size=[8, 8], strides=[4, 4],
activation=tf.nn.elu, reuse=reuse, name="conv_1")
conv2 = tf.layers.conv2d(conv1, 32, kernel_size=[4, 4], strides=[2, 2],
activation=tf.nn.elu, reuse=reuse, name="conv_2")
hidden = c_layers.flatten(conv2)
for j in range(num_layers):
hidden = tf.layers.dense(hidden, h_size, use_bias=False, activation=activation)
return hidden
with tf.variable_scope(scope+'/'+'flat_encoding'):
hidden_flat = self.create_continuous_observation_encoder(hidden, h_size, activation,
num_layers, scope, reuse)
return hidden_flat
def create_discrete_state_encoder(self, s_size, h_size, activation, num_layers):
@staticmethod
def create_discrete_observation_encoder(observation_input, s_size, h_size, activation,
num_layers, scope, reuse):
:param reuse: Whether to re-use the weights within the same scope.
:param scope: The scope of the graph within which to create the ops.
:param observation_input: Discrete observation.
:param s_size: state input size (discrete).
:param h_size: Hidden layer size.
:param activation: What type of activation function to use for layers.

vector_in = tf.reshape(self.vector_in, [-1])
state_onehot = c_layers.one_hot_encoding(vector_in, s_size)
hidden = state_onehot
for j in range(num_layers):
hidden = tf.layers.dense(hidden, h_size, use_bias=False, activation=activation)
with tf.variable_scope(scope):
vector_in = tf.reshape(observation_input, [-1])
state_onehot = tf.one_hot(vector_in, s_size)
hidden = state_onehot
for i in range(num_layers):
hidden = tf.layers.dense(hidden, h_size, use_bias=False, activation=activation,
reuse=reuse, name="hidden_{}".format(i))
def create_new_obs(self, num_streams, h_size, num_layers):
def create_observation_streams(self, num_streams, h_size, num_layers):
"""
Creates encoding stream for observations.
:param num_streams: Number of streams to create.
:param h_size: Size of hidden linear layers in stream.
:param num_layers: Number of hidden linear layers in stream.
:return: List of encoded streams.
"""
s_size = brain.vector_observation_space_size * brain.num_stacked_vector_observations
if brain.vector_action_space_type == "continuous":
activation_fn = tf.nn.tanh
else:

for i in range(brain.number_visual_observations):
height_size, width_size = brain.camera_resolutions[i]['height'], brain.camera_resolutions[i]['width']
bw = brain.camera_resolutions[i]['blackAndWhite']
visual_input = self.create_visual_input(height_size, width_size, bw, name="visual_observation_" + str(i))
visual_input = self.create_visual_input(brain.camera_resolutions[i], name="visual_observation_" + str(i))
self.create_vector_input(s_size)
vector_observation_input = self.create_vector_input()
if brain.number_visual_observations > 0:
if self.v_size > 0:
encoded_visual = self.create_visual_encoder(self.visual_in[j], h_size, activation_fn, num_layers)
encoded_visual = self.create_visual_observation_encoder(self.visual_in[j], h_size,
activation_fn, num_layers,
"main_graph_{}_encoder{}"
.format(i, j), False)
s_size = brain.vector_observation_space_size * brain.num_stacked_vector_observations
hidden_state = self.create_continuous_state_encoder(h_size, activation_fn, num_layers)
hidden_state = self.create_continuous_observation_encoder(vector_observation_input,
h_size, activation_fn, num_layers,
"main_graph_{}".format(i), False)
hidden_state = self.create_discrete_state_encoder(s_size, h_size,
activation_fn, num_layers)
hidden_state = self.create_discrete_observation_encoder(vector_observation_input, self.o_size,
h_size, activation_fn, num_layers,
"main_graph_{}".format(i), False)
if hidden_state is not None and hidden_visual is not None:
final_hidden = tf.concat([hidden_visual, hidden_state], axis=1)
elif hidden_state is None and hidden_visual is not None:

final_hiddens.append(final_hidden)
return final_hiddens
def create_recurrent_encoder(self, input_state, memory_in, name='lstm'):
@staticmethod
def create_recurrent_encoder(input_state, memory_in, sequence_length, name='lstm'):
:param sequence_length: Length of sequence to unroll.
:param input_state: The input tensor to the LSTM cell.
:param memory_in: The input memory to the LSTM cell.
:param name: The scope of the LSTM cell.

lstm_input_state = tf.reshape(input_state, shape=[-1, self.sequence_length, s_size])
lstm_input_state = tf.reshape(input_state, shape=[-1, sequence_length, s_size])
memory_in = tf.reshape(memory_in[:, :], [-1, m_size])
recurrent_state, lstm_state_out = tf.nn.dynamic_rnn(rnn_cell, lstm_input_state,
initial_state=lstm_vector_in,
time_major=False,
dtype=tf.float32)
recurrent_output, lstm_state_out = tf.nn.dynamic_rnn(rnn_cell, lstm_input_state,
initial_state=lstm_vector_in)
recurrent_state = tf.reshape(recurrent_state, shape=[-1, _half_point])
return recurrent_state, tf.concat([lstm_state_out.c, lstm_state_out.h], axis=1)
recurrent_output = tf.reshape(recurrent_output, shape=[-1, _half_point])
return recurrent_output, tf.concat([lstm_state_out.c, lstm_state_out.h], axis=1)
num_streams = 1
hidden_streams = self.create_new_obs(num_streams, h_size, num_layers)
"""
Creates Discrete control actor-critic model.
:param h_size: Size of hidden linear layers.
:param num_layers: Number of hidden linear layers.
"""
hidden_streams = self.create_observation_streams(1, h_size, num_layers)
self.prev_action_oh = c_layers.one_hot_encoding(self.prev_action, self.a_size)
hidden = tf.concat([hidden, self.prev_action_oh], axis=1)
prev_action_oh = tf.one_hot(self.prev_action, self.a_size)
hidden = tf.concat([hidden, prev_action_oh], axis=1)
hidden, self.memory_out = self.create_recurrent_encoder(hidden, self.memory_in)
self.memory_out = tf.identity(self.memory_out, name='recurrent_out')
hidden, memory_out = self.create_recurrent_encoder(hidden, self.memory_in, self.sequence_length)
self.memory_out = tf.identity(memory_out, name='recurrent_out')
self.output = tf.multinomial(self.policy, 1)
self.output = tf.identity(self.output, name="action")
output = tf.multinomial(self.policy, 1)
self.output = tf.identity(output, name="action")
self.value = tf.layers.dense(hidden, 1, activation=None)
self.value = tf.identity(self.value, name="value_estimate")
value = tf.layers.dense(hidden, 1, activation=None)
self.value = tf.identity(value, name="value_estimate")
self.selected_actions = c_layers.one_hot_encoding(self.action_holder, self.a_size)
self.selected_actions = tf.one_hot(self.action_holder, self.a_size)
self.all_old_probs = tf.placeholder(shape=[None, self.a_size], dtype=tf.float32, name='old_probabilities')

def create_cc_actor_critic(self, h_size, num_layers):
num_streams = 2
hidden_streams = self.create_new_obs(num_streams, h_size, num_layers)
"""
Creates Continuous control actor-critic model.
:param h_size: Size of hidden linear layers.
:param num_layers: Number of hidden linear layers.
"""
hidden_streams = self.create_observation_streams(2, h_size, num_layers)
if self.use_recurrent:
tf.Variable(self.m_size, name="memory_size", trainable=False, dtype=tf.int32)

hidden_streams[0], self.memory_in[:, :_half_point], name='lstm_policy')
hidden_streams[0], self.memory_in[:, :_half_point], self.sequence_length, name='lstm_policy')
hidden_streams[1], self.memory_in[:, _half_point:], name='lstm_value')
hidden_streams[1], self.memory_in[:, _half_point:], self.sequence_length, name='lstm_value')
self.mu = tf.layers.dense(hidden_policy, self.a_size, activation=None, use_bias=False,
kernel_initializer=c_layers.variance_scaling_initializer(factor=0.01))
mu = tf.layers.dense(hidden_policy, self.a_size, activation=None,
kernel_initializer=c_layers.variance_scaling_initializer(factor=0.01))
log_sigma_sq = tf.get_variable("log_sigma_squared", [self.a_size], dtype=tf.float32,
initializer=tf.zeros_initializer())
sigma_sq = tf.exp(log_sigma_sq)
epsilon = tf.random_normal(tf.shape(mu), dtype=tf.float32)
# Clip and scale output to ensure actions are always within [-1, 1] range.
self.output_pre = mu + tf.sqrt(sigma_sq) * epsilon
output_post = tf.clip_by_value(self.output_pre, -3, 3) / 3
self.output = tf.identity(output_post, name='action')
self.selected_actions = tf.stop_gradient(output_post)
# Compute probability of model output.
a = tf.exp(-1 * tf.pow(tf.stop_gradient(self.output_pre) - mu, 2) / (2 * sigma_sq))
b = 1 / tf.sqrt(2 * sigma_sq * np.pi)
all_probs = tf.multiply(a, b)
self.all_probs = tf.identity(all_probs, name='action_probs')
self.entropy = tf.reduce_mean(0.5 * tf.log(2 * np.pi * np.e * sigma_sq))
self.log_sigma_sq = tf.get_variable("log_sigma_squared", [self.a_size], dtype=tf.float32,
initializer=tf.zeros_initializer())
value = tf.layers.dense(hidden_value, 1, activation=None)
self.value = tf.identity(value, name="value_estimate")
self.sigma_sq = tf.exp(self.log_sigma_sq)
self.epsilon = tf.random_normal(tf.shape(self.mu), dtype=tf.float32)
self.output = self.mu + tf.sqrt(self.sigma_sq) * self.epsilon
self.output = tf.identity(self.output, name='action')
a = tf.exp(-1 * tf.pow(tf.stop_gradient(self.output) - self.mu, 2) / (2 * self.sigma_sq))
b = 1 / tf.sqrt(2 * self.sigma_sq * np.pi)
self.all_probs = tf.multiply(a, b, name="action_probs")
self.entropy = tf.reduce_mean(0.5 * tf.log(2 * np.pi * np.e * self.sigma_sq))
self.value = tf.layers.dense(hidden_value, 1, activation=None)
self.value = tf.identity(self.value, name="value_estimate")
# We keep these tensors the same name, but use new nodes to keep code parallelism with discrete control.
self.probs = tf.identity(self.all_probs)
self.old_probs = tf.identity(self.all_old_probs)

138
python/unitytrainers/ppo/models.py


class PPOModel(LearningModel):
def __init__(self, brain, lr=1e-4, h_size=128, epsilon=0.2, beta=1e-3, max_step=5e6,
normalize=False, use_recurrent=False, num_layers=2, m_size=None):
normalize=False, use_recurrent=False, num_layers=2, m_size=None, use_curiosity=False,
curiosity_strength=0.01, curiosity_enc_size=128):
"""
Takes a Unity environment and model-specific hyper-parameters and returns the
appropriate PPO agent model for the environment.

:param m_size: Size of brain memory.
"""
LearningModel.__init__(self, m_size, normalize, use_recurrent, brain)
self.use_curiosity = use_curiosity
if num_layers < 1:
num_layers = 1
self.last_reward, self.new_reward, self.update_reward = self.create_reward_encoder()

else:
self.create_dc_actor_critic(h_size, num_layers)
if self.use_curiosity:
self.curiosity_enc_size = curiosity_enc_size
self.curiosity_strength = curiosity_strength
encoded_state, encoded_next_state = self.create_curiosity_encoders()
self.create_inverse_model(encoded_state, encoded_next_state)
self.create_forward_model(encoded_state, encoded_next_state)
self.create_ppo_optimizer(self.probs, self.old_probs, self.value,
self.entropy, beta, epsilon, lr, max_step)

update_reward = tf.assign(last_reward, new_reward)
return last_reward, new_reward, update_reward
def create_curiosity_encoders(self):
"""
Creates state encoders for current and future observations.
Used for implementation of Curiosity-driven Exploration by Self-supervised Prediction
See https://arxiv.org/abs/1705.05363 for more details.
:return: current and future state encoder tensors.
"""
encoded_state_list = []
encoded_next_state_list = []
if self.v_size > 0:
self.next_visual_in = []
visual_encoders = []
next_visual_encoders = []
for i in range(self.v_size):
# Create input ops for next (t+1) visual observations.
next_visual_input = self.create_visual_input(self.brain.camera_resolutions[i],
name="next_visual_observation_" + str(i))
self.next_visual_in.append(next_visual_input)
# Create the encoder ops for current and next visual input. Not that these encoders are siamese.
encoded_visual = self.create_visual_observation_encoder(self.visual_in[i], self.curiosity_enc_size,
self.swish, 1, "stream_{}_visual_obs_encoder"
.format(i), False)
encoded_next_visual = self.create_visual_observation_encoder(self.next_visual_in[i],
self.curiosity_enc_size,
self.swish, 1,
"stream_{}_visual_obs_encoder".format(i),
True)
visual_encoders.append(encoded_visual)
next_visual_encoders.append(encoded_next_visual)
hidden_visual = tf.concat(visual_encoders, axis=1)
hidden_next_visual = tf.concat(next_visual_encoders, axis=1)
encoded_state_list.append(hidden_visual)
encoded_next_state_list.append(hidden_next_visual)
if self.o_size > 0:
# Create the encoder ops for current and next vector input. Not that these encoders are siamese.
if self.brain.vector_observation_space_type == "continuous":
# Create input op for next (t+1) vector observation.
self.next_vector_in = tf.placeholder(shape=[None, self.o_size], dtype=tf.float32,
name='next_vector_observation')
encoded_vector_obs = self.create_continuous_observation_encoder(self.vector_in,
self.curiosity_enc_size,
self.swish, 2, "vector_obs_encoder",
False)
encoded_next_vector_obs = self.create_continuous_observation_encoder(self.next_vector_in,
self.curiosity_enc_size,
self.swish, 2,
"vector_obs_encoder",
True)
else:
self.next_vector_in = tf.placeholder(shape=[None, 1], dtype=tf.int32,
name='next_vector_observation')
encoded_vector_obs = self.create_discrete_observation_encoder(self.vector_in, self.o_size,
self.curiosity_enc_size,
self.swish, 2, "vector_obs_encoder",
False)
encoded_next_vector_obs = self.create_discrete_observation_encoder(self.next_vector_in, self.o_size,
self.curiosity_enc_size,
self.swish, 2, "vector_obs_encoder",
True)
encoded_state_list.append(encoded_vector_obs)
encoded_next_state_list.append(encoded_next_vector_obs)
encoded_state = tf.concat(encoded_state_list, axis=1)
encoded_next_state = tf.concat(encoded_next_state_list, axis=1)
return encoded_state, encoded_next_state
def create_inverse_model(self, encoded_state, encoded_next_state):
"""
Creates inverse model TensorFlow ops for Curiosity module.
Predicts action taken given current and future encoded states.
:param encoded_state: Tensor corresponding to encoded current state.
:param encoded_next_state: Tensor corresponding to encoded next state.
"""
combined_input = tf.concat([encoded_state, encoded_next_state], axis=1)
hidden = tf.layers.dense(combined_input, 256, activation=self.swish)
if self.brain.vector_action_space_type == "continuous":
pred_action = tf.layers.dense(hidden, self.a_size, activation=None)
squared_difference = tf.reduce_sum(tf.squared_difference(pred_action, self.selected_actions), axis=1)
self.inverse_loss = tf.reduce_mean(tf.dynamic_partition(squared_difference, self.mask, 2)[1])
else:
pred_action = tf.layers.dense(hidden, self.a_size, activation=tf.nn.softmax)
cross_entropy = tf.reduce_sum(-tf.log(pred_action + 1e-10) * self.selected_actions, axis=1)
self.inverse_loss = tf.reduce_mean(tf.dynamic_partition(cross_entropy, self.mask, 2)[1])
def create_forward_model(self, encoded_state, encoded_next_state):
"""
Creates forward model TensorFlow ops for Curiosity module.
Predicts encoded future state based on encoded current state and given action.
:param encoded_state: Tensor corresponding to encoded current state.
:param encoded_next_state: Tensor corresponding to encoded next state.
"""
combined_input = tf.concat([encoded_state, self.selected_actions], axis=1)
hidden = tf.layers.dense(combined_input, 256, activation=self.swish)
# We compare against the concatenation of all observation streams, hence `self.v_size + int(self.o_size > 0)`.
pred_next_state = tf.layers.dense(hidden, self.curiosity_enc_size * (self.v_size + int(self.o_size > 0)),
activation=None)
squared_difference = 0.5 * tf.reduce_sum(tf.squared_difference(pred_next_state, encoded_next_state), axis=1)
self.intrinsic_reward = tf.clip_by_value(self.curiosity_strength * squared_difference, 0, 1)
self.forward_loss = tf.reduce_mean(tf.dynamic_partition(squared_difference, self.mask, 2)[1])
def create_ppo_optimizer(self, probs, old_probs, value, entropy, beta, epsilon, lr, max_step):
"""
Creates training-specific Tensorflow ops for PPO models.

:param lr: Learning rate
:param max_step: Total number of training steps.
"""
self.mask_input = tf.placeholder(shape=[None], dtype=tf.float32, name='masks')
self.mask = tf.equal(self.mask_input, 1.0)
self.value_loss = tf.reduce_mean(tf.boolean_mask(tf.maximum(v_opt_a, v_opt_b), self.mask))
self.value_loss = tf.reduce_mean(tf.dynamic_partition(tf.maximum(v_opt_a, v_opt_b), self.mask, 2)[1])
self.r_theta = probs / (old_probs + 1e-10)
self.p_opt_a = self.r_theta * self.advantage
self.p_opt_b = tf.clip_by_value(self.r_theta, 1.0 - decay_epsilon, 1.0 + decay_epsilon) * self.advantage
self.policy_loss = -tf.reduce_mean(tf.boolean_mask(tf.minimum(self.p_opt_a, self.p_opt_b), self.mask))
r_theta = probs / (old_probs + 1e-10)
p_opt_a = r_theta * self.advantage
p_opt_b = tf.clip_by_value(r_theta, 1.0 - decay_epsilon, 1.0 + decay_epsilon) * self.advantage
self.policy_loss = -tf.reduce_mean(tf.dynamic_partition(tf.minimum(p_opt_a, p_opt_b), self.mask, 2)[1])
tf.boolean_mask(entropy, self.mask))
tf.dynamic_partition(entropy, self.mask, 2)[1])
if self.use_curiosity:
self.loss += 10 * (0.2 * self.forward_loss + 0.8 * self.inverse_loss)
self.update_batch = optimizer.minimize(self.loss)

373
python/unitytrainers/ppo/trainer.py


# # Unity ML Agents
# ## ML-Agent Learning (PPO)
# Contains an implementation of PPO as described [here](https://arxiv.org/abs/1707.06347).
# Contains an implementation of PPO as described (https://arxiv.org/abs/1707.06347).
import logging
import os

class PPOTrainer(Trainer):
"""The PPOTrainer is an implementation of the PPO algorythm."""
"""The PPOTrainer is an implementation of the PPO algorithm."""
def __init__(self, sess, env, brain_name, trainer_parameters, training, seed):
"""

:param training: Whether the trainer is set for training.
"""
self.param_keys = ['batch_size', 'beta', 'buffer_size', 'epsilon', 'gamma', 'hidden_units', 'lambd',
'learning_rate',
'max_steps', 'normalize', 'num_epoch', 'num_layers', 'time_horizon', 'sequence_length',
'summary_freq',
'use_recurrent', 'graph_scope', 'summary_path', 'memory_size']
'learning_rate', 'max_steps', 'normalize', 'num_epoch', 'num_layers',
'time_horizon', 'sequence_length', 'summary_freq', 'use_recurrent',
'graph_scope', 'summary_path', 'memory_size', 'use_curiosity', 'curiosity_strength',
'curiosity_enc_size']
for k in self.param_keys:
if k not in trainer_parameters:

super(PPOTrainer, self).__init__(sess, env, brain_name, trainer_parameters, training)
self.use_recurrent = trainer_parameters["use_recurrent"]
self.use_curiosity = bool(trainer_parameters['use_curiosity'])
self.step = 0
self.has_updated = False
if self.use_recurrent:
if self.m_size == 0:
raise UnityTrainerException("The memory size for brain {0} is 0 even though the trainer uses recurrent."
.format(brain_name))

normalize=trainer_parameters['normalize'],
use_recurrent=trainer_parameters['use_recurrent'],
num_layers=int(trainer_parameters['num_layers']),
m_size=self.m_size)
m_size=self.m_size,
use_curiosity=bool(trainer_parameters['use_curiosity']),
curiosity_strength=float(trainer_parameters['curiosity_strength']),
curiosity_enc_size=float(trainer_parameters['curiosity_enc_size']))
if self.use_curiosity:
stats['forward_loss'] = []
stats['inverse_loss'] = []
stats['intrinsic_reward'] = []
self.intrinsic_rewards = {}
self.stats = stats
self.training_buffer = Buffer()

self.is_continuous_observation = (env.brains[brain_name].vector_observation_space_type == "continuous")
self.use_observations = (env.brains[brain_name].number_visual_observations > 0)
self.use_states = (env.brains[brain_name].vector_observation_space_size > 0)
self.use_visual_obs = (env.brains[brain_name].number_visual_observations > 0)
self.use_vector_obs = (env.brains[brain_name].vector_observation_space_size > 0)
self.summary_path = trainer_parameters['summary_path']
if not os.path.exists(self.summary_path):
os.makedirs(self.summary_path)

self.inference_run_list = [self.model.output, self.model.all_probs, self.model.value,
self.model.entropy, self.model.learning_rate]
if self.is_continuous_action:
self.inference_run_list.append(self.model.output_pre)
if self.use_recurrent:
self.inference_run_list.extend([self.model.memory_out])
if (self.is_training and self.is_continuous_observation and
self.use_vector_obs and self.trainer_parameters['normalize']):
self.inference_run_list.extend([self.model.update_mean, self.model.update_variance])
return '''Hypermarameters for the PPO Trainer of brain {0}: \n{1}'''.format(
return '''Hyperparameters for the PPO Trainer of brain {0}: \n{1}'''.format(
self.brain_name, '\n'.join(['\t{0}:\t{1}'.format(x, self.trainer_parameters[x]) for x in self.param_keys]))
@property

Returns the number of steps the trainer has performed
:return: the step count of the trainer
"""
return self.sess.run(self.model.global_step)
return self.step
@property
def get_last_reward(self):

"""
return self.sess.run(self.model.last_reward)
def increment_step(self):
"""
Increment the step count of the trainer
"""
self.sess.run(self.model.increment_step)
def update_last_reward(self):
def increment_step_and_update_last_reward(self):
Updates the last reward
Increment the step count of the trainer and Updates the last reward
self.sess.run(self.model.update_reward, feed_dict={self.model.new_reward: mean_reward})
def running_average(self, data, steps, running_mean, running_variance):
"""
Computes new running mean and variances.
:param data: New piece of data.
:param steps: Total number of data so far.
:param running_mean: TF op corresponding to stored running mean.
:param running_variance: TF op corresponding to stored running variance.
:return: New mean and variance values.
"""
mean, var = self.sess.run([running_mean, running_variance])
current_x = np.mean(data, axis=0)
new_mean = mean + (current_x - mean) / (steps + 1)
new_variance = var + (current_x - new_mean) * (current_x - mean)
return new_mean, new_variance
self.sess.run([self.model.update_reward,
self.model.increment_step],
feed_dict={self.model.new_reward: mean_reward})
else:
self.sess.run(self.model.increment_step)
self.step = self.sess.run(self.model.global_step)
Decides actions given state/observation information, and takes them in environment.
Decides actions given observations information, and takes them in environment.
steps = self.get_step
feed_dict = {self.model.batch_size: len(curr_brain_info.vector_observations), self.model.sequence_length: 1}
run_list = [self.model.output, self.model.all_probs, self.model.value, self.model.entropy,
self.model.learning_rate]
if self.is_continuous_action:
run_list.append(self.model.epsilon)
elif self.use_recurrent:
feed_dict[self.model.prev_action] = np.reshape(curr_brain_info.previous_vector_actions, [-1])
if self.use_observations:
for i, _ in enumerate(curr_brain_info.visual_observations):
feed_dict[self.model.visual_in[i]] = curr_brain_info.visual_observations[i]
if self.use_states:
feed_dict[self.model.vector_in] = curr_brain_info.vector_observations
feed_dict = {self.model.batch_size: len(curr_brain_info.vector_observations),
self.model.sequence_length: 1}
if not self.is_continuous_action:
feed_dict[self.model.prev_action] = curr_brain_info.previous_vector_actions.flatten()
run_list += [self.model.memory_out]
if (self.is_training and self.is_continuous_observation and
self.use_states and self.trainer_parameters['normalize']):
new_mean, new_variance = self.running_average(
curr_brain_info.vector_observations, steps, self.model.running_mean, self.model.running_variance)
feed_dict[self.model.new_mean] = new_mean
feed_dict[self.model.new_variance] = new_variance
run_list = run_list + [self.model.update_mean, self.model.update_variance]
if self.use_visual_obs:
for i, _ in enumerate(curr_brain_info.visual_observations):
feed_dict[self.model.visual_in[i]] = curr_brain_info.visual_observations[i]
if self.use_vector_obs:
feed_dict[self.model.vector_in] = curr_brain_info.vector_observations
values = self.sess.run(run_list, feed_dict=feed_dict)
run_out = dict(zip(run_list, values))
values = self.sess.run(self.inference_run_list, feed_dict=feed_dict)
run_out = dict(zip(self.inference_run_list, values))
return (run_out[self.model.output],
run_out[self.model.memory_out],
[str(v) for v in run_out[self.model.value]],
run_out)
return run_out[self.model.output], run_out[self.model.memory_out], None, run_out
else:
return run_out[self.model.output], None, None, run_out
def generate_intrinsic_rewards(self, curr_info, next_info):
"""
Generates intrinsic reward used for Curiosity-based training.
:param curr_info: Current BrainInfo.
:param next_info: Next BrainInfo.
:return: Intrinsic rewards for all agents.
"""
if self.use_curiosity:
if curr_info.agents != next_info.agents:
raise UnityTrainerException("Training with Curiosity-driven exploration"
" and On-Demand Decision making is currently not supported.")
feed_dict = {self.model.batch_size: len(curr_info.vector_observations), self.model.sequence_length: 1}
if self.is_continuous_action:
feed_dict[self.model.output] = next_info.previous_vector_actions
else:
feed_dict[self.model.action_holder] = next_info.previous_vector_actions.flatten()
if self.use_visual_obs:
for i in range(len(curr_info.visual_observations)):
feed_dict[self.model.visual_in[i]] = curr_info.visual_observations[i]
feed_dict[self.model.next_visual_in[i]] = next_info.visual_observations[i]
if self.use_vector_obs:
feed_dict[self.model.vector_in] = curr_info.vector_observations
feed_dict[self.model.next_vector_in] = next_info.vector_observations
if self.use_recurrent:
if curr_info.memories.shape[1] == 0:
curr_info.memories = np.zeros((len(curr_info.agents), self.m_size))
feed_dict[self.model.memory_in] = curr_info.memories
intrinsic_rewards = self.sess.run(self.model.intrinsic_reward,
feed_dict=feed_dict) * float(self.has_updated)
return intrinsic_rewards
return (run_out[self.model.output],
None,
[str(v) for v in run_out[self.model.value]],
run_out)
return None
def generate_value_estimate(self, brain_info, idx):
"""
Generates value estimates for bootstrapping.
:param brain_info: BrainInfo to be used for bootstrapping.
:param idx: Index in BrainInfo of agent.
:return: Value estimate.
"""
feed_dict = {self.model.batch_size: 1, self.model.sequence_length: 1}
if self.use_visual_obs:
for i in range(len(brain_info.visual_observations)):
feed_dict[self.model.visual_in[i]] = [brain_info.visual_observations[i][idx]]
if self.use_vector_obs:
feed_dict[self.model.vector_in] = [brain_info.vector_observations[idx]]
if self.use_recurrent:
if brain_info.memories.shape[1] == 0:
brain_info.memories = np.zeros(
(len(brain_info.vector_observations), self.m_size))
feed_dict[self.model.memory_in] = [brain_info.memories[idx]]
if not self.is_continuous_action and self.use_recurrent:
feed_dict[self.model.prev_action] = brain_info.previous_vector_actions[idx].flatten()
value_estimate = self.sess.run(self.model.value, feed_dict)
return value_estimate
def add_experiences(self, curr_all_info: AllBrainInfo, next_all_info: AllBrainInfo, take_action_outputs):
"""

"""
curr_info = curr_all_info[self.brain_name]
next_info = next_all_info[self.brain_name]
intrinsic_rewards = self.generate_intrinsic_rewards(curr_info, next_info)
for agent_id in curr_info.agents:
self.training_buffer[agent_id].last_brain_info = curr_info

stored_info = self.training_buffer[agent_id].last_brain_info
stored_take_action_outputs = self.training_buffer[agent_id].last_take_action_outputs
if stored_info is None:
continue
else:
if stored_info is not None:
if self.use_observations:
if self.use_visual_obs:
self.training_buffer[agent_id]['observations%d' % i].append(stored_info.visual_observations[i][idx])
if self.use_states:
self.training_buffer[agent_id]['states'].append(stored_info.vector_observations[idx])
self.training_buffer[agent_id]['visual_obs%d' % i].append(
stored_info.visual_observations[i][idx])
self.training_buffer[agent_id]['next_visual_obs%d' % i].append(
next_info.visual_observations[i][idx])
if self.use_vector_obs:
self.training_buffer[agent_id]['vector_obs'].append(stored_info.vector_observations[idx])
self.training_buffer[agent_id]['next_vector_in'].append(
next_info.vector_observations[next_idx])
if self.is_continuous_action:
epsi = stored_take_action_outputs[self.model.epsilon]
self.training_buffer[agent_id]['epsilons'].append(epsi[idx])
if self.is_continuous_action:
actions_pre = stored_take_action_outputs[self.model.output_pre]
self.training_buffer[agent_id]['actions_pre'].append(actions_pre[idx])
self.training_buffer[agent_id]['rewards'].append(next_info.rewards[next_idx])
if self.use_curiosity:
self.training_buffer[agent_id]['rewards'].append(next_info.rewards[next_idx] +
intrinsic_rewards[next_idx])
else:
self.training_buffer[agent_id]['rewards'].append(next_info.rewards[next_idx])
self.training_buffer[agent_id]['action_probs'].append(a_dist[idx])
self.training_buffer[agent_id]['value_estimates'].append(value[idx][0])

if self.use_curiosity:
if agent_id not in self.intrinsic_rewards:
self.intrinsic_rewards[agent_id] = 0
self.intrinsic_rewards[agent_id] += intrinsic_rewards[next_idx]
if not next_info.local_done[next_idx]:
if agent_id not in self.episode_steps:
self.episode_steps[agent_id] = 0
self.episode_steps[agent_id] += 1

for l in range(len(info.agents)):
agent_actions = self.training_buffer[info.agents[l]]['actions']
if ((info.local_done[l] or len(agent_actions) > self.trainer_parameters['time_horizon'])
and len(agent_actions) > 0):
and len(agent_actions) > 0):
agent_id = info.agents[l]
if info.local_done[l] and not info.max_reached[l]:
value_next = 0.0

else:
bootstrapping_info = info
idx = l
feed_dict = {self.model.batch_size: len(bootstrapping_info.vector_observations), self.model.sequence_length: 1}
if self.use_observations:
for i in range(len(bootstrapping_info.visual_observations)):
feed_dict[self.model.visual_in[i]] = bootstrapping_info.visual_observations[i]
if self.use_states:
feed_dict[self.model.vector_in] = bootstrapping_info.vector_observations
if self.use_recurrent:
if bootstrapping_info.memories.shape[1] == 0:
bootstrapping_info.memories = np.zeros((len(bootstrapping_info.vector_observations), self.m_size))
feed_dict[self.model.memory_in] = bootstrapping_info.memories
if not self.is_continuous_action and self.use_recurrent:
feed_dict[self.model.prev_action] = np.reshape(bootstrapping_info.previous_vector_actions, [-1])
value_next = self.sess.run(self.model.value, feed_dict)[idx]
value_next = self.generate_value_estimate(bootstrapping_info, idx)
self.training_buffer[agent_id]['advantages'].set(
get_gae(

gamma=self.trainer_parameters['gamma'],
lambd=self.trainer_parameters['lambd'])
)
lambd=self.trainer_parameters['lambd']))
self.training_buffer.append_update_buffer(agent_id,
batch_size=None, training_length=self.sequence_length)
self.training_buffer.append_update_buffer(agent_id, batch_size=None,
training_length=self.sequence_length)
self.stats['cumulative_reward'].append(self.cumulative_rewards[agent_id])
self.stats['episode_length'].append(self.episode_steps[agent_id])
self.stats['cumulative_reward'].append(
self.cumulative_rewards.get(agent_id, 0))
self.stats['episode_length'].append(
self.episode_steps.get(agent_id, 0))
if self.use_curiosity:
self.stats['intrinsic_reward'].append(
self.intrinsic_rewards.get(agent_id, 0))
self.intrinsic_rewards[agent_id] = 0
def end_episode(self):
"""

self.cumulative_rewards[agent_id] = 0
for agent_id in self.episode_steps:
self.episode_steps[agent_id] = 0
if self.use_curiosity:
for agent_id in self.intrinsic_rewards:
self.intrinsic_rewards[agent_id] = 0
def is_ready_update(self):
"""

return len(self.training_buffer.update_buffer['actions']) > \
max(int(self.trainer_parameters['buffer_size'] / self.sequence_length), 1)
size_of_buffer = len(self.training_buffer.update_buffer['actions'])
return size_of_buffer > max(int(self.trainer_parameters['buffer_size'] / self.sequence_length), 1)
num_epoch = self.trainer_parameters['num_epoch']
total_v, total_p = 0, 0
value_total, policy_total, forward_total, inverse_total = [], [], [], []
num_epoch = self.trainer_parameters['num_epoch']
buffer = self.training_buffer.update_buffer
_buffer = self.training_buffer.update_buffer
self.model.mask_input: np.array(_buffer['masks'][start:end]).reshape(
[-1]),
self.model.returns_holder: np.array(_buffer['discounted_returns'][start:end]).reshape(
[-1]),
self.model.old_value: np.array(_buffer['value_estimates'][start:end]).reshape([-1]),
self.model.advantage: np.array(_buffer['advantages'][start:end]).reshape([-1, 1]),
self.model.all_old_probs: np.array(
_buffer['action_probs'][start:end]).reshape([-1, self.brain.vector_action_space_size])}
self.model.mask_input: np.array(buffer['masks'][start:end]).flatten(),
self.model.returns_holder: np.array(buffer['discounted_returns'][start:end]).flatten(),
self.model.old_value: np.array(buffer['value_estimates'][start:end]).flatten(),
self.model.advantage: np.array(buffer['advantages'][start:end]).reshape([-1, 1]),
self.model.all_old_probs: np.array(buffer['action_probs'][start:end]).reshape(
[-1, self.brain.vector_action_space_size])}
feed_dict[self.model.epsilon] = np.array(
_buffer['epsilons'][start:end]).reshape([-1, self.brain.vector_action_space_size])
feed_dict[self.model.output_pre] = np.array(buffer['actions_pre'][start:end]).reshape(
[-1, self.brain.vector_action_space_size])
feed_dict[self.model.action_holder] = np.array(
_buffer['actions'][start:end]).reshape([-1])
feed_dict[self.model.action_holder] = np.array(buffer['actions'][start:end]).flatten()
feed_dict[self.model.prev_action] = np.array(
_buffer['prev_action'][start:end]).reshape([-1])
if self.use_states:
feed_dict[self.model.prev_action] = np.array(buffer['prev_action'][start:end]).flatten()
if self.use_vector_obs:
feed_dict[self.model.vector_in] = np.array(
_buffer['states'][start:end]).reshape(
[-1, self.brain.vector_observation_space_size * self.brain.num_stacked_vector_observations])
total_observation_length = self.brain.vector_observation_space_size * \
self.brain.num_stacked_vector_observations
feed_dict[self.model.vector_in] = np.array(buffer['vector_obs'][start:end]).reshape(
[-1, total_observation_length])
if self.use_curiosity:
feed_dict[self.model.next_vector_in] = np.array(buffer['next_vector_in'][start:end]) \
.reshape([-1, total_observation_length])
feed_dict[self.model.vector_in] = np.array(
_buffer['states'][start:end]).reshape([-1, self.brain.num_stacked_vector_observations])
if self.use_observations:
feed_dict[self.model.vector_in] = np.array(buffer['vector_obs'][start:end]).reshape(
[-1, self.brain.num_stacked_vector_observations])
if self.use_curiosity:
feed_dict[self.model.next_vector_in] = np.array(buffer['next_vector_in'][start:end]) \
.reshape([-1, self.brain.num_stacked_vector_observations])
if self.use_visual_obs:
_obs = np.array(_buffer['observations%d' % i][start:end])
(_batch, _seq, _w, _h, _c) = _obs.shape
feed_dict[self.model.visual_in[i]] = _obs.reshape([-1, _w, _h, _c])
_obs = np.array(buffer['visual_obs%d' % i][start:end])
if self.sequence_length > 1 and self.use_recurrent:
(_batch, _seq, _w, _h, _c) = _obs.shape
feed_dict[self.model.visual_in[i]] = _obs.reshape([-1, _w, _h, _c])
else:
feed_dict[self.model.visual_in[i]] = _obs
if self.use_curiosity:
for i, _ in enumerate(self.model.visual_in):
_obs = np.array(buffer['next_visual_obs%d' % i][start:end])
if self.sequence_length > 1 and self.use_recurrent:
(_batch, _seq, _w, _h, _c) = _obs.shape
feed_dict[self.model.next_visual_in[i]] = _obs.reshape([-1, _w, _h, _c])
else:
feed_dict[self.model.next_visual_in[i]] = _obs
feed_dict[self.model.memory_in] = np.array(_buffer['memory'][start:end])[:, 0, :]
v_loss, p_loss, _ = self.sess.run(
[self.model.value_loss, self.model.policy_loss,
self.model.update_batch], feed_dict=feed_dict)
total_v += v_loss
total_p += p_loss
self.stats['value_loss'].append(total_v)
self.stats['policy_loss'].append(total_p)
mem_in = np.array(buffer['memory'][start:end])[:, 0, :]
feed_dict[self.model.memory_in] = mem_in
run_list = [self.model.value_loss, self.model.policy_loss, self.model.update_batch]
if self.use_curiosity:
run_list.extend([self.model.forward_loss, self.model.inverse_loss])
values = self.sess.run(run_list, feed_dict=feed_dict)
self.has_updated = True
run_out = dict(zip(run_list, values))
value_total.append(run_out[self.model.value_loss])
policy_total.append(np.abs(run_out[self.model.policy_loss]))
if self.use_curiosity:
inverse_total.append(run_out[self.model.inverse_loss])
forward_total.append(run_out[self.model.forward_loss])
self.stats['value_loss'].append(np.mean(value_total))
self.stats['policy_loss'].append(np.mean(policy_total))
if self.use_curiosity:
self.stats['forward_loss'].append(np.mean(forward_total))
self.stats['inverse_loss'].append(np.mean(inverse_total))
def write_summary(self, lesson_number):
"""
Saves training statistics to Tensorboard.
:param lesson_number: The lesson the trainer is at.
"""
if (self.get_step % self.trainer_parameters['summary_freq'] == 0 and self.get_step != 0 and
self.is_training and self.get_step <= self.get_max_steps):
steps = self.get_step
if len(self.stats['cumulative_reward']) > 0:
mean_reward = np.mean(self.stats['cumulative_reward'])
logger.info(" {}: Step: {}. Mean Reward: {:0.3f}. Std of Reward: {:0.3f}."
.format(self.brain_name, steps, mean_reward, np.std(self.stats['cumulative_reward'])))
summary = tf.Summary()
for key in self.stats:
if len(self.stats[key]) > 0:
stat_mean = float(np.mean(self.stats[key]))
summary.value.add(tag='Info/{}'.format(key), simple_value=stat_mean)
self.stats[key] = []
summary.value.add(tag='Info/Lesson', simple_value=lesson_number)
self.summary_writer.add_summary(summary, steps)
self.summary_writer.flush()
def discount_rewards(r, gamma=0.99, value_next=0.0):

39
python/unitytrainers/trainer.py


import logging
import tensorflow as tf
import numpy as np
from unityagents import UnityException, AllBrainInfo

self.trainer_parameters = trainer_parameters
self.is_training = training
self.sess = sess
self.stats = {}
self.summary_writer = None
def __str__(self):
return '''Empty Trainer'''

"""
raise UnityTrainerException("The get_last_reward property was not implemented.")
def increment_step(self):
"""
Increment the step count of the trainer
"""
raise UnityTrainerException("The increment_step method was not implemented.")
def update_last_reward(self):
def increment_step_and_update_last_reward(self):
Updates the last reward
Increment the step count of the trainer and updates the last reward
raise UnityTrainerException("The update_last_reward method was not implemented.")
raise UnityTrainerException("The increment_step_and_update_last_reward method was not implemented.")
def take_action(self, all_brain_info: AllBrainInfo):
"""

Saves training statistics to Tensorboard.
:param lesson_number: The lesson the trainer is at.
"""
raise UnityTrainerException("The write_summary method was not implemented.")
if (self.get_step % self.trainer_parameters['summary_freq'] == 0 and self.get_step != 0 and
self.is_training and self.get_step <= self.get_max_steps):
if len(self.stats['cumulative_reward']) > 0:
mean_reward = np.mean(self.stats['cumulative_reward'])
logger.info(" {}: Step: {}. Mean Reward: {:0.3f}. Std of Reward: {:0.3f}."
.format(self.brain_name, self.get_step,
mean_reward, np.std(self.stats['cumulative_reward'])))
else:
logger.info(" {}: Step: {}. No episode was completed since last summary."
.format(self.brain_name, self.get_step))
summary = tf.Summary()
for key in self.stats:
if len(self.stats[key]) > 0:
stat_mean = float(np.mean(self.stats[key]))
summary.value.add(tag='Info/{}'.format(key), simple_value=stat_mean)
self.stats[key] = []
summary.value.add(tag='Info/Lesson', simple_value=lesson_number)
self.summary_writer.add_summary(summary, self.get_step)
self.summary_writer.flush()
def write_tensorboard_text(self, key, input_dict):
"""

:param input_dict: A dictionary that will be displayed in a table on Tensorboard.
"""
try:
s_op = tf.summary.text(key,
tf.convert_to_tensor(([[str(x), str(input_dict[x])] for x in input_dict]))
)
s_op = tf.summary.text(key, tf.convert_to_tensor(([[str(x), str(input_dict[x])] for x in input_dict])))
s = self.sess.run(s_op)
self.summary_writer.add_summary(s, self.get_step)
except:

45
python/unitytrainers/trainer_controller.py


class TrainerController(object):
def __init__(self, env_path, run_id, save_freq, curriculum_file, fast_simulation, load, train,
worker_id, keep_checkpoints, lesson, seed, docker_target_name, trainer_config_path):
worker_id, keep_checkpoints, lesson, seed, docker_target_name, trainer_config_path,
no_graphics):
:param env_path: Location to the environment executable to be loaded.
:param run_id: The sub-directory name for model and summary statistics
:param save_freq: Frequency at which to save model

:param seed: Random seed used for training.
:param docker_target_name: Name of docker volume that will contain all data.
:param trainer_config_path: Fully qualified path to location of trainer configuration file
:param no_graphics: Whether to run the Unity simulator in no-graphics mode
env_path = (env_path.strip()
.replace('.app', '')
.replace('.exe', '')
.replace('.x86_64', '')
.replace('.x86', '')) # Strip out executable extensions if passed
if env_path is not None:
env_path = (env_path.strip()
.replace('.app', '')
.replace('.exe', '')
.replace('.x86_64', '')
.replace('.x86', '')) # Strip out executable extensions if passed
# Recognize and use docker volume if one is passed as an argument
if docker_target_name == '':
self.docker_training = False

self.model_path = '/{docker_target_name}/models/{run_id}'.format(
docker_target_name=docker_target_name,
run_id=run_id)
env_path = '/{docker_target_name}/{env_name}'.format(docker_target_name=docker_target_name,
env_name=env_path)
if env_path is not None:
env_path = '/{docker_target_name}/{env_name}'.format(docker_target_name=docker_target_name,
env_name=env_path)
if curriculum_file is None:
self.curriculum_file = None
else:

tf.set_random_seed(self.seed)
self.env = UnityEnvironment(file_name=env_path, worker_id=self.worker_id,
curriculum=self.curriculum_file, seed=self.seed,
docker_training=self.docker_training)
self.env_name = os.path.basename(os.path.normpath(env_path)) # Extract out name of environment
docker_training=self.docker_training,
no_graphics=no_graphics)
if env_path is None:
self.env_name = 'editor_'+self.env.academy_name
else:
self.env_name = os.path.basename(os.path.normpath(env_path)) # Extract out name of environment
def _get_progress(self):
if self.curriculum_file is not None:

scopes += [scope]
if self.trainers[brain_name].parameters["trainer"] == "imitation":
nodes += [scope + x for x in ["action"]]
elif not self.trainers[brain_name].parameters["use_recurrent"]:
else:
else:
node_list = ["action", "value_estimate", "action_probs", "recurrent_out", "memory_size"]
nodes += [scope + x for x in node_list]
if self.trainers[brain_name].parameters["use_recurrent"]:
nodes += [scope + x for x in ["recurrent_out", "memory_size"]]
if len(scopes) > 1:
self.logger.info("List of available scopes :")
for scope in scopes:

take_action_outputs[brain_name]) = trainer.take_action(curr_info)
new_info = self.env.step(vector_action=take_action_vector, memory=take_action_memories,
text_action=take_action_text)
for brain_name, trainer in self.trainers.items():
trainer.add_experiences(curr_info, new_info, take_action_outputs[brain_name])
trainer.process_experiences(curr_info, new_info)

# Write training statistics to Tensorboard.
trainer.write_summary(self.env.curriculum.lesson_number)
if self.train_model and trainer.get_step <= trainer.get_max_steps:
trainer.increment_step()
trainer.update_last_reward()
if self.train_model and trainer.get_step <= trainer.get_max_steps:
trainer.increment_step_and_update_last_reward()
if self.train_model:
global_step += 1
if global_step % self.save_freq == 0 and global_step != 0 and self.train_model:
# Save Tensorflow model

if global_step != 0 and self.train_model:
self._save_model(sess, steps=global_step, saver=saver)
self._save_model(sess, steps=global_step, saver=saver)
print('--------------------------Now saving model-------------------------')
if self.train_model:
self.logger.info("Learning was interrupted. Please wait while the graph is generated.")
self._save_model(sess, steps=global_step, saver=saver)

130
unity-environment/Assets/ML-Agents/Editor/AgentEditor.cs


using UnityEngine;
using UnityEditor;
namespace MLAgents
{
[CustomEditor(typeof(Agent), true)]
[CanEditMultipleObjects]
public class AgentEditor : Editor
{
public override void OnInspectorGUI()
[CustomEditor(typeof(Agent), true)]
[CanEditMultipleObjects]
public class AgentEditor : Editor
SerializedObject serializedAgent = serializedObject;
serializedAgent.Update();
SerializedProperty brain = serializedAgent.FindProperty("brain");
SerializedProperty actionsPerDecision = serializedAgent.FindProperty(
"agentParameters.numberOfActionsBetweenDecisions");
SerializedProperty maxSteps = serializedAgent.FindProperty(
"agentParameters.maxStep");
SerializedProperty isResetOnDone = serializedAgent.FindProperty(
"agentParameters.resetOnDone");
SerializedProperty isODD = serializedAgent.FindProperty(
"agentParameters.onDemandDecision");
SerializedProperty cameras = serializedAgent.FindProperty(
"agentParameters.agentCameras");
public override void OnInspectorGUI()
{
SerializedObject serializedAgent = serializedObject;
serializedAgent.Update();
EditorGUILayout.PropertyField(brain);
SerializedProperty brain = serializedAgent.FindProperty("brain");
SerializedProperty actionsPerDecision = serializedAgent.FindProperty(
"agentParameters.numberOfActionsBetweenDecisions");
SerializedProperty maxSteps = serializedAgent.FindProperty(
"agentParameters.maxStep");
SerializedProperty isResetOnDone = serializedAgent.FindProperty(
"agentParameters.resetOnDone");
SerializedProperty isODD = serializedAgent.FindProperty(
"agentParameters.onDemandDecision");
SerializedProperty cameras = serializedAgent.FindProperty(
"agentParameters.agentCameras");
EditorGUILayout.LabelField("Agent Cameras");
for (int i = 0; i < cameras.arraySize; i++)
{
EditorGUILayout.PropertyField(
cameras.GetArrayElementAtIndex(i),
new GUIContent("Camera " + (i + 1).ToString() + ": "));
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add Camera", EditorStyles.miniButton))
{
cameras.arraySize++;
}
if (GUILayout.Button("Remove Camera", EditorStyles.miniButton))
{
cameras.arraySize--;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(brain);
EditorGUILayout.PropertyField(
maxSteps,
new GUIContent(
"Max Step", "The per-agent maximum number of steps."));
EditorGUILayout.PropertyField(
isResetOnDone,
new GUIContent(
"Reset On Done",
"If checked, the agent will reset on done. Else, AgentOnDone() will be called."));
EditorGUILayout.PropertyField(
isODD,
new GUIContent(
"On Demand Decisions",
"If checked, you must manually request decisions."));
if (!isODD.boolValue)
{
EditorGUILayout.LabelField("Agent Cameras");
for (int i = 0; i < cameras.arraySize; i++)
{
EditorGUILayout.PropertyField(
cameras.GetArrayElementAtIndex(i),
new GUIContent("Camera " + (i + 1).ToString() + ": "));
}
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add Camera", EditorStyles.miniButton))
{
cameras.arraySize++;
}
if (GUILayout.Button("Remove Camera", EditorStyles.miniButton))
{
cameras.arraySize--;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(
maxSteps,
new GUIContent(
"Max Step", "The per-agent maximum number of steps."));
EditorGUILayout.PropertyField(
isResetOnDone,
new GUIContent(
"Reset On Done",
"If checked, the agent will reset on done. Else, AgentOnDone() will be called."));
actionsPerDecision,
isODD,
"Decision Frequency",
"The agent will automatically request a decision every X" +
" steps and perform an action at every step."));
actionsPerDecision.intValue = Mathf.Max(1, actionsPerDecision.intValue);
}
"On Demand Decisions",
"If checked, you must manually request decisions."));
if (!isODD.boolValue)
{
EditorGUILayout.PropertyField(
actionsPerDecision,
new GUIContent(
"Decision Frequency",
"The agent will automatically request a decision every X" +
" steps and perform an action at every step."));
actionsPerDecision.intValue = Mathf.Max(1, actionsPerDecision.intValue);
}
serializedAgent.ApplyModifiedProperties();
serializedAgent.ApplyModifiedProperties();
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
base.OnInspectorGUI();
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
base.OnInspectorGUI();
}
}
}

159
unity-environment/Assets/ML-Agents/Editor/BrainEditor.cs


using UnityEditor;
using System.Linq;
namespace MLAgents
{
[CustomEditor (typeof(Brain))]
public class BrainEditor : Editor
{
[SerializeField]
bool _Foldout = true;
public override void OnInspectorGUI ()
[CustomEditor(typeof(Brain))]
public class BrainEditor : Editor
Brain myBrain = (Brain)target;
SerializedObject serializedBrain = serializedObject;
[SerializeField] bool _Foldout = true;
if (myBrain.transform.parent == null) {
EditorGUILayout.HelpBox ("A Brain GameObject must be a child of an Academy GameObject!", MessageType.Error);
} else if (myBrain.transform.parent.GetComponent<Academy> () == null) {
EditorGUILayout.HelpBox ("The Parent of a Brain must have an Academy Component attached to it!", MessageType.Error);
}
public override void OnInspectorGUI()
{
Brain myBrain = (Brain) target;
SerializedObject serializedBrain = serializedObject;
BrainParameters parameters = myBrain.brainParameters;
if (parameters.vectorActionDescriptions == null || parameters.vectorActionDescriptions.Length != parameters.vectorActionSize)
parameters.vectorActionDescriptions = new string[parameters.vectorActionSize];
serializedBrain.Update();
if (myBrain.transform.parent == null)
{
EditorGUILayout.HelpBox(
"A Brain GameObject must be a child of an Academy GameObject!",
MessageType.Error);
}
else if (myBrain.transform.parent.GetComponent<Academy>() == null)
{
EditorGUILayout.HelpBox(
"The Parent of a Brain must have an Academy Component attached to it!",
MessageType.Error);
}
_Foldout = EditorGUILayout.Foldout(_Foldout, "Brain Parameters");
int indentLevel = EditorGUI.indentLevel;
if (_Foldout)
{
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("Vector Observation");
EditorGUI.indentLevel++;
BrainParameters parameters = myBrain.brainParameters;
if (parameters.vectorActionDescriptions == null ||
parameters.vectorActionDescriptions.Length != parameters.vectorActionSize)
parameters.vectorActionDescriptions = new string[parameters.vectorActionSize];
SerializedProperty bpVectorObsType = serializedBrain.FindProperty("brainParameters.vectorObservationSpaceType");
EditorGUILayout.PropertyField(bpVectorObsType, new GUIContent("Space Type", "Corresponds to whether state " +
"vector contains a single integer (Discrete) " +
"or a series of real-valued floats (Continuous)."));
serializedBrain.Update();
_Foldout = EditorGUILayout.Foldout(_Foldout, "Brain Parameters");
int indentLevel = EditorGUI.indentLevel;
if (_Foldout)
{
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("Vector Observation");
EditorGUI.indentLevel++;
SerializedProperty bpVectorObsType =
serializedBrain.FindProperty("brainParameters.vectorObservationSpaceType");
EditorGUILayout.PropertyField(bpVectorObsType, new GUIContent("Space Type",
"Corresponds to whether state " +
"vector contains a single integer (Discrete) " +
"or a series of real-valued floats (Continuous)."));
SerializedProperty bpVectorObsSize =
serializedBrain.FindProperty("brainParameters.vectorObservationSize");
EditorGUILayout.PropertyField(bpVectorObsSize, new GUIContent("Space Size",
"Length of state " +
"vector for brain (In Continuous state space)." +
"Or number of possible values (in Discrete state space)."));
SerializedProperty bpVectorObsSize = serializedBrain.FindProperty("brainParameters.vectorObservationSize");
EditorGUILayout.PropertyField(bpVectorObsSize, new GUIContent("Space Size", "Length of state " +
"vector for brain (In Continuous state space)." +
"Or number of possible values (in Discrete state space)."));
SerializedProperty bpNumStackedVectorObs =
serializedBrain.FindProperty("brainParameters.numStackedVectorObservations");
EditorGUILayout.PropertyField(bpNumStackedVectorObs, new GUIContent(
"Stacked Vectors", "Number of states that" +
" will be stacked before beeing fed to the neural network."));
SerializedProperty bpNumStackedVectorObs = serializedBrain.FindProperty("brainParameters.numStackedVectorObservations");
EditorGUILayout.PropertyField(bpNumStackedVectorObs, new GUIContent("Stacked Vectors", "Number of states that" +
" will be stacked before beeing fed to the neural network."));
EditorGUI.indentLevel--;
SerializedProperty bpCamResol =
serializedBrain.FindProperty("brainParameters.cameraResolutions");
EditorGUILayout.PropertyField(bpCamResol, new GUIContent("Visual Observation",
"Describes height, " +
"width, and whether to greyscale visual observations for the Brain."), true);
EditorGUI.indentLevel--;
SerializedProperty bpCamResol = serializedBrain.FindProperty("brainParameters.cameraResolutions");
EditorGUILayout.PropertyField(bpCamResol, new GUIContent("Visual Observation", "Describes height, " +
"width, and whether to greyscale visual observations for the Brain."), true);
EditorGUILayout.LabelField("Vector Action");
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("Vector Action");
EditorGUI.indentLevel++;
SerializedProperty bpVectorActionType =
serializedBrain.FindProperty("brainParameters.vectorActionSpaceType");
EditorGUILayout.PropertyField(bpVectorActionType, new GUIContent("Space Type",
"Corresponds to whether state" +
" vector contains a single integer (Discrete) " +
"or a series of real-valued floats (Continuous)."));
SerializedProperty bpVectorActionType = serializedBrain.FindProperty("brainParameters.vectorActionSpaceType");
EditorGUILayout.PropertyField(bpVectorActionType, new GUIContent("Space Type", "Corresponds to whether state" +
" vector contains a single integer (Discrete) " +
"or a series of real-valued floats (Continuous)."));
SerializedProperty bpVectorActionSize =
serializedBrain.FindProperty("brainParameters.vectorActionSize");
EditorGUILayout.PropertyField(bpVectorActionSize, new GUIContent("Space Size",
"Length of action vector " +
"for brain (In Continuous state space)." +
"Or number of possible values (In Discrete action space)."));
SerializedProperty bpVectorActionSize = serializedBrain.FindProperty("brainParameters.vectorActionSize");
EditorGUILayout.PropertyField(bpVectorActionSize, new GUIContent("Space Size", "Length of action vector " +
"for brain (In Continuous state space)." +
"Or number of possible values (In Discrete action space)."));
SerializedProperty bpVectorActionDescription =
serializedBrain.FindProperty("brainParameters.vectorActionDescriptions");
EditorGUILayout.PropertyField(bpVectorActionDescription, new GUIContent(
"Action Descriptions", "A list of strings used to name" +
" the available actions for the Brain."), true);
SerializedProperty bpVectorActionDescription = serializedBrain.FindProperty("brainParameters.vectorActionDescriptions");
EditorGUILayout.PropertyField(bpVectorActionDescription, new GUIContent("Action Descriptions", "A list of strings used to name" +
" the available actions for the Brain."), true);
}
}
EditorGUI.indentLevel = indentLevel;
SerializedProperty bt = serializedBrain.FindProperty("brainType");
EditorGUILayout.PropertyField(bt);
EditorGUI.indentLevel = indentLevel;
SerializedProperty bt = serializedBrain.FindProperty("brainType");
EditorGUILayout.PropertyField(bt);
if (bt.enumValueIndex < 0) {
bt.enumValueIndex = (int)BrainType.Player;
}
if (bt.enumValueIndex < 0)
{
bt.enumValueIndex = (int) BrainType.Player;
}
serializedBrain.ApplyModifiedProperties();
serializedBrain.ApplyModifiedProperties();
myBrain.UpdateCoreBrains ();
myBrain.coreBrain.OnInspector ();
myBrain.UpdateCoreBrains();
myBrain.coreBrain.OnInspector();
#if !NET_4_6 && ENABLE_TENSORFLOW
#if !NET_4_6 && ENABLE_TENSORFLOW
}
}
}

2
unity-environment/Assets/ML-Agents/Editor/MLAgentsEditModeTest.cs


using NUnit.Framework;
using System.Reflection;
namespace MLAgentsTests
namespace MLAgents.Tests
{
public class TestAcademy : Academy
{

199
unity-environment/Assets/ML-Agents/Editor/ResetParameterDrawer.cs


using System.Linq;
using UnityEditor.SceneManagement;
[CustomPropertyDrawer(typeof(ResetParameters))]
public class ResetParameterDrawer : PropertyDrawer
namespace MLAgents
private ResetParameters _Dictionary;
private const float lineHeight = 17f;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
[CustomPropertyDrawer(typeof(ResetParameters))]
public class ResetParameterDrawer : PropertyDrawer
CheckInitialize(property, label);
return (_Dictionary.Count + 2) * lineHeight;
}
private ResetParameters _Dictionary;
private const float lineHeight = 17f;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
CheckInitialize(property, label);
position.height = lineHeight;
EditorGUI.LabelField(position, label);
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
CheckInitialize(property, label);
return (_Dictionary.Count + 2) * lineHeight;
}
EditorGUI.BeginProperty(position, label, property);
foreach (var item in _Dictionary)
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
var key = item.Key;
var value = item.Value;
position.y += lineHeight;
CheckInitialize(property, label);
position.height = lineHeight;
EditorGUI.LabelField(position, label);
// This is the rectangle for the key
var keyRect = position;
keyRect.x += 20;
keyRect.width /= 2;
keyRect.width -= 24;
EditorGUI.BeginChangeCheck();
var newKey = EditorGUI.TextField(keyRect, key);
if (EditorGUI.EndChangeCheck())
EditorGUI.BeginProperty(position, label, property);
foreach (var item in _Dictionary)
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
try
var key = item.Key;
var value = item.Value;
position.y += lineHeight;
// This is the rectangle for the key
var keyRect = position;
keyRect.x += 20;
keyRect.width /= 2;
keyRect.width -= 24;
EditorGUI.BeginChangeCheck();
var newKey = EditorGUI.TextField(keyRect, key);
if (EditorGUI.EndChangeCheck())
_Dictionary.Remove(key);
_Dictionary.Add(newKey, value);
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
try
{
_Dictionary.Remove(key);
_Dictionary.Add(newKey, value);
}
catch (Exception e)
{
Debug.Log(e.Message);
}
break;
catch (Exception e)
// This is the Rectangle for the value
var valueRect = position;
valueRect.x = position.width / 2 + 15;
valueRect.width = keyRect.width - 18;
EditorGUI.BeginChangeCheck();
value = EditorGUI.FloatField(valueRect, value);
if (EditorGUI.EndChangeCheck())
Debug.Log(e.Message);
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
_Dictionary[key] = value;
break;
break;
// This is the Rectangle for the value
var valueRect = position;
valueRect.x = position.width / 2 + 15;
valueRect.width = keyRect.width - 18;
EditorGUI.BeginChangeCheck();
value = EditorGUI.FloatField(valueRect, value);
if (EditorGUI.EndChangeCheck())
// This is the rectangle for the Add button
position.y += lineHeight;
var AddButtonRect = position;
AddButtonRect.x += 20;
AddButtonRect.width /= 2;
AddButtonRect.width -= 24;
if (GUI.Button(AddButtonRect, new GUIContent("Add New",
"Add a new item to the default reset paramters"), EditorStyles.miniButton))
_Dictionary[key] = value;
break;
AddNewItem();
}
// This is the rectangle for the Add button
position.y += lineHeight;
var AddButtonRect = position;
AddButtonRect.x += 20;
AddButtonRect.width /= 2;
AddButtonRect.width -= 24;
if (GUI.Button(AddButtonRect, new GUIContent("Add New",
"Add a new item to the default reset paramters"), EditorStyles.miniButton))
{
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
AddNewItem();
}
// This is the rectangle for the Remove button
var RemoveButtonRect = position;
RemoveButtonRect.x = position.width / 2 + 15;
RemoveButtonRect.width = AddButtonRect.width - 18;
if (GUI.Button(RemoveButtonRect, new GUIContent("Remove Last",
"Remove the last item to the default reset paramters"), EditorStyles.miniButton))
{
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
RemoveLastItem();
}
// This is the rectangle for the Remove button
var RemoveButtonRect = position;
RemoveButtonRect.x = position.width / 2 + 15;
RemoveButtonRect.width = AddButtonRect.width - 18;
if (GUI.Button(RemoveButtonRect, new GUIContent("Remove Last",
"Remove the last item to the default reset paramters"), EditorStyles.miniButton))
{
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
RemoveLastItem();
}
EditorGUI.EndProperty();
EditorGUI.EndProperty();
}
}
private void CheckInitialize(SerializedProperty property, GUIContent label)
{
if (_Dictionary == null)
private void CheckInitialize(SerializedProperty property, GUIContent label)
var target = property.serializedObject.targetObject;
_Dictionary = fieldInfo.GetValue(target) as ResetParameters;
_Dictionary = new ResetParameters();
fieldInfo.SetValue(target, _Dictionary);
var target = property.serializedObject.targetObject;
_Dictionary = fieldInfo.GetValue(target) as ResetParameters;
if (_Dictionary == null)
{
_Dictionary = new ResetParameters();
fieldInfo.SetValue(target, _Dictionary);
}
}
private void ClearResetParamters()
{
_Dictionary.Clear();
}
private void RemoveLastItem()
{
if (_Dictionary.Count > 0)
private void ClearResetParamters()
string key = _Dictionary.Keys.ToList()[_Dictionary.Count - 1];
_Dictionary.Remove(key);
_Dictionary.Clear();
}
private void AddNewItem()
{
string key = "Param-" + _Dictionary.Count.ToString();
var value = default(float);
try
private void RemoveLastItem()
_Dictionary.Add(key, value);
if (_Dictionary.Count > 0)
{
string key = _Dictionary.Keys.ToList()[_Dictionary.Count - 1];
_Dictionary.Remove(key);
}
catch (Exception e)
private void AddNewItem()
Debug.Log(e.Message);
string key = "Param-" + _Dictionary.Count.ToString();
var value = default(float);
try
{
_Dictionary.Add(key, value);
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
}

3
unity-environment/Assets/ML-Agents/Examples.meta


fileFormatVersion: 2
guid: 6584f096f53dc43eeb32803b91f36c5c
folderAsset: yes
timeCreated: 1504127503
licenseType: Pro
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

1
unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAcademy.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class Ball3DAcademy : Academy
{

42
unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DAgent.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
private Rigidbody ballRb;
ballRb = ball.GetComponent<Rigidbody>();
}
public override void CollectObservations()

AddVectorObs((ball.transform.position - gameObject.transform.position));
AddVectorObs(ball.transform.GetComponent<Rigidbody>().velocity);
SetTextObs("Testing " + gameObject.GetInstanceID());
AddVectorObs(ball.transform.position - gameObject.transform.position);
AddVectorObs(ballRb.velocity);
float action_z = 2f * Mathf.Clamp(vectorAction[0], -1f, 1f);
if ((gameObject.transform.rotation.z < 0.25f && action_z > 0f) ||
(gameObject.transform.rotation.z > -0.25f && action_z < 0f))
var actionZ = 2f * Mathf.Clamp(vectorAction[0], -1f, 1f);
var actionX = 2f * Mathf.Clamp(vectorAction[1], -1f, 1f);
if ((gameObject.transform.rotation.z < 0.25f && actionZ > 0f) ||
(gameObject.transform.rotation.z > -0.25f && actionZ < 0f))
gameObject.transform.Rotate(new Vector3(0, 0, 1), action_z);
gameObject.transform.Rotate(new Vector3(0, 0, 1), actionZ);
float action_x = 2f * Mathf.Clamp(vectorAction[1], -1f, 1f);
if ((gameObject.transform.rotation.x < 0.25f && action_x > 0f) ||
(gameObject.transform.rotation.x > -0.25f && action_x < 0f))
if ((gameObject.transform.rotation.x < 0.25f && actionX > 0f) ||
(gameObject.transform.rotation.x > -0.25f && actionX < 0f))
gameObject.transform.Rotate(new Vector3(1, 0, 0), action_x);
gameObject.transform.Rotate(new Vector3(1, 0, 0), actionX);
SetReward(0.1f);
}
if ((ball.transform.position.y - gameObject.transform.position.y) < -2f ||
Mathf.Abs(ball.transform.position.x - gameObject.transform.position.x) > 3f ||

SetReward(-1f);
}
else
{
SetReward(0.1f);
}
}
public override void AgentReset()

gameObject.transform.Rotate(new Vector3(0, 0, 1), Random.Range(-10f, 10f));
ball.GetComponent<Rigidbody>().velocity = new Vector3(0f, 0f, 0f);
ball.transform.position = new Vector3(Random.Range(-1.5f, 1.5f), 4f, Random.Range(-1.5f, 1.5f)) + gameObject.transform.position;
ballRb.velocity = new Vector3(0f, 0f, 0f);
ball.transform.position = new Vector3(Random.Range(-1.5f, 1.5f), 4f, Random.Range(-1.5f, 1.5f))
+ gameObject.transform.position;
}

1
unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DDecision.cs


using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class Ball3DDecision : MonoBehaviour, Decision
{

42
unity-environment/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DHardAgent.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
private Rigidbody ballRb;
public override void InitializeAgent()
{
ballRb = ball.GetComponent<Rigidbody>();
}
public override void CollectObservations()
{

public override void AgentAction(float[] vectorAction, string textAction)
{
float action_z = 2f * Mathf.Clamp(vectorAction[0], -1f, 1f);
if ((gameObject.transform.rotation.z < 0.25f && action_z > 0f) ||
(gameObject.transform.rotation.z > -0.25f && action_z < 0f))
{
gameObject.transform.Rotate(new Vector3(0, 0, 1), action_z);
}
float action_x = 2f * Mathf.Clamp(vectorAction[1], -1f, 1f);
if ((gameObject.transform.rotation.x < 0.25f && action_x > 0f) ||
(gameObject.transform.rotation.x > -0.25f && action_x < 0f))
var actionZ = 2f * Mathf.Clamp(vectorAction[0], -1f, 1f);
var actionX = 2f * Mathf.Clamp(vectorAction[1], -1f, 1f);
if ((gameObject.transform.rotation.z < 0.25f && actionZ > 0f) ||
(gameObject.transform.rotation.z > -0.25f && actionZ < 0f))
gameObject.transform.Rotate(new Vector3(1, 0, 0), action_x);
gameObject.transform.Rotate(new Vector3(0, 0, 1), actionZ);
if (!IsDone())
if ((gameObject.transform.rotation.x < 0.25f && actionX > 0f) ||
(gameObject.transform.rotation.x > -0.25f && actionX < 0f))
SetReward( 0.1f);
gameObject.transform.Rotate(new Vector3(1, 0, 0), actionX);
}
}
if ((ball.transform.position.y - gameObject.transform.position.y) < -2f ||

Done();
SetReward(-1f);
}
else
{
SetReward(0.1f);
}
}
public override void AgentReset()

gameObject.transform.Rotate(new Vector3(0, 0, 1), Random.Range(-10f, 10f));
ball.GetComponent<Rigidbody>().velocity = new Vector3(0f, 0f, 0f);
ball.transform.position = new Vector3(Random.Range(-1.5f, 1.5f), 4f, Random.Range(-1.5f, 1.5f)) + gameObject.transform.position;
ballRb.velocity = new Vector3(0f, 0f, 0f);
ball.transform.position = new Vector3(Random.Range(-1.5f, 1.5f), 4f, Random.Range(-1.5f, 1.5f))
+ gameObject.transform.position;
}

955
unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBall.bytes
文件差异内容过多而无法显示
查看文件

2
unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBall.bytes.meta


fileFormatVersion: 2
guid: e91b53b17600f4c23a270f97bad1e60d
guid: 93f91f35982184949a09d9ce97965cd5
TextScriptImporter:
externalObjects: {}
userData:

959
unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBallHard.bytes
文件差异内容过多而无法显示
查看文件

2
unity-environment/Assets/ML-Agents/Examples/3DBall/TFModels/3DBallHard.bytes.meta


fileFormatVersion: 2
guid: 0e03e86d2b6f24436a00cad74dcd5d5f
guid: 477e2fb07d79544e48897e8ba162a74f
TextScriptImporter:
externalObjects: {}
userData:

10
unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Prefabs/RLArea.prefab


normalMaterial: {fileID: 2100000, guid: 260483cdfc6b14e26823a02f23bd8baa, type: 2}
badMaterial: {fileID: 2100000, guid: 882d882b99bce44c6863ec8d3760e9ca, type: 2}
goodMaterial: {fileID: 2100000, guid: 80ffa2c5b96364e4b80fbb2e42b0af3d, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 1
--- !u!114 &114319858423652580
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 260483cdfc6b14e26823a02f23bd8baa, type: 2}
badMaterial: {fileID: 2100000, guid: 882d882b99bce44c6863ec8d3760e9ca, type: 2}
goodMaterial: {fileID: 2100000, guid: 80ffa2c5b96364e4b80fbb2e42b0af3d, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 1
--- !u!114 &114816434626527468
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 260483cdfc6b14e26823a02f23bd8baa, type: 2}
badMaterial: {fileID: 2100000, guid: 882d882b99bce44c6863ec8d3760e9ca, type: 2}
goodMaterial: {fileID: 2100000, guid: 80ffa2c5b96364e4b80fbb2e42b0af3d, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 1
--- !u!114 &114846764322938622
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 260483cdfc6b14e26823a02f23bd8baa, type: 2}
badMaterial: {fileID: 2100000, guid: 882d882b99bce44c6863ec8d3760e9ca, type: 2}
goodMaterial: {fileID: 2100000, guid: 80ffa2c5b96364e4b80fbb2e42b0af3d, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 1
--- !u!114 &114875485509234200
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 260483cdfc6b14e26823a02f23bd8baa, type: 2}
badMaterial: {fileID: 2100000, guid: 882d882b99bce44c6863ec8d3760e9ca, type: 2}
goodMaterial: {fileID: 2100000, guid: 80ffa2c5b96364e4b80fbb2e42b0af3d, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 1

63
unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Prefabs/TeachingArea.prefab


m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 88b9ae7af2c1748a0a1f63407587a601, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 88b9ae7af2c1748a0a1f63407587a601, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: ea4e6e61f90ae46daaf643b945c080ed, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 88b9ae7af2c1748a0a1f63407587a601, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 88b9ae7af2c1748a0a1f63407587a601, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 262d8cbc02b104990841408098431457, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 88b9ae7af2c1748a0a1f63407587a601, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 9efa4522ab2a04af4bdbcf95ddef5711, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
m_StaticBatchInfo:

normalMaterial: {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
badMaterial: {fileID: 2100000, guid: 0483e5b320b23418b8318497c636bf8e, type: 2}
goodMaterial: {fileID: 2100000, guid: 624b24bbec31f44babfb57ef2dfbc537, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 0
--- !u!114 &114038595653051694
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
badMaterial: {fileID: 2100000, guid: 0483e5b320b23418b8318497c636bf8e, type: 2}
goodMaterial: {fileID: 2100000, guid: 624b24bbec31f44babfb57ef2dfbc537, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 0
--- !u!114 &114142328162608466
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
badMaterial: {fileID: 2100000, guid: 0483e5b320b23418b8318497c636bf8e, type: 2}
goodMaterial: {fileID: 2100000, guid: 624b24bbec31f44babfb57ef2dfbc537, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 0
--- !u!114 &114217618254455056
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
badMaterial: {fileID: 2100000, guid: 0483e5b320b23418b8318497c636bf8e, type: 2}
goodMaterial: {fileID: 2100000, guid: 624b24bbec31f44babfb57ef2dfbc537, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 0
--- !u!114 &114983848801657944
MonoBehaviour:
m_ObjectHideFlags: 1

normalMaterial: {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
badMaterial: {fileID: 2100000, guid: 0483e5b320b23418b8318497c636bf8e, type: 2}
goodMaterial: {fileID: 2100000, guid: 624b24bbec31f44babfb57ef2dfbc537, type: 2}
frozenMaterial: {fileID: 2100000, guid: 866f7a84824d141dbbe50dd1893207d9, type: 2}
useVectorObs: 0
--- !u!136 &136272331299970796
CapsuleCollider:
m_ObjectHideFlags: 1

1
unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaAcademy.cs


using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using MLAgents;
public class BananaAcademy : Academy
{

65
unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaAgent.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class BananaAgent : Agent
{

bool shoot;
float frozenTime;
float effectTime;
Rigidbody agentRB;
Rigidbody agentRb;
private int bananas;
// Speed of agent rotation.
public float turnSpeed = 300;

public Material normalMaterial;
public Material badMaterial;
public Material goodMaterial;
int bananas;
public Material frozenMaterial;
RayPerception rayPer;
private RayPerception rayPer;
public bool useVectorObs;
agentRB = GetComponent<Rigidbody>();
agentRb = GetComponent<Rigidbody>();
Monitor.verticalOffset = 1f;
myArea = area.GetComponent<BananaArea>();
rayPer = GetComponent<RayPerception>();

public override void CollectObservations()
{
float rayDistance = 50f;
float[] rayAngles = { 20f, 90f, 160f, 45f, 135f, 70f, 110f };
string[] detectableObjects = { "banana", "agent", "wall", "badBanana", "frozenAgent" };
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 0f, 0f));
Vector3 localVelocity = transform.InverseTransformDirection(agentRB.velocity);
AddVectorObs(localVelocity.x);
AddVectorObs(localVelocity.z);
AddVectorObs(System.Convert.ToInt32(frozen));
AddVectorObs(System.Convert.ToInt32(shoot));
if (useVectorObs)
{
float rayDistance = 50f;
float[] rayAngles = { 20f, 90f, 160f, 45f, 135f, 70f, 110f };
string[] detectableObjects = { "banana", "agent", "wall", "badBanana", "frozenAgent" };
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 0f, 0f));
Vector3 localVelocity = transform.InverseTransformDirection(agentRb.velocity);
AddVectorObs(localVelocity.x);
AddVectorObs(localVelocity.z);
AddVectorObs(System.Convert.ToInt32(frozen));
AddVectorObs(System.Convert.ToInt32(shoot));
}
public Color32 ToColor(int HexVal)
public Color32 ToColor(int hexVal)
byte R = (byte)((HexVal >> 16) & 0xFF);
byte G = (byte)((HexVal >> 8) & 0xFF);
byte B = (byte)((HexVal) & 0xFF);
return new Color32(R, G, B, 255);
byte r = (byte)((hexVal >> 16) & 0xFF);
byte g = (byte)((hexVal >> 8) & 0xFF);
byte b = (byte)(hexVal & 0xFF);
return new Color32(r, g, b, 255);
}
public void MoveAgent(float[] act)

Vector3 dirToGo = Vector3.zero;
Vector3 rotateDir = Vector3.zero;
if (!frozen)
{
bool shootCommand = false;

rotateDir = transform.up * Mathf.Clamp(act[1], -1f, 1f);
shootCommand = Mathf.Clamp(act[2], 0f, 1f) > 0.5f;
shootCommand = Mathf.Clamp(act[2], -1f, 1f) > 0.5f;
switch ((int)(act[0]))
switch ((int)act[0])
{
case 1:
dirToGo = transform.forward;

{
shoot = true;
dirToGo *= 0.5f;
agentRB.velocity *= 0.75f;
agentRb.velocity *= 0.75f;
agentRB.AddForce(dirToGo * moveSpeed, ForceMode.VelocityChange);
agentRb.AddForce(dirToGo * moveSpeed, ForceMode.VelocityChange);
if (agentRB.velocity.sqrMagnitude > 25f) // slow it down
if (agentRb.velocity.sqrMagnitude > 25f) // slow it down
agentRB.velocity *= 0.95f;
agentRb.velocity *= 0.95f;
}
if (shoot)

RaycastHit hit;
if (Physics.SphereCast(transform.position, 2f, position, out hit, 25f))
{
if (hit.collider.gameObject.tag == "agent")
if (hit.collider.gameObject.CompareTag("agent"))
{
hit.collider.gameObject.GetComponent<BananaAgent>().Freeze();
}

gameObject.tag = "frozenAgent";
frozen = true;
frozenTime = Time.time;
gameObject.GetComponent<Renderer>().material.color = Color.black;
gameObject.GetComponent<Renderer>().material = frozenMaterial;
}

Unpoison();
Unsatiate();
shoot = false;
agentRB.velocity = Vector3.zero;
agentRb.velocity = Vector3.zero;
bananas = 0;
myLaser.transform.localScale = new Vector3(0f, 0f, 0f);
transform.position = new Vector3(Random.Range(-myArea.range, myArea.range),

{
myAcademy.totalScore -= 1;
}
}
if (collision.gameObject.CompareTag("wall"))
{
Done();
}
}

1
unity-environment/Assets/ML-Agents/Examples/BananaCollectors/Scripts/BananaArea.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class BananaArea : Area
{

986
unity-environment/Assets/ML-Agents/Examples/BananaCollectors/TFModels/Banana.bytes
文件差异内容过多而无法显示
查看文件

1
unity-environment/Assets/ML-Agents/Examples/Basic/Scripts/BasicAcademy.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class BasicAcademy : Academy {

18
unity-environment/Assets/ML-Agents/Examples/Basic/Scripts/BasicAgent.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class BasicAgent : Agent
{

public override void AgentAction(float[] vectorAction, string textAction)
{
float movement = vectorAction[0];
var movement = (int)vectorAction[0];
if (movement == 0) { direction = -1; }
if (movement == 1) { direction = 1; }
switch (movement)
{
case 0:
direction = -1;
break;
case 1:
direction = 1;
break;
}
position += direction;
position += direction;
if (position < minPosition) { position = minPosition; }
if (position > maxPosition) { position = maxPosition; }

1
unity-environment/Assets/ML-Agents/Examples/Basic/Scripts/BasicDecision.cs


using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class BasicDecision : MonoBehaviour, Decision
{

1
unity-environment/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAcademy.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class BouncerAcademy : Academy {

42
unity-environment/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerAgent.cs


using System.Collections;
using System.Collections;
using MLAgents;
public class BouncerAgent : Agent {

Rigidbody rb;
Vector3 lookDir;
public float strength = 10f;
float jumpCooldown = 0f;
float jumpCooldown;
int numberJumps = 20;
int jumpLeft = 20;

public override void AgentAction(float[] vectorAction, string textAction)
{
float x = Mathf.Clamp(vectorAction[0], -1, 1);
float y = Mathf.Clamp(vectorAction[1], 0, 1);
float z = Mathf.Clamp(vectorAction[2], -1, 1);
rb.AddForce( new Vector3(x, y+1, z) *strength);
for (int i = 0; i < vectorAction.Length; i++)
{
vectorAction[i] = Mathf.Clamp(vectorAction[i], -1f, 1f);
}
float x = vectorAction[0];
float y = ScaleAction(vectorAction[1], 0, 1);
float z = vectorAction[2];
rb.AddForce( new Vector3(x, y+1, z) * strength);
AddReward(-0.05f * (
vectorAction[0] * vectorAction[0] +

private void FixedUpdate()
{
if ((Physics.Raycast(transform.position, new Vector3(0f,-1f,0f), 0.51f))
&& jumpCooldown <= 0f)
if (Physics.Raycast(transform.position, new Vector3(0f,-1f,0f), 0.51f) && jumpCooldown <= 0f)
{
RequestDecision();
jumpLeft -= 1;

if (gameObject.transform.position.y < -1)
{
AddReward(-1);

if ((gameObject.transform.localPosition.x < -19)
||(gameObject.transform.localPosition.x >19)
|| (gameObject.transform.localPosition.z < -19)
|| (gameObject.transform.localPosition.z > 19)
)
if (gameObject.transform.localPosition.x < -19 || gameObject.transform.localPosition.x >19
|| gameObject.transform.localPosition.z < -19 || gameObject.transform.localPosition.z > 19)
{
AddReward(-1);
Done();

Done();
}
bodyObject.transform.rotation = Quaternion.Lerp(bodyObject.transform.rotation,
Quaternion.LookRotation(lookDir),
Time.fixedDeltaTime * 10f);
}
private void Update()
{
if (lookDir.magnitude > float.Epsilon)
{
bodyObject.transform.rotation = Quaternion.Lerp(bodyObject.transform.rotation,
Quaternion.LookRotation(lookDir),
Time.deltaTime * 10f);
}
}
}

14
unity-environment/Assets/ML-Agents/Examples/Bouncer/Scripts/BouncerBanana.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
void Start(){
}
// Update is called once per frame
void FixedUpdate () {
gameObject.transform.Rotate(new Vector3(1, 0, 0), 0.5f);

{
Agent agent = collision.gameObject.GetComponent<Agent>();
if (agent != null)
{

(1 - 2 * Random.value) *5f,
2f+(Random.value) *5f,
(1 - 2 * Random.value) *5f);
(1 - 2 * Random.value) * 5f,
2f+ Random.value * 5f,
(1 - 2 * Random.value) * 5f);
}
}

340
unity-environment/Assets/ML-Agents/Examples/Bouncer/TFModels/Bouncer.bytes


7
global_stepConst*
dtype0*
value B :��
value B :��
R
global_step/readIdentity global_step*
T0*

�
running_meanConst*
dtype0*]
valueTBR"H��Y=A f? BB=�f�� }@��I<��q=T�z?��D=�$��6ڊ@��7<iπ=�l�?jN=��
��)�@�sX<
valueTBR"H��`�?�n�=�y�<,�@W_'��~����?=:�=�o�<��@s&C��÷��|�?�G�=?��<��@�L�
U
running_mean/readIdentity running_mean*
T0*

running_varianceConst*
dtype0*]
valueTBR"Hb��K�K�HUD�K8�TJ��J��VJO��Kx`�H-�K�6iJe�IpkJM��KꛒH�KZ�~J
�hI3t�J
valueTBR"Hq�9K�.I�(8K��6J��I�W7J��GKKeI�QFK��BJ i�I�BJ�XK!ISCVKNJ�XOI�QNJ
a
running_variance/readIdentityrunning_variance*
T0*#

dense/kernelConst*
dtype0*�
value�B�8"����<���ty>���2�M=f3H�̗@��FN>
K�>�.{>i�N>D��>[Z���v�=��=��%���Ծ�����݅�6�>6��=TM�=�7O>ӡ3����=�A4>��>��$>� ��Y�Ux+>��_���>�2�=`
5��a��F�>0y�='u�;�$<_��;�r,>v �u��������1=����>3�O>O )�9�p>�`>;�+>��.�Q�}����=e�2Ƌ>F����?�>�i>;�ɽ��>u�l�4}�>��D<�NB��q�=M���������WE��Ⱥ�=������>�@���D>\��>�[�;�Ǩ�nl"<�`��\����ڽ��Ծyvļ3Fv>�$���E�=�����:;-�v>2� >��'���f>�$b������|�l�x>�Nݾ��#�8��>��d�<6�D����&�==6 �q�4���F>0w>j��HI�=�6O=>3>ˠ;;��=lͪ�c����R���y�;f�_>�Բ>� :>}�>|�#>)6潙:�=�㨾Ů��A>(Oc=Ե�r�돼>^K >K�/�5꡾�Eq=����;>O��>C�>�+>�跽��'����= �y=�6�>��4>�?��>KC=,
��ǃ�>��1=~z�=��W���Ǿ敭>.٪>�/��P��=3q+>K��=���>�Yþ�>�>���> ����3��;�u�=�1I�h��<��>�w�=�/s>xt�)�j�T��>��,>��=;վ��ͼ\'�=u��<d3>
r̽����/+�>
r*=}��bi��#Ѿp�=��n�I�>�A��{W��b����aZ�<�w�>rґ>���G>ư�@�mz>ou(�l�־" Ҽ�<Ͼ8���x��>ytn�����ޕ<%�>�Y�<疠>��K��K&��Y>�ھـ�=���=\�i��ڵ�)\�=/���Rh�)�A>�r����>Kŧ��K��[�>�X`>�#>x�>q��>�y�<�m=��=�7��Sq?>0!�=�r�%H��ym�L���w$>��u=�{þd�=� &>1v�= �ڽP�B�*l>��}�*p�>��=��-�sS�>�2:�{�]>���WD��m��<a��>��T��4���e���5����VE�=ύ��V��=:܃�d�(<Y;�>��>�׹>H�Ž�]��1 b���0>+�W�گ��D��=&�ҽI��>Vf�>�VC>�"O����>� >��׽㫽�E���]�=I�|�vL�>��%��<N���i�>�o�>�A�=��w��ٯ<]��=��˾͐��h�=
lD>���=Hm[�����J��>a�>�����J>�A�>�F���p�>7��~�m<�Ҳ��KS�w��=�W��`��=���=�����/�=�Ͻw� ==��/�<����> 8�/{�>r�\>���ԭ�E`��|׍�68f�a�Ľ( I�3�=o�����=c)~>/���?��=�φ=D�a��v%��H��lp��'���'> =���Τ� κ���b>��>�2)>Po��ٖ��m8��^���<�>"c����Ͼ�׭=�����k�z6G��H���a>BI�=�3��~J>7`�=�q�=�F'>�˂>#Y�<Xw�=q�ھ���=�?�����=�t=*�>�"6=ll��I¾�>=S�ýjɮ��#��j����>+�\�A7�>��R�J��>����O�f9���q�>�$��1f>L�4=�˾���a���\Ab>��:�b���2�k�����v�������E�>��F<WgU>��>9���y��>�R�=�U >m�>J5v��h���>"���Ӎ=���>�������*˜��>�=�c&�i1ȽI�#�y-�=%>~�o�zY���J�>E�3��~S��b�>0颾iz��Kz��g<(�i����= ��=���\�c>`x=�ǩ>���>l�F�Zrh�a�>!l>���=Sh��D;ӨI>C������3�i>��=�Oƽ�!S�84=�R�>n9�>�Hɼ|&�����<���OĽ��'>�d>vx�Ljb>�� >���=�=�g�׾��Ҿ��P��_��!����->�ɼi�= U>>���=|� �lVl�j�%>�2C>�#e���e<7Lw����=�T��6�>qF��ГY��w����>G��>rU�;2v���_�>].�>p�< �Ƚ�Mܼ ٽ^C=�(�=G�=M�ξW��`h�=wy�>{x½$�f��+�+�����>a���743>�B����=3Š=I��<�c �I���5 �>��>��U�����A�>�4��4b��׳<S�> ���#@��s�V�=:�>=�)<������%>�ǧ����� c}>�н>��i�Y��>�V ? �~�5����|:>f���T�=�8H>L��>��>�ؕ�q��_�ٽ��>.��=Ks�>��<l������=U="�Q=k#�<� м���>Q�;=�J@=�J>� .>�I<U����)=� ˾��ȽL�����>�u��=�f�ЀN>�2ľ�ʫ>f��#=ȿ���#=�Z >���=ZO�=.���% �=c
ξ K�=�K����>�$3=cqT�$)>�be>7ʰ��������W潫��>Jc:>��־����wF>7�=��>�ð�ה��'>_�/�өu>m<s=�ٓ=�i��D��>�CB��I��8�t>� ���I�>��>$�5�Cґ>o��>��>0��<�➾�j�
<���
�|H���#/��s�]��0�����J��u�<=�k�>��C>� ?B�h>._�>�3��\K�|�>� վ��7=h������>�t��G�>(���ɂ��?�Z[>Pt���格^��=����z�����Fv>N�����?ؽ�>)��>8z�>��c�?[�>ZKk��VF���?�QϾ\+�>�6}>��˼(7��/��y����>T�,?���>௴����>�ü�(Ͼ]��=�ʃ>����ي>���\�a=��>��="L��87y�Й=L�>/t��_���x��r�%>}�ʾ�捾U�H=���������ҽ��qL��ݎỞ����+i>�~�>^� >zڒ< �>��>͔��20%9y�>D�;<==��̾�\ݾB��=E��>T�о^�0�gkG>��>���5�3� Ui�F��$Yg>v`�tǾV�h� �ּ]����+��TU>opR��ܾ> ����` ��[��ݍ�q���s��<�"?�m���)?QJ�.� ?WK@��!���MɾR�b��˾�q��&�� F4�c�>G���V�=����i�>��*=� �>\��v��>�h>ֲ>������>>���D�)����>6�`=�c4�Dk
?X*� ;��@�����>���荾Lj��~�>Y��,�T>=��>�"P>�ü6*>=�ھ��;>rP>D~0=���G��=s���������*C�=��4���־r۞=���
����Y>�D�=�
�=�6\>�>��>qh=p�o>t[>�<>�;v>��T>L)N��ā=��P>=��=m̩>�D˾�t�=��о8��=�d�=/tT�!�>Ed<��m콿$>�a��h>p�=�B/� t�>��0�)��=1��=Ǿ�Yg��_�E���>{%<��m�Rg >���=k>5?l<�=WF.=����M2Z�&}7>u��>C9�=wB�=.��<r���������s�y S��읽�a>����1c��o3>3>q��=�<�>̘����?7?iǶ>���=!$ýB�O>�a��0p���v��O����*�t�_�%�}< �>��T>��8>�G>j�>,������=D��Gex>�z�<؈�> ��� {a>m7ݾ򛾢ƒ>+H�%T�>��ž~���'�����>��R>�G��_$�"��=3a��k�E��3��mF⾧�=?�%��4�> �2�������>�����һ>� @����KD>YH>���=/���j>�(�=X �=�9=��N:>ȁ">���)ܢ��E����>῭=_�<e$��^�= ���wq>�]Լ�T�>�2?��5 =?��=�-�# <��>Cy�����m��<vv>�EC��,�>Q�ƾ�w��I�=
value�B�8"��I�B8G�!O� �Ϸ^>�F��u�>|�F��L�=F+˾��
>r�Ž� *�?��>�1�y&�C�v�'���d��2�\�lPD�������>֤��L?����O�>��=A�[����=HU�=�>;��<3!�;�~N��
>���=�i����>\퐾��=�T�>4�y> �=K� >�#�=��>>Wʽ| ܾ;�U>�·=��c���x>;=X�ֽΖ�=[�V�l@�=�a�UL �� ����ٽ�W8�����[�������r?>��=��)k��ſF>���*|l=���=N��8B># k>E�>�ؒ��!�<J |�_��;�׼d¾.F����=5��Rj�=.��>�Q<>������N��>��k>�Z޽����{8>X�f>�ג����<�����F�<��R���=� �=�.�)o>���Y�N)9�e1>�;�t�G=N.W���ƾߒ>J]��)����?>
��Q"����>BG�n�[>��=��}�{��>�h½X%�`$�>
ŽD���R >�J�<�ք�@;�>S�a��$< @�9���=t��������>Ӈ_>�1\;�%F��>*��>��>J �f��>2â�t��&� >�H7=K���/ޱ=�C�=�q�>���>�U&�Y1�>���9�v�����'�&>#b>�s�=I|=>���=64��:�n�`?�͙>3K�����=��v>���>�{>>0�>&?"=��=���>J4��.+��߽h�=��;v@��'�>l��> ��$�8>G�V>9#>�z�>�x&>�-6>Pύ> κ=_�?�)j>{��=0 Ľ]�=��¾E�����<��P=2�<��>U�>�ѽw
ʽ ��= �R>�۳=v.��<jq�-�=�%D���Q�2̟>?`�r� >ox�>^J�=�p���>��2>��>&U>k^*>������>���> �=�N<�4$�>�*ٽ����ڱ���]>��>�������=x����Ț>+bӽ}g�=��̾"�s>�6�=5�
>��7=&S
��K*<�ѧ;a<*b!��n�<J
��`�h=t�k��U0���=>��;>�D�=��ͽC�Y�S^�1��=�F�JGݾ��5>�9Ƚ���w�w>� >���?d���>����>|�+�<����;�^��
E�����4����;UO1�:��=Ӱ��3�󾏉E���ҽ�򲾲4���i�+6�>ͦ=����+m��^��[,5=pB>N����#>9��>M��=�����:=�7I=;�>"��!�;-�L>[��n��=ރþŲ>���>C.��S�����3>+��=�s&�~����B�>!��0�';���� � ������>�����r$�R�>Ħ>�6+���½yK;>��㽇�D�W���侈2*=���>�i��
��<����g�<�&�>MH���������>̻G=w�x>X��=�P�=^^�=�������>HĆ��M>.>��8��2�>kԄ�Jӽ���=�.�>z�> ��=�C>/ؾ*d���ż��
>&��>�G>S��=@��>-5">����*.>����m��1��>����)�U������rW�o=�4|�7�H�-4�> �n=�C>�{�=H[=���l��=\�<�e >�<{��%7>v�D�9r>!�=f�&>�5G>�(>��Ⱦ��s>c�>���=��^<V�M�Ư�>�^3����>�bX>df��9>�.ռ p����<��`>�/K=�E�>�6���=>�I>��~��kvȾ���=�*��XY��9�M�{~=���Fx��SN;�.�>[c|>���>w�Z=�=L���\��=�ڥ=c?=H�=���=���J� �ω>i���]K0�������>x�>��>2�������>����B>W/��$`?z����/=/����<�����2�=�;�� �ֽk�(��Y=;r��-�9�6">BS��� ��C���×>tYC���=+En>+)5=Q�=Q���뽩�x=���=lI�=d%�=�����m�f��>�u�.ؤ=�(�>���=��7=^5i���L>.,��"��7�]q$��]��`�-�7t׽�T�=�bᄁ�%>�l���pT��>��@>+�>֬�>������>x>���#��$��R@�AǢ�a� >9��=D]@>(���W<���"����ܯ>�q�<S�=�D�<zY��C�Ž�!l�oB$�s�f>�hD���>�;<l�>���0�w��v����>�'=bN�<��*�"ʾ��v��,\>͗�>T`�>�¼$�=�,�<ؘ�=����޾Eʄ=4�<����>q>���&Ҋ�]�˽8�۾ ?s��=J���20�>i)<.W_< ��=E��=m�����Q>�ep��&.=8·�Tm�cl�=��Ͼ��B>^嶾�;q�M�C�F<�=]��>��Žg�x>���=R$>�3S>gvN��|�>B^S>�� >1/��+>� �>4�O�@M�>v�����8��'�<���=4c������y �� �>T�=�[�>��#=��żU�`��I��=W�=��>�m�=s��= {�> ����G����>�I��wSk=
�O<�p��
Y>��x><��av}>l�I�/q �4�!��ь��uk�l��=�&�==������ub�>x��>��<���;+� �Y7?��� �/��w�0>�u��į>��>����w��L�d��8;h&�>���Y��>*����&D�CB9>��<���>Z?�������<���>��U��⽲�> ׆>QE>�w�>a,1�J߰�+���K����01�J_���>��+�v � ����z>.-?)N�;��ؽ���=���>�N=�>t��R \=뤎��RV�e-�>�;þ���>/ꪾUp�>�.��}D����G���F=P^�=4fe>Md���̾�q��;�۾��ﻋ�i��ٶ>��>�q�=�U>�1$�x��>)�����@؏<�ȥ<>�>���<�Լ;)�=n�<<�>��>#��������>��F>|. �j6��Zb�>3u >���$�>϶ҾVT�=5�x=nG�>��A�+�;oͽ��k����>Q5a���ᾮ �>cr��O�>5S>��o����>W�ټ�c?6S~<�q���l%���n�rh�����t��;j�˾5���z�� B>5����@�;r���B���?�R�>Uȿ�f�:>\���Y�>���>A=�0޻+^�����>��>.������i�׽���<�Lھ3�Ͻ�=i)�7�����z>|�Ѿ��ľ�-�>�����>GN$����>����g��������>��>�+�>C�Y�꤅�����:پ�sx>m0G�]J�=���}�e>���>�K۾�񹼐��>�A�>��m�˾>��>ck���R>p��=��(���!=����?ƽ��*<��y��>�=��)�@+#��۟��*<���=�9�=e���3�>>�h>m)>� ��ؽ�qA��[[�Gأ�=��>�1�L�����>f�'=k���R�>DLl>�񳾓�B>5�����>4�c�?^A�--���m�>7�=ke�=11�dRC=7���O:��Y�-� Y2��Z�=O�>�A���i>���ú���&s�yx���z>3��=Q`>�c�����>��;�c�^���dO���s�_Y�=/�Ͼ����PaV��#J=+�M>w�d��TH>������;={���КQ>
^Y�m��%8�>f<�����;׎޾n�p��{��u�>M��>���=80�<'P��f���z>����xW�K�����>\FY�j� �5P����>�:K>��>�~߾a��7�,>禂���X=O�>��<TDm�X�f>$ϽS�>m����{��<Rַ��:>j����`�P��>��>"���퓟>Pb����Q��B>���=�ֺ=��Q�����ҥ->�V>z��;�(�>�5Y�)'0���0����>~0�=Za�>�r���y>&d=�S�>���>ŗ��u��-���PK.���==E/A>�ǩ�8��>ۈ><0m>^����3b��C���=���<�j�
U
dense/kernel/readIdentity dense/kernel*
T0*

dense/biasConst*
dtype0*�
value�B�8"�A�=k ��
ʼ�(=ݜ/=W ׺�cY��ͳ�LE=U�_=���`%;��=����"�ʼL�N=���d��:ю��������\=�롽w�T�cG���e����<���<-��=�p�;�X�h޹=�Z�;,�<��3���꼢7��a]q;��ʼ�q)���<��,�I+9�F4�H�����F<C�$�Ǧ���z�=>�l����<U_�=��=���=��T=
value�B�8"�A`=�AҼT`�<!�Y=�F!�f#O<�\<��5=NW���:d"3<^�!�p��=վ���N<Cw=��<n];=l�<W���ܓ<��
�Vj�<�Oa�ٜS;~Q�=��=�s�<d/H�]*�1�*<��V=s����Ŋ=Hs���i�#)�<Bㅼ� =v<�ф� �U==m�<��5�����[�:�Y��E=�-���bi���2��p�<yZ�<�� =�Z�gܠ�
O
dense/bias/readIdentity
dense/bias*

�b
dense_1/kernelConst*
dtype0*�b
value�bB�b88"�b�xI� ӝ�S'r<���bz�w8�R��8�&��d˼Oܽ��f>oK�=�Q���/H>�d�>�ݧ��x�Ϫ/<>���!V�=D�=��J>+OO��u��$=Y��}J=���y{=b�作� > =�+н�\����=O�> P���}>E>+� ��2���YE�0 =�x���k`�(<M�>�^� ;�=�V>��T����<�{G<�T>Q>�=W�v>�� >��3������$�=9�����{�pE`='�=�m,�|�$>�E�x6>��N�^L�>_��=�e8����>���j�h=5��<�S�M���ˣ7>.�l=�끽uF,�LS<w�8��Y>���� }��T >��Z���=��;Ɇ����=��� �=�P�<y� ��\>$�> ڹ�̛ � �>}���%�>>�4�=&��=����|�1<�C�>򠻬!�<p� >�@��{ >~h�0I�=��z�1��<�y����<;*��y">�������; Z->
2 >]DO�Jk=��$���#�\��z�=SU�:v��>B�{;��-={�&> _���>��P���&>�'�=�����=�d>��� ��L�]��>��<=�i�=��U=J��< ��=���=�'����=4�3>���=�3Ϻ���=>P=e������7i��)ȼH4��\7�>��ڽ��4�&�vN+�5�v="�_���'�(���ڦ�VL�����=?D|>.{^�]}�=.ܼ�o�C���D>��*<(�� 󚽯>^�<T��>�H�|��ц��:�ͽ��»��e�…>92��v@>|lN>�ٽ��|�Uܧ=4�A>6�l>B��;�Z�� Խ��F��4�7<�#�>�-e>]֥������=��Q>�=da�� �9>Җ4>s�`���B;��.���-���M=a�����0��w菾|��;�\�=q���ǼE>u�K>/��/�%�����8�����=2M�� �L=츸�w�!����=��V��>��:��vB�G>&��=��[=�p�;%*�>���=���� R\>��ٽ���=��<�R����� �.=pV|�E7��˽-=��H>4KM�qoY=\K=@7�>����%W=1��� T><M�6)#=ƼV�B�����=����ͽ��>+T�=@�g��>{�p����`"����r>,�8�0���p�����,� ^d�Q����D=盌���0�]�>�wQ�z���0Ł<�i��)Y=��|�@�ؽ��>zeC<1Ul��s�ր���ټ^f��2:��)��~��=>,�=,����II=L���?�����>�[�<��]>�Ñ���޽ p��=t�������=R
�:�^���0h�F�="��>��>���>�k>�!�=�[�=B�p�Z~�>"f�aVx>h<g����&:0>�6j�y7>�̸�0=oN�=����B��$(�<��E�b߼���<W�>B!>�֐>�0>��r>M�f�12�=�=>�^����> �"�낏��?�=' =f5����7;t O��^���������=%[=恑�j���ǰ�k(�R|�V��<Nw ��f�O�K���ҽ�x���8+��SW�/^*��� �G-�=��;'���b�<m|;�E�.�.�'>D��GB�9a#I>�Ӆ���F>5���sp�N�%��->�b-=+B��Eڔ����=�q�}Z��6�a�~l�=�B�=_8>��]�V�}=����^�=.J��P۽`���R:��qS��Z���~��� �`�,=��==FI}=,�s�X+t<H.?=��-�>j�<g��=1!>�ʑ>�� >��c>߶>��P>>!��Q >B�`>��f>���<9����>:>=R��h^���>�Z��/�$��2�9@>ڋ7>(Ӱ�Ϻ�=���V�)�0��,+��zD�DA�L_?= �H����q=]�E=�hG<F�=�IH>+�=�V�*>��ܼ<�=p�G=X�^�&���E�=~:D�����ꮾ����</>.Y��B|M�k�yU����>��.���z=S�ҽ�9>�<�==�F�$�C=?$(>�6l�+���IJ�!�^��`�>���&�4=o�P=�dֽ(v��f�z�eœ��b����b��Ͻ� � Vo>�`�=�w�=�7=�����+��+�V�������V�m�F=��.>/[���Wh���L>�5<��6>��A��5E����]�=�2�3>j��N����M>��<�QڽE�t<u"C>�*>��N�i=��k��� >�W�@�=���w��=}�f>�>�>9�<)4z>M�'>�L�;:=���0>�n?��� >�ҧ���L�U�=��a��Z>�9/>!�
>lʏ>i�C���Յ=sv����/<���>����z�ҽ�ν=Q /�v�&��y��-k�>Ą�=�R����#>Ҙ�9���>n�=]n̼7��J�7�[��x��=�=� �=�#��Щٽ���t��� �;�$�6�=8���\���½f <��.@�X ��:�g��7
>����@��[��K��< x�=�=�>�X��<��=C��IWY�^�ۼcC>���<L���i��Ф>�j�������>��>�-��z! >=�>�˽���=i:> �л�$"=O�M>K��%�6�r���V�l>�h9jtD>�'#>��>&?�=΁�O��<0E�=#U>��'��m����={_��kR=?�4�ɋE=�[���j`�]s�=*���FJ�=��l�����Fx�>�����I>!�G�N�x��]�>����yX=Dν��Q�bł�Sw��R
>�M >
Eo=n��ժ�>�Z��0�J��'=40������q�N�=�O9�Z����К=N!��j=؟u>XF�ԟ �yE�>���=����q�=�%a=2ḽ��B>��=q�X�L�=;L�=��j>.3��’>��7�&�=�<�=괾v��o�ٖ�=�v6�j���,"�rO�>KǮ���;���=�x���P�<������;Q�ܼ����Q&�<�{V��/>���>��s����>�z�=��>rk�<@n=<je�z��=?
|��{J>=8��#Q���ν�w>�\S=�E��g<ҽ��켨�]>�(�=nT!>#�>��= ��)� >�l>�k�>$X=P��=܇ֽ0�>+#���.>��1>�T���y'���$��|˽�����>�{�=�{>��)>��I����=�?�������۽�a=? ѽ�敽qd�=ս���{�=��p���,>֮�)�";��c>M�E��`=(�W�u��<�x>�R��9�����`���u�f��=�>��n>U�Q�W��>�i�=iF���=�h}>W ^�P��߉_>xw)=�F�=,4���G�>�H;�At�\(=,j���D�� ������F������
�(�>um>�Q=��"���Z���=��W�x۽��=;�L>���[}�����<�n����p=l���d!�^Y�<�SL>���> ���X_x<-���(>u>��=C�]<�(>�$>��W�&���(�����>�0�=�E=[��}i�4mM�Z���ۃ>�{e>����x8�����^ҽm�V��{2�aY潝�*>��,�K�T=��>��1>1>��k��D���޽<'=����En��p=U�=�]&>}�.��2>j #����=�O��J��
�F>�+=��ͽ�ά=�H =�
=o��䋽 �4���<�=�&��)�1������f>P��� t�e�>h��=�4<)��=�0�������>V��=&���?�����l��}�=2����K��b�>]�߽�eX�{�c>��]�Niw���6=ǽ�?���Ɏ>��K��c;bdb�Xi�=��F>f�N=�H��Wd��k܇=�C�=r|�=7��<I ��8��P
�.���D��>�1��a�w>؄!��l~<�ʛ>� e��j�=�<�b
=�c>+��<�>F�{�S�G���$�����cw�>LI>/�;�$>���ɶ>>�B��輓>�>E���T=1JH���=و>.�>+�=ES����=A*=-0/<q��>�FD>n+Q�.� >�]L>��ɽ�F�>����D��ˀ>,F<=%��;b]&<�v&>���=���bzm>' >js�=��g>����`>� �=��%<�
��@��Š> 갽E݉=�t��򋾜RO�� �=�������=w��A#]���P�u�G>[\�{$��XU�=Ԋ�>�>B��=�鼆\½c��<.w =��-<i!�>�G�=r��q�ν4f> [<.�ƽZ+C>3�>� �=i�F=�Iڽ��<=�ܽ�J�=�{>����e�o>��=������=EUb>~�$>�&����^<2<w>ў���!�=��=�T�=1�ܽ�:� �l>Y��uy�=����:P���E�ƕ+>��d���/>�B��I����l��� �>}ˤ>Ȣ�=R�>N�B��F��-|���B��Wh>����.>�d@> ��� a>�_�ܱ>�����]��g�g��ᒾ������M�Ž&�c=�
�=�kJ�k���#0=�\�=���>)+j���ü�J>�E�>�<�Y$�>!I�>Wf=N.�=�TP�iq���m��-g<�/�>���=�M>!�_>�_:�D>?DI�.薾 ���Ё>9i�=��B���=����=�w���v�=����]K�+(�>������>ё=$$�V��>]�:��^ݽ ������>pn�<�� >}�=�:�=��,�� N�7o�=�Я��
�'b���=5s�=�Z۽�呾�o:9��:'j;����Ǯ�8����[>f>W����;=��=+��Jc)��A�Ȓ >ڮT<B��<@D>
v���b��Y�ӻJ�>��h<�F�<�E�=!���o�>j�y�_M��qO<s��@X>^�>���;�߽
_� �=�߭9rܲ��m�=ꗽ�۞�[� �X{<ͻ���Ղ� ?�;ǩ=+%=� x�w5���9�>�ё>�*�r���.�<�/�>�6�=���<h� >�W���]=e$=�s�ּ������ަ� \c>FY�=��� �����W>��>Z2�}��=��T�+*<$����> >v>#烼���T�D>p���/��<C�B>�m�>z�;:.=G�`>�ڡ=�SY���`��7�;J�<�x\���[=~�>3/;>�I>�X�<�f�=��D=矎=� &>F[ݼ�G轔 �>�q�=�9�<5>����=r�R>�<�N��S�F�<�<�'>����A��<�fT��ɩ=�ň�ʿ�=�z��Ѱ>��="(������A
����� ��,�� |����6�<�\��q�"��=κk>��ؽ�du=�ou>�_|�Fu�����<4��=q*�=xHٽ�(7>S�����&=AT��}f�=
�o�~������!�C>8
y���ʼp�&�]^F>��=�Et>L7q=2���V�;�\���'�/?ݽ ����Eo >韯=�>�8/>�L���o�T�}��� ���f@>+Ѧ=�� =�p>���=_�G�p�O>_t'=0p�=.�5�˾���*>Ah���Ǽ�Z >g]�<]�D�l��=
�>qǠ����>UI%=8��=81�=��꽲HM>��}���=�p�=|%<��=_�4���=�#�<_'>�}6=8��=�?�>4!$�M�<i��=�S�������=�|�3�Q�n��㙟�J��=g�C����=1Ru��M��.$>@Dt�ٛ�=�Y<`�^�Y!>D�S��>=<�<����>4�h>��0>pwM=�9���7=�8 >���=w����. >-^�=4��i�üD��<��>N^����&�!=�W��"�=GT��)�=���=-> )|�����if����>��/>�@4��|<~n>�#>����%�=�p���:�=�v�=�$#��S�<Rۄ=U�:>m�>~]���>���4�۽�Q ��|>i��8V����P�5L6�]��{u%�#Ơ>s�ҽ�M�<��S=�ܽ,Q��]K�;�B,��Z{>��>����M�=���=�1�=Y=&�>>:pu=�ft>nK�=�Hz>����N1�S�=���<"I�=υ>X�˽ �P��4ʼJʻ�-���u����<  ������b{<�tS�(��=�$�>0Aj���hʾ��ܽ�c��� =|���*ৼK�=��%���n��=��9=�v����<<Da>��r��qý� ȼ�{#>��1=%M>��7���N=�C�=l�>;�C=yt�>��x> ��g͞�FFý�V��_�@�E!�=*�>��ཛ����b̽���>��{�Љ]9C5O>�Z >�1#����¬�=%a�A����<��� k�����/&4�S�J�[d>k��<�PS��'��iX4�D�˽y�=3�����R�Z?�sj'=(�->G4���4>Ɩ%�[��>NV�y16<����Y>��>����l���Z<v:��x�C�}d.�rP>�X*��
ս%T����='K�=�1=���<8s��{�콄&m�0 W�̩S����<��Ӽk���J�#_>� >�ܹ>�s�< ��:��5>E꽤s�9����|�x��#
�e�|��\$�nx���d�=�)�:�>R�C�#��=nc���=�씽��ǽ�|w>���= ���m���P����W_����=��b>}��I�'����<��d�.А> "�>7�>�( >��/���k=�4���,>1�ý��`>-$ =l����'%>�]>�&�>*\����>��a������Y�/B������X|F�,�ؽ��`�"Dü` >�����5>�{>�*���H��>�<>��=4J�<}�=��Y��,@>�?�=���.V>��'���>v�ڽ�RS�^�2<(2}=�`��"�>V��=I����F�������;�<� <%�T��Ƞ=���i�����1���=&O�>y!�=W��=V���VF>_�L=����?�5�ld���������B.�=�b�U�>���=�-�<�eF=�70>�D<���b픾�0sd=F��=[+� tw����cj=Bu�H\?=��,�P�z��z>��C��.�=���<�u������Ⱦ�R.>�X���/=�R> a!>#a���4��1>(������ �5�=�9½ �%�m���<$>8*<����mQ��d8���:�Udv�:i���p�*�2<�|���쵽�tW��ה���<*�6�2�1>��g��Ǣ�������b���>!�2�;j���W=�`I<+2�>�R��Ke��CI���h>x~=�=�� ����!>Z���2��NW���s=�B[<��=���<u{�>��<�'(>.;j=����ⱄ<&wv=�)�=i�ۼ퟽#K@�f���~ ��=㳼#Խ6��=.X��hǼ9^K>5�e>��8>ͣ=Ƒ�G�x>�}�˔H>W�����F>!x�;
s*����;�b������
3=�<�*�����>C���E�B= Jl>wBҽ�6 �KU;> 2�>gq3=�r�=�J�=�"�O{�=�r���f�<���;��'���k>`�%= '�>C�� ����<n5=��ؼ�rp� ���G<�z�F��ӱ���|��� �����'kӽ9��<m�0�7��=���x��3���ذQ�sv�� �K�\��=ڔ���|��o��"#6����=�
�<�}>��=3�}>������콟E_>к�<5h��q�1=%��r� >��Y=��r��Mo=Ǔe>hEm�P�\=>��h���bK���S*���F=���<0+�� �:�d����B>wz1�٭�<�$/>؎��ͬ9��T>�*�aR=$* >A��<q��=uc����=5Z��e�����>�`>?\��۵߼�O��g1��A�C�/� ����=�_�� �z;2C�=�7׽��1�G�B= ��_�=�pA>��@��/����=C���s>��= k~��,[>y�y���A>O����e�>�� ��.���4�������s>������>�>_���>A2 >w=\=(u=�Q��2Ɂ>��>t�@>���<V��<�m*��}2�e�;���=�0��]�"�^:y˽�.���
<m�t���Q=�{�8������<[��=΋��sp��VN-���������*E>E����n >��!>�3<���=&}��B!��x}�� 6>����A��!1��0=w����������J2<z0�<᭝>�Y��{�+>�w>�� =9\�<�P6��@��w��ڞ��<>)녽Hq(���=ޅj>l}=�`��c��=��t>��h=k�J��ٕ>?岼�&���Y���=�X�v<M��a1<��~=%-�=
U�=��ܽ׽N#>:.P�.q�=�^+>�{F>�bq�A��=�ё�������m=��j>λ��e=�����7�r0�OH >f����n>�����3>�����F����>�� ���E>���;�Uܼy{.�l_g=��">��� ����@>�/>��L��3)�Y�w�������b>K�0>J���ɺD��5=#>Ӿ��=�>���@<��̽�#ֽk�[��ؽ=k^⦅�|���/�����NvI��*��?������,����ͽ}ۻ=ґ=���>Eu,�n�Y>Lҧ<>^~=shC��|ݾY<�=L�y���=�
����n>k5>lʫ=�&�="O޼WI_��괾*�Ͻ������q>�r�=->-��>�E����=�%ٽ���n�>���>e�g��@m��U���(z�\SN�h�ὃzn<B�#���q�$;
�$C��Z,n=��}=� n���B��&>���6 �=��=>��k>:�p�ad�:L
�hE���R�����],>i�z�R!޼��p�m�5o =��<���=��>�ר�Y=��U� �<?����(�ºo>��=��k>���<����j ���S��t);�Yn=�������>_����+>�Fo;��ֽ�� �y�L=4/�<� �<&_�=jD>���=DB>�}> >��*<Q�^>�k�>�э> |i>�h�=L̜< �o>�����t>�����$���̥�o�;��G��f��<�ɱ�M��=8�<��=A�>^�s=}F*>��;�,/��lN>@�+��j��V]��O�=%�>Ğ���=je��K�G=;v�=Y��=]SC���;��x;>v�H=��ľ*�)���=�'>k� >��,�U����׼�E��@�<]EH���>�;N>}Nn�`
R��,��ٵ�>f���W1{=��a=��>J^�
b�=�:��lv�)�=l0>a��=��W>Bр>�d�>�߈>9G���#>г2<=�>�>�Z���9�t>^hK���>�m>G���=q��=,���I��1F=���� ����>��= ��H�Pz�<����A=~�Ƚ;y�<*>��ý�ٳ<�d>>� ��<<�N�P\�����eGK��`3=@"e�H½�噾�ʀ�5r ��֞�J�=�����8A>�=�=J�p��Tq����F��Qr9��y8��}��VQ<�1�=Y(���H�x�>���=�����߰���=�[���=UX�ZIm����>sDŽ>( ��G���Z�����u=;���۴�� ��QqٽT�Ѻ{�>����n?�;�=5jU>#�0<d>=~bʽ�XF�5�B�wjx>�&>�gq�=�AH>��G�͔ >��->e�<���=��L�"��S[>���<�1���-��P_����e=~4&=�
�=xܽ/�>���c:�=��=���f�>���=�Hd>���=���3W`>� m��U���Y�<�����gk>��B>H��>���>o�6>ړ=_>�<�s����ܽ��= �S<���>���K�ǽ.��<,u>�x/=G҄= š= 8�=`P��#�uo�>'g�k���[>�z���A�we�gC�=�����BG�Q+�9HTP=�_�=R�����O4��q���A�;�Ҡ��!���]ֽ!>�>��5�4��>���=�������챾���>�/^��/>I�ݽ��"���=J��=7y�=�=��{>mi�<:�.��Xn�Wi���1�=`f�>��\�;���l�=����?�=��=��4۩=V==��J>�G�=�n���99>���������M>H��=ɀ�=��r>༛=\��������<=�c>�(=�)f>xo�>+=����<ҋ�=2I>4�<~_�=H]k��2>(� �V5�=�9սU��=�)&<��=���=��&>".h>:�>�b��>�m򽑸8��h>� �Ttw�If=��*>�;6�����&���TB�<� <>�d�W�F�k�}=�U�;@G#�DM�=
U�=ʚi>ί�z�Q���>�,�z���Z K���\�[��G:ؽ�t7�����C���� � 3�yr�;�88��o<]hL�����{�Ҽ� e>„�=N���m "�f�$>ArD>��ܽkG� VO;�Z=Y��:�46e> �+���\>�-G>��*>̈ܽ�l >6 o>��=R��>�*���F=h*/>���<{zj;l��9>ws>4f��cJt���9>�#���<�����l>B��=�����y��@��>�S�;�|���-ļ�/�=K��=���[�&��UR�i{�<`+�=`Q�=--�O꽍�����X>�w�����Ő��h���>��!=?{�=�sp=�)n��T>�=�,�=tog>.⋾�"��|D�=Y7>V��<>��=��=��I>���=�'=����=>�"�>�Mp��^=F(9:��};l5.���'��[�=�j�h�=�Ņ= �>I��>�?G_�7у���<��!����^��������=" 9>1z8����<e->�Җ=�,n<�+>pP�>��S>Q-�=`=i�@��>����P$0>f�������ҽ=NJ�=#`����%>� >�V�=n�;�yzE�zo>���<��=�A�����=_zv���s>� k>�C;��r�<Sp�=�;A>�s2�H�f� �ٽ�;V>���>���=Z�F����zڽ6�>����j2=�Q�*q0�G��=�?a�K 4���=G5>����BwI��ee>�tZ>�IZ��Y>�Q�=�*��ϔ�<(��DWB�*w�##���>�=K�[=�yŽ߰�=�[\��=1<��սX;�;!b�����=!�>H <}5�=MO����A>R^<�iw��3]�5_��/�����(����b����> v꽅�2w>E��=\�>LdO�i+��yҽW�X��$����ӼE�\=��>��C>c�;��M>���� T�]����Z��+j9��o��Mod�u��;]=����n��Z^�=�R��y��=<=2<�>H��=v�����'>��N����=�o����>�M�L>RA��)M=��N>#�?>�)'��3�=�-�=Ɗ��ID�=,t >�a)�@S+<#�b�`o���z���;>�[$��9�<�9�-dﻅ2A��ޑ�g�=M�\J�=aB��)bS>��=�P��� d>j����Mڼ�3,�7��> �������L>4�U>R�<ou6>��>�@Qm>���_�h>�SK>k�>:���K�s<��>��>r7����>Q�=�C�=�C�<mG��w�z= r����_�O>s'C>��нg>p0=��=81;Bj�>$m�����=_J�e }=0����>�bh��X������0�����)��-��dI=R<L��=��ӽJM���8U>�v�>�A���B�愦�����D.+>��߽� ��D���*߽xIؾ8=B>�)
��y;�a=��Ὁ�h>H����� ���Q��<���=|���6-*��\��e�����Z>���.�>��=ox��&��=��ľ�o�<j� �['���@/��^<�,�dQ?�~�=��w=M>l<q�=����;9�>h�N>e�5�ʫ�>�� ��*G>K�2���V=�X3=���>� >ǎj>З�=� �=��>%O�=ed>۳��V}�<�����0�o[H���=��/>g�'��v���a=�?�<Nel<�U=��`Y>��=9��K��=�l���Pn�5s�=�8ս��8�]�께�3�&3�<�V;��>��¼2�=�-|=���<,b=�j=���=�J_=+���﫚�l�^=Qc��� ��4@�ֳ>X�U��Kg�B�����U��>�'X>�)&�1Iz�b�*�f��;�lr�#���Q<a!����:<�=4>���d�E>$���s�=ܾ�=Ո�=ns��N�$�1oj>m�����;����f�h��K=� �=�:@���=��g�k=����Յؽ��>f:�$�>:���a;<>H>>��=.r��t���J>��뽦q9�߅���?���,���<��?���F<B\��gQ�9����F� ��;}��=�v�=<�����=��M=�'9>������=��(����eb�>9=<� ��\��=�b=�|p�^d��)�>?)q�k��<3�����ƽ^0l>�Gt���r;�n<53�S �� Tm��u>Qz7��l4=��:�>B����<ֻ_�꽳n)�\�F��~ҽX1S;>��=�.|Y>�ϝ<��M��J>�n8>�G�=�2I<�sT>��J=A�b�#,鼔�N��Mv�_
�=�hݼ��%���`�9�=����*>�>
value�bB�b88"�b �׼�Ҋ�Q�y�]�>bD�>
@�=ǝ>8�f��+r��W�=�=A ��j+Խz<�;k������<�{�>� ��ým]J��lu�^�Q�1��>g��?��>C1g�Yq���v�D*(>0��=o@ʽ$������bj��{ �a>X���@ 6>�5�=��ۀ�=��s�?�<>���=p��s�m���d=*��� �Pa!�=z=���=��J��2��dH=*��=SQ6=4�>ֳa�\.�=\�;��E%>3P�=���>�u�={h>^�>Xsu<���a]>V>bG4��;�F��<���=>f�g�F>c�Z���-=uh>4aн2�>ٸ��UT>a�&>�qN=X�=k��=��%�;RܽzV>�7���u��LR�>Ҡ��bz����;j�i��UN>p�����>3]A�V�;��s>�F����a>k���|�}� � =��p��1>jv�=��N��od>��j�s-��<���;N>�H��B~��Y��ʀr<�(!�������=���=�v#>���>-y>� ���'�=�3o>��m="h3>�/��D��=�<�=U >sFr=��0>�h�<Q;��=+�>�fk>}��=�?����E=�����6���s�"T�>jxk���@���n�� >�S�=�B&=��.��I��.�g=�j���ȼ</��M��o>������p�:���gѽ�W>аS�mOo>�"�>T#K=�D>z]�>п��r�C���<_�=ɨ��������i0d>y��=���=��_>7Ǿ���=�h>��b�E�bH�=O���xw�; 1>M�v��9>r�!=���<�%8�v�½IT��փ�>X3>�ۿ�L��}�>7 �O�>꯻�Lڏ���<V)>�ۅ�߽�=���=�(���R��l�<?ph�,޷��?<�����r�=#��>r >?b���9���=DB���>\ �NT�����D���٨�<��N>`�b<�s��wt�����`��^:�=떑=V����=v� ����=/�<�Y�=0->U&���� >��*>�PI�������=��=V%�=��U<�bV>R�J>wO���<J>�Ri��(<Y�R=�蝾E��� Sc�Y��>��⽲K����P��L
���� = ��=�dm��������mw�=�2��֟>8�߽���=�}��/轻�o�k�/� :E��o/�`R�=�l'>�L�;}�!�@���E�Ż�@(�5�W>A���qd�==\뽻b>_��=�:J�mU�o8t>��2=��z=
�=C�G>� �=OȽ2u>��+>'�p��ϧ=5�)<Ȳ�=^�=��=H�=�M���.>?2����J�=��{���e���3=!�r�%��;��5�=_i��. �0ݼ1>Y�G�~t*>�eQ>��Y>�͘�
@=
g���ӥ=A^���߼�9�;ut���v�=�a>���<�q�=����Z��;-R"�!�=,�]=+�����=�>0oQ>u�ϼ
�㽳C>#G�=���=�H)��]ۼM��>���7�s�8�A>,|�=L�==,/>b����P>�jT=���=�7���F>��l�?�>7��=䀎��y6��0�=�� >b��=`��<@��YZ���=��?�%9!�k�����>�!P=�T��*�=��>�؈<�e�<�X&�񿙾c�_>׬$>o#>���;Bț>�� >)x�>�O���3���f���z���fݼL�l��+������<.Y,�Ʉo>�[�����ȶ��Y��# �� ����͖=��=^-T�&��z�a��z�=0����0��l>��B=�Z�����,�>�P��=�z;=,&��2���.?����=��b4h=�~l�^��=�B>��(>t�=UF�=U&��{c!�ߤN>��<.aJ= ��:�:�I����f$>�.�[��:Zԍ��3T=�G����a>� >S&�#�ǽ�E��ދ����򥁾���!�==�x �sWu>�)=֜=�5�=���mm:���>���l|>����� ���B�R?�=
����5̽�Y齛�&�NU�>�(㽇4$���,� )+��� ��% >nZ�>�">�!�>�X��o�=[d�=n��=0�,��x���p�=�x�=�� :p���������L��=7�m�>��Q<��c��Ȫ���>���=<� ��f�\�V�XD=�齋���'[���be>��y�>�2�\�{>���g=\"K�U�ʽ���>��=rT>��s�-�k>.�g�og�!=P>��V���3>��3> Of��P���
>�ئ>�ƴ=�N��I�q�� ���ܼ���� �W=x�=q��=�=���ձ��V���B�"=LW�<0������<�)?���= /��j�=�><lv��,0�=� \�4������C}�=��X=�"�#�V>O��
j��`:>�>��<�$����iн^��>qbE>� <%������=�.�>��'�-0�=�iB=χ�<P���'��������O �լ���;�Ő<Їq>�[�>������=� ��P���5vS;��U���v��^W>��U>�r^�'I��%���,��U\H>[-G=�2b= >�C�ڽ���A�����`<}���=BY�rD~>�F>f�}>ɝ�� �=�;�;��>�;!�"���{Y�<�͌�o� >��P�AW�+=S�#�(U�<k��Fd=�@�� >�F��`����ӧ=��,�}>���<y#�>qvb�e�,�/pM�W _=�y ��)>��r=M��w>s�->���=�-M�\N�=i�O�������=�]>-D�;0�5>J8�=ly>��X>9 =�H���=��� V���-�+��=���� �g=�5�����<�P�=���<��=�1P����ZN�=Tҽ�,>�3= ���g��=e��������V�,�U=�U8>��a=2�<xS$��;�=iE6=�c2>�j�-�;�'�=����})=�=s��X�?����=�Ҡ��.����>���=�O�= �>����N�x=-U����#�!Ǹ����%HC�E�6� V�<��ü(Q�=V�U=�+b��:5�h{�d ��\ꅾR:����ڽ�]b�R
V=�>϶�=2 ��J�=�o&>�'����=���=�s��IM$��� =Ej�=��F���>��~�$�)=qfI=S��>ƃ����>G.�?$<���"=Eϯ�C��=��=��н��>
'Ѻ ��w������=����v�>a�}=,�L��Z�=�n�� �=+��=tㇾ_ >�+��;>+mW<O>Z>���=j���6�#�h�'���:=�+�==K¼�,>S��=�<�=l���A>��s��P<�`ͽ��V�dX�=��^����Ɯr��Y=�䚾��A�τl=X\��
v��cA��c >��QQ�;!9�=�cM>}���D-< >w9�>#_��[yy��W�>��>�û=�>b��J缒�O9��=� A��c�Y��=B%?>~={�8��Da��(3�j�|<�ݑ;؎ >���=�A��+�=ji=��J>���:T����<�t�5;&�m>kkٽHY:>m�/=Ş�>)�9�#�>�h/�u�����R��M�P����}��= � ��7�=;��< ���.$=�H�<pk�_��x�?�@ԣ�;��= �;>J�0=?��=�a��l�2>: C�5G�<X�,>�}ڽlj2�n�(���)>�^�>�I���>Q?`�+O ��g�=x���b1F�k�Q<����讑>'S�=Y!x���#�S1c��e�=v��<�O���F���X�j>��ֽ�I�z%�=�Ք<��>�*_���]�52>Ƕ�>���m��#ߵ�P����׀<�O[�PQ�����
�K>��D����=k��==<(��$�;Gƽ�J=v9��>w��c{��I߮>d4��C>#�ý�JP��T7�Yz���N=#V�����=���>8\�=��>T~\>ia�>Z<�$��>m�ǽ���<�e��= \>;{2����+>F]i=�]>[�V��=� =5�U>I�?>� �-#�>g�y���P�,׽w�3�{%e>�n�=�����YW��Ƣ=�4>V"�=lt�>��Y>���=�i���=��9�=/��=�\޽H��=���>�ZE�~�K>TG <��>u��>�+�=���x�i�B�=�)L>E�½9�������.
���\���=�
�>݊ٽ�:۽Wս�.<>:u>�N�`z��� ;u��h$�}9�=��1>�L[=�� �lR#�YF>>˽=~)�<�N⸽����'>�7޼�U�=�bf=n���.�Y=�>�F>#�ȽD�>��n;�� ���/���;{���<��*o=��&�mp�=6� =�Х�~p������p^�;�=0o=a�>�.>��>�"�#j]�Q_=#p>�v�=������3���J>�P����H>T�=�-=3&4�\��=���=�m6>��нb��������X�vuL>��.���� cP>���}�ѽ�*>�7�=}��=^aݽl���X��լ��D�����d%=KZ��&��>��-��ٙ�%j^>֔%>ǵ<2�<S1<���>�|T=�j�BC�(�����F
����`��+I>��>����k/��b�N�i�^� �5>��E�pq>_7A���T=�\���vv=IZ��遾��{��=N="�A*��j��>կ>�BR<����9��=5@Z�1���\o>�Wʽf�<>)�i>� ��䣽n�}���4� �S=(Nc>>�F�bA�7q�=G��D���S�=����D��=�3;�g>�W;>��{���*��H
���>Џ�=K���ф�]�k>�<�r�=��I=�E[��!>��v�_�T>DWH>nB1���V=�Μ�C;$L��,���V�X� ���<�[2�� >���ݽO�*�:|>���=�z�=��=�c�����=@�i�&�S�eN�=R�����K>��\��P>��=�5�����$��ԛ���k>כ�=��ZoĽ�Ŕ>�G�1彷�˽��>h�"�yJ��F���xk>�
>���=}�p��;m�=�� �$Ľ����;\u�=%@ƼD��'F��Z��=s�λ��Ͻ�v�<R�b�s�j��*������Q��uk����=Z��H#�������н�S�>�=ҭ�=�����v>8��<Uv��S���j|�=�~�=܋�=>R� �'g�� ��=���۾=A��|���4�=��>6+=�1�=�6F��3�=~�=F�<��v�z.q>tҼ%M��ª ��K��s�=��,>�x���&5>�]b>|�`��K����RF;͑K>���<� �=�G�������x��c�����=���!�=![=�u ���>��R��LD<�ͽ���=� ����=X�׼��;��P=�hb�=�,�W\�;p탾�� =��{= ?��mx����=��ܼ�4�Y����<���=f}>zʿ=+s��,�gM��^茽��ٽ�Ϋ��SB=�&a��
���=w�R�#=Ԯ.>C�t�S�7>u_y��&>��;��}�=�>��=������L�j���/齃ƻ��k �?�9=��a>l6Ͻl�r;0K�=���������=���=f?� �_>sە=�� >����Vc���7>��ӽ��|=�X��3i>g�=�,��´=�<,�R> &����#���>�6N���<�#�=�=H�c�->��t=�u�>9I>4AW�(��<��d�ؼ�c�=i>\�=>1���kD��l��g���‡��J.����sj >��t�X>#���ƽ ��=T[M�� =�0�<h1����1����X=�Y=�W>�s��y���E#>|~�=N��<�C����<����y>�f��<�,�.Xu�T�<����(A>P[��e����=_w�=N>x=�-�=[��ǰ=xmd>��q��ӼIz���:�=�\>o��=�Y�<l1�=�Xz=��k=�j?>rB.=�<o���%><��=��>��=�V8>�]�����<��c=�(">
�7>)z�>ݎf>YX���,����.=�_=X �=��F�H��=�#�>t�:a;Q�d=���vG>
�۽���<���=څ�����=�z��a����}�=̼�=�'�����=w>��-�h)>���=jͽ����f�j���=>\�&��g�=~<U�fv>�_�=9��=�'��(��zy5���.>�F�=?��x~L��~���9��"�= ����s="���"�J�l�=>�Ž#��;�^�:�j�<�?b>����\:>��F> �E����=\�����>����'r��a�]���#s<� O>�{����d��X>������&>#P(<��>��G<X��=R�8=���"�z#��,>�ི:d=U��� ��5�\P�<7��;ϯ�=|�M�B=� ��T*>��d�R8��6y/�#'�;�4@=w���md>�`�e���υ=Ơ�=��R���d>��>=��>�J��l�6���/>W�W�_6��x䴽��=�*3>s�����l�=!D�=Ü�<� =��L�<+N�=�?=q�=s%7��������=+�j��JL����=:Jj�c��>���S '=_�9>n�?��R�=��p��7����[>����"�A���=B��=�<OR��&�=��=#v���m��Q=�0��'�>�+>�4�>2���a��|h>�c��R<�Aq��>b�=C���#�=pC�`��<��+��="L/��������=Q⽸�z���M>�L�<�ǽgg�>I�M���n��[E�5d���{8�sܚ��5���>(mS>�}��A��>��n>��l�R��v�>��>Ziý� ��-g�V�>/,>81�>(==��^��N��諾��ҽT<}��_[�6��a�:>)�<>|dl=���>�~�K�3�j@5�Q48�����9>N���h�i���ս��Ҽ=9!�=-��afD��^%>��=�9*��_�j��=�Z��9>�R>�%۽^/�=��>�.>%-����:�>�j�<����Δ>Y=�½�l�=vF����=]]ռw�P>�C�=�D*�X>�|af>r���v�S���Y��>����`�
�NTH>��ս�<�<lh������l����=�7�=�B��8V^�>M0>7����n5�e� ��o;= �s>�e�=�9>|ٺ=��O�要��j�������齺f����=�*>��d� _>~>�w����Ƚ�Nt��ZA>�/�>^�%>br��x����-=dx�=P��=|�<J���/;�;_�d�I�a>B1���9�>�߈>�>d���>��r���>��Y�i >�/�oJ>*��8��>��x==^�=�\�/���,�o>���([�|Ԇ�H�u=�jn>xf������aݲ���d>�y���.$��>~8A�K����?��Ľ?_D> ��=�߼������d>�M�M|�x �O;���>�=�G���+<u�
���+>y+.��Q��1�T����1�> Yw;A����=#/$�l�x>m��<�9>|��:vU�= �T>$��'�Y>�i������T<%D>XU>j�[=��=8Cs=�A�;�#>4�n����<Jn>�>R>3{�;��z=�*>�����U�
�;@F�=����\��Ն��K�S��>tݽc�X<,K��v��>]!��8��g�-��>�c6>X$>G���\ ��P��=}:��˭I��?�q��<��/���q>"�)��=� 9>"(>� ==�^V� Ya="�G������'���^�>~<����f<�E������Z>@Hk��}�����;�2 ��k)=F�<L�=�J�9f���T��>��ѽ-��=p��s:�=�I
>�
y��^��\��=�S�/9)�\�<r !>�̰=�����<5���,)����˽ ���{�;�BE�<�4�=*���jZ:>����<c>vY�?��>�%_=�ٝ���ڽ�拾��׼/�����|^I�T�ƽNIJ�4|Q>�6e�x��'N��B1F��`n���޽�~c>��A�T2���:T���=��[�Ndl���3>�ؽ!�������C>�10>�޽�]<Ƥr�D`&;�>l��=�,l>j�� =6�
�'�l�����s�=J���;3�<��f�>4��Р2���t=�(�>�� �V ����=�T@>�� �L�=qw�=����pl@�-�>n�o<�R����E>A��\����`��=�����?�=��>#]�>��]>^G���=�`�Ǽa�o=ͧ�0K;>��=�:��NżP$�=Q@4<�p�=r�:�bE1�u�,>N��=b;>�Fa<�=>r�=6ܽ
м@���'���)q>
���.8>�����={���/&��h���4����=uu����-B=W @>��E��kս<D<rz ��M>�}>|���,U�=���=�…�J���f� ��(>!ƽ�W�=�׽�]�<n�>�j�]󒽇4�>�>�y��Ú=@,M>N�>� �=R����R�>��K�����Xy�>�
�;`�=��@�N�$�0O���>23��������=�s�����`�i�5���@>�7 �����%[����.ة;ӥ>� =lĉ��3=DUj����a�ӱ�=�ۼ��={%>* L>����CV2>/z]���&�u��=mr�=��żxƽ��z>��=���>2n >;��>��m>@��< �O>e�%>�I�>�(�5��keu>;��>��=l����L;>!Z�:$�h>=��!�����>��w<�l= �>"��=�%I��=�>F�#�Kp���5>S��<)bo�Z�»4����;��ء<L>�VU>Dљ��� ��νHۈ>�
Q>e<&�
>1��<i��i����̷=���<�d>�UD=��D=Ӎ>=������A�C�G�z� �`��>�"���Y�;�p>:F�=�d��ఽ3��C�s>g�]>#�P�dN���|;>�6>�<R�Љ����ż���<�I��&��� >h杽��>sW�=^{y=�@X��*->�~���e}=L]8�q�����=�k���ۼ��+>F[D>B�����<��'>f�꽛�w��ׯ�l燽eF<+�=>@����<���;q�W=`<���>4f�P��ӫ����߽ô<Os��Soe�c�F=P��<p-~�/�!=Oޙ=�&�=���;���=����i�=yMҽ�"/=">��*>l>a��5s�=�>]>��������h;>G)��y�ؽ�Y�>v���=��X�J�Y��Ɠ=z�=�_��z�=5�>��z>dc>��b>��ӽP��9R�R���ʔ�m�T>L���c)��#*>�wd��.J�>�r�G��=�y�=��= J޽u��by>�!�=�̽�^ڻK��=���F<�=�L߽���<[J>�H=��E�>�$�=T.w�X�h>��;���<�w
<XX����l��,�<ޡ��#N��0���O <%���„��p{>F��=w�*>�t�<�Ê���Ҽ�Ƽ��4=��:<�J>�Oh>��'��K>y�=�R��OЃ=q��;��������=��;�YP>��w��ī=��1��n����o�����u�G���X>�q��9�[�#&�=��g����h�j�HO���&<<��~�ǜν�c�=��=�1Y���=� >�`�����=&���=Ue�0�"=�F>)� �[�6��ڽ�zw�AIQ>p�!�bW>=H8>L�6�oJ�>�!�>TT>���}�=��o>��=IwU>��=؝�<���h�X�M�N>�0޽J�=9ֽ4ӻ��
<�7��(i޼S��=Շ>��u=���;Y`���>�W�Z���*>�L��e염Y�>�^�=��L���۽�Ȥ=�:>��L�t�;>�������=���=^ӄ���C9���=��> �>=q�q��9������� >��&�D_��4�⽮>#�0 D�᭴=�,��N���E�p�4��-ý쩌��`�>;== a �ȼ�=�.\�3ھ=�۳�'�>RR;�J�=9�=�K'=��?��En� �1��,<��4��@���p�2�Z�V�)��jټ��x��}/��ͽ��.���罌re>�˶��c>H�|>�/���D>�`/�=����O�=
h��gz���[|>��t>�� ��=Ab>��|�܍���n�����>���=Vz�cel�i[�<��b� f���*�REI>��~�[@�����b>RY�=na�=*H/>�q%�:$Z<i���I9��MV=��!><'*�� �<v9�=�,g>��E=���< ƽ���<J��X� =��5=���= ���� x�󒮽���=,B>f�[���ν ��=�o\>��d=�ya���>P�=�n���3A>�����U��/v�;_u>�2S>��~�@=�Z[�<Rj۽�mM=�n"�q+6>��m>
'>IAO>7�D=
z>��p�j�=hsm�ɬR���<��WZ�z�x=0���T<�mX>c�=��>���<έ��λ7���{�=��=�t�F�=��f����t,<!��=��>N�4œ=����ʽ]>w/��cg��{�[�t>pU�����>ҿ;��==��Y���彌�!2�=q�>�},����;�n
=4\���C���=�����{����̼�橾z#�f�C� t὾���?�=!p�>.6��<&+>68�<"�k�II�=�d�>���ڣ>)b��:w>z$e�H�>/s��%�<Kc�����q�>�H>���>��2>��=�<�|���\ý=ns�([A>y>$��=i�U>E=�e�=�:�a���8�=���<��>g6��ӹ0�2�K�=��>a���� <ϡ���a7�|>�̍<�o�<���=�]a>�u��>��0򽘤E��r0>/ll�?>*����=�';dd��Ŀ��P��BE>���4�</t^��nֻ�1Խͽ=Wt�f�=�U_���v�{��=b[�<&w>�I�#��=� =���=�/'>�F�� �*>
.� s>��@��;R<�a���@��E�X��9�=�Rb���.>�1�>[���j=�=J:�=72���!<����|�>, ��]ν��U<P��>6b>n�L����7mk=������=K�/���P�3��>��>"x>�y���7<�=q��==�$�R`�F�&�#+�<?~\>ň.��m���u���U8>�>��`=�s��o��=���=��=��.�X�3> 2E>�~:>�X?�;�=|к=TaZ:=ir=�x��1��� ߽D�c��F��t^"��c2��ȼ�P�=�x���d=���e=P���-�=�&��E ׽�,�>�}��/�c䇼1R��Yu>�_ֽ[e��q�����=d=�G�=��F=P��<�]d���=Z�!���"�T)O�fMW�X�?=#�ݽ�n�=�D�n���`�ge����s>� �=Q�=�V�����<��ܽ,�>m�< ��>����xd�<N�
>�R"����ң��r�x>����J;��螽���=�S<p������x1G�q���D���Ć >�ݽ�B9>Ti�=���=���=���<|������d�d��J>q��>^-R>A+M=��<>�s�>���<���=πx���9=�>�]��<;"F������I�1((=n�$�X�=<>����mڄ��ep<7�>�A�<� ���͆���������>E����V>��!;A��=>n���X`>t��>��ٽ�D<t�q>�Q���[��
">�ߌ>Fx*�>>�K�=�X&�����Y��S_,�I�`��W���Z ��M���= �r=PC}>��.��D�=��v>W��=Džɽ�!���>/'H>��=�8 �=�؅�<)�=�4�=�~@==�2�;E�;=���=�����N,=�I�� �=�f�\�E����=8���=8c�x���6� ���)�+Ā����>����Ġ��=^D��49>�<6�� p��c>�1>����}�>,�۽�2���.�= e�=)�����SC���ӽ����-�=����*��<������=L�A=E�>�p>;�%>c
>�{��|<�'�=ꢾ�b\��\��Ĺ3>F>%�fti>`�h>9`>��6>�lF��=�<�$!>ѫW�
g;�n�;��ܚ�=��#�ι�7���M>�9y����=�����P�nҔ>�}%�
� =�TҼ��>?��<$[e>?����F���u=5F2��N=�U=�o>�y9=��%�i�9�S=��3Y��[$=D���N�l=� ��#�>| ½��L>fo۽qk=�=S�&�G�$z�=2�8��#1�o/�_K
���9�S5�z0�;j��䥦��^>��f> u�==[?<$P��/�[��>;>gO�����=���< =QQL<�?��>��O��)��N��=0�'=x(��@���Ҵ>d�;�j�p>�\;��� ���]��ҽ��<����~�����b��X��0�R>b��=�H�<y����>���V1!>ž>�J���OH:�p�=P*�hA>Xݰ=@�r>S�8� �Ͻ����>'�a=���;f�)>��G�����K�Y��5�=b>e�=����W'=�ՠ>m�A�C��#%">�w�=��>)$��\:>��<���=g����7<
[
dense_1/kernel/readIdentitydense_1/kernel*
T0*!

dense_1/biasConst*
dtype0*�
value�B�8"�bH׼[�=j|=I2=T���0�=�Ί����<�ŽM� �-"�;%j�<�� ������4�=�C���8�r��;�
J�&� �qai��O
���%<'P��KF�G�=C>���=������y=3���u��<x�N=��s��,�=xdc��k�����<|�-=K�>H���;���B�<�U̽j>=�g�=Ϻڽ�ʽ��o=��=v�+�ɷ����=��<Ys��Bf��
value�B�8"�&�=��e��
��ܑ�=>Ѵ�aj��o�=<c�;��Q� ����༝8�<�Fv= k�=�J%<�l��Қ�=�g<Ӵλ7? <pG>'� �6N�=Y��<���<*�[=0(=��u<��8=�����;�%�����p�p=E��_�=��=���;H;�<YR����p<���=��3���h=Ј�'��˾�<�R`�#M��n4=�ή<���=��w<`�K� � :�=
U
dense_1/bias/readIdentity dense_1/bias*
T0*

dense_2/kernelConst*
dtype0*�
value�B�8"�O�#>w|߽���=M[��9����v\>��ڽ�>�5D>��u�f{=N�9�Vf->��I>w���gm<�a>�L�>�d��ӭ����r��>
y�=v=z<׊˻HC��p1�^)���0>O�>Q[B<8 �>��N��a6<Rf�����=Mc�>"�>�h���n�>�A���,-����і�;�!���Ͻ�:�>�u�=_�6>rUW>g�>�#q<wq��( =�w�>#�S�
�i���o>�f��q��[>�� ��W�e<������A�>h�<�<H���>~�������0����eӽ�86>�k��<2¸�<���� �� N���U�0>�OI���=B��Ǭ=Ҍ>���aZ���E����H#� Ŷ��!���B��O;~�>OT(��+���qm>-���#@ͼ����_��R�=
|�<::����ܼ4�~���>��=i҂�@����+>񃈽�R�=�dɽ������l8q���=�->]����>�=�컾�{=8Q0=sݷ=�@>�W�>�I��B=>2S��<�=Cgm��v �p>����/k>V�>`�L=���\ٴ=�ʲ�ڤٽ�+Ľ-E�> ��>��.��r�=| �tᅾ�1
��h��\ͽm(I����>�`>�a>Pҽ��9�9 >�$�>D1����z��ݭ���>��޼�Y�>���=4tx>��*=��=����Լ0>OƩ��R2�Sɾ�;�S�<;1�;ʨ>�&�>����ʔ�=���Um?��&���z>lp!��[��/��>���=�߹=!Z����>�U��*6<�K>q�>��>���>M�H�y��=�+,�!���I�=�u��5�H���Y�#]彳����v��R��=�ޙ>?�Z>�w��6=G�'8�+�># �>+��>PM¾ƥV����>Cި����>�D�����<n
����ă�=�H���B�>P f<@[B��n���������<��e>m5�=T��>B���:���O��k>pq㾥��>��=��>�˟>��ʾϏ���j>� �>1&>,]�>�B>-���,��=o�T>�e=|J��D��=zg���+��n3 >£侇n彩�r>�?C>�Eн���>�eY>���>�є>��>��$������>�G�>^D>�c���2P���<�򨺈U���%C=��>�s�=�h��,��SH>��>���=�݃��|�ҳ�>Ѯ�=�K�=#g�ە��K=���=-)p�+zl��@*���2�G\M�D2/>pӻ=��s��<=)a��1ɠ>�w�>����v>V�!��� >�7�� a>@�^�B~>$��=j�˾ ���m�A��g�;�P^=t ��H%��c>uZ�<•w=�J��\���dZ�>�_{>�,�����%;�as>���>�ą�7�>�}>|�>��;D>���rlX=���>�b�=�$۾v�=>�8>���<4�A=�b>5��=5�=���<����s����1N��(�^�/=���=�<Ry<���=�
Ĺ��d>0MA>x�@>ƓJ�<>x����>&ϓ>md�����W���Ne�>z2">*�>fۓ���=��>�L�>�9(��⻾�Q��A����5>�Z���<h��>���$�X���N�1斾��>����%2�>m���E�>Nf3>��о�>h<���2j�b����>>���R��=Z X>�-=j���D��/U��^ͥ�Ý�>͚�0щ=ˠ����E>�X���{�����Dg@�YL����|=+�]�y����7>u���#�,h9=�n�>[Ծ��I=E�A>�a���s̽����5 �����>��,>A�&�w�=x0���9<aS|�G�E��nz�L�
>�n��8z��#���K2>�bn�q��>N��=� �>}>>M :��\>��O�-��� �>0z�>\�->�G��
�>��;�L�=���H&�<���X��=���>�����p�;�|��p�>8�=���>0��+=���?�=� �=�y>7c߼A��>�R~>dx>���=\��;G��=�麾 K�p#�����>/�i=�{����6�X'�>z�=���a����+>49L��Ǿ��t���>�P>>������Uh��m�=�a�=b���ܡ���}�=����LqI�m�v>
r=m�������_ >���>�ӽ�=�>���Jϕ>��S>Vp=U�ؐ�rM=R��>-���)|��D7m<���=?ؙ����~4�= R`=��->i����0�*96�dD�=b��;��� �D>W1=�����޽��z>H�o��H4=���>�= &>r;n>�t��v%?�
�=Z2$��e�={�D>�w�>?�u�Q�>�GE=���>�����W���8H>�;>J���G=� ]���g�Yn=� Ҿ�XQ�Ts�"|�>ӄ>g��>\�=�^|> >*<�=���E#��ǘ���F�>�z>1��=�<r�f�����z�u�I��=��> ���‚t���@>��>]�k<���k+�=��C*�>�q>_�l�ؐ>���=�4�<Z �~�X�A?=%b>k1�>O��>+�����о - ������0&�<fe<�.)����=t>�>���>�`>x籽�R�>s�f�:�� ��G㾖�$=�{<��#���d��ýԬ>���Vd�=�P<f���B"нiZ:>}5=�%¾�_h�����FYt<����=��N:���6A=)W>����Z������>+��>I%����$>|O#> �\�S�!>�+�<�<�tM���<b>.�g>��>�$�b�=�Wc>D��>6)n�/�����>�o��� �>y��>6^��p��>i�>��t���=���L=�dټҼ?��e]�*"">�ò>���=��v<#G��u�=���@wн����&��h�v>"�K�\,�<1%>�Ⓗ���<s��>*������#��<������==���>ij������c;�]e�y���t�=f ��9�>��ɾ�.��"K�d >|i�>���=�OI���ʼ` �>԰��������><a>�;�d��6�>�Y>�����?V�����u>��P>I�>O2>��
���;��,=���=1�a>B���Y
�J/����=լ�a�>6��=�m��<C�>K�>H��������\�8��>� �����=������>�b�>�i�>��<�T�=xL�<Y�G����=N,̾��v=Kq+���>R�7�ҋ�>�Fa�.����O���S>9�����|�f>.�����0$>�Y�>�h���羪��>S���5q�=t��� Df>��^>Jѩ>cye���G>bּ>���>0���>��=_���kϽ��#=� >�>�>���6rQ�H�����I>�C��^!u�V����>���<�ܼLk�>�?_�Wz>j�=�\˾(؃���=8� �(6��0��>SИ����>L�>�lJ�ت�=d�>fOK>�$=����2�C>�.ֽz��<� [>;�>�(
>�����Ͻ����X�վ��=i>���O":>Ӎ�>�|>�����H=��3=�����j7.8̾�&4>Ӹv��x�=یм���=�CN��Ѓ>�H��lt0>@"8;iu[>�#>mc9>[j����z>�;�>�u�>8g�r�]*�=��5��+�<օ�> �T���?>ǎ�>�T�����<�ן�S4m>[�y>BAy� ӣ>�]>fﲽ7΃�H�<bQ�>/�n>���>j"���>F��θ�<^��>�ю>_d=�H�>Q7�=��ƽ����Xt>�D�>1f �I���_C�>i>��r�oˤ=���zH��\:�$j������>��=�D����� ~��(�>�d-�D�*�S1�=��e�_ �> ��>
J?<�7�����>(U =��>���� ���8�<�`�=�����&�>1��p�<t�>��󽂙�>W ��^��= �P�E>m��=�,�������ӽo�.= �9�Ӡ:=й����l���J<�7�/󕾾̢>!�?>ݙ�=���=�����%>����?����y&>r�=Rr���_�>'��=hO��.�ݾ�HڼFI�;�� ��P�>mū>�r��'�>N �
value�B�8"��e�1T> y�=/�u�[�۽g��k��;b� D��"�=��w�Pe�=K?:�+�<<@��=R�_���p>��/=~;�>��>��8�|����I@�2/g>qo =�>��*~~�c����T��z�>X�N�d_=����H���sΡ=0��kj��� ����>]��B�t�}j���r��sN=k41����>����>�W�=�m>���>��<٥g>͜>��>"Ͻ���=��W�^N����>�/�=ħ}�!��>A��h6�>������1��._��<:���h�ڑm>��m>p�y>���?s���`� P>��o��ѐ���üKQ4��{:�Z �24�=K�!>�E��Q!�=�����}���:���*�>�!�<9���j��]Ӭ=<�&>ײ>o�<E��>��=}/S�M�>�3;R��+a �s�c>҆>�8�><7=���=���Z������%s=���8"C<� F�Q��<Q�2=)���=,>�B��M i��#�>j�>�6�>;�D>�6�>}�>R�X�(µ��Č���>i��XJ�l���"�=_��=��<�噾��^z!�VG�=O��>vĎ=u�^>6�ž�F�����>kKM>�������R�>����ʉ������/;��m�>3&Ǿx�p�~ >�e�<�PҾ��U�P ��
���Õ�>�X��&�> ��I�>�z�>��=�8�>'Lֽʹ�>ת�>��_�v��X�w>�:�>B�=Y��� �=�E���d����#�>�@���`���M��WH>\�ս��>�1>��==�V-����>�(C>E]�>p�3>p������gz���� =��;���=my�y�B��: =gs����?���;�尾Hw�>���=�о��=X�S= s��6��N@�V��=�IJ�3U>vs�<����_a������'>���>�A�6�^��`����=��1>�w&���)��3�<R0�, )>1<�=���=%�=�����S��B�����Ȕ��O��>?��=� �<�,�>��=�(N=]�>�N滚�A�>R�>�%�>���=�}���a;�e^��q�D<[�[����$::>�+��&�;����=��P�������>Q��=�A��rL�!4 >cw�>�����>��}�����ؾ�]F<,M/��=��0s���kE>�O�>���,�n��P��FϽ)�:�7�R=�x�7����d<ؾ�=�ռ��|��ߘ>A*�>D���$0�>rX���G���{���h��}���K>� ý�a�=���#C�>�$��nG�>���>���>�+��Gj�;�D=7N��=��=CC�=ɹ�=�޼�1�>�O����O&I=��=�K�;m���a��y����>'�ľ'̾�v�=���>�˷�>�W�.˾ԗ;>Q���򗽍՟>���X⬼+��=o��>��=��:=Y@t>d!�<��>�3}���6���W�]�>K<��CV��9��=�N�=�䀾�!Ⱦ���=0�:���N>��T>�&=��>��:�8�� $@�_K5� T>9Ts>k7>���M��~=�c~)>w��=�MԾф��&�Ӽ�`K�@>q*��/��>���< (G>rc�2nݽ�>}�3�����uy��n�E�� ʽ��.>?��>�?>`<L�cdr�I�t��f�>Q�<õ-=�~g��Ӿy�x>�Y���>�ڨ�U|_�a1�<���>�??��>Ε>����D>���= �_��h����=�C�=�ˌ>�da=L^���e�9"м�J>n��>(A'>����_&��Q̾�G�=��l=Ԣ�>�?�k1���پ����>��> �=v%�����iK�I��Q���ľ��Ҽ��>i�4�R�X>�@n>H�@�T�������~�<_�G�X�5Q��Ϯ>�U��enȼ��������%��>V�ڽ�׽?��� )>�r�>bx�>��S>+�>d��>8��e�a��5i>��~>��f>�^�O���g ���y���!N���ؾN�<>_�� J�`£������#Ͼ.�a<�� >�V�>=%��9���?=�7-�=Zs&>C�ؽv�> &H>�瑽�k��L4��i�E=OT׻�o�>,=���#w�Lx�>���>ӓ�Z�=�o> /j=a1�|q�={V�����������<>�b�>�xW>�I0�F�<>���_ă>�;�p o��>g������{��=7ž����r=W2K�������=���>l���"̽:P � �]��_>*��Y�˾Wn?�����Vo���<�.>rwe>�ɻ�k�s����� W�<��T=x����կ�"�>&*�=_�:>%˔=��<��4=H�>�D�=���>���=$з>�Ò��n½��&�J��>,�A��-*>�j�=��7� ���O-�=�ܛ=n�X=�)*�]?.>И#��C��R򯾌�׽��=� >p�$����>������<?RF���>ƹ<]�= ���w�>��g��>��>���>}��>�����¼�U���'y�g��uV�.��>Nm>)�`=���祿<T,=2 >�Y��O��ʢ�kV^;S��>�[-����>'�C�3�N�r4K>�В��Xѽ��u��j>�\�=�sD�%[=��>؞P=�[ �1��,������&zݾ� J�^tо
�����Խ^\¾Q *�M���p |��_>��>1��<F[/� ��>� �>�-�@�p�Z@=0�="�p=$��>�#��eQ=NW<��:���<J�~�����=(����&�c{ܾ�dI>-�>f���Bv�՚U=��۽�[��A�Z���g>�S�=B=�=�}�>��>���=���I�Ǿ�X�>�C��F�M>5r�>�t�-v=����&�=�!�Lu�>M �>>�Ľ�~(�mfs>�V=$�-��-l>2�8>�\�W�彃{�AE���>䣾Q�U<�k�����>��<)18�>C|���>�g�>]h���<h�B>��G>�᷽bx��pQ>)9�=UA���c����k>���=$(b=�F>��>y�5�J��=�3��g�=�g�� &?Wٮ=+= =bV���?z?�� ��+��(<(=du2�1߯=�0p��+�>�Ӽ�#�>�O�=�=� �Y�+>5��=�>R_���g�1���0>�ۃ>�y�=߆�>#g������;���S�>��=>0���a���ju�=�� >��=/j��*�~�A��<��6>n�����l�������۞��5[�;�j�����L��@��8�>
v[��v�>�����>� �>�x0<��=}��<OI�< �;���=>T�p�|�>�߾b� <#�����-�~&���� =<y½ʫ[>7�l=�!8�`%�� ^=�a��t޼���=SI�=�7<ԩ>�Pa>>ɼ��ވ��8�=�=֥.�cӽ�T�=�����f~>�x�>��: >�ن<�5���K� þS����&>"W>�6>���>�"� ����>9;!=E�=/��=��Ҟ�=��&����=bVE>R\������Kz�>Wmо�|�=�� �yڴ>�M�>��龡��;1R��X�Y�G
���Fh��ڽ®v>��=|>=�O>4�?>���� )���輊��>I7���K^�&L��C�. a�`(�=vK�=�h=xO^>�_;�v=1 �>����o��>Q�>�4�>���=��q=X��������>� ټ��������m>ŒZ�����f� >[\>��)�>�aF>��V�����2D>�W�=�Dl����>EU>����>�!ƽ��+��1�>c'>T>���=�+E���=���=L�<>Ml���U���=�>���>��P�s�)> �=��=�ںBL@>*��� ݊�@4?> R���rؾ����7܌=(���YS��xV}��G�=T�0��'k=?�V��"��W7����l���e���q��>�'>�!>@���z�>�U޽�6z��ƾ���=��>䔌>X�>�q�>�����У�(J��
mn�3��=��<6�=!$ľ���=&Z罆 >��=Ctڽ�)�=�����l>
[
dense_2/kernel/readIdentitydense_2/kernel*
T0*!

dense_2/biasConst*
dtype0*�
value�B�8"�Xy&�����SC����TcV>U�>-Zj=��6><��+�B\�=ZJ��2�>F�i=s۽��=|t�>g�;�c >�w����]�m����ƽ؄��A� >;����.�����~'>��׽���=�Z,>����4ʽ�O��M�������D���/>����C�����<�=�����J���\\�=����W���8�J�}˽ɺ���i��-�}��r�=�2;
value�B�8"�2x�T�=_�(�[�H> >0Y���$>�7>��>��?�(&��>T������>�_1>~�->�H!>��>Q�)���)>T�>����b.>=K!��5>��2�%���p0>���tB>@I9>e�4>:i&��*���"�A,�- ������E(�Ǚ�ޖ->l>������p>���=� >�m5>K�7>)�2�zX��w�%>A�->Y>
U
dense_2/bias/readIdentity dense_2/bias*
T0*

�b
dense_3/kernelConst*
dtype0*�b
value�bB�b88"�b�>#�$>��=�l5�����AD����>�%&���&>g><�=k�@�]���`��=�#=�#�>��ҽ�ݽR�>��0>:5�= g��C�>��=@3;���=�w<��R��=pG�;Y
���<>M�.��[�=�gJ�#7����E;:�!>��X<��{�I�E�3��=����>1=:ހ>M9T>�L?�%5��h^�=�ͻN��=o8��QM?>m���F;=�]���i�����K�ż��=3d=!g�<um���vz�6E���>�n;>6�s=�S�=�o���:۾=�'�=��D>�u����D>aO�k����|<�� ��9ż�n��56��U)������[U�IP��\n�=��#=�v~��� <��}�X����$��;�ӻ��O<���j�������|�9>.���y>],6�4�ֽw=�� �wr<=�,�������'J=�U�=Z+��PŽ��>�4#��������y��v>���=P���@�=�2�>M㎽@�?��Ь�(�׽0{�<�ζ<� �<�>�Jν1\D>�o�=�'���������<���<�0{>�)ŽG@�����~t��k3�= �=��=� V<YV]>5)����==|c=� ;��%�������y���~�)�<�tq�W��<6�>1�L=���
�>�1�'�ĽhkM�x�;Є�<-�e>�뒾6*��Z~F� [�=7�j���k��_,��\!=a�N=�4�=��$>L����U>B1?�:�F���J>������=3���B*>$3=.�S>Zr��;l��}��{_� Ղ=:KF���.�+F&�ҿ
�5��=���=�ɽ���={��%Mi=a�D��%ν%ͽ�㢽���>���>A����={ )��U�=٢=A4W=���<���N��<8���I�=��>=�>�=aʃ�\�=l}==bKQ>&�.���@>�z6�l>�9��pJ=�/����ؽ�g�#� �#��>���=�>�Y>�'>n�<�ԓ��sR>C{ >��,��E�=��W��5Z>I|�@��=��������|�G� �:Ƨ=3}K>��޼K�(>�_��vB��eX��e��#��t�N�� �����y#�=�������;���!Eֽs�=Ji����6��� <���=�e�
Z�B^X=Ғ)�&�W<.�F�R7�=�ٽ��I>��N�ԧ���5�=��= BV>x�>&g<��>�nwv>��R>��>���=H��=(Ձ=h�*��!��(��Cm��´�= Qa��:�=kQm=�c���/5��T>6z>���=���������C=9�ؼ��&���o=��Y>�r�<P.�or/=��>y�&O�=
��<�1>pu�<�Ƚݵ=ܰ+=D� ��a:�s�-��޼��S�DMC;��A���׽��<ë���W���-8���=����=��=�=����>� ̼��n��=�)�=�)=�ڍ>� �=2�;ė>����@�=�>&F����h��˾���L=��I>��==�I+�Ж�>o�"��?#>�#A���R=�t��/��=�L=�]P<i���4�;Α��i>/�`=_���8䃽JF�=��ڻ�ݠ=��:=��8>�!>� >u�p�J�����=Pʭ�>e���(��g=5�>r%�=���=�V�;�JI��)�<��hZ�����=��>����5>PV=�m>j�hq>_��;֒�=5�=�(>�M�=�$<��T>�9�=���>�=q�3<� �=�P������?.>P�l=�����=�[B�S��<lM=�ۥн6S�=t�c�^�Լ��0�s�e=���=ל8��>��"����nf>�<���=��b=KҨ<=�����`8��[��rH=��2�L�K=�+�<�΃>�sY>.9$>�X�=�ۼo�ֽ
�=��B>mn�=�n4>#[��%��=�0��8>���=�����F���ʮ=�K�������aF=�x�=IE)�Q�>�$�;5�m=)�V>�Qs>�~��d;>k�=�_�$i�=�Aѽ��;����d0��y�4=Ì�=�(>z="�=
��9׊<��<�>��}�1e��|)=}�-�i�!=�(��D԰�k�/��)>�E����>=L�V>���;�>��*�)R�� ʑ>)�< ږ>b��y���ұ=�K>g�=�����o�=�x>A`Z��k��;,O���X�A� >�塚,�>K#j�T潀��J�b>��=��8>���<'H%�F��=;;߼K! >��N�r0>׋��ױ������?[f>Ad`=��a>�\ >��>!�>��5�ͻ�:S�Q��]�f�:�s�>"�>4�t�,���/=a�$>3٬��ѻ��B��Y�=��l=-�<�
5=�f��0oj�bb��n�=��=ŋ��ӥ����->Y�>� �=tkp>T!x;��@��7@>����M?<�ڃ��m�pm�=m #��K�֧)>���ۦ=�P$���;�D�=?o����=Yv\�]�t�b(��7|m��轘n7�f�<">�df>\j={�<>���>|�A��x4=��<�UY�
���1r��g+�l�>r޽gJ�=��ڽ���=�� >Ӳ/=���Խ�ǵ=L�����>V��>��=�e�>M�<>����������=̹�a7����=��=��H��$�>�Y�=N��>�<� �A������>B~�h�=��w����b�O=����[�f=��>�+�;;Z����Ľ��E��-&�VO@�H����Т��
�������;&>^�e=W&1<ȵ���� >�?��» �L
&��� >�c�=�ۑ<�2>>�;���=�B�=�b���ua�#�V��:=V��=9ڍ��;���t>C�e�q�q>�A>rB>�
H>���U(�=��:>��
����+d��˱��(�<��1=a����a��%�=�ꏻ�ė�K)>"Tx����=�mA���S��FC�� ���_ʽv��>���-�>�؞���>��#�t?��x��=��'�:T��b���`d>���=�wν��8���p=Pn[�X��=�OA>�+c��K��벽d2p=�o>� ��y=y�w�Æ>�v�\(�<o^=�B��"ݽ�'=T@>�(���C>c��<-�N=��<e�1>�=�<|�<F
,��� =W�B���%> K��Q���W�~dO���=�{v��f>XЄ���.@�;|ʽ �>v�=���=�����">߄)=��ҽbR����������0����=~s�-R>�C�Pi>���=�D�=�Ń�<1�HѼ8%>
"+�Fſ<��?��،=�=������x�_m =a��<�������=��c>�1���e �u'��l_>�f�s���*�ݽ 8;��콞�=A{��ʫ=O�
m���Ps>��I��2����a��Ë����>9_�=�Z��\�<r��<����kw>B� ;=y!>�.��lP��Ӽ�5�<a��<�|ʽX�/>&E�<��.>(��>=g�+b&>��,>�T�=�Pm��_s���t=��>�~�������A>w7�>�5���=���Owi�ꦆ>��=�������<���=*Gc�G�a��i�eE�<�~oZ>�j+<��̽/U�֖�<4~0>�B�`��=]��A'>e�a= �"=i�p>�c���R�죮�?�<=9�A>�&$=YG>j�����`>�a��q4d��!�<,� �'�8>�j�k�T���*>{�r������<��BN<�n���� ��[��=��=˞g�)�%>��V>ٝ����=> ��޿��4m��ֵ����d��=Z�ټ׎$���=R�E=����@>�l��(���_w>�=��An�xL��ZE�scI>��߽M����=9p*>���=���m꛼��=� >��=� D>B����c�B�X=�톾�AL�H��=�K&>�A��2ʰ��-I<�v>���J>k�=��=�}<=�.���^��}�B=*ԡ;�=Ee����)>Kr=����b`�=ıP>�w>��}>���=B ~>�*��[>Y��=�j�wDֽ/����M ��> qR�V�x���-<&�`��)d=-�>:� =�)=�/X�r�B>: >l_��1>�Xܽg��=�`�;w��<y���W�U>b,���L>���=߷�=x�<� >e΃��<%��� ��y�� >�"L=�� =� ���s�=l��m��V�cL��B��=�dS�om�����Z�5��7��l�=N�2� �>Z7�n�5���r����<��s<]� �G���ǀ<��B��=�.:��?F��>��C�)�;=d� >e� =�ּZ�Ľ��<d|� ��=R�W=�)����>BT��aH*<A7A�;�f� ��=cJ�<�U\�md%��eO;��
>�*B>�.X>�U�=#O��ک�4�H=�$�A���a;��{��7����=�[X>a��>s/� ���M>P�h=�����1=㍸�tdc<�=��r�ӷ=R�c�S�I���j����</�Z��� �x�:�n=� ��Ȼ���o��E��a�g�0 �'��=�� >�=�*��7M >*>��/�%�)SC=��T>��e=�$�=y��L>s>�1Ƽ�@>����% ��>L� U�=n2ۼݤ�;��F>�`����=h��>V��=
�>`�H�E��<�,[�[M+�q�=�3\����<k�������=��\6�<�=��=�(������� =r(��{>X�=�6�=@*�k�=���� � >M�>@@�=�m��u޼l���n裾ͥj=�X_�.3���
>M9,>+4=�߽�s(>L�u��{�=J�����=�Z=�W�=�r<�E��{��1�e���`��/=������b>_������=�*=$��=cC�����}p!��D���"޽g�;��7= 8��|2p�B���D�� �=\pW�;��]޽�ȝ=� =1gb��b�=k���:����#=�L�;�ݠ>��'>Wҽ��,;�1>�}�>�,>yYv>Em���Ľ��� Q\�6�<W�n=��t<�i��eh�����ꊽ�脾O�>�MJ=�K>�y�=�l4>sD>�Gy�:TV=�_-���#��h>�1�������>l0=0�B=�D�<�Ҽ�̽��;=#�#�-%'���A �n��=�L����9�i(>��A�g��;���=���k�=T��n�;�GP>���K\���Ԃ���>EA7��6�=>���(a"�?�G����=F7�=p﷽l��<\ᶽ�B%>�ס�#Fd>�����=�.!>K��=��/=�,P��x3����=�m��^=0ܫ��e��N��<@�=��>�� =�Z�xS�=hW�=�>�\D�.�G<o=j<�җ�=s�}�ԊK>q_f=^�= �=�)��|�u�LJ;Q�7=o� �^�Z�" �=ZTE=�dx>���=�"�!�K>V�D��0<$=��q>�z�<�p-���r>�L�n� >��a>��^�T�]=����5(���n�=Pƽ��g>Ÿ���g�f�k=���<D=v>=������<Eߌ=���� ��`���I�$=0���n���R��N��=�"6>ߐ �-I>G�]�V�T>j�7�kY6�� �r�8��[ >�@(=VPA>H�7��v,>�T>&">>†=�B�==�r=�2 �������_�2'N>� _�M5>��D����=�^�� �>������;FW��j�网S�^ԙ�b���vU>t>��=~�>����@�0>�j��ű= T�=�Jk���6�p_ý�f >���>��b>!i�=H"�>$��Ĕ�=9�i�����r��� �(�^=�i�<�`>�1E>7��=�zA��!��V½�����S��ԊE�˧=�Y#�����2���g<��y�<�%>��<�0������;�=��=�4 >�F��}���n�����p���N`�������F={��=���kT;��[�=��3�� i�M�$���=Xg��XN> �&�Ζ0>�G����}�=ޝ����=���>:����R��5ǻ}Xa������/�=|
����4pR>fĽ�$ý�E>���:ݱD=�x������ "��鑼���=uwG�=���=������=�&�=2�=/=���=�$�_���� 5��D��&<2�����x���<y�C�.G^���>���"3��QP>�ɷ=�@����7� �S�|� >!��;B�Y��ma��A���=��H>�{>�p�?�6�h">)�ǽC�k=U��=eZ>��4>� �A0�G5=�T�<�U'��������Z6���>��6�s�'��t���l�&�N> ����AZ=[�=y>6�
>:h�=O ����C�)f �x�D��6�=
�d�*=ƨ�=�;=�1q>@S�<��>�v�=Q�����=�@>�-=�2�=8S=��<��<�� >�˶�{�)���6>]0ٽ�u*���G<�����k��>Q��.
���e�=Ѳ> �n�X- �=��= �K�=��=���=�3�����
��r�=�ݼs��=�Ї�
;^�[삽w2�=29�{��G�;#��>�oX��>-���?{=;q���N>�B1<����]�t=�D���t�5`h��->}�+�� ���_=�(>No�=*�>j��<+��8��=����<<�J>��)>�����w�=����9�Q�"ר=fܿ=֋>17N>_7��?[,�#[�=x9����O�?֏>Zu�<�̽��<]��=>��=�3����d<6�>�>5��;�� �^�=yL�̖���>�+N�G,p=���cӘ�<�=�9$id�gl>��0�^�Ѽ�8��?�<�R��7�<)��=�8 ��QD<��q>5����]�T7b>��l�պ/=�(f�� �=89�=���;� żq�B>�6P>"s�h��;F�=l`�Hl<u`+<��һ�V>�Q6=!�`=�i�<�k>.�3>Ѳ+��C�{��> ��>���>�W=��<�8E��l>��J���>�!�=���=�6�=��"��)�=�;��->��>��a>(���^��g<���>(��,��<ѽ;>Ȋ=�e�>@<I���M> �Z�|��<f�ܽ ���W�B�E<�=`_�<w)���#��;>���1�=|��;���=¼�Q=]��=w/{��3�΅Q���Z=�%*��i�/�
=�L>�k׼,t,�mM���C�=z�5�2����ʼn�������=]�1��C��>l��=�ܽ&4��X=YA>�#�\}7�#�M>|r���=2�L��=�� ռM�>��4��E�=��ѽF��=c$����콫�c>�{i��E(� g>��B�����=�%�>���=���=i�콢ߘ=�G����>1s���F�&���q��<>dU� -��-c�q�>�W�ѳ5>30���q�v�+���b��{������c�<��j�s���p����1y>A�1>�VO���e�P�<-��=�� ��,>g:�d�>>� =ޚ
>���ce�<� U>�R�o1�=.k>:���`XĽ0��=�L>��< p ��� >#�=��>d&���T>
�v=x��=��ڽ_��=ոF>_���>=��=o�8>լ>�f���������=,�D>�.�<�Hh<�T��DJ�J���w�<U�L>�T>�3�=�
�R4M>��E>`l��4���F�e��=�߃=��l�u;!��� ������� �m<��M��:9���H����=* �=�~��2`����.�k��)�=�,�T�#>
�!=��9�O���T�>~�ԽKI7=o� ��1VG>J;�=�-�<�;k<�Ah�Kf>�6>�ka=��<�;��h�=���t#V=@-������W�>�Y������>�9>4�`��">�k=��=��>���<?� ������5��R��=��Y��J��,;>�Ĵ�d���s�<��+�a<�R>�f[>�?ս ؽr>���=8�)����=ϗ>��O>u��=���=<V�<H���Q�+��O(�_u>��>��û鏻o��=�o��K>x#=������@���-�M4�����<�$0�a�GA?���;=ȭQ��o��Ee=ݑ��fz��%O�l��=�wӽ[�Y>�8$�����}4=e�i>�M���kH> �>V�>N&��o�>M*=��=��-�S�U>ԉI��p�:1=��y�$x�=��> �:>�k= `�=-4�=�.C�?�;=+vʻ�fĽhD�=��'z��8F=ӌ8IQ�� ��=�J�=�~b>uϳ���E�t$>v�˽�m>�0w�B��=v�=�]�=�m~>Z1�Fo�=��������2���1����=��|�J!>�* >��>��]=֡ �5Q����_>����ӂ=_ZY>��� P���H�"��=�����J��[9���O�MK��p7�=�,�={X�%s�=����MH��TA�=�ּ��������0Ƣ<pL#��C>V���<.Ś�
vH��>�H!(=������=8�/����=�l��
e=���=��<>屽pR�<X����<9Q�=���Z�K�E}�=�q�=�����>��Խݞ�=V�'>Q>�Ɗ=�#������">�B��-)�� ֻ"�8> ���ĺ.=�!(=�$�>�Ê=>h��=�6�>2X��5)�������P��}>kZ>��>u��=�Ԅ��c�܊D=nW��z,>K/��A�۽D�8h�E�;�">V���<�H�D��<�ܳ�N e>K��<���=��)>v׾=B0=�D�Q�q=] >$L�����=��=I�<���ڥ�<IM��L"����>��">y��<�#=I �=8ӽ�Mq>��#�3>8�r�Y.���S�m��լ�=%�����=jh�=�G�W�� ��=�q��*�e>F�㽜F�=�WQ�c��=寈�iy_>�%@����=����:�m�ku��:�&�t��=�M�=c�-x�=�h> �S�i�=����˩8=�Ai>.$�=�6��s�P���^�V�g>�->_�S��8��ܤ�=�[=+��1�<=��T���/<i,�=A�Z�U&>i����������F���ݻ>Cv����=aЫ�}]���I�=���k%��MY���>��L��� �����=N��3Z���R���U>��k�.�=�<sD>I�!�m���K� �]2]>���=Œ >���=���<S…>b�;>-�>t./��Y�T�=����%����$z;p=Ӳ�=f.��Z�=_AD�@���n����7��z����>=�l��
���[|���/�!�<����>��&=O��=x�c<���=���94<�f��W �<���%R>J�D=N(��h�>���?�->%�;�������=J�S�X=WA=��lg�<��X��*���>���&lE��� >�(��|�������<A<\l���[.�x�1��o��S蔾u=��������� I<v^7�g�
>�F��%(%<ϞL=��=vI1=������T�T�<���;����Ж;q�!�� >�]����ý�3��%\�<�� ;�!�;_�L�� �<)����=�@=e4r��u��'��$��=����*� >�_L�kz=u�:�o:>���=oi��"h���{�=��Vi�>ݤ��|9>,�>��w;M����!�>�W�\/��-ֽ��=�-�_=!lv<���$�:�c�����=]���J=hz>�k�܎�>�(j=�?w��*�� ��s2;�1A����j��= �m����=n�@���>>�$M>+�v>��=�1>>nz��f���$�
�0(#��}e��0<uY<��>���-�K�[n��7�>�Y�=EX½ �:�2]�<��C>�
Y�?=zu2>�.>]h���W�`<s>�s>pr����ּ$��=|�ǽg9+>�rY�͸��V�����;�>�-0�l�D>~sb�"ɘ�-_��Ǎ�<Cyj=䊀��l>�y�!��w�����F~�=h�W=t��=�慾'�x>����� >nS>��ѻ��=X�v>v*�=yѯ=�a��m
�=��">��>2m��M������Y�=-u�"2!���J����<}f>����d�Ƽ�4��p>�;G�Q�P>�м���>V&���</ſ;!�;��>�+�NJ��3>6�=�-�=Ԋ���p#��L�����T1-=�$���=��D��������>ٳ���b�07<@��=�iý3����7��������=�.�=��4�}> >.�> �h��!>1��`M�=iZ#>���=�~�=*���i���A��9����I���3��%�m�>=R��;(�y> Y�kYn> �
>����*�{>O�Y>�:Y>*�����=$�Z>�M���1=*œ=]3C�(m;�E�<�1@�髓�S�n��&��i#=�f=�i)��=�t�������҅�<�p���>�y��~�=Z��=�W�=K j��ȿ�=�2>P����~���&���Z'=�)�=�k����==����^=M*�={�<
6>Mr���A�5ٱ�u���9���������.��=���=^⼪u">�#M���#>��Z>x[H>ng������<�Tû�rJ>#U\=`�)����>^
��=�W1='OҽsE>N 8�o0<hY��$�>�xR=emI�.
c����l��Z%��ܢU�ڎ���v�=Ǜm>c �=�N>�Q7��I>���<�l�=k��OL�=�8Ƚ{�;>�/��#��<�8��>��Z>r�==Cm>=|�>(�F+�;k[��-��=3 ƽh+�>"&�����~��H�=
�=�ɩ�k��;�O�=�~u��y>yU�������O�v>�''>���=Ȑ���=�-\<w �=t1�=9���)�P=�k��6\����S<��,��˨=�2�=;�<�+>FQ�=�D������t"=���=���{w �l[[�|-�G0'>X�н�f��=C47=0�=Ê�=[C��, ,>[���DJ�>MoD�ч>D�5���`>�A�kQ�w@��DŽ=t%��U6>GtD���I����=�y!��Ȁ������ _=�d�=��<=E��=5�>�N۽0ē=�q�=uE���=t�#=��=J4?>�0��u��c� �a�R��͊=B�����f�ԼB'>𰚼 /=���v�>0�R>�B7>����:$���=�
���z&>�]>@'��{�3=~�.�������=��<��*�P��=S}<�_�5�4Z �̺E��0¼_->)�����=.2l==,ڼc��o0�tM�=�xr��6���z>�݆�I�i>|w߼H̽���=���k��<sq)� Y�ηt=���<�.�=�>q]p�$�<x�����1>��y> �=���<+�<>n�)>!I��I=�=Ƅ= �v=o63���0>(\>/�6>��˽aW��I�=4
���ҽ�L�=E�ܽA=D��=� >ڎ!�]]�O�
���0=�\Ѽ����J��=�����,�.���:�>�JA=���n�j=�z�J���hIe>���Uم�P�>���=稸��K���Ω=A�>���=C��=�����
=����E=��=��)<9��� �>��0��3>�h=�|=j��:.���!����=�5o�-M��!�=Sbټ}�6>��սC= �Ľ^*��j�w�u}�P�H� R�=ڿA>�>}0ݼOy>�6��M���{�,ڼ���>��z>NR��~�C>8��N���� >�8���Խ�f���=~��=<��=f� ���+=�\!��Z�=�4��ٝ=3i�`��;��2��޶�{������D�<v��=�n>�=>{ޙ=�;3=�8;���๎=Z��*�� dv>��X=��E�$'=ꉽ��<�=X�6<�0==MW��n:��f�=6J%����=2 A��K=�Pɻ� �=�o�< �2���2��D>q>~�B���O=~O�=SZ!�:VM��Xa��S��?�����E=��O=2�S>��<�a���B�c�r�?ܭ<cBٽB?A>A”����=�" >XǢ<��\=D�#��*,�r��<�6 >. �=�u7���z�Q�L=�у�ajh�#�-�݅q�6��=�^��a,�E�=�'�=Vo��/:L>��|�w��ūe>2cD�Y-$����=�i�<a�'>�q�=��t����6%�=��ĒQ>g,L��_�<R��<���<� 潰��<<�G�s���PT>�\�w,>� =�u >y��<��=$����� =M��X_�=S�=�y@=��@��ܹ����?�\=��$���_>��:�8K<P�����2�H>�����>���=j�[>B���ω���|��g��b�����=O����4r=o�< '�"2�=�h����#��<Y�b��Q�:�Q�����B�ӽ�޶=���F#= �h>+0交�h��Ƽ8_ ��B�u4�=6f=�Z�=�\a>JN�[�)>/�ݼ����S�>/#��B=Qp>3?7=���=���=v��=+Br��_�<&偾���5�)>�Ǥ���=�ּ����6>�{����>K#b��A =W�<�>><ʫa���<�����0=c�=�j=�/(�
l�=r�=G>r�ռ�ѥ=
value�bB�b88"�bT�=�]�<>��=>�8>��ҽ*r��ѐǻ�(�����;��>���=�ŽO�D>f0�=�s�=U���O�%���3�4�y��z`��V3�$��a�6���>� =��>�H=�Dt=Ar��d˰��6>R#>Ȱ�=�M>�TR�м����=?�|>N� <�� ��d�����<�d������=b��Z �k ��9�!>�.�#��>T(=l�:>}2,=�-d=��L>���%�������;>���;}�����=���E{e=�%>���=�x���7��3>{a"=�X�<�Խ�{�;@����<�>Qx>�r7=�="��=��d<�<�>Q����5>��j=���fo�=‡� �?=����m��g���C�='~���#�=�M>�=>�׽,$^�����2Q>���J� >��V>��=��-�ĭD="�/>@�"<��ѽQh�<��ݽ>��=hϲ=�2>^I��̊�=|Ӿ�c�Z��<~��=�[�ν���<�,��(�u;W\˽�q]=ƚ=��Y�u���`.:炙�dj���������\��=�}��O�����>!�=���>�(28=1I���`�;��E��ݽ��G>`9H>/�>\r���=��<��>4w,�Eֽ��=����m>��{o>�Խ�ҋ<dj�<�i]=W!B��v�=�F>� ��4<�J�!>ҧ�= ���v �z�k>�r��ȟ�#�v>�ƽ*�>+���ø�R3"��yؼ�f���ps���_��=|=Տ��oI���=8-��x��Շ�=�!�=t��=DWE=1M��mo#>6`n��~�=���)�0+�=�v�=�'H=�,w������Q��z5=N�� ����-�=�J�j"�>G�=yHӽ�^��iy�<�\#>1N���ɗ�xw5=F?����l>/ݼ�;�j=��[��L���=}�>[�u�C_@�����R�н�_*>ѝ���:=�н5�ƽ�6i���-�<9�=����G��Q�3=yfV�q�>�o�[P=p��>R�Z>�n�<w��=�Z6>�c=5��O��=G$
�h�:=3���Vt�;q'�ɆY>��(�"�V>�2��=K��घ���ӽ�\Q>����j=5!�=P .>wڕ���>�4�=d�=Z
>��#=��i��B>�4H��l>Y�D�G��3K>9�:�jB�=r���Sx>6^>�|==��ɽjI�>��M����P(��t>�r���;=i�U���U=��=n��,�
�fCf>��i�m�O>����\�2���k�&=E���>PC>&衽����R����H>��K>6�����l��j/:Sf���KȽ8��=[�Һ�����\����������>H�>(B���c��<ڢ=��7��H9>��>ix�<W���V��=([>��k�z">��>���L�۽,��Q���ȰE>�k��V9>��=w9�>�� >!<��;!�>� �=h �=��M�����v>k{���_������(�>��>���^v�Q��V��=S[A���=�iM���/�Ш�=ܔ>6�<P�I�7���n=���"�K�������熪�>�J6>�������mڪ�����՝>UP�=-��>����R�>������B��g�=�e��#9=KG��D�K�nCc>��>�ɥ�P6
��b)>�->}��<��:�J�={ 1���.>h�<Y��=l=�=���=vD>�ԗ�wNi=�4=�t�=�Ρ<�T#��=нk�߽�R�<�нXI������qQ��M�<�� ��k��1>$ˍ���T�Լ'���"*->k��@:�ۇ'>}���j��=͌;<U�= >��ɼ����ӽ[!�=�� >� :> �6x=�����V��=W����9#>��㽠�N;w��Ln&���M�ɒ��W��+d�o�*=|D�<�d<��v���=Q�>>�{=���<���= E���Cн} �&dy><�34v=������=�=I�+�ɑ�>�vT=�e=>D�<�i��^�=o}q�vX�=
����ɗ=�O���K>LG>04��Ӥ��Ь��6<�^=�!5>t�v=�́>�\��;=Jia��(�<�/�4=>i��O3��p䕾НP�����'Q����=�� �j�>��Kɽ���=�4 ��V|��L��O�5S�=7:_�����#�=>g�&> C�<L��K��;r=;�*�=\�=��.������Z��:��=�{>����;�u޽ ��ĽMps=�2e��Ɔ<������=��S�8F/>@��=��R����씽2�Z>�����)�3��=tvC=�4-��D�=� �>�$����4����;�ʐ>���<�e�=���SB>��=W�(�a��=\z�=��=�}��m �=k��+d�Y�'���u���a����=�T�B+Ͻt���3f2�~v��F3R�y=�C����=��\��>0Qսy��<ɮ�=�r4����>;~��O��W=��=1m�>�c>l��>�Ȼ��F>C��< ��;��������P>�_Ž�!������D���􍕾d��c;�;qJ+��과�ʜ=- ��=�k�����=S�=���>�=�<g`�=W6
>����
ɍ>[�!�j2>���=�0⼁�
=F7l��k�^�`�G�>G�P��"f�ȝ��s�P��+[� �=3��� B<�t|�j������������>�{2�[滼�������=�V�"�����Y>w��(�U> �P��S�=�@>-�Ž�S��ߋ�.�<'o=Z4>U������Q�>�4j>�-��ݠ�L4���U=��>�� >:�n>��M�
�7�2~���ڽ(�5���(=F�=G��Η>_�=U|�<�0�= ���F��?e�������;�9������ [�sz��v�R��{=������>�>���B�>.�E=��޼�eབ�t�H�z��Ǝ�C]��Z <)�I>��8>8M=�V�=~[�s5߻��7<[���dS�=��= .�a[%�ۘ�>2����}>^���I������=�pG�� >
� � �9=F�>A�I<�>F�M=Q���,�=�y1���t>��< �
��@�=IR=1+�;4Ι��PJ>�n�&���.*�'g���)Խ��N=S�<�s>j��= ֽM�-=%<�m@'�����8@<E��<�U�=Q�˽�Dܽ��ʼ��>8�a>B|���S��,�\��z2��q�����;&~b::d�;�K>����m7>�o=t)/��=�<dѨ=�z�>�����!�=�8 �L�`���=i�D>L�>�
J�Ĉ=~];�:���19k��֥>�9�=��D>ǩ��]��;W
����/���<>��>�P<���=[U�����S��vt�:(Z�!�;� ����<�j�>��>kP��P>��C>e���4�\��\��6>�Q�=�>��"�̲�����8����4 =l�>8C�=ͽ>�'=����{ ��и*�T4>�����<�'�w�-�*������<�p�I�<$#0=����a1�<kϽ���M"~>& |��w^�� �0~>���=$�=��=M�F>�����j���,��� >�2M��Ge�*�>���aC���=k�|��X|��=]�C>���<mg�=��$�"�u>`:]=�ԩ>���=��A>nfp�>��=>�5=g�>0�J=?���*���(\���C>�=>�"��Tf��e>���<$� ����*�>�p�>o;:�2N%��"D=(3�>�������C�\F��<�����u<��\�T��J�<b����->�n�=��cOJ=��5<�X�)85��o��+�$�a�6>�iz=p�s;�s���>�Y�= g=���=��?<���﷽=74��&Y�>$!<�lͽX�<��$�mg�=�{;<���T�H��g�=F+a��T�<�ǀ�V>��F>�K�>g�.��|F<A�x=4�=���B��>Eh>=��=�| >�0�=�k����<s�z=� >��O��=2y�=l��|ۥ=�뜽����5��=����|-ǽ� ;�I*�]��''S�B�V����=��>�kG<����^��༴)���~���-�>O4�=&1��nf>1:���X^<� н��n���H��B�N�W���<���;z�5>��Z�����\�=ƛB>�[���N?9��_=Dje>�0m;�&=
>R@�:4k;�1=���!7�>3�������t?=u>`K>��w��,=i��:t^�=u9S=S�p����:��0���� \>#O��g���Խ��5>m!�L�=�}����=G��3��>a�>;�@��Ӽ��t=f�> @@=����4��ƭ=3��@��;w���>3��=z�=�8;=��>�x����� =��<}Mn>����t��:O{~<�*���&�����=j�k=�kE=��m�ui�E��=��=E�Y�� x��$U� !7=W���|�.��=���=?��<)�>�:��I1>S�>Y�>��L��������$�>|�l>�B>տ���<��->CD>B�㼽������`�Z���ֽ5�=&UY=3�U���:>�@=¯>]/�=7A"��^>t6�=��p>�1��� �w)f����=-u>�T�=hlV=��>2��=bF�=jGH������l>�h6�C�n>��l<�b�>%$ѽfr9��;t��:�_9�}ԯ�ڻ=1l�����=Zѽ�H��/�<�'�
e�:n��=d��=|u�=� 1���
�l� �R�������=m>P>�)>��!>}kO��x*=Ds ��)���W<��F=�7� 0�z�6>�8>�r� ��=<�vN�=)0V��Ǝ=���=��>�D�� ��mf�=Ɂ�=����ҟ>�ԟ��{G���ѽ;wp>�LH�on==̝�� -��>O��<�#q��\�>�:G�jҐ=MJA>��(�TL����ǽ�����<lG��F��Y1W=*����t=52 >����B>��=����������7<�gнY��>'�;ї�= ��=�99��:��pY=�N��A�<�R�>:��q�g�΋���'>v�i='�<c���=�b;�[�������>M�T=Gr>/<��!�=�E>�R>9�5>�Y�� ���]V><z9,��<�C�=5��=p��=�ם=A���T>���<���(�">���l�=8~��Q�=r�&<@�H�/i���z�>��>��L��b�==2��:��=��=�ma=��>�`�=��8>҈����;�;=��8='��JS.=�7<M�>��|�<-���4$>�uټ������>N;�>!��=�'��~�=��=���=I��]G�=���=����Y���ޯz<S �< ����ۘ�w����!�����<�=i� ���a�O��=wd�@p>����Yx۽�������gB=�$Y=��ýA�i���v�9 ����w>"�='+p>k4>��g=�ۓ�x��NN����=�pF=3�V�>z�z�����m/��/����T>�IL>J����>�$�F<$6=�hn��9�=^(�=jí��2v���>Q�}>�C'>xȽ2�{=�m��.�>.��f>!u˽��C>���=�py=��6>�Â�M�=RS��Ї�5ũ=Ł��8ѝ;�hU���;>�U$=��&=���=��g��=�R���j���Ἵ!��<t��J->�}�>�P=�������Rb�=�� �"K���~�>��=K�g=��<�m:3<X��=�=��<4���m�=]�׻w�½��>�~L�Y)��{K��;�<�dC�T��= ?!>%Sy���=m��=G�L�P!B=�(�Q��r�ռ'�.��H�tn�<T&ɽ��>#:��>�����%�=���ȥG�"� >�ή=r�z���ͽ��w�����*����-��fM�=� ��i��ˢ<��\�yH=G$;��Q齋�+��Ix;p�%<�i�=a �>n�V=ɤj�%Ѽ� �&>6�����>�0��5>�t8>2�޼5'"<��3�F ��v2k���<� �>M�A><�˽�8�=!O ��+�=4ʣ=_�#��NȻ�(��'�=�4H���<�z>�
��<��Y{���䄼-:z=��=�H��Bܨ=1�i���ϽA�:F7>Z&�n�'=����$��<]E7�33���g�
�Y�e���| >D��= �>�gr>[h"�L�ֽ�[*=D��P;�;ѓ��[���=�E�=��&�҃i>��I��RJ>j����>� �0�ֽ﻾�!7��p=��Y>O������=���=b�!>\7��dR>���=��f�X���%)�Z�ͽ��>|��=�>�q �� ����>�/̻�>�b!�<�4�35>rC���T�@H>tPT>N㑽��g�:�;��,>�Y�<�I���<n�=�*i>KS=t�
�i��=��9�
=��ɽ�X_>}ҳ<?=��<��{x=� 6��=���=�R޻����U/�������(�=���=��「�-�@�N�T�������^�>�= �
<��㽴�������.���e>�'��:7���= <f>��=��/<�s��ƒ���k=���='�;�
�>
��Y �<���=L;>�>.��� }����<"�S��&>���<{��>���ĭ�;��>W�J�MD7�`Љ>�:���%���`=�-����g<��T���z�>��=Z�>�R��;�s=�s�<��@��=U�>�kE>��>g��=��g����>W< �|e%�����B�=W>���<VN���'� �x�VɅ�h��>��P�m�~>TM�?�ὮOǽ�q�E��=Fa>��=�]>�����Y�+�O>~K�=���sVB�&N�=��=���f�=tSV>� !����=��6>$�#=9甽Ƶ���&ཱҺ<��0>J�6�.'9��ѹ�ː���v�=�]h����=�.�=�5���=�{�){��� O�Y�<}u��Aި�٪c��a������k����i*1>�M�>� �=Ӡヲ��<a�g���>VM}�M�P=>�ӽ(��<�� =!*O=r�X=�y->��+�Nk�>�3,>� ��nT>[n�=��:>�Л>@�c�����a;��=Q5�=c@R���=e�:>��D>�>y��=腉>'x7=�"<��>߱>Գ=P�>�hƻQ���낾�v���@�P����<ӡs�v��<���獺�B���t>uȯ��?{>�.�=e�>�޽̠ʽ�d>����=�@ �� �qހ�N=�����3�<�V𽮡ƽux==���>�=3�=��$>��;(�;>����f⎾�V�= �*�X��=�rν.ۯ� ���C�;>)����e���ջ���;h �=���=�_�<�<�>8yQ�����
��=��=`@�>�±�., �bg���Y��Xb�%�>�wO">5�6>� �Ɏ�=u�����:�vɼ�1�R!w>�w���3S> �A=��&>�2��!=�> �����>=j���5��\<q�E�|�<p1�t��Ę=G�佘� =��>>wv >M��<fW���D<&�=�#
=+M,�o�X��|�&׀>���l|Ƚ�v�<g}ʽ���6 �M\�����t����\>|L��1<�E+=�K=>����� �>ӻ=���=��H=�l�7)~�� ���.ѽ�֠�F��*>~="��h�ē#��[F���׽/z\>TH=5[���G�(����U�-�T>�s˽���=�K=�i>�+���j=m7�ω>���<�[��C�{�̎b=si�=L���Ry�R8�=��
>E��<ѭx>��3=��>fv=�4?�i��_����/�>8��'��5y�����=�4>)&*>��>��>��=%%K>���=:&�\e���K��dx��g�>���=��FbV=X8��vގ=�,>=����2ԛ<�J�=w_�8¦�����.����e޽�R������{%>�~�=��>2�^��=W
�=�VK�"d=l������=g���_�>
�@I#=��=e���\TR= r����>5X>�m�E��=����=��Y>��
�8��^+�=�܆=.��<Ia��k?:��>�X�=���=ة�=uN!��x�Ȕ�=Fh��$L1>g$��o����Y��� �7�^>���=�Q�>A)>G�;����Ӹ��K�S�� V����өK;J0n>nJ�����=�ؼ� >��=!���m�i>���=c�\>.�*>g+�:E��=_%'>f�u�w�:Ć=IT�����<�M�<F����w�<a�+��f�=�E>-�>��=�V��4S�=S�F>#A�<!*��$��=QT�<���]/� ���R���"�ڽެ����>�� >|=3��=����
�U������:>WG�=wN>y�=�l>k�>�.�=PU�=j��� yl:,���1-��:P�S�t=:��>�9`=��H�jg����+=�er�$t=�M�=��$�*��<T8����<f&���c�>c� ���=>�&�>���@��,��=��ļʻ�=+醽1۽>x>r�=��3���>(�"=��$=�k�<�6�=~���Lv>�B]��mE>�L �Us�������<ҭ<2t����=<��=����<,�p&=��ix�>�����>b�>�F=@�F��?Z=��=sC>ŌT�^gJ<��߽.=8�(� �<�i>iy=ف����o�ۘM=p��u�>�vٽ���={\r>b �#<����ڼa�h��N�>��K=��E>�*�N�*>m2��Nc�/��Y�����<�3��c�<�n���� 1>��5>�᯽)���~ �����7�=��!=�D�=�\�>~V>�t;�>���Ҽ[�Ľ`$��.�?������>�VZ�n�/�WB�=D �=���<)=2����=w��=BC�<���o�=q@R>��g<ީ;�R��=G�����=h›=�J�;��_=�@,��e:��-�3���=�҈= ��=��/>F�^=����Ӭ����+>
'==�0ɽ�2$�ݓ�=�(��˱�=����T'�<��=GF�Cg
=|<A��F��B��=#?�=�=*�HC,���ʽ1�K>�Tm�y�=S�W�ZY=���=��y=��ý����c�=2b�= &=�KX>���<j58>�o�=��O<h[=Ogɼ&%-����=p0=���>1�,>���<06�`�=}��=0��sy]����>�"������b�j��=��)�y�5>ۛ����=>c��<��ͽ���3��=��9=OĤ�7�">�Z�=o�м����{�����S�F����=̡��M����|>F�= @+�H����B�>��I>���=���9^>�,�=ON=�s>��6=��S=�P>��>�X�s�o>��="��=Ӂg�>>[���dyU� h����p=�e��H�#k��I�<�j\>Wr�=��0=�VC>��>�>�=3�5�䇇�9R=��U�!�=���;u����e{�-�l���E>i =1+ �n�S��F�~��=8�=~ɣ�&Mk�^rM>��<��S�VB��>wz�=����QQ����^�cBj<�
����L�Z��=�g = ������;���J$=��D�^+�=a#V�/n>�'��o����=q���4>����l���!�=�8/>�G8>O>x�9>Mg߼y�9>��<��I��=)9���M��6�^9���*�=��=Da�6��:�0�<�x�=���<�$��Ɛ�=�l���[����='��(>���</X�>im�m0�=��> ���Rn��~�����#� ��нl���_� H~>���<yw>��m>���=^���w���*.>�
>���b�]���>��XP=��轰a��D鯽�4����)=�����y�6dM=�8��,��1'�����vέi�=��e>*������<8֡����<�M~�ʿ޼���&�P>����W�����= |C����<�th>Av���&�V�
�m0�>�����o���d����=p���a���9>>�˽,s��4��=��\�h?��3:������h��=G�{>XX����>A~!��5>��<>*��|��̻���c���M���~�=�R(>hZȽ��=�Zb�y�H>�05=g��=J�%��N�>����$���P<���?.�#�ν��%>�dO>,x�=I�=�%<o1����P��JQ���g=��>���=�S?>�yp��g>nl�<TZ��Os<��'<�$ ���5��ȝ�µ�=���<~���K���6�r���G>�\�ll����T��ֽ�K{�۪@�+��=� c=r�>!J�=���N�J>�c�=G�>n>Ɯ<���=�P����=�;н���;�q>`�Q>c���,aI>�
�?�G>#'�=��>/��<ٵ=�x½l�f�������=7`>����18>�J��8H>��O�o�&<ϧ=>[��>�N >tV'�%#��*��~H�/�ͽ扑�{��I%���>5�/����Om>���<ty�W N�ݮ�� p�>N��:��=}邽���=��[>�����J>i"���\���}5��z*�#��g�=� U��9�pL>X�2>�Z��� >��*>�Ä�i>1>���F�u�n<��?�U3��㱍<]�>h����p����=�B����=�P��r̎<��n�k�:��4> ����=�e=��
>x}<B�=��>f_��>�>��=E�=�xZ��� �$">'tu=��������d�{>$=� �^:��ļ��w�f�o��p�<l�<�k��E��=\��Qǀ=��ýTD=I݇=���~ğ<대=F�=��I>9�H<��=ҟ\�Qm
��>˨~>:���P�o��=�z-�Ky�w�o=)���D`��_�ʽw�;�*�䵍=��>�n�w;���,h�q@3>t.&�^J���}x���=c�$>o=2=� ��}[�<C{=���� S��`m<�ݗ=�&����=~�t��������=a�����=M(�=�Ȼ�]I<d�нZU����P��m�b���_K>-�;C�O�l>��R/�>i��=+��k��=�+3��J� ^D>�zK<�ڬ=��k�1�Q�-��6غ����;Y0�>����Z��>�^����i>��߽(D���=�^>4E=��>T�r�MȽ����>�o�:� >�=.<}q�;e��<���A��� � ����`�=�B>�"w<C�)=�,�<ш�=,j��8'�=��=���C�e�:����Qľx�۽��Y�'y���>< B��`y=�؃>\k.���G�=rĽ{�/���e>����=+���~T���������=��Ž��d��tz���)��؞��'9���>͒4>�$���l�u�==�&=.X=��'�s>�>5,ٽ6W̽�R>�"M� �K�ʡ0��5i��G��}�R=r��=.�|=�6�<�L6<!Q>�/���}>��=�-�;S=0=�>��|�w����⽧n"=��޽��<=S�>�㉾/��=\m��.ޤ=�,�=��6��י>�����b<>�S�Vo<>|��=�<[>��>���=�{�<��A��3>4��<�T;�!�K�Qk��c�=t�";_�|;W�?^0>(%�>BOC��ڌ���c���=�;6���d�2( >A>A�v_+>"����a>➪��r>>kt�N77�*3>?[=�����h���Y�=�O>���>W2�=ߘ����[=F����o�����������[��1���G>ܸ�>0��=���t1Y�R�> D=�<��@=�i��2��=��˽��r=L��� �=.��=�3��UƼ)ʽ�� �?Ub>�@��EM���\>2R�=�=|�nWB>��=@!�<C���E �H3�>z�>J�p>®�=�0�=��>� >g#�=�>�~=�i=�>U����vڻ��<_9G>7 �%��=%����x�=��;�M��нh[5>&dc=�4�A۽���y��0҈�?�ἰ��޹��n����)=#γ��F�A��>O���y��$Wt=�QA>�sb>t\��⯎>>�k�CB4=$���Y̌�`�N��v��6, >Me�=(M<%�����➓��ҽW=�c���Mѽ:�>>˙�<=F���
ݼ
���є>�Ÿ�Й�=�0B�[����E����<U狼P *<�R⼖�0�'9>�=!b�<�����8��s`��"݆�C ĽZ:��o�=�g�-�=��z�?�����o���S>���=�t>5� ��\ >�����Y��m�4>J��:�>K3�<JU�]s=&>M��>��=�RW�qF >���=>�� �َ��4 \>ڞ'>ҩ�<�����>U�ʽU�=�Q#>� �=3=�Q� Ǽ�>�!�k��;D�M=K����>$s;=�,=��O>g�V;��=�� >�s�=>���,)>p�M>�%�=T�>�\��X���,>��-�]�5>*[�=��=�j���/�<��t>D��=�ż<c�$>��2�-�N���ԽK9>/X���p:վZ>��5�+�8>������� *��W>E��="����=�u����'=3�>���0=���?�=ii�����=d���;�$��=������(>1�Z<
[
dense_3/kernel/readIdentitydense_3/kernel*
T0*!

dense_3/biasConst*
dtype0*�
value�B�8"��k�= �=�?ս�gڽ����r��=�T�=��=C�[��Tؽ����=�=ǵ�=��=���=�������=�(н9��=�׽��_>$��=���=`�Խ~$�=�J�ɴ�=6~㽑Z�==W�=�(�=��ҽ�,���k۽Xl�=��=u��=�B�=�a��D��=�d׽��ٽ��=m���WS׽���ؚ�=��=�nսY_�=�J�=`Q�=!��=˯F��ӽ޽
value�B�8"���8� ���l>W�>�@>[ >�w>������l�
>?^��>]�>`��p?�@�����@�>��>�z >[a
���>jM>�->�9��
>�>��>:��b���>� >��>�4�W�>v- > ��� �A&
� �>�� ���>r�
��">��>$_�H�>R >�O��p>��=O��Q�g��������
U
dense_3/bias/readIdentity dense_3/bias*
T0*

�
dense_4/kernelConst*
dtype0*�
value�B�8"�!G>�Y=)�x���Z= ڽ`'���=��~��pܽ��=Q|J�ӡ��0��=E��:7Ľ=In�F~ռk��ӵ</��=c0̽�)��.�N<�q��o�`\>D=V��=]{����n=�_½Y���ܟ�d��=��ϼ���=*g�]�<X�;�YK�����=/f�=�H�=t���ﺿ�F��~<�sE���q= �=@�5=���������Aż� $=� �=g ν�J���v�=�5�<n�����躌ݳ���='h�<*U�=Y�j<���G�=ZfI=��;-k�]����='=,b�=,�=?ܡ�TQN�l�=F >3��<��Sb��8O� �[��(k=#\Y=���F{���Ẽ�e��.�H<�I���a;� �=�R�=p^��`��=�C�:Rď=����V$�ꌱ�����$aw=�}�_Ȍ=ß>�M �=d��=����� ޼7�=���=�rR���+��i�=@�=p�޽��=V4�=�o ����=m6+=y�A=˷�=
��J ߼&lj=j�>(�e<V��]�B�#P�=Ӌz=�먽���=�����c�=����\��=�K�=�I6��*`��J�C$�=b�*=V?z����=���=\��=�"f=��=� �=�T�=;��=����w��<X��=I� ��=/�=�,"=�#��=�S�Дi=䥐=
value�B�8"��F�=�Ba�Jh~ ���<a����
=��@<�6ֽ=��=eٓ�uU�=���=M� �U��=[���_&�;���=�� �\B�<�=����"�����CD � 9< ��=�}��@�m<4�=�I��M��;�� �Փ��N?��e�t��Z�9��9f������멽2����[�������̿�=�\�=w=���=��`�hH�=� ��7���W��=�����:Y�>Д��b�0p���k��/ɽ���<���=���<0ǽg$�=��G����=���Vc)�?���0Z�=cM���w���b��A4���Wu�=8�E��.�=� V=ۡ9�JyŽh�<.�`���=����8���Ao=��ͽ�-��[-�=����7�.=�fK=4��=(a=���ܨ���[�L�=�щ=Y��<���=��=J���Q�<г�=��g��9Q�e ;��nq�:>��̽�V��F��==�g=H#�=�W��n?�=YP��4m����լ��U���==Ji!=���=�ֽd��$�t��1>��;�:�ƽOs�=M��=���=�.�Tt�����=���r=�G�=Sp��Π=��׽cMt=xMW�`<���۽�~Q���=|��=�:ݽ������G�3}�2ؽ%�^=;C<����=%�<Ծ=�w4�B��
E
dense_4/biasConst*
dtype0*!
valueB" ��:�R ��;
U
dense_4/bias/readIdentity dense_4/bias*
T0*
_class
loc:@dense_4/bias
]
dense_5/BiasAddBiasAdddense_5/MatMuldense_4/bias/read*
T0*
data_formatNHWC
valueB" �8���Ϥ��^��
valueB" �L��=���D�
d
log_sigma_squared/readIdentitylog_sigma_squared*
T0*$

ExpExplog_sigma_squared/read*
T0
7
ShapeShapedense_5/MatMul*
8
ShapeShapedense_5/BiasAdd*
T0*
out_type0
?

dtype0
r
"random_normal/RandomStandardNormalRandomStandardNormalShape*
seed��2*
seed2y*
seed��*
seed2~*
dtype0*
T0
[

*
mulMulSqrt_1 random_normal*
T0
*
add_1Adddense_5/MatMulmul*
+
add_1Adddense_5/BiasAddmul*
T0
D
clip_by_value/Minimum/yConst*
value B
*@@*
dtype0
I
clip_by_value/MinimumMinimumadd_1clip_by_value/Minimum/y*
T0
<
clip_by_value/yConst*
value B
*@�*
dtype0
I
clip_by_valueMaximumclip_by_value/Minimumclip_by_value/y*
T0
8
truediv_2/yConst*
value B
*@@*
dtype0
9
truediv_2RealDiv clip_by_value truediv_2/y*
"
actionIdentityadd_1*
&
actionIdentity truediv_2*
-
StopGradient StopGradientaction*
,
StopGradient StopGradientadd_1*
3
sub_1Sub StopGradientdense_5/MatMul*
4
sub_1Sub StopGradientdense_5/BiasAdd*
T0
2
Pow/yConst*

mul_2Mulmul_2/xExp*
T0
+
truediv_2RealDivmul_1mul_2*
truediv_3RealDivmul_1mul_2*
Exp_1Exp truediv_2*
Exp_1Exp truediv_3*
T0
4
mul_3/xConst*

Sqrt_2Sqrtmul_4*
T0
8
truediv_3/xConst*
truediv_4/xConst*
truediv_3RealDiv truediv_3/xSqrt_2*
truediv_4RealDiv truediv_4/xSqrt_2*
T0
%
MulMulExp_1 truediv_4*
.
action_probsMulExp_1 truediv_3*
&
action_probsIdentityMul*
value�B�8"����>�=E���Io ��z*�sf>L}�=���=�D��
z8�h���m��=嬪>֫�>N��>U�z���L>�G)��#Z>�v � <�=�B�>POQ=Л���<�=�mĽ��>�����>�: >oQ�>�`��Km����P3=~i$>�Ic>��>1���>� �����g`�>$����@�?��=���>@N����=�-u>QT�>���>��8���٥�
value�B�8"�o����[B��">��>��>4]> /�>��1���ٽg��>�ž��>��}>�����9�1㾾cZ�����> ��>�R�>�����6�>���>Yu�>������>�%>>��>�7��[s��p��>U&�>Nt�>ڻ��e{><5�>�;��j�������ǎ�>�L¾��>,����>Z��>4ۆ��P�>�Vq>�ݛ�r��>�9���.I��۫��4�*w������
[
dense_5/kernel/readIdentitydense_5/kernel*
T0*!

dense_5/biasConst*
dtype0*
valueB*1P�=
valueB*
�=
U
dense_5/bias/readIdentity dense_5/bias*
T0*

2
unity-environment/Assets/ML-Agents/Examples/Bouncer/TFModels/Bouncer.bytes.meta


fileFormatVersion: 2
guid: f6197a66bd242464e8b654ef1ac01faf
timeCreated: 1520401579
licenseType: Free
TextScriptImporter:
externalObjects: {}
userData:

5
unity-environment/Assets/ML-Agents/Examples/Crawler.meta


fileFormatVersion: 2
guid: f156237910cf946e78a82c48410fef52
guid: 3aea709eb8dc04856aaa6d93573fb0df
timeCreated: 1517447132
licenseType: Free
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

2
unity-environment/Assets/ML-Agents/Examples/Crawler/Prefabs.meta


fileFormatVersion: 2
guid: f444e57207b384a2e868d864d2bae755
guid: c9cb9a4fa201d4f579ff66de92b0317f
folderAsset: yes
timeCreated: 1508478093
licenseType: Free

881
unity-environment/Assets/ML-Agents/Examples/Crawler/Prefabs/Crawler.prefab
文件差异内容过多而无法显示
查看文件

5
unity-environment/Assets/ML-Agents/Examples/Crawler/Prefabs/Crawler.prefab.meta


fileFormatVersion: 2
guid: 3db4283e33af74336bfedb01d0e011bf
timeCreated: 1508548205
licenseType: Free
guid: 0e8a62cb7c8f0483ebd12046bae9ca05
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName:

2
unity-environment/Assets/ML-Agents/Examples/Crawler/Scripts.meta


fileFormatVersion: 2
guid: 464b7b589acd8464c8c447efa71f95ed
guid: be27b48ac06d945b5865f65f96d7d008
folderAsset: yes
timeCreated: 1508478093
licenseType: Free

9
unity-environment/Assets/ML-Agents/Examples/Crawler/Scripts/CrawlerAcademy.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class CrawlerAcademy : Academy
{

Physics.defaultSolverIterations = 12;
Physics.defaultSolverVelocityIterations = 12;
Time.fixedDeltaTime = 0.01333f; // (75fps). default is .2 (60fps)
Time.maximumDeltaTime = .15f; // Default is .33
}
}

5
unity-environment/Assets/ML-Agents/Examples/Crawler/Scripts/CrawlerAcademy.cs.meta


fileFormatVersion: 2
guid: 19a3d2012efe74376a579f7f8fbfe13d
timeCreated: 1507584900
licenseType: Free
guid: 05e76ca0a155e48caa36ee60e64ee9c9
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0

5
unity-environment/Assets/ML-Agents/Examples/Crawler/TFModels.meta


fileFormatVersion: 2
guid: 4a3b975c6f9424f52aa1d7b9b87b6e1a
guid: 0b737d19c4232404389d1325808e5b4d
timeCreated: 1508478093
licenseType: Free
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

1
unity-environment/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAcademy.cs


using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using MLAgents;
public class GridAcademy : Academy

11
unity-environment/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine;
using Newtonsoft.Json;
using System.Net;
using System.Net.Sockets;
using System.Text;
using MLAgents;
public class GridAgent : Agent
{

1
unity-environment/Assets/ML-Agents/Examples/Hallway/Prefabs/HallwayArea.prefab


redGoal: {fileID: 1185286572034058}
orangeBlock: {fileID: 1972707284972814}
redBlock: {fileID: 1627706890143466}
useVectorObs: 1
--- !u!114 &114569343444552314
MonoBehaviour:
m_ObjectHideFlags: 1

33
unity-environment/Assets/ML-Agents/Examples/Hallway/Scenes/Hallway.unity


objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

m_Name: (Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)
m_EditorClassIdentifier:
broadcast: 1
continuousPlayerActions:
keyContinuousPlayerActions:
- key: 97
index: 1
value: -1

- key: 115
index: 0
value: -1
axisContinuousPlayerActions: []
discretePlayerActions:
- key: 97
value: 3

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

objectReference: {fileID: 0}
- target: {fileID: 1745841960385024, guid: f3a451555dc514f46a69319857762eda, type: 2}
propertyPath: m_IsActive
value: 0
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: f3a451555dc514f46a69319857762eda, type: 2}

1
unity-environment/Assets/ML-Agents/Examples/Hallway/Scripts/HallwayAcademy.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class HallwayAcademy : Academy {

16
unity-environment/Assets/ML-Agents/Examples/Hallway/Scripts/HallwayAgent.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class HallwayAgent : Agent
{

public GameObject redGoal;
public GameObject orangeBlock;
public GameObject redBlock;
public bool useVectorObs;
RayPerception rayPer;
Rigidbody shortBlockRB;
Rigidbody agentRB;

{
base.InitializeAgent();
academy = FindObjectOfType<HallwayAcademy>();
brain = FindObjectOfType<Brain>();
rayPer = GetComponent<RayPerception>();
agentRB = GetComponent<Rigidbody>();
groundRenderer = ground.GetComponent<Renderer>();

public override void CollectObservations()
{
float rayDistance = 12f;
float[] rayAngles = { 20f, 60f, 90f, 120f, 160f };
string[] detectableObjects = { "orangeGoal", "redGoal", "orangeBlock", "redBlock", "wall" };
AddVectorObs((float)GetStepCount() / (float)agentParameters.maxStep);
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 0f, 0f));
if (useVectorObs)
{
float rayDistance = 12f;
float[] rayAngles = { 20f, 60f, 90f, 120f, 160f };
string[] detectableObjects = { "orangeGoal", "redGoal", "orangeBlock", "redBlock", "wall" };
AddVectorObs(GetStepCount() / (float)agentParameters.maxStep);
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 0f, 0f));
}
}
IEnumerator GoalScoredSwapGroundMaterial(Material mat, float time)

427
unity-environment/Assets/ML-Agents/Examples/PushBlock/Prefabs/PushBlockArea.prefab


m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1125452240183160}
m_IsPrefabParent: 1
--- !u!1 &1031626148046192
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224466290764107542}
- component: {fileID: 222598618761215410}
- component: {fileID: 114458416987814396}
m_Layer: 5
m_Name: Description
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1077193491009950
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224325127091428956}
- component: {fileID: 222592601827262212}
- component: {fileID: 114796667970995290}
m_Layer: 5
m_Name: Description
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1125452240183160
GameObject:
m_ObjectHideFlags: 0

m_Layer: 0
m_Name: wall
m_TagString: wall
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1277485392796660
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224826767683413188}
- component: {fileID: 222663697153731606}
- component: {fileID: 114472968767706776}
m_Layer: 5
m_Name: PushBlock Basic
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0

m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1658241275278046
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224499971457369232}
- component: {fileID: 223130197460698574}
- component: {fileID: 114548077184658240}
- component: {fileID: 114826966374760500}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!1 &1730676124158560
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224846694890606296}
- component: {fileID: 222351596845747018}
- component: {fileID: 114098955560590180}
m_Layer: 5
m_Name: Reward Function
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1738131294272224
GameObject:
m_ObjectHideFlags: 1

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 4207862233523270}
- {fileID: 224499971457369232}
- {fileID: 4188187884171146}
- {fileID: 4643236529171504}
- {fileID: 4228459933126600}

m_Children:
- {fileID: 4469888496441150}
m_Father: {fileID: 4006990431719496}
m_RootOrder: 2
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!4 &4207862233523270
Transform:

m_LocalScale: {x: 25, y: 0.32738775, z: 5}
m_Children: []
m_Father: {fileID: 4006990431719496}
m_RootOrder: 4
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!4 &4255825541504078
Transform:

m_LocalScale: {x: 2, y: 0.75, z: 2}
m_Children: []
m_Father: {fileID: 4006990431719496}
m_RootOrder: 5
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!4 &4355212199748136
Transform:

m_LocalScale: {x: 25, y: 1, z: 25}
m_Children: []
m_Father: {fileID: 4006990431719496}
m_RootOrder: 3
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!4 &4673786987537112
Transform:

m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: f4abcb290251940948a31b349a6f9995, type: 2}
- {fileID: 2100000, guid: fd56382c5d1a049b6a909c184a4c6d42, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

serializedVersion: 2
m_Size: {x: 1, y: 20, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &114098955560590180
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1730676124158560}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.47794116, g: 0.47794116, b: 0.47794116, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 40
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 4
m_MaxSize: 236
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Reward Function
--- !u!114 &114350292539814250
MonoBehaviour:
m_ObjectHideFlags: 1

m_Script: {fileID: 11500000, guid: bb172294dbbcc408286b156a2c4b553c, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &114458416987814396
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1031626148046192}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.47794116, g: 0.47794116, b: 0.47794116, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 17
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 4
m_MaxSize: 236
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'Learned Behavior:
1. Don''t fall off the edge.
2. Don''t push the Orange Cube off the edge.
3. Push the Orange Cube to the goal.'
--- !u!114 &114472968767706776
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1277485392796660}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.47794116, g: 0.47794116, b: 0.47794116, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 40
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 4
m_MaxSize: 236
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: PushBlock Basic
--- !u!114 &114505490781873732
MonoBehaviour:
m_ObjectHideFlags: 1

goal: {fileID: 1441513772919942}
block: {fileID: 1293433783856340}
goalDetect: {fileID: 0}
--- !u!114 &114548077184658240
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1658241275278046}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!114 &114796667970995290
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1077193491009950}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.47794116, g: 0.47794116, b: 0.47794116, a: 1}
m_RaycastTarget: 0
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 17
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 4
m_MaxSize: 236
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'Agent falls off: -1
Orange Cube falls off: -1
Existential Pain: -.001 Every Tick (Hurry Up)
Orange Cube touches goal: +1
'
--- !u!114 &114826966374760500
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1658241275278046}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!222 &222351596845747018
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1730676124158560}
--- !u!222 &222592601827262212
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1077193491009950}
--- !u!222 &222598618761215410
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1031626148046192}
--- !u!222 &222663697153731606
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1277485392796660}
--- !u!223 &223130197460698574
Canvas:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1658241275278046}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 2
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &224325127091428956
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1077193491009950}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224846694890606296}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 141, y: -71.35101}
m_SizeDelta: {x: 600, y: 300}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224466290764107542
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1031626148046192}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224826767683413188}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 140, y: -59.2}
m_SizeDelta: {x: 600, y: 300}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224499971457369232
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1658241275278046}
m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 0.015000001, y: 0.015000008, z: 0.0010000005}
m_Children:
- {fileID: 224826767683413188}
- {fileID: 224846694890606296}
m_Father: {fileID: 4006990431719496}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: -6.8925495, y: 0.53999996}
m_SizeDelta: {x: 400, y: 200}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224826767683413188
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1277485392796660}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224466290764107542}
m_Father: {fileID: 224499971457369232}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 250, y: 36}
m_SizeDelta: {x: 600, y: 300}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224846694890606296
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1730676124158560}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1.0000006, z: 1.0000004}
m_Children:
- {fileID: 224325127091428956}
m_Father: {fileID: 224499971457369232}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 750, y: 37.57045}
m_SizeDelta: {x: 600, y: 300}
m_Pivot: {x: 0.5, y: 0.5}
useVectorObs: 1

361
unity-environment/Assets/ML-Agents/Examples/PushBlock/Scenes/PushBlock.unity


objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 31
value: 30
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 19
value: 18
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 28
value: 27
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 12
value: 11
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 8
value: 7
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 4
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &269719766
Prefab:

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 23
value: 22
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 15
value: 14
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

- {fileID: 365376271}
- {fileID: 1265651286}
m_Father: {fileID: 0}
m_RootOrder: 6
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &331588493
Prefab:

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 30
value: 29
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 26
value: 25
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
m_IsPrefabParent: 0
--- !u!1 &375852114
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 375852116}
- component: {fileID: 375852115}
m_Layer: 0
m_Name: OverviewCam
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!20 &375852115
Camera:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 375852114}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: 0.39609292, g: 0.49962592, b: 0.6509434, a: 0}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 65
orthographic: 0
orthographic size: 6.98
m_Depth: 2
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &375852116
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 375852114}
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 60, y: 65, z: 100.4}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
--- !u!1001 &465433533
Prefab:
m_ObjectHideFlags: 0

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 27
value: 26
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 20
value: 19
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 21
value: 20
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 9
value: 8
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 17
value: 16
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
m_IsPrefabParent: 0
--- !u!1001 &858315359
Prefab:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 5
objectReference: {fileID: 0}
- target: {fileID: 114505490781873732, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 226584073}
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}
- target: {fileID: 1125452240183160, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_Name
value: Area
objectReference: {fileID: 0}
- target: {fileID: 23549423015434358, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: m_DynamicOccludee
value: 1
objectReference: {fileID: 0}
- target: {fileID: 23658098095345942, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
- target: {fileID: 23149278028506196, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
- target: {fileID: 23242721846513294, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
- target: {fileID: 23154762680579788, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 214660f4189b04cada2137381f5c3607, type: 2}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
m_IsPrefabParent: 0
--- !u!1001 &880015598
Prefab:
m_ObjectHideFlags: 0

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 33
value: 32
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 29
value: 28
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 11
value: 10
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 18
value: 17
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 13
value: 12
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 34
value: 33
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 25
value: 24
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 36
value: 35
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 32
value: 31
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 10
value: 9
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

m_Children:
- {fileID: 226584072}
m_Father: {fileID: 0}
m_RootOrder: 3
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &1646905052
Prefab:

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 22
value: 21
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 35
value: 34
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 24
value: 23
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

m_Name: (Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)
m_EditorClassIdentifier:
broadcast: 1
continuousPlayerActions:
keyContinuousPlayerActions:
- key: 97
index: 0
value: -1

- key: 115
index: 1
value: -1
axisContinuousPlayerActions: []
discretePlayerActions:
- key: 97
value: 3

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 37
value: 36
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 7
value: 6
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
m_IsPrefabParent: 0
--- !u!1001 &1848135470
Prefab:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 4
objectReference: {fileID: 0}
- target: {fileID: 114505490781873732, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 226584073}
- target: {fileID: 1125452240183160, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_Name
value: Area
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
m_IsPrefabParent: 0
--- !u!1001 &1848987248
Prefab:
m_ObjectHideFlags: 0

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 16
value: 15
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

objectReference: {fileID: 0}
- target: {fileID: 4006990431719496, guid: 03bcc81e249714a22bb411dddcc5d15e, type: 2}
propertyPath: m_RootOrder
value: 14
value: 13
- target: {fileID: 223130197460698574, guid: 03bcc81e249714a22bb411dddcc5d15e,
type: 2}
- target: {fileID: 0}
propertyPath: m_Camera
value:
objectReference: {fileID: 1009000887}

19
unity-environment/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class PushAgentBasic : Agent
{

[HideInInspector]
public GoalDetect goalDetect;
public bool useVectorObs;
Rigidbody blockRB; //cached on initialization
Rigidbody agentRB; //cached on initialization
Material groundMaterial; //cached on Awake()

void Awake()
{
// There is one brain in the scene so this should find our brain.
brain = FindObjectOfType<Brain>();
academy = FindObjectOfType<PushBlockAcademy>(); //cache the academy
}

public override void CollectObservations()
{
float rayDistance = 12f;
float[] rayAngles = { 0f, 45f, 90f, 135f, 180f, 110f, 70f };
string[] detectableObjects;
detectableObjects = new string[] { "block", "goal", "wall" };
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 0f, 0f));
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 1.5f, 0f));
if (useVectorObs)
{
var rayDistance = 12f;
float[] rayAngles = { 0f, 45f, 90f, 135f, 180f, 110f, 70f };
var detectableObjects = new[] { "block", "goal", "wall" };
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 0f, 0f));
AddVectorObs(rayPer.Perceive(rayDistance, rayAngles, detectableObjects, 1.5f, 0f));
}
}
/// <summary>

1
unity-environment/Assets/ML-Agents/Examples/PushBlock/Scripts/PushBlockAcademy.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MLAgents;
public class PushBlockAcademy : Academy
{

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存