浏览代码

Merge pull request #357 from Unity-Technologies/feature/containerization

Feature/containerization
/develop-generalizationTraining-TrainerController
GitHub 7 年前
当前提交
a3c7b426
共有 13 个文件被更改,包括 410 次插入100 次删除
  1. 7
      .gitignore
  2. 4
      docs/installation.md
  3. 18
      python/learn.py
  4. 4
      python/requirements.txt
  5. 2
      python/trainer_config.yaml
  6. 3
      python/unityagents/environment.py
  7. 90
      python/unitytrainers/trainer_controller.py
  8. 132
      unity-environment/Assets/ML-Agents/Examples/Crawler/Crawler.unity
  9. 12
      Dockerfile
  10. 59
      docs/Using-Docker.md
  11. 176
      images/docker_build_settings.png
  12. 3
      unity-volume/.gitignore

7
.gitignore


/unity-environment/Assets/AssetStoreTools*
# Tensorflow Model Info
/python/models
/python/summaries
/models
/summaries
python/models
python/summaries
# Environemnt logfile
*unity-environment.log

*.egg-info*
*.eggs*
*.gitignore.swp
.DS_Store

4
docs/installation.md


* docopt (Training)
* TensorFlow (1.0+) (Training)
## Docker-based Installation (experimental)
If you’d like to use Docker for ML Agents, please follow [this guide](Using-Docker.md).
### Installing Dependencies
To install dependencies, go into the `python` sub-directory of the repositroy, and run (depending on your python version) from the command line:

18
python/learn.py


import logging
import os
from docopt import docopt
from unitytrainers.trainer_controller import TrainerController

--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 Parameters
if options['--docker-target-name'] == 'Empty':
docker_target_name = ''
else:
docker_target_name = options['--docker-target-name']
# General parameters
run_id = options['--run-id']

save_freq = int(options['--save-freq'])
env_name = options['<env>']
env_path = options['<env>']
keep_checkpoints = int(options['--keep-checkpoints'])
worker_id = int(options['--worker-id'])
curriculum_file = str(options['--curriculum'])

fast_simulation = not bool(options['--slow'])
tc = TrainerController(env_name, run_id, save_freq, curriculum_file, fast_simulation, load_model, train_model,
worker_id, keep_checkpoints, lesson, seed)
# Constants
# Assumption that this yaml is present in same dir as this file
base_path = os.path.dirname(__file__)
TRAINER_CONFIG_PATH = os.path.abspath(os.path.join(base_path, "trainer_config.yaml"))
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)
tc.start_learning()

4
python/requirements.txt


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

docopt
pyyaml
pyyaml

2
python/trainer_config.yaml


summary_freq: 1000
normalize: true
batch_size: 1000
buffer_size: 10000
buffer_size: 10000
hidden_units: 64
max_steps: 1.0e4

3
python/unityagents/environment.py


