Google I / O kehrt vom 18. bis 20. Mai zurück! Reservieren Sie Platz und erstellen Sie Ihren Zeitplan Registrieren Sie sich jetzt
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Trainieren Sie ein Deep Q-Netzwerk mit TF-Agenten

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

Einführung

Dieses Beispiel zeigt, wie ein DQN- Agent (Deep Q Networks) in der Cartpole-Umgebung mithilfe der TF-Agents-Bibliothek trainiert wird.

Cartpole-Umgebung

Es führt Sie durch alle Komponenten einer RL-Pipeline (Reinforcement Learning) für Schulung, Bewertung und Datenerfassung.

Um diesen Code live auszuführen, klicken Sie oben auf den Link "In Google Colab ausführen".

Einrichten

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

sudo apt-get update
sudo apt-get install -y xvfb ffmpeg
pip install -q 'imageio==2.4.0'
pip install -q pyvirtualdisplay
pip install -q tf-agents
from __future__ import absolute_import, division, print_function

import base64
import imageio
import IPython
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import PIL.Image
import pyvirtualdisplay

import tensorflow as tf

from tf_agents.agents.dqn import dqn_agent
from tf_agents.environments import suite_gym
from tf_agents.environments import tf_py_environment
from tf_agents.eval import metric_utils
from tf_agents.metrics import tf_metrics
from tf_agents.networks import sequential
from tf_agents.policies import random_tf_policy
from tf_agents.replay_buffers import tf_uniform_replay_buffer
from tf_agents.trajectories import trajectory
from tf_agents.specs import tensor_spec
from tf_agents.utils import common
# Set up a virtual display for rendering OpenAI gym environments.
display = pyvirtualdisplay.Display(visible=0, size=(1400, 900)).start()
tf.version.VERSION
'2.4.1'

Hyperparameter

num_iterations = 20000 # @param {type:"integer"}

initial_collect_steps = 100  # @param {type:"integer"} 
collect_steps_per_iteration = 1  # @param {type:"integer"}
replay_buffer_max_length = 100000  # @param {type:"integer"}

batch_size = 64  # @param {type:"integer"}
learning_rate = 1e-3  # @param {type:"number"}
log_interval = 200  # @param {type:"integer"}

num_eval_episodes = 10  # @param {type:"integer"}
eval_interval = 1000  # @param {type:"integer"}

Umgebung

Beim Reinforcement Learning (RL) repräsentiert eine Umgebung die zu lösende Aufgabe oder das zu lösende Problem. Standardumgebungen können in TF-Agents mithilfe der Suites tf_agents.environments . TF-Agents verfügt über Suiten zum Laden von Umgebungen aus Quellen wie OpenAI Gym, Atari und DM Control.

Laden Sie die CartPole-Umgebung aus der OpenAI Gym Suite.

env_name = 'CartPole-v0'
env = suite_gym.load(env_name)

Sie können diese Umgebung rendern, um zu sehen, wie sie aussieht. Eine frei schwingende Stange ist an einem Wagen befestigt. Das Ziel ist es, den Wagen nach rechts oder links zu bewegen, damit die Stange nach oben zeigt.

env.reset()
PIL.Image.fromarray(env.render())

png

Die Methode environment.step führt eine action in der Umgebung aus und gibt ein TimeStep Tupel zurück, das die nächste Beobachtung der Umgebung und die Belohnung für die Aktion enthält.

Die Methode time_step_spec() gibt die Spezifikation für das TimeStep Tupel zurück. Das observation zeigt die Form der Beobachtungen, die Datentypen und die Bereiche der zulässigen Werte. Das reward zeigt dieselben Details für die Belohnung an.

print('Observation Spec:')
print(env.time_step_spec().observation)
Observation Spec:
BoundedArraySpec(shape=(4,), dtype=dtype('float32'), name='observation', minimum=[-4.8000002e+00 -3.4028235e+38 -4.1887903e-01 -3.4028235e+38], maximum=[4.8000002e+00 3.4028235e+38 4.1887903e-01 3.4028235e+38])
print('Reward Spec:')
print(env.time_step_spec().reward)
Reward Spec:
ArraySpec(shape=(), dtype=dtype('float32'), name='reward')

Die Methode action_spec() gibt die Form, die Datentypen und die zulässigen Werte gültiger Aktionen zurück.

print('Action Spec:')
print(env.action_spec())
Action Spec:
BoundedArraySpec(shape=(), dtype=dtype('int64'), name='action', minimum=0, maximum=1)

