Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

SAC-Minitaurus mit der Actor-Learner-API

Copyright 2020 Die Autoren der TF-Agenten.

Ansicht auf TensorFlow.org In Google Colab ausführen Quelle auf GitHub anzeigen Notizbuch herunterladen

Einführung

Dieses Beispiel zeigt, wie Sie einen Soft Actor Critic- Agenten in der Minitaur- Umgebung trainieren .

Wenn Sie das DQN Colab durchgearbeitet haben, sollte sich dies sehr vertraut anfühlen. Bemerkenswerte Änderungen umfassen:

  • Ändern des Agenten von DQN zu SAC.
  • Training auf Minitaur, einer viel komplexeren Umgebung als CartPole. Die Minitaur-Umgebung zielt darauf ab, einen Vierbeiner zu trainieren, um sich vorwärts zu bewegen.
  • Verwenden der TF-Agents Actor-Learner-API für verteiltes Reinforcement-Lernen.

Die API unterstützt sowohl die verteilte Datenerfassung mithilfe eines Erfahrungswiedergabepuffers und eines variablen Containers (Parameterserver) als auch das verteilte Training auf mehrere Geräte. Die API ist sehr einfach und modular aufgebaut. Wir verwenden Reverb sowohl für den Wiedergabepuffer als auch für den variablen Container und die TF DistributionStrategy-API für verteiltes Training auf GPUs und TPUs.

Wenn Sie die folgenden Abhängigkeiten nicht installiert haben, führen Sie Folgendes aus:

sudo apt-get install -y xvfb ffmpeg
pip install -q gym
pip install -q 'imageio==2.4.0'
pip install -q matplotlib
pip install -q PILLOW
pip install -q tf-agents[reverb]
pip install -q pybullet



ffmpeg is already the newest version (7:3.4.8-0ubuntu0.2).
xvfb is already the newest version (2:1.19.6-1ubuntu4.7).
The following packages were automatically installed and are no longer required:
  dconf-gsettings-backend dconf-service dkms freeglut3 freeglut3-dev
  glib-networking glib-networking-common glib-networking-services
  gsettings-desktop-schemas libcairo-gobject2 libcolord2 libdconf1
  libegl1-mesa libepoxy0 libglu1-mesa libglu1-mesa-dev libgtk-3-0
  libgtk-3-common libice-dev libjansson4 libjson-glib-1.0-0
  libjson-glib-1.0-common libproxy1v5 librest-0.7-0 libsm-dev
  libsoup-gnome2.4-1 libsoup2.4-1 libxi-dev libxmu-dev libxmu-headers
  libxnvctrl0 libxt-dev linux-gcp-headers-5.0.0-1026
  linux-headers-5.0.0-1026-gcp linux-image-5.0.0-1026-gcp
  linux-modules-5.0.0-1026-gcp pkg-config policykit-1-gnome python3-xkit
  screen-resolution-extra xserver-xorg-core-hwe-18.04
Use 'sudo apt autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 91 not upgraded.

Installieren

Zuerst importieren wir die verschiedenen Tools, die wir benötigen.

import base64
import imageio
import IPython
import matplotlib.pyplot as plt
import os
import reverb
import tempfile
import PIL.Image

import tensorflow as tf

from tf_agents.agents.ddpg import critic_network
from tf_agents.agents.sac import sac_agent
from tf_agents.agents.sac import tanh_normal_projection_network
from tf_agents.environments import suite_pybullet
from tf_agents.experimental.train import actor
from tf_agents.experimental.train import learner
from tf_agents.experimental.train import triggers
from tf_agents.experimental.train.utils import spec_utils
from tf_agents.experimental.train.utils import strategy_utils
from tf_agents.experimental.train.utils import train_utils
from tf_agents.metrics import py_metrics
from tf_agents.networks import actor_distribution_network
from tf_agents.policies import greedy_policy
from tf_agents.policies import py_tf_eager_policy
from tf_agents.policies import random_py_policy
from tf_agents.replay_buffers import reverb_replay_buffer
from tf_agents.replay_buffers import reverb_utils

tempdir = tempfile.gettempdir()

Hyperparameter

env_name = "MinitaurBulletEnv-v0" # @param {type:"string"}

# Use "num_iterations = 1e6" for better results (2 hrs)
# 1e5 is just so this doesn't take too long (1 hr)
num_iterations = 100000 # @param {type:"integer"}

