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

Puffer erneut abspielen

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

Einführung

Verstärkungslernalgorithmen verwenden Wiedergabepuffer, um Erfahrungsverläufe beim Ausführen einer Richtlinie in einer Umgebung zu speichern. Während des Trainings werden Wiederholungspuffer nach einer Teilmenge der Trajektorien (entweder einer sequentiellen Teilmenge oder einer Stichprobe) abgefragt, um die Erfahrung des Agenten "wiederzugeben".

In dieser Spalte werden zwei Arten von Wiedergabepuffern untersucht: Python-Backed und Tensorflow-Backed, wobei eine gemeinsame API verwendet wird. In den folgenden Abschnitten beschreiben wir die API, jede der Pufferimplementierungen und deren Verwendung während des Datenerfassungstrainings.

Konfiguration

Installieren Sie tf-agent, falls Sie dies noch nicht getan haben.

pip install -q tf-agents
pip install -q gym
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import numpy as np

from tf_agents import specs
from tf_agents.agents.dqn import dqn_agent
from tf_agents.drivers import dynamic_step_driver
from tf_agents.environments import suite_gym
from tf_agents.environments import tf_py_environment
from tf_agents.networks import q_network
from tf_agents.replay_buffers import py_uniform_replay_buffer
from tf_agents.replay_buffers import tf_uniform_replay_buffer
from tf_agents.specs import tensor_spec
from tf_agents.trajectories import time_step

tf.compat.v1.enable_v2_behavior()

Replay Buffer API

Die Replay Buffer-Klasse hat die folgende Definition und Methoden:

class ReplayBuffer(tf.Module):
  """Abstract base class for TF-Agents replay buffer."""

  def __init__(self, data_spec, capacity):
    """Initializes the replay buffer.

    Args:
      data_spec: A spec or a list/tuple/nest of specs describing
        a single item that can be stored in this buffer
      capacity: number of elements that the replay buffer can hold.
    """

  @property
  def data_spec(self):
    """Returns the spec for items in the replay buffer."""

  @property
  def capacity(self):
    """Returns the capacity of the replay buffer."""

  def add_batch(self, items):
    """Adds a batch of items to the replay buffer."""

  def get_next(self,
               sample_batch_size=None,
               num_steps=None,
               time_stacked=True):
    """Returns an item or batch of items from the buffer."""

  def as_dataset(self,
                 sample_batch_size=None,
                 num_steps=None,
                 num_parallel_calls=None):
    """Creates and returns a dataset that returns entries from the buffer."""


  def gather_all(self):
    """Returns all the items in buffer."""
    return self._gather_all()

  def clear(self):
    """Resets the contents of replay buffer"""

Beachten Sie, dass beim Initialisieren des Wiedergabepufferobjekts die data_spec der Elemente erforderlich ist, die data_spec werden sollen. Diese Spezifikation entspricht der TensorSpec der Trajektorienelemente, die dem Puffer hinzugefügt werden. Diese Spezifikation wird normalerweise durch einen Blick auf die agent.collect_data_spec eines Agenten agent.collect_data_spec die die Formen, Typen und Strukturen definiert, die der Agent beim Training erwartet (dazu später mehr).

TFUniformReplayBuffer

TFUniformReplayBuffer ist der am häufigsten verwendete Wiedergabepuffer in TF-Agents. TFUniformReplayBuffer wir ihn hier in unserem Tutorial verwenden. In TFUniformReplayBuffer die Speicherung des Sicherungspuffers durch Tensorflow-Variablen und ist somit Teil des Berechnungsgraphen.

Der Puffer speichert Stapel von Elementen und hat eine maximale Kapazität von max_length Elementen pro max_length . Somit beträgt die batch_size x max_length elements. Die im Puffer gespeicherten Elemente müssen alle eine übereinstimmende Datenspezifikation haben. Wenn der Wiedergabepuffer für die Datenerfassung verwendet wird, ist die Spezifikation die Erfassungsdatenspezifikation des Agenten.

Puffer erstellen:

Um einen TFUniformReplayBuffer zu erstellen, TFUniformReplayBuffer wir:

  1. die Spezifikation der Datenelemente, die der Puffer speichern wird
  2. Die batch size entspricht der Chargengröße des Puffers
  3. Die max_length Anzahl von Elementen pro max_length

Hier ist ein Beispiel für die Erstellung eines TFUniformReplayBuffer mit Beispieldatenspezifikationen, batch_size 32 und max_length 1000.