In der Cartpole-Umgebung:

  • observation ist eine Anordnung von 4 Schwimmern:
    • die Position und Geschwindigkeit des Wagens
    • die Winkelposition und Geschwindigkeit des Pols
  • reward ist ein skalarer Float-Wert
  • action ist eine skalare Ganzzahl mit nur zwei möglichen Werten:
    • 0 - "nach links bewegen"
    • 1 - "nach rechts bewegen"
time_step = env.reset()
print('Time step:')
print(time_step)

action = np.array(1, dtype=np.int32)

next_time_step = env.step(action)
print('Next time step:')
print(next_time_step)
Time step:
TimeStep(step_type=array(0, dtype=int32), reward=array(0., dtype=float32), discount=array(1., dtype=float32), observation=array([ 0.01730286,  0.04666085,  0.01145206, -0.0473538 ], dtype=float32))
Next time step:
TimeStep(step_type=array(1, dtype=int32), reward=array(1., dtype=float32), discount=array(1., dtype=float32), observation=array([ 0.01823608,  0.24161673,  0.01050499, -0.3364016 ], dtype=float32))

Normalerweise werden zwei Umgebungen instanziiert: eine für das Training und eine für die Bewertung.

train_py_env = suite_gym.load(env_name)
eval_py_env = suite_gym.load(env_name)

Die Cartpole-Umgebung ist wie die meisten Umgebungen in reinem Python geschrieben. Dies wird mithilfe des TFPyEnvironment Wrappers in TensorFlow TFPyEnvironment .

Die API der ursprünglichen Umgebung verwendet Numpy-Arrays. Die TFPyEnvironment konvertiert diese in Tensors , um sie mit Tensorflow-Agenten und -Richtlinien kompatibel zu machen.

train_env = tf_py_environment.TFPyEnvironment(train_py_env)
eval_env = tf_py_environment.TFPyEnvironment(eval_py_env)

Agent

Der zur Lösung eines RL-Problems verwendete Algorithmus wird von einem Agent . TF-Agents bietet Standardimplementierungen einer Vielzahl von Agents , einschließlich:

Der DQN-Agent kann in jeder Umgebung verwendet werden, die über einen diskreten Aktionsraum verfügt.

Das Herzstück eines DQN-Agenten ist ein QNetwork , ein neuronales Netzwerkmodell, das anhand einer Beobachtung aus der Umgebung lernen kann, QValues (erwartete Renditen) für alle Aktionen vorherzusagen.

Wir werden tf_agents.networks. um ein QNetwork zu erstellen. Das Netzwerk besteht aus einer Folge von tf.keras.layers.Dense Ebenen, wobei die letzte Ebene für jede mögliche Aktion 1 Ausgabe hat.

fc_layer_params = (100, 50)
action_tensor_spec = tensor_spec.from_spec(env.action_spec())
num_actions = action_tensor_spec.maximum - action_tensor_spec.minimum + 1

# Define a helper function to create Dense layers configured with the right
# activation and kernel initializer.
def dense_layer(num_units):
  return tf.keras.layers.Dense(
      num_units,
      activation=tf.keras.activations.relu,
      kernel_initializer=tf.keras.initializers.VarianceScaling(
          scale=2.0, mode='fan_in', distribution='truncated_normal'))

# QNetwork consists of a sequence of Dense layers followed by a dense layer
# with `num_actions` units to generate one q_value per available action as
# it's output.
dense_layers = [dense_layer(num_units) for num_units in fc_layer_params]
q_values_layer = tf.keras.layers.Dense(
    num_actions,
    activation=None,
    kernel_initializer=tf.keras.initializers.RandomUniform(
        minval=-0.03, maxval=0.03),
    bias_initializer=tf.keras.initializers.Constant(-0.2))
q_net = sequential.Sequential(dense_layers + [q_values_layer])

Verwenden tf_agents.agents.dqn.dqn_agent nun tf_agents.agents.dqn.dqn_agent , um einen DqnAgent zu instanziieren. Zusätzlich zu time_step_spec , action_spec und dem QNetwork benötigt der Agentenkonstruktor einen Optimierer (in diesem Fall AdamOptimizer ), eine Verlustfunktion und einen ganzzahligen Schrittzähler.

optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)

train_step_counter = tf.Variable(0)

agent = dqn_agent.DqnAgent(
    train_env.time_step_spec(),
    train_env.action_spec(),
    q_network=q_net,
    optimizer=optimizer,
    td_errors_loss_fn=common.element_wise_squared_loss,
    train_step_counter=train_step_counter)