initial_collect_steps = 10000 # @param {type:"integer"}
collect_steps_per_iteration = 1 # @param {type:"integer"}
replay_buffer_capacity = 10000 # @param {type:"integer"}

batch_size = 256 # @param {type:"integer"}

critic_learning_rate = 3e-4 # @param {type:"number"}
actor_learning_rate = 3e-4 # @param {type:"number"}
alpha_learning_rate = 3e-4 # @param {type:"number"}
target_update_tau = 0.005 # @param {type:"number"}
target_update_period = 1 # @param {type:"number"}
gamma = 0.99 # @param {type:"number"}
reward_scale_factor = 1.0 # @param {type:"number"}

actor_fc_layer_params = (256, 256)
critic_joint_fc_layer_params = (256, 256)

log_interval = 5000 # @param {type:"integer"}

num_eval_episodes = 20 # @param {type:"integer"}
eval_interval = 10000 # @param {type:"integer"}

policy_save_interval = 5000 # @param {type:"integer"}

Umgebung

Umgebungen in RL stellen die Aufgabe oder das Problem dar, die wir lösen möchten. Standardumgebungen können in TF-Agenten mithilfe von suites einfach erstellt werden. Wir haben verschiedene suites zum Laden von Umgebungen aus Quellen wie OpenAI Gym, Atari, DM Control usw., denen ein String-Umgebungsname zugewiesen wurde.

Laden wir nun die Minituar-Umgebung aus der Pybullet-Suite.

env = suite_pybullet.load(env_name)
env.reset()
PIL.Image.fromarray(env.render())
current_dir=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_envs/bullet
urdf_root=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_data

/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/gym/logger.py:30: UserWarning: WARN: Box bound precision lowered by casting to float32
  warnings.warn(colorize('%s: %s'%('WARN', msg % args), 'yellow'))

png

In dieser Umgebung besteht das Ziel darin, dass der Agent eine Richtlinie trainiert, die den Minitaur-Roboter steuert und ihn so schnell wie möglich vorwärts bringt. Episoden dauern 1000 Schritte und die Rückkehr ist die Summe der Belohnungen während der gesamten Episode.

Betrachten wir die Informationen, die die Umgebung bereitstellt, als observation , observation derer die Richtlinie actions generiert.

print('Observation Spec:')
print(env.time_step_spec().observation)
print('Action Spec:')
print(env.action_spec())
Observation Spec:
BoundedArraySpec(shape=(28,), dtype=dtype('float32'), name='observation', minimum=[  -3.1515927   -3.1515927   -3.1515927   -3.1515927   -3.1515927
   -3.1515927   -3.1515927   -3.1515927 -167.72488   -167.72488
 -167.72488   -167.72488   -167.72488   -167.72488   -167.72488
 -167.72488     -5.71        -5.71        -5.71        -5.71
   -5.71        -5.71        -5.71        -5.71        -1.01
   -1.01        -1.01        -1.01     ], maximum=[  3.1515927   3.1515927   3.1515927   3.1515927   3.1515927   3.1515927
   3.1515927   3.1515927 167.72488   167.72488   167.72488   167.72488
 167.72488   167.72488   167.72488   167.72488     5.71        5.71
   5.71        5.71        5.71        5.71        5.71        5.71
   1.01        1.01        1.01        1.01     ])
Action Spec:
BoundedArraySpec(shape=(8,), dtype=dtype('float32'), name='action', minimum=-1.0, maximum=1.0)

Wie wir sehen können, ist die Beobachtung ziemlich komplex. Wir erhalten 28 Werte, die die Winkel, Geschwindigkeiten und Drehmomente für alle Motoren darstellen. Im Gegenzug erwartet die Umgebung 8 Werte für die Aktionen zwischen [-1, 1] . Dies sind die gewünschten Motorwinkel.

Normalerweise erstellen wir zwei Umgebungen: eine zum Sammeln von Daten während des Trainings und eine zum Auswerten. Die Umgebungen sind in reinem Python geschrieben und verwenden Numpy-Arrays, die von der Actor Learner-API direkt verwendet werden.

collect_env = suite_pybullet.load(env_name)
eval_env = suite_pybullet.load(env_name)
urdf_root=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_data
urdf_root=/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/pybullet_data

Vertriebsstrategie