data_spec =  (
        tf.TensorSpec([3], tf.float32, 'action'),
        (
            tf.TensorSpec([5], tf.float32, 'lidar'),
            tf.TensorSpec([3, 2], tf.float32, 'camera')
        )
)

batch_size = 32
max_length = 1000

replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
    data_spec,
    batch_size=batch_size,
    max_length=max_length)

Schreiben in den Puffer:

Um dem Wiedergabepuffer Elemente hinzuzufügen, verwenden wir die Methode add_batch(items) , bei der items eine Liste / ein Tupel / ein Nest von Tensoren ist, die den Stapel von Elementen darstellen, die dem Puffer hinzugefügt werden sollen. Jedes Element von items muss eine äußere Dimension haben, die gleich batch_size und die verbleibenden Dimensionen müssen der Datenspezifikation des Elements entsprechen (genau wie die an den Wiedergabepufferkonstruktor übergebenen Datenspezifikationen).

Hier ist ein Beispiel für das Hinzufügen eines Stapels von Elementen

action = tf.constant(1 * np.ones(
    data_spec[0].shape.as_list(), dtype=np.float32))
lidar = tf.constant(
    2 * np.ones(data_spec[1][0].shape.as_list(), dtype=np.float32))
camera = tf.constant(
    3 * np.ones(data_spec[1][1].shape.as_list(), dtype=np.float32))
  
values = (action, (lidar, camera))
values_batched = tf.nest.map_structure(lambda t: tf.stack([t] * batch_size),
                                       values)
  
replay_buffer.add_batch(values_batched)

Lesen aus dem Puffer

Es gibt drei Möglichkeiten, Daten aus dem TFUniformReplayBuffer zu lesen:

  1. get_next() - gibt ein Sample aus dem Puffer zurück. Die Größe des Beispielstapels und die Anzahl der zurückgegebenen Zeitschritte können über Argumente für diese Methode angegeben werden.
  2. as_dataset() - gibt den Wiedergabepuffer als tf.data.Dataset . Man kann dann einen Dataset-Iterator erstellen und die Beispiele der Elemente im Puffer durchlaufen.
  3. gather_all() - gibt alle Elemente im Puffer als Tensor mit der Form [batch, time, data_spec]

Nachfolgend finden Sie Beispiele zum Lesen aus dem Wiedergabepuffer mit jeder dieser Methoden:

# add more items to the buffer before reading
for _ in range(5):
  replay_buffer.add_batch(values_batched)

# Get one sample from the replay buffer with batch size 10 and 1 timestep:

sample = replay_buffer.get_next(sample_batch_size=10, num_steps=1)

# Convert the replay buffer to a tf.data.Dataset and iterate through it
dataset = replay_buffer.as_dataset(
    sample_batch_size=4,
    num_steps=2)

iterator = iter(dataset)
print("Iterator trajectories:")
trajectories = []
for _ in range(3):
  t, _ = next(iterator)
  trajectories.append(t)
  
print(tf.nest.map_structure(lambda t: t.shape, trajectories))

# Read all elements in the replay buffer:
trajectories = replay_buffer.gather_all()

print("Trajectories from gather all:")
print(tf.nest.map_structure(lambda t: t.shape, trajectories))