agent.initialize()

Richtlinien

Eine Richtlinie definiert, wie sich ein Agent in einer Umgebung verhält. In der Regel besteht das Ziel des verstärkten Lernens darin, das zugrunde liegende Modell zu trainieren, bis die Richtlinie das gewünschte Ergebnis erzielt.

In diesem Tutorial:

  • Das gewünschte Ergebnis ist, die Stange aufrecht über dem Wagen zu halten.
  • Die Richtlinie gibt für jede time_step Beobachtung eine Aktion (links oder rechts) time_step .

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.
eval_policy = agent.policy
collect_policy = agent.collect_policy

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

random_policy = random_tf_policy.RandomTFPolicy(train_env.time_step_spec(),
                                                train_env.action_spec())

Rufen Sie die Methode policy.action(time_step) auf, um eine Aktion aus einer Richtlinie policy.action(time_step) . Der time_step enthält die Beobachtung aus der Umgebung. Diese Methode gibt einen PolicyStep , bei dem es sich um ein benanntes Tupel mit drei Komponenten handelt:

  • action - die auszuführende Aktion (in diesem Fall 0 oder 1 )
  • state - wird für statusbehaftete (dh RNN-basierte) Richtlinien verwendet
  • info - Hilfsdaten, wie z. B. Protokollwahrscheinlichkeiten von Aktionen
example_environment = tf_py_environment.TFPyEnvironment(
    suite_gym.load('CartPole-v0'))
time_step = example_environment.reset()
random_policy.action(time_step)
PolicyStep(action=<tf.Tensor: shape=(1,), dtype=int64, numpy=array([1])>, state=(), info=())

Metriken und Auswertung

Die am häufigsten zur Bewertung einer Richtlinie verwendete Metrik ist die durchschnittliche Rendite. Die Rendite ist die Summe der Belohnungen, die beim Ausführen einer Richtlinie in einer Umgebung für eine Episode erzielt werden. Es werden mehrere Episoden ausgeführt, wodurch eine durchschnittliche Rendite erzielt wird.

Die folgende Funktion berechnet die durchschnittliche Rendite einer Richtlinie unter Berücksichtigung der Richtlinie, der Umgebung und einer Anzahl von Episoden.

def compute_avg_return(environment, policy, num_episodes=10):

  total_return = 0.0
  for _ in range(num_episodes):

    time_step = environment.reset()
    episode_return = 0.0

    while not time_step.is_last():
      action_step = policy.action(time_step)
      time_step = environment.step(action_step.action)
      episode_return += time_step.reward
    total_return += episode_return

  avg_return = total_return / num_episodes
  return avg_return.numpy()[0]


# See also the metrics module for standard implementations of different metrics.
# https://github.com/tensorflow/agents/tree/master/tf_agents/metrics

random_policy diese Berechnung auf random_policy , wird eine random_policy in der Umgebung random_policy .

compute_avg_return(eval_env, random_policy, num_eval_episodes)
16.1

Puffer wiedergeben

Der Wiedergabepuffer verfolgt die aus der Umgebung gesammelten Daten. In diesem Tutorial wird tf_agents.replay_buffers.tf_uniform_replay_buffer.TFUniformReplayBuffer , da dies am häufigsten vorkommt.

Der Konstruktor benötigt die Spezifikationen für die Daten, die er sammeln wird. Dies ist vom Agenten mithilfe der Methode collect_data_spec verfügbar. Die Chargengröße und die maximale Pufferlänge sind ebenfalls erforderlich.

replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
    data_spec=agent.collect_data_spec,
    batch_size=train_env.batch_size,
    max_length=replay_buffer_max_length)

Für die meisten Agenten ist collect_data_spec ein benanntes Tupel namens Trajectory , das die Spezifikationen für Beobachtungen, Aktionen, Belohnungen und andere Elemente enthält.

agent.collect_data_spec
Trajectory(step_type=TensorSpec(shape=(), dtype=tf.int32, name='step_type'), observation=BoundedTensorSpec(shape=(4,), dtype=tf.float32, name='observation', minimum=array([-4.8000002e+00, -3.4028235e+38, -4.1887903e-01, -3.4028235e+38],
      dtype=float32), maximum=array([4.8000002e+00, 3.4028235e+38, 4.1887903e-01, 3.4028235e+38],
      dtype=float32)), action=BoundedTensorSpec(shape=(), dtype=tf.int64, name='action', minimum=array(0), maximum=array(1)), policy_info=(), next_step_type=TensorSpec(shape=(), dtype=tf.int32, name='step_type'), reward=TensorSpec(shape=(), dtype=tf.float32, name='reward'), discount=BoundedTensorSpec(shape=(), dtype=tf.float32, name='discount', minimum=array(0., dtype=float32), maximum=array(1., dtype=float32)))