Wir verwenden die DistributionStrategy-API, um die Ausführung der Zugschrittberechnung über mehrere Geräte wie mehrere GPUs oder TPUs mithilfe von Datenparallelität auszuführen. Der Zugschritt:

  • Erhält eine Reihe von Trainingsdaten
  • Teilt es auf die Geräte auf
  • Berechnet den Vorwärtsschritt
  • Aggregiert und berechnet die BEDEUTUNG des Verlusts
  • Berechnet den Rückwärtsschritt und führt eine Aktualisierung der Gradientenvariablen durch

Mit der TF-Agents Learner API und der DistributionStrategy API können Sie ganz einfach zwischen dem Ausführen des Zugschritts auf GPUs (mit MirroredStrategy) und TPUs (mit TPUStrategy) wechseln, ohne die unten stehende Trainingslogik zu ändern.

Aktivieren der GPU

Wenn Sie versuchen möchten, auf einer GPU ausgeführt zu werden, müssen Sie zuerst die GPUs für das Notebook aktivieren:

  • Navigieren Sie zu Bearbeiten → Notebook-Einstellungen
  • Wählen Sie GPU aus der Dropdown-Liste Hardware Accelerator

Eine Strategie auswählen

Verwenden Sie strategy_utils , um eine Strategie zu generieren. Übergeben Sie unter der Haube den Parameter:

use_gpu = True

strategy = strategy_utils.get_strategy(tpu=False, use_gpu=use_gpu)
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

Alle Variablen und Agenten müssen unter strategy.scope() , wie Sie unten sehen werden.

Agent

Um einen SAC-Agenten zu erstellen, müssen wir zuerst die Netzwerke erstellen, die er trainieren wird. SAC ist ein Schauspieler-Kritiker-Agent, daher brauchen wir zwei Netzwerke.

Der Kritiker wird uns Wertschätzungen für Q(s,a) . Das heißt, es wird als Eingabe eine Beobachtung und eine Handlung erhalten, und es wird uns eine Schätzung geben, wie gut diese Handlung für den gegebenen Zustand war.

observation_spec, action_spec, time_step_spec = (
      spec_utils.get_tensor_specs(collect_env))

with strategy.scope():
  critic_net = critic_network.CriticNetwork(
        (observation_spec, action_spec),
        observation_fc_layer_params=None,
        action_fc_layer_params=None,
        joint_fc_layer_params=critic_joint_fc_layer_params,
        kernel_initializer='glorot_uniform',
        last_kernel_initializer='glorot_uniform')

Wir werden diese Kritiker verwenden , um einen Zug actor - Netzwerk , das uns Aktionen eine Beobachtung gegeben generieren können.

Das ActorNetwork Parameter für eine tanh-gequetschte MultivariateNormalDiag- Verteilung voraus. Diese Verteilung wird dann unter Berücksichtigung der aktuellen Beobachtung abgetastet, wann immer wir Aktionen generieren müssen.

with strategy.scope():
  actor_net = actor_distribution_network.ActorDistributionNetwork(
      observation_spec,
      action_spec,
      fc_layer_params=actor_fc_layer_params,
      continuous_projection_net=(
          tanh_normal_projection_network.TanhNormalProjectionNetwork))

Mit diesen Netzwerken können wir jetzt den Agenten instanziieren.

with strategy.scope():
  train_step = train_utils.create_train_step()

  tf_agent = sac_agent.SacAgent(
        time_step_spec,
        action_spec,
        actor_network=actor_net,
        critic_network=critic_net,
        actor_optimizer=tf.compat.v1.train.AdamOptimizer(
            learning_rate=actor_learning_rate),
        critic_optimizer=tf.compat.v1.train.AdamOptimizer(
            learning_rate=critic_learning_rate),
        alpha_optimizer=tf.compat.v1.train.AdamOptimizer(
            learning_rate=alpha_learning_rate),
        target_update_tau=target_update_tau,
        target_update_period=target_update_period,
        td_errors_loss_fn=tf.math.squared_difference,
        gamma=gamma,
        reward_scale_factor=reward_scale_factor,
        train_step_counter=train_step)

  tf_agent.initialize()

Puffer wiedergeben

Um den Überblick über die aus der Umgebung gesammelten Daten zu behalten, verwenden wir Reverb , ein effizientes, erweiterbares und benutzerfreundliches Wiedergabesystem von Deepmind. Es speichert Erfahrungsdaten, die von den Schauspielern gesammelt und vom Lernenden während des Trainings konsumiert wurden.