WARNING:tensorflow:From <ipython-input-6-1f9907631cb9>:7: 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.
Iterator trajectories:
[(TensorShape([4, 2, 3]), (TensorShape([4, 2, 5]), TensorShape([4, 2, 3, 2]))), (TensorShape([4, 2, 3]), (TensorShape([4, 2, 5]), TensorShape([4, 2, 3, 2]))), (TensorShape([4, 2, 3]), (TensorShape([4, 2, 5]), TensorShape([4, 2, 3, 2])))]
WARNING:tensorflow:From <ipython-input-6-1f9907631cb9>:24: ReplayBuffer.gather_all (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=True)` instead.
Trajectories from gather all:
(TensorShape([32, 6, 3]), (TensorShape([32, 6, 5]), TensorShape([32, 6, 3, 2])))

PyUniformReplayBuffer

PyUniformReplayBuffer hat die gleiche Funktion wie der TFUniformReplayBuffer aber anstelle von tf-Variablen werden seine Daten in numpy-Arrays gespeichert. Dieser Puffer kann für die Datenerfassung außerhalb des Diagramms verwendet werden. Wenn der Sicherungsspeicher in numpy gespeichert ist, kann es für einige Anwendungen einfacher sein, Daten zu bearbeiten (z. B. Indizierung zum Aktualisieren von Prioritäten), ohne Tensorflow-Variablen zu verwenden. Diese Implementierung bietet jedoch nicht den Vorteil von Diagrammoptimierungen mit Tensorflow.

Im Folgenden finden Sie ein Beispiel für die Instanziierung eines PyUniformReplayBuffer aus den PyUniformReplayBuffer des Agenten:

replay_buffer_capacity = 1000*32 # same capacity as the TFUniformReplayBuffer

py_replay_buffer = py_uniform_replay_buffer.PyUniformReplayBuffer(
    capacity=replay_buffer_capacity,
    data_spec=tensor_spec.to_nest_array_spec(data_spec))

Verwenden von Wiederholungspuffern während des Trainings

Jetzt, da wir wissen, wie man einen Wiedergabepuffer erstellt, Elemente darauf schreibt und daraus liest, können wir damit Trajektorien während des Trainings unserer Agenten speichern.

Datensammlung

Schauen wir uns zunächst an, wie der Wiedergabepuffer während der Datenerfassung verwendet wird.

In TF-Agents verwenden wir einen Driver (weitere Informationen finden Sie im Treiber-Tutorial), um Erfahrungen in einer Umgebung zu sammeln. Um einen Driver , geben wir einen Observer , der eine Funktion ist, die der Driver ausführen soll, wenn er eine Flugbahn empfängt.

add_batch(items) dem Wiedergabepuffer Trajektorienelemente hinzuzufügen, fügen wir einen Beobachter hinzu, der add_batch(items) , um einen (Stapel von) Elementen zum Wiedergabepuffer hinzuzufügen.

Unten sehen Sie ein Beispiel dafür mit TFUniformReplayBuffer . Wir erstellen zunächst eine Umgebung, ein Netzwerk und einen Agenten. Dann erstellen wir einen TFUniformReplayBuffer . Beachten Sie, dass die Spezifikationen der Trajektorienelemente im Wiedergabepuffer der Erfassungsdatenspezifikation des Agenten entsprechen. Anschließend legen wir die add_batch Methode als Beobachter für den Fahrer fest, der die während unseres Trainings add_batch Daten add_batch :

env = suite_gym.load('CartPole-v0')
tf_env = tf_py_environment.TFPyEnvironment(env)

q_net = q_network.QNetwork(
    tf_env.time_step_spec().observation,
    tf_env.action_spec(),
    fc_layer_params=(100,))

agent = dqn_agent.DqnAgent(
    tf_env.time_step_spec(),
    tf_env.action_spec(),
    q_network=q_net,
    optimizer=tf.compat.v1.train.AdamOptimizer(0.001))

replay_buffer_capacity = 1000

replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
    agent.collect_data_spec,
    batch_size=tf_env.batch_size,
    max_length=replay_buffer_capacity)

# Add an observer that adds to the replay buffer:
replay_observer = [replay_buffer.add_batch]

collect_steps_per_iteration = 10
collect_op = dynamic_step_driver.DynamicStepDriver(
  tf_env,
  agent.collect_policy,
  observers=replay_observer,
  num_steps=collect_steps_per_iteration).run()
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tf_agents/drivers/dynamic_step_driver.py:203: calling while_loop_v2 (from tensorflow.python.ops.control_flow_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.while_loop(c, b, vars, back_prop=False)
Use:
results = tf.nest.map_structure(tf.stop_gradient, tf.while_loop(c, b, vars))

Daten für einen Zugschritt lesen

Nach dem Hinzufügen von Trajektorienelementen zum Wiedergabepuffer können wir Stapel von Trajektorien aus dem Wiedergabepuffer lesen, um sie als Eingabedaten für einen Zugschritt zu verwenden.

Hier ist ein Beispiel für das Trainieren von Trajektorien aus dem Wiedergabepuffer in einer Trainingsschleife:

# Read the replay buffer as a Dataset,
# read batches of 4 elements, each with 2 timesteps:
dataset = replay_buffer.as_dataset(
    sample_batch_size=4,
    num_steps=2)

iterator = iter(dataset)

num_train_steps = 10

for _ in range(num_train_steps):
  trajectories, _ = next(iterator)
  loss = agent.train(experience=trajectories)

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))