agent.collect_data_spec._fields
('step_type',
 'observation',
 'action',
 'policy_info',
 'next_step_type',
 'reward',
 'discount')

Datensammlung

Führen Sie nun die Zufallsrichtlinie für einige Schritte in der Umgebung aus und zeichnen Sie die Daten im Wiedergabepuffer auf.

def collect_step(environment, policy, buffer):
  time_step = environment.current_time_step()
  action_step = policy.action(time_step)
  next_time_step = environment.step(action_step.action)
  traj = trajectory.from_transition(time_step, action_step, next_time_step)

  # Add trajectory to the replay buffer
  buffer.add_batch(traj)

def collect_data(env, policy, buffer, steps):
  for _ in range(steps):
    collect_step(env, policy, buffer)

collect_data(train_env, random_policy, replay_buffer, initial_collect_steps)

# This loop is so common in RL, that we provide standard implementations. 
# For more details see tutorial 4 or the drivers module.
# https://github.com/tensorflow/agents/blob/master/docs/tutorials/4_drivers_tutorial.ipynb 
# https://www.tensorflow.org/agents/api_docs/python/tf_agents/drivers

Der Wiedergabepuffer ist jetzt eine Sammlung von Trajektorien.

# For the curious:
# Uncomment to peel one of these off and inspect it.
# iter(replay_buffer.as_dataset()).next()

Der Agent benötigt Zugriff auf den Wiedergabepuffer. Dies wird durch Erstellen einer iterierbarentf.data.Dataset Pipeline bereitgestellt, die dem Agenten Datentf.data.Dataset .

Jede Zeile des Wiedergabepuffers speichert nur einen einzigen Beobachtungsschritt. Da der DQN-Agent jedoch sowohl die aktuelle als auch die nächste Beobachtung benötigt, um den Verlust zu berechnen, werden in der Dataset-Pipeline zwei benachbarte Zeilen für jedes Element im Stapel num_steps=2 ( num_steps=2 ).

Dieses Dataset wird auch optimiert, indem parallele Aufrufe ausgeführt und Daten vorab abgerufen werden.

# Dataset generates trajectories with shape [Bx2x...]
dataset = replay_buffer.as_dataset(
    num_parallel_calls=3, 
    sample_batch_size=batch_size, 
    num_steps=2).prefetch(3)