In diesem Lernprogramm ist dies weniger wichtig als max_size In einer verteilten Umgebung mit asynchroner Erfassung und Schulung möchten Sie wahrscheinlich mit rate_limiters.SampleToInsertRatio experimentieren und dabei ein samples_per_insert zwischen 2 und 1000 verwenden. Beispiel:

rate_limiter=reverb.rate_limiters.SampleToInsertRatio(samples_per_insert=3.0, min_size_to_sample=3, error_buffer=3.0))
table_name = 'uniform_table'
table = reverb.Table(
    table_name,
    max_size=replay_buffer_capacity,
    sampler=reverb.selectors.Uniform(),
    remover=reverb.selectors.Fifo(),
    rate_limiter=reverb.rate_limiters.MinSize(1))

reverb_server = reverb.Server([table])

Der Wiedergabepuffer wird unter Verwendung von Spezifikationen erstellt, die die zu speichernden Tensoren beschreiben, die vom Agenten unter Verwendung von tf_agent.collect_data_spec abgerufen werden tf_agent.collect_data_spec .

Da der SAC-Agent sowohl die aktuelle als auch die nächste Beobachtung benötigt, um den Verlust zu berechnen, setzen wir sequence_length=2 .

reverb_replay = reverb_replay_buffer.ReverbReplayBuffer(
    tf_agent.collect_data_spec,
    sequence_length=2,
    table_name=table_name,
    local_server=reverb_server)

Jetzt generieren wir einen TensorFlow-Datensatz aus dem Reverb-Wiedergabepuffer. Wir werden dies an den Lernenden weitergeben, um Erfahrungen für das Training zu sammeln.

dataset = reverb_replay.as_dataset(
      sample_batch_size=batch_size, num_steps=2).prefetch(50)
experience_dataset_fn = lambda: dataset

Richtlinien

In TF-Agents stellen Richtlinien den Standardbegriff von Richtlinien in RL dar: time_step ein time_step , wird eine Aktion oder eine Verteilung über Aktionen erzeugt. Die Hauptmethode ist policy_step = policy.step(time_step) wobei policy_step ein benanntes Tupel PolicyStep(action, state, info) . Die policy_step.action ist die action , die auf die Umgebung angewendet werden soll. Der state stellt den Status für Stateful (RNN) -Richtlinien dar, und die info können zusätzliche Informationen wie Protokollwahrscheinlichkeiten der Aktionen enthalten.

Agenten enthalten zwei Richtlinien:

  • agent.policy - Die Hauptrichtlinie, die für die Evaluierung und Bereitstellung verwendet wird.
  • agent.collect_policy - Eine zweite Richtlinie, die für die Datenerfassung verwendet wird.
tf_eval_policy = tf_agent.policy
eval_policy = py_tf_eager_policy.PyTFEagerPolicy(
  tf_eval_policy, use_tf_function=True)
tf_collect_policy = tf_agent.collect_policy
collect_policy = py_tf_eager_policy.PyTFEagerPolicy(
  tf_collect_policy, use_tf_function=True)

Richtlinien können unabhängig von Agenten erstellt werden. Verwenden Sie beispielsweise tf_agents.policies.random_py_policy , um eine Richtlinie zu erstellen, die zufällig eine Aktion für jeden Zeitschritt auswählt.

random_policy = random_py_policy.RandomPyPolicy(
  collect_env.time_step_spec(), collect_env.action_spec())

Schauspieler

Der Akteur verwaltet die Interaktionen zwischen einer Richtlinie und einer Umgebung.

  • Die Actor-Komponenten enthalten eine Instanz der Umgebung (als py_environment ) und eine Kopie der Richtlinienvariablen.
  • Jeder Actor-Worker führt eine Folge von Datenerfassungsschritten unter Berücksichtigung der lokalen Werte der Richtlinienvariablen aus.
  • Variablenaktualisierungen werden explizit mithilfe der Client-Instanz des Variablencontainers im Trainingsskript durchgeführt, bevor actor.run() .
  • Die beobachtete Erfahrung wird in jedem Datenerfassungsschritt in den Wiedergabepuffer geschrieben.