: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.
"""
atexit.register(self.close)
self.port = base_port + worker_id
self._buffer_size = 12000

file_name = (file_name.strip()
.replace('.app', '').replace('.exe', '').replace('.x86_64', '').replace('.x86', ''))
true_filename = os.path.basename(os.path.normpath(file_name))
logger.debug('The true file name is {}'.format(true_filename))
launch_string = None
if platform == "linux" or platform == "linux2":
candidates = glob.glob(os.path.join(cwd, file_name) + '.x86_64')

"Provided filename does not match any environments."
.format(true_filename))
else:
logger.debug("This is the launch string {}".format(launch_string))
# Launch Unity environment
proc1 = subprocess.Popen(
[launch_string,

90
python/unitytrainers/trainer_controller.py


class TrainerController(object):
def __init__(self, env_name, run_id, save_freq, curriculum_file, fast_simulation, load, train,
worker_id, keep_checkpoints, lesson, seed):
self.model_path = './models/{}'.format(run_id)
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):
"""
: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 curriculum_file: Curriculum json file for environment
:param fast_simulation: Whether to run the game at training speed
:param load: Whether to load the model or randomly initialize
:param train: Whether to train model, or only run inference
:param worker_id: Number to add to communication port (5005). Used for multi-environment
:param keep_checkpoints: How many model checkpoints to keep
:param lesson: Start learning from this lesson
: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
"""
self.trainer_config_path = trainer_config_path
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.model_path = './models/{run_id}'.format(run_id=run_id)
self.curriculum_file = curriculum_file
self.summaries_dir = './summaries'
else:
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 curriculum_file is None:
self.curriculum_file = None
else:
self.curriculum_file = '/{docker_target_name}/{curriculum_file}'.format(
docker_target_name=docker_target_name,
curriculum_file=curriculum_file)
self.summaries_dir = '/{docker_target_name}/summaries'.format(docker_target_name=docker_target_name)
self.curriculum_file = curriculum_file
self.lesson = lesson
self.fast_simulation = fast_simulation
self.load_model = load

self.seed = seed
np.random.seed(self.seed)
tf.set_random_seed(self.seed)
self.env = UnityEnvironment(file_name=env_name, worker_id=self.worker_id,
self.env = UnityEnvironment(file_name=env_path, worker_id=self.worker_id,
self.env_name = (env_name.strip().replace('.app', '').replace('.exe', '').replace('.x86_64', '')
.replace('.x86', ''))
self.env_name = os.path.basename(os.path.normpath(self.env_name))
self.logger.info(str(self.env))
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:

self.logger.info("\t" + n)
return nodes
def _save_model(self, sess, saver, model_path="./", steps=0):
def _save_model(self, sess, saver, steps=0):
:param model_path: Designated model path.
last_checkpoint = model_path + '/model-' + str(steps) + '.cptk'
last_checkpoint = self.model_path + '/model-' + str(steps) + '.cptk'
tf.train.write_graph(sess.graph_def, model_path, 'raw_graph_def.pb', as_text=False)
tf.train.write_graph(sess.graph_def, self.model_path, 'raw_graph_def.pb', as_text=False)
self.logger.info("Saved Model")
def _export_graph(self):

if len(self.env.external_brain_names) > 1:
graph_scope = re.sub('[^0-9a-zA-Z]+', '-', brain_name)
trainer_parameters['graph_scope'] = graph_scope
trainer_parameters['summary_path'] = './summaries/{}'.format(
str(self.run_id)) + '_' + graph_scope
trainer_parameters['summary_path'] = '{basedir}/{name}'.format(
basedir=self.summaries_dir,
name=str(self.run_id) + '_' + graph_scope)
trainer_parameters['summary_path'] = './summaries/{}'.format(self.run_id)
trainer_parameters['summary_path'] = '{basedir}/{name}'.format(
basedir=self.summaries_dir,
name=str(self.run_id))
if brain_name in trainer_config:
_brain_key = brain_name
while not isinstance(trainer_config[_brain_key], dict):

raise UnityEnvironmentException("The trainer config contains an unknown trainer type for brain {}"
.format(brain_name))
@staticmethod
def _load_config(config_filename):
def _load_config(self):
with open(config_filename) as data_file:
with open(self.trainer_config_path) as data_file:
raise UnityEnvironmentException("The file {} could not be found. Will use default Hyperparameters"
.format("trainer_config.yaml"))
raise UnityEnvironmentException("""Parameter file could not be found here {}.
Will use default Hyper parameters"""
.format(self.trainer_config_path))
raise UnityEnvironmentException("There was an error decoding {}".format("trainer_config.yaml"))
raise UnityEnvironmentException("There was an error decoding Trainer Config from this path : {}"
.format(self.trainer_config_path))
@staticmethod
def _create_model_path(model_path):

def start_learning(self):
self.env.curriculum.set_lesson_number(self.lesson)
trainer_config = self._load_config("trainer_config.yaml")
trainer_config = self._load_config()
self._create_model_path(self.model_path)
tf.reset_default_graph()

global_step += 1
if global_step % self.save_freq == 0 and global_step != 0 and self.train_model:
# Save Tensorflow model
self._save_model(sess, model_path=self.model_path, steps=global_step, saver=saver)
self._save_model(sess, steps=global_step, saver=saver)
self._save_model(sess, model_path=self.model_path, steps=global_step, saver=saver)
self._save_model(sess, steps=global_step, saver=saver)
self._save_model(sess, model_path=self.model_path, steps=global_step, saver=saver)
self._save_model(sess, steps=global_step, saver=saver)
pass
self.env.close()
if self.train_model:

132
unity-environment/Assets/ML-Agents/Examples/Crawler/Crawler.unity


m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.4465934, g: 0.49642956, b: 0.5748249, a: 1}
m_IndirectSpecularColor: {r: 0.4465785, g: 0.49641252, b: 0.574817, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4

debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!114 &140901381
--- !u!114 &157493879
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}

m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41e9bda8f3cf1492fa74926a530f6f70, type: 3}
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)
m_Script: {fileID: 11500000, guid: 8b23992c8eb17439887f5e944bf04a40, type: 3}
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)
continuousPlayerActions:
- key: 101
index: 0
value: -1
- key: 101
index: 1
value: -1
- key: 101
index: 2
value: -1
- key: 101
index: 3
value: -1
- key: 114
index: 3
value: 1
- key: 116
index: 11
value: -1
- key: 100
index: 1
value: 1
- key: 119
index: 7
value: -1
discretePlayerActions: []
defaultAction: 0
graphModel: {fileID: 4900000, guid: 3569492a1961e4abe87b232f5ccaac90, type: 3}
graphScope:
graphPlaceholders: []
BatchSizePlaceholderName: batch_size
StatePlacholderName: state
RecurrentInPlaceholderName: recurrent_in
RecurrentOutPlaceholderName: recurrent_out
ObservationPlaceholderName: []
ActionPlaceholderName: action
brain: {fileID: 393360180}
--- !u!1 &393360178
GameObject:

m_EditorClassIdentifier:
brainParameters:
stateSize: 117
stackedStates: 1
actionSize: 12
memorySize: 0
cameraResolutions: []

stateSpaceType: 1
brainType: 3
CoreBrains:
- {fileID: 140901381}
- {fileID: 722649573}
- {fileID: 1365757417}
- {fileID: 1527314308}
instanceID: 38818
--- !u!114 &722649573
- {fileID: 1543732223}
- {fileID: 681646356}
- {fileID: 2072160993}
- {fileID: 157493879}
instanceID: 17776
--- !u!114 &681646356
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}

m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 943466ab374444748a364f9d6c3e2fe2, type: 3}
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)
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)
m_EditorClassIdentifier:
broadcast: 1
brain: {fileID: 393360180}

m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 3db4283e33af74336bfedb01d0e011bf, type: 2}
m_IsPrefabParent: 0
--- !u!114 &1365757417
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 35813a1be64e144f887d7d5f15b963fa, type: 3}
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)
m_EditorClassIdentifier:
brain: {fileID: 393360180}
--- !u!1 &1392866527
GameObject:
m_ObjectHideFlags: 0

m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10

m_PrefabParentObject: {fileID: 4491788954268586, guid: 3db4283e33af74336bfedb01d0e011bf,
type: 2}
m_PrefabInternal: {fileID: 1808602249}
--- !u!114 &1527314308
--- !u!114 &1543732223
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}

m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8b23992c8eb17439887f5e944bf04a40, type: 3}
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)
m_Script: {fileID: 11500000, guid: 41e9bda8f3cf1492fa74926a530f6f70, type: 3}
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)
graphModel: {fileID: 4900000, guid: 3569492a1961e4abe87b232f5ccaac90, type: 3}
graphScope:
graphPlaceholders:
- name: epsilon
valueType: 1
minValue: -1
maxValue: 1
BatchSizePlaceholderName: batch_size
StatePlacholderName: state
RecurrentInPlaceholderName: recurrent_in
RecurrentOutPlaceholderName: recurrent_out
ObservationPlaceholderName: []
ActionPlaceholderName: action
continuousPlayerActions:
- key: 101
index: 0
value: -1
- key: 101
index: 1
value: -1
- key: 101
index: 2
value: -1
- key: 101
index: 3
value: -1
- key: 114
index: 3
value: 1
- key: 116
index: 11
value: -1
- key: 100
index: 1
value: 1
- key: 119
index: 7
value: -1
discretePlayerActions: []
defaultAction: 0
brain: {fileID: 393360180}
--- !u!1001 &1599453071
Prefab:

m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!114 &2072160993
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 35813a1be64e144f887d7d5f15b963fa, type: 3}
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)
m_EditorClassIdentifier:
brain: {fileID: 393360180}
--- !u!1 &2095421678
GameObject:
m_ObjectHideFlags: 0

- key: steps
value: 0
done: 0
maxStepReached: 0
episodeCount: 0
currentStep: 0

12
Dockerfile


# Use an official Python runtime as a parent image
FROM python:3.6-slim
RUN apt-get update && apt-get -y upgrade
ADD python/requirements.txt .
RUN pip install --trusted-host pypi.python.org -r requirements.txt
WORKDIR /execute
COPY python /execute/python
ENTRYPOINT ["python", "python/learn.py"]

59
docs/Using-Docker.md


# Using Docker For ML Agents (Experimental)
We are currently offering an experimental solution for Windows and Mac users who would like to do training or inference using Docker. This option may be appealing to users who would like to avoid dealing with Python and TensorFlow installation on their host machines. This setup currently forces both TensorFlow and Unity to rely on _only_ the CPU for computation purposes. As such, we currently only support training using environments that only contain agents which use vector observations, rather than camera-based visual observations. For example, the [GridWorld](Example-Environments.md#gridworld) environment which use visual observations for training is not supported.
## Requirements
- Unity Linux Standalone Player ([Link](https://unity3d.com/get-unity/download?ref=professional&_ga=2.161111422.259506921.1519336396-1357272041.1488299149))
- Docker ([Link](https://www.docker.com/community-edition#/download))
## Setup
- Install Docker (see link above) if you don't have it setup on your machine.
- Since Docker runs a container in an environment that is isolated from the host machine, we will be using a mounted directory, e.g. `unity-volume` in your host machine in order to share data, e.g. the Unity executable, curriculum files and tensorflow graph.
## Usage
- Docker typically runs a container sharing a (linux) kernel with the host machine, this means that the
Unity environment **has** to be built for the **linux platform**. From the Build Settings Window, please select the architecture to be `x86_64` and choose the build to be `headless` (_This is important because we are running it in a container that does not have graphics drivers installed_).
Save the generated environment in the directory to be mounted (e.g. we have conveniently created an empty directory called at the top level `unity-volume`).
![Build Settings For Docker](../images/docker_build_settings.png)
- Ensure that `unity-volume/<environment-name>.x86_64` and `unity-volume/environment-name_Data`. So for example, `<environment_name>` might be `3Dball` and you might want to ensure that `unity-volume/3Dball.x86_64` and `unity-volume/3Dball_Data` are both present in the directory `unity-volume`.
- Make sure the docker engine is running on your machine, then build the docker container by running `docker build -t <image_name> .` . in the top level of the source directory. Replace `<image_name>` by the name of the image that you want to use, e.g. `balance.ball.v0.1`.
- Run the container:
```
docker run --mount type=bind,source="$(pwd)"/unity-volume,target=/unity-volume \
<image-name>:latest <environment-name> \
--docker-target-name=unity-volume \
--train --run-id=<run-id>
```
For the `3DBall` environment, for example this would be:
- Run the container:
```
docker run --mount type=bind,source="$(pwd)"/unity-volume,target=/unity-volume \
balance.ball.v0.1:latest 3Dball \
--docker-target-name=unity-volume \
--train --run-id=<run-id>
```
**Notes on argument values**
- `source` : Reference to the path in your host OS where you will store the Unity executable.
- `target`: Tells docker to mount the `source` path as a disk with this name.
- `docker-target-name`: Tells the ML-Agents python package what the name of the disk where it can read the Unity executable and store the graph.**This should therefore be identical to the `target`.**
- `train`, `run-id`: ML-Agents arguments passed to `learn.py`. `train` trains the algorithm, `run-id` is used to tag each experiment with a unique id.
For more details on docker mounts, look at [these](https://docs.docker.com/storage/bind-mounts/) docs from Docker.

176
images/docker_build_settings.png

之前 之后
宽度: 632  |  高度: 599  |  大小: 68 KiB

3
unity-volume/.gitignore


*
# Ignore everything in this directory except for .gitignore. This directory is for illustrative purposes
!.gitignore
正在加载...
取消
保存