dataset
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/autograph/operators/control_flow.py:1218: ReplayBuffer.get_next (from tf_agents.replay_buffers.replay_buffer) is deprecated and will be removed in a future version.
Instructions for updating:
Use `as_dataset(..., single_deterministic_pass=False) instead.
<PrefetchDataset shapes: (Trajectory(step_type=(64, 2), observation=(64, 2, 4), action=(64, 2), policy_info=(), next_step_type=(64, 2), reward=(64, 2), discount=(64, 2)), BufferInfo(ids=(64, 2), probabilities=(64,))), types: (Trajectory(step_type=tf.int32, observation=tf.float32, action=tf.int64, policy_info=(), next_step_type=tf.int32, reward=tf.float32, discount=tf.float32), BufferInfo(ids=tf.int64, probabilities=tf.float32))>
iterator = iter(dataset)
print(iterator)
<tensorflow.python.data.ops.iterator_ops.OwnedIterator object at 0x7fc0c5abc780>
# For the curious:
# Uncomment to see what the dataset iterator is feeding to the agent.
# Compare this representation of replay data 
# to the collection of individual trajectories shown earlier.

# iterator.next()

Schulung des Agenten

Während der Trainingsschleife müssen zwei Dinge passieren:

  • Sammeln Sie Daten aus der Umgebung
  • Verwenden Sie diese Daten, um die neuronalen Netze des Agenten zu trainieren.

In diesem Beispiel wird die Richtlinie auch regelmäßig ausgewertet und die aktuelle Punktzahl gedruckt.

Der folgende Vorgang dauert ca. 5 Minuten.

try:
  %%time
except:
  pass

# (Optional) Optimize by wrapping some of the code in a graph using TF function.
agent.train = common.function(agent.train)

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

# Evaluate the agent's policy once before training.
avg_return = compute_avg_return(eval_env, agent.policy, num_eval_episodes)
returns = [avg_return]

for _ in range(num_iterations):

  # Collect a few steps using collect_policy and save to the replay buffer.
  collect_data(train_env, agent.collect_policy, replay_buffer, collect_steps_per_iteration)

  # Sample a batch of data from the buffer and update the agent's network.
  experience, unused_info = next(iterator)
  train_loss = agent.train(experience).loss

  step = agent.train_step_counter.numpy()

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

  if step % eval_interval == 0:
    avg_return = compute_avg_return(eval_env, agent.policy, num_eval_episodes)
    print('step = {0}: Average Return = {1}'.format(step, avg_return))
    returns.append(avg_return)
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/util/dispatch.py:201: calling foldr_v2 (from tensorflow.python.ops.functional_ops) with back_prop=False is deprecated and will be removed in a future version.
Instructions for updating:
back_prop=False is deprecated. Consider using tf.stop_gradient instead.
Instead of:
results = tf.foldr(fn, elems, back_prop=False)
Use:
results = tf.nest.map_structure(tf.stop_gradient, tf.foldr(fn, elems))
step = 200: loss = 28.54922866821289
step = 400: loss = 11.265779495239258
step = 600: loss = 118.93780517578125
step = 800: loss = 6.945855140686035
step = 1000: loss = 81.30548095703125
step = 1000: Average Return = 100.5
step = 1200: loss = 583.738525390625
step = 1400: loss = 84.12023162841797
step = 1600: loss = 1195.0528564453125
step = 1800: loss = 798.727294921875
step = 2000: loss = 1214.359619140625
step = 2000: Average Return = 80.5
step = 2200: loss = 119.32345581054688
step = 2400: loss = 89.71794128417969
step = 2600: loss = 77.56394958496094
step = 2800: loss = 200.96832275390625
step = 3000: loss = 687.2619018554688
step = 3000: Average Return = 200.0
step = 3200: loss = 273.20257568359375
step = 3400: loss = 1348.410400390625
step = 3600: loss = 7291.123046875
step = 3800: loss = 9693.671875
step = 4000: loss = 11049.0078125
step = 4000: Average Return = 200.0
step = 4200: loss = 19630.55078125
step = 4400: loss = 162683.890625
step = 4600: loss = 188355.25
step = 4800: loss = 1085961.625
step = 5000: loss = 28136.2421875
step = 5000: Average Return = 200.0
step = 5200: loss = 41078.0703125
step = 5400: loss = 463938.15625
step = 5600: loss = 37489.6875
step = 5800: loss = 85520.1875
step = 6000: loss = 54998.30078125
step = 6000: Average Return = 200.0
step = 6200: loss = 57353.96875
step = 6400: loss = 82274.921875
step = 6600: loss = 480124.1875
step = 6800: loss = 125073.3515625
step = 7000: loss = 109867.765625
step = 7000: Average Return = 200.0
step = 7200: loss = 95796.765625
step = 7400: loss = 84803.3828125
step = 7600: loss = 174417.65625
step = 7800: loss = 145947.21875
step = 8000: loss = 857481.8125
step = 8000: Average Return = 200.0
step = 8200: loss = 198140.53125
step = 8400: loss = 184674.125
step = 8600: loss = 284932.15625
step = 8800: loss = 140546.625
step = 9000: loss = 1301324.125
step = 9000: Average Return = 200.0
step = 9200: loss = 2169464.0
step = 9400: loss = 192097.03125
step = 9600: loss = 95835.109375
step = 9800: loss = 362408.4375
step = 10000: loss = 234460.84375
step = 10000: Average Return = 200.0
step = 10200: loss = 2636405.0
step = 10400: loss = 406090.9375
step = 10600: loss = 218874.421875
step = 10800: loss = 314460.375
step = 11000: loss = 313773.625
step = 11000: Average Return = 200.0
step = 11200: loss = 235539.46875
step = 11400: loss = 230301.625
step = 11600: loss = 195967.515625
step = 11800: loss = 529188.25
step = 12000: loss = 559874.75
step = 12000: Average Return = 200.0
step = 12200: loss = 517803.1875
step = 12400: loss = 379510.1875
step = 12600: loss = 192517.515625
step = 12800: loss = 254534.40625
step = 13000: loss = 247311.53125
step = 13000: Average Return = 200.0
step = 13200: loss = 467653.5625
step = 13400: loss = 266234.1875
step = 13600: loss = 254158640.0
step = 13800: loss = 273959.4375
step = 14000: loss = 1116587.125
step = 14000: Average Return = 200.0
step = 14200: loss = 556657.3125
step = 14400: loss = 657635.75
step = 14600: loss = 637587.5625
step = 14800: loss = 518682.375
step = 15000: loss = 427786.5
step = 15000: Average Return = 200.0
step = 15200: loss = 393602.625
step = 15400: loss = 470813.375
step = 15600: loss = 49263600.0
step = 15800: loss = 18822354.0
step = 16000: loss = 1389915.625
step = 16000: Average Return = 200.0
step = 16200: loss = 179496144.0
step = 16400: loss = 3241569.5
step = 16600: loss = 12142488.0
step = 16800: loss = 922398.3125
step = 17000: loss = 1751954.625
step = 17000: Average Return = 200.0
step = 17200: loss = 70321296.0
step = 17400: loss = 2027174.0
step = 17600: loss = 103143216.0
step = 17800: loss = 71887584.0
step = 18000: loss = 1041745.375
step = 18000: Average Return = 200.0
step = 18200: loss = 899747.5
step = 18400: loss = 1508126.375
step = 18600: loss = 18633292.0
step = 18800: loss = 1058055.25
step = 19000: loss = 2446145.0
step = 19000: Average Return = 200.0
step = 19200: loss = 2081777.875
step = 19400: loss = 1023876.875
step = 19600: loss = 1734647.25
step = 19800: loss = 1467883.75
step = 20000: loss = 90669328.0
step = 20000: Average Return = 200.0

Visualisierung

Grundstücke

Verwenden Sie matplotlib.pyplot , um matplotlib.pyplot , wie sich die Richtlinie während des Trainings verbessert hat.

Eine Iteration von Cartpole-v0 besteht aus 200 Cartpole-v0 . Die Umgebung gibt eine Belohnung von +1 für jeden Schritt, bei dem die Stange oben bleibt, sodass die maximale Rendite für eine Episode 200 beträgt. Die Diagramme zeigen, dass die Rendite jedes Mal, wenn sie während des Trainings bewertet wird, auf dieses Maximum ansteigt. (Es kann etwas instabil sein und nicht jedes Mal monoton ansteigen.)

iterations = range(0, num_iterations + 1, eval_interval)
plt.plot(iterations, returns)
plt.ylabel('Average Return')
plt.xlabel('Iterations')
plt.ylim(top=250)
(61.0849967956543, 250.0)

png

Videos

Charts sind nett. Spannender ist es jedoch, wenn ein Agent tatsächlich eine Aufgabe in einer Umgebung ausführt.

Erstellen Sie zunächst eine Funktion zum Einbetten von Videos in das Notizbuch.

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)

Durchlaufen Sie nun einige Episoden des Cartpole-Spiels mit dem Agenten. Die zugrunde liegende Python-Umgebung (die "innerhalb" des TensorFlow-Umgebungs-Wrappers) bietet eine render() -Methode, die ein Bild des Umgebungsstatus ausgibt. Diese können in einem Video gesammelt werden.

def create_policy_eval_video(policy, filename, num_episodes=5, fps=30):
  filename = filename + ".mp4"
  with imageio.get_writer(filename, fps=fps) as video:
    for _ in range(num_episodes):
      time_step = eval_env.reset()
      video.append_data(eval_py_env.render())
      while not time_step.is_last():
        action_step = policy.action(time_step)
        time_step = eval_env.step(action_step.action)
        video.append_data(eval_py_env.render())
  return embed_mp4(filename)




create_policy_eval_video(agent.policy, "trained-agent")
WARNING:root:IMAGEIO FFMPEG_WRITER WARNING: input image is not divisible by macro_block_size=16, resizing from (400, 600) to (400, 608) to ensure video compatibility with most codecs and players. To prevent resizing, make your input image divisible by the macro_block_size or set the macro_block_size to None (risking incompatibility). You may also see a FFMPEG warning concerning speedloss due to data not being aligned.

Vergleichen Sie zum Spaß den geschulten Agenten (oben) mit einem Agenten, der sich zufällig bewegt. (Es funktioniert nicht so gut.)

create_policy_eval_video(random_policy, "random-agent")
WARNING:root:IMAGEIO FFMPEG_WRITER WARNING: input image is not divisible by macro_block_size=16, resizing from (400, 600) to (400, 608) to ensure video compatibility with most codecs and players. To prevent resizing, make your input image divisible by the macro_block_size or set the macro_block_size to None (risking incompatibility). You may also see a FFMPEG warning concerning speedloss due to data not being aligned.