Während die Akteure Datenerfassungsschritte ausführen, geben sie Trajektorien von (Status, Aktion, Belohnung) an den Beobachter weiter, der sie zwischenspeichert und in das Reverb-Wiedergabesystem schreibt.

Wir speichern Trajektorien für Frames [(t0, t1) (t1, t2) (t2, t3), ...], weil stride_length=1 .

rb_observer = reverb_utils.ReverbAddTrajectoryObserver(
  reverb_replay.py_client,
  table_name,
  sequence_length=2,
  stride_length=1)

Wir erstellen einen Akteur mit der Zufallsrichtlinie und sammeln Erfahrungen, um den Wiedergabepuffer zu setzen.

initial_collect_actor = actor.Actor(
  collect_env,
  random_policy,
  train_step,
  steps_per_run=initial_collect_steps,
  observers=[rb_observer])
initial_collect_actor.run()

Instanziieren Sie einen Schauspieler mit der Sammlungsrichtlinie, um während des Trainings mehr Erfahrungen zu sammeln.

env_step_metric = py_metrics.EnvironmentSteps()
collect_actor = actor.Actor(
  collect_env,
  collect_policy,
  train_step,
  steps_per_run=1,
  metrics=actor.collect_metrics(10),
  summary_dir=os.path.join(tempdir, learner.TRAIN_DIR),
  observers=[rb_observer, env_step_metric])

Erstellen Sie einen Akteur, mit dem die Richtlinie während des Trainings bewertet wird. Wir übergeben actor.eval_metrics(num_eval_episodes) , um Metriken später zu protokollieren.

eval_actor = actor.Actor(
  eval_env,
  eval_policy,
  train_step,
  episodes_per_run=num_eval_episodes,
  metrics=actor.eval_metrics(num_eval_episodes),
  summary_dir=os.path.join(tempdir, 'eval'),
)

Lernende

Die Learner-Komponente enthält den Agenten und führt mithilfe von Erfahrungsdaten aus dem Wiedergabepuffer Gradientenschrittaktualisierungen an den Richtlinienvariablen durch. Nach einem oder mehreren Trainingsschritten kann der Lernende einen neuen Satz variabler Werte in den variablen Container verschieben.

saved_model_dir = os.path.join(tempdir, learner.POLICY_SAVED_MODEL_DIR)

# Triggers to save the agent's policy checkpoints.
learning_triggers = [
    triggers.PolicySavedModelTrigger(
        saved_model_dir,
        tf_agent,
        train_step,
        interval=policy_save_interval),
    triggers.StepPerSecondLogTrigger(train_step, interval=1000),
]

agent_learner = learner.Learner(
  tempdir,
  train_step,
  tf_agent,
  experience_dataset_fn,
  triggers=learning_triggers)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/linalg/linear_operator_diag.py:166: calling LinearOperator.__init__ (from tensorflow.python.ops.linalg.linear_operator) with graph_parents is deprecated and will be removed in a future version.
Instructions for updating:
Do not pass `graph_parents`.  They will  no longer be used.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/ops/linalg/linear_operator_diag.py:166: calling LinearOperator.__init__ (from tensorflow.python.ops.linalg.linear_operator) with graph_parents is deprecated and will be removed in a future version.
Instructions for updating:
Do not pass `graph_parents`.  They will  no longer be used.
WARNING:absl:WARNING: Could not serialize policy.distribution() for policy "<tf_agents.policies.actor_policy.ActorPolicy object at 0x7f20f97bae10>". Calling saved_model.distribution() will raise the following assertion error: Unable to make a CompositeTensor for "tfp.distributions.SquashToSpecNormal("ActorDistributionNetwork_TanhNormalProjectionNetwork_SquashToSpecNormal", dtype=float32)" of type `<class 'tf_agents.distributions.utils.SquashToSpecNormal'>`. Email `tfprobability@tensorflow.org` or file an issue on github if you would benefit from this working. (Unable to convert dependent entry 'scale' of object 'tfp.distributions.SquashToSpecNormal("ActorDistributionNetwork_TanhNormalProjectionNetwork_SquashToSpecNormal", dtype=float32)': Failed to convert object of type <class 'tensorflow.python.ops.linalg.linear_operator_diag.LinearOperatorDiag'> to Tensor. Contents: <tensorflow.python.ops.linalg.linear_operator_diag.LinearOperatorDiag object at 0x7f20f96c71d0>. Consider casting elements to a supported type.)
WARNING:absl:WARNING: Could not serialize policy.distribution() for policy "<tf_agents.policies.actor_policy.ActorPolicy object at 0x7f20f97bae10>". Calling saved_model.distribution() will raise the following assertion error: Unable to make a CompositeTensor for "tfp.distributions.SquashToSpecNormal("ActorDistributionNetwork_TanhNormalProjectionNetwork_SquashToSpecNormal", dtype=float32)" of type `<class 'tf_agents.distributions.utils.SquashToSpecNormal'>`. Email `tfprobability@tensorflow.org` or file an issue on github if you would benefit from this working. (Unable to convert dependent entry 'scale' of object 'tfp.distributions.SquashToSpecNormal("ActorDistributionNetwork_TanhNormalProjectionNetwork_SquashToSpecNormal", dtype=float32)': Failed to convert object of type <class 'tensorflow.python.ops.linalg.linear_operator_diag.LinearOperatorDiag'> to Tensor. Contents: <tensorflow.python.ops.linalg.linear_operator_diag.LinearOperatorDiag object at 0x7f20f94f71d0>. Consider casting elements to a supported type.)
WARNING:absl:WARNING: Could not serialize policy.distribution() for policy "<tf_agents.policies.actor_policy.ActorPolicy object at 0x7f20f97bae10>". Calling saved_model.distribution() will raise the following assertion error: Unable to make a CompositeTensor for "tfp.distributions.SquashToSpecNormal("ActorDistributionNetwork_TanhNormalProjectionNetwork_SquashToSpecNormal", dtype=float32)" of type `<class 'tf_agents.distributions.utils.SquashToSpecNormal'>`. Email `tfprobability@tensorflow.org` or file an issue on github if you would benefit from this working. (Unable to convert dependent entry 'scale' of object 'tfp.distributions.SquashToSpecNormal("ActorDistributionNetwork_TanhNormalProjectionNetwork_SquashToSpecNormal", dtype=float32)': Failed to convert object of type <class 'tensorflow.python.ops.linalg.linear_operator_diag.LinearOperatorDiag'> to Tensor. Contents: <tensorflow.python.ops.linalg.linear_operator_diag.LinearOperatorDiag object at 0x7f20f946dcc0>. Consider casting elements to a supported type.)

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/tracking/tracking.py:111: Layer.updates (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.

INFO:tensorflow:Assets written to: /tmp/policies/collect_policy/assets

INFO:tensorflow:Assets written to: /tmp/policies/collect_policy/assets

INFO:tensorflow:Assets written to: /tmp/policies/greedy_policy/assets

INFO:tensorflow:Assets written to: /tmp/policies/greedy_policy/assets

INFO:tensorflow:Assets written to: /tmp/policies/policy/assets

INFO:tensorflow:Assets written to: /tmp/policies/policy/assets

Metriken und Auswertung

Wir haben den eval Actor oben actor.eval_metrics instanziiert, wodurch die am häufigsten verwendeten Metriken während der Richtlinienbewertung erstellt werden:

  • Durchschnittliche Rendite. Die Rendite ist die Summe der Belohnungen, die beim Ausführen einer Richtlinie in einer Umgebung für eine Episode erzielt werden. In der Regel wird dies über einige Episoden gemittelt.
  • Durchschnittliche Episodenlänge.

Wir führen den Akteur aus, um diese Metriken zu generieren.

def get_eval_metrics():
  eval_actor.run()
  results = {}
  for metric in eval_actor.metrics:
    results[metric.name] = metric.result()
  return results

metrics = get_eval_metrics()
def log_eval_metrics(step, metrics):
  eval_results = (', ').join(
      '{} = {:.6f}'.format(name, result) for name, result in metrics.items())
  print('step = {0}: {1}'.format(step, eval_results))

log_eval_metrics(0, metrics)
step = 0: AverageReturn = -0.037663, AverageEpisodeLength = 40.750000

Überprüfen Sie das Metrikmodul auf andere Standardimplementierungen verschiedener Metriken.

Schulung des Agenten

Die Trainingsschleife umfasst sowohl das Sammeln von Daten aus der Umgebung als auch das Optimieren der Netzwerke des Agenten. Unterwegs werden wir gelegentlich die Richtlinien des Agenten bewerten, um festzustellen, wie es uns geht.

try:
  %%time
except:
  pass

# Reset the train step
tf_agent.train_step_counter.assign(0)

# Evaluate the agent's policy once before training.
avg_return = get_eval_metrics()["AverageReturn"]
returns = [avg_return]

for _ in range(num_iterations):
  # Training.
  collect_actor.run()
  loss_info = agent_learner.run(iterations=1)

  # Evaluating.
  step = agent_learner.train_step_numpy

  if eval_interval and step % eval_interval == 0:
    metrics = get_eval_metrics()
    log_eval_metrics(step, metrics)
    returns.append(metrics["AverageReturn"])

  if log_interval and step % log_interval == 0:
    print('step = {0}: loss = {1}'.format(step, loss_info.loss.numpy()))

rb_observer.close()
reverb_server.stop()
step = 5000: loss = -61.24901580810547
step = 10000: AverageReturn = -1.638705, AverageEpisodeLength = 603.799988
step = 10000: loss = -58.81383514404297
step = 15000: loss = -28.42072296142578
step = 20000: AverageReturn = -0.165534, AverageEpisodeLength = 294.200012
step = 20000: loss = -19.651765823364258
step = 25000: loss = -15.67559814453125
step = 30000: AverageReturn = -0.613882, AverageEpisodeLength = 632.599976
step = 30000: loss = -8.940147399902344
step = 35000: loss = -7.067249774932861
step = 40000: AverageReturn = -0.978639, AverageEpisodeLength = 616.349976
step = 40000: loss = -3.7042970657348633
step = 45000: loss = -1.8215680122375488
step = 50000: AverageReturn = -0.773452, AverageEpisodeLength = 575.700012
step = 50000: loss = -1.2989206314086914
step = 55000: loss = -0.9446927905082703
step = 60000: AverageReturn = -0.716697, AverageEpisodeLength = 623.349976
step = 60000: loss = -2.262794017791748
step = 65000: loss = -1.2334147691726685
step = 70000: AverageReturn = -0.042324, AverageEpisodeLength = 182.600006
step = 70000: loss = -1.5959842205047607
step = 75000: loss = -0.675437331199646
step = 80000: AverageReturn = 0.343009, AverageEpisodeLength = 712.349976
step = 80000: loss = -3.788991928100586
step = 85000: loss = 0.5005127191543579
step = 90000: AverageReturn = 0.619534, AverageEpisodeLength = 432.799988
step = 90000: loss = 1.4043999910354614
step = 95000: loss = 2.0433547496795654
step = 100000: AverageReturn = 0.928888, AverageEpisodeLength = 518.450012
step = 100000: loss = 1.0085809230804443

Visualisierung

Grundstücke

Wir können die durchschnittliche Rendite im Vergleich zu globalen Schritten darstellen, um die Leistung unseres Agenten zu sehen. In Minitaur basiert die Belohnungsfunktion darauf, wie weit der Minitaur in 1000 Schritten geht und den Energieverbrauch bestraft.

steps = range(0, num_iterations + 1, eval_interval)
plt.plot(steps, returns)
plt.ylabel('Average Return')
plt.xlabel('Step')
plt.ylim()
(-1.767085188627243, 1.0572681367397307)

png

Videos

Es ist hilfreich, die Leistung eines Agenten zu visualisieren, indem die Umgebung bei jedem Schritt gerendert wird. Bevor wir das tun, erstellen wir zunächst eine Funktion zum Einbetten von Videos in diese Spalte.

def embed_mp4(filename):
  """Embeds an mp4 file in the notebook."""
  video = open(filename,'rb').read()
  b64 = base64.b64encode(video)
  tag = '''
  <video width="640" height="480" controls>
    <source src="data:video/mp4;base64,{0}" type="video/mp4">
  Your browser does not support the video tag.
  </video>'''.format(b64.decode())

  return IPython.display.HTML(tag)

Der folgende Code veranschaulicht die Richtlinien des Agenten für einige Episoden:

num_episodes = 3
video_filename = 'sac_minitaur.mp4'
with imageio.get_writer(video_filename, fps=60) as video:
  for _ in range(num_episodes):
    time_step = eval_env.reset()
    video.append_data(eval_env.render())
    while not time_step.is_last():
      action_step = eval_actor.policy.action(time_step)
      time_step = eval_env.step(action_step.action)
      video.append_data(eval_env.render())

embed_mp4(video_filename)