Tamponları Tekrar Oynat

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Tanıtım

Takviye öğrenme algoritmaları, bir ortamda bir ilke yürütülürken deneyim yörüngelerini depolamak için yeniden yürütme arabelleklerini kullanır. Eğitim sırasında, aracının deneyimini "tekrar oynatmak" için yörüngelerin bir alt kümesi (sıralı bir alt küme veya bir örnek) için tekrar arabellekleri sorgulanır.

Bu ortak çalışmada, iki tür yeniden oynatma arabelleği keşfediyoruz: ortak bir API'yi paylaşan python destekli ve tensorflow destekli. Aşağıdaki bölümlerde API'yi, arabellek uygulamalarının her birini ve bunların veri toplama eğitimi sırasında nasıl kullanılacağını açıklıyoruz.

Kurmak

Henüz yapmadıysanız, tf-agent'ları yükleyin.

pip install tf-agents
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

Tampon API'sini Tekrar Oynat

Replay Buffer sınıfı aşağıdaki tanım ve yöntemlere sahiptir:

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

Not tekrar tampon nesne başlatıldı zaman, ihtiyaç duyduğu data_spec depolanması ki elementlerin. Bu spec karşılık TensorSpec tamponu eklenir yörünge elemanları. Bu Spec genellikle vekilin bakarak elde edilir agent.collect_data_spec (daha sonra bu konuda daha fazla) eğitim sırasında ajan tarafından beklenen şekiller, türleri ve yapıları tanımlar.

TFUniformReplayBuffer

TFUniformReplayBuffer böylece biz burada Öğretici kullanacağız, TF-Agents en yaygın olarak kullanılan yeniden oynatma tampondur. Gelen TFUniformReplayBuffer arka tampon bellek tensorflow değişkenler tarafından yapılan ve bu şekilde işlem grafik bir parçasıdır.

Tampon depolar elemanlarının toplu halde ve bir maksimum kapasitesi max_length toplu kesimi başına elemanları. Bu durumda, toplam ara bellek kapasitesi batch_size x max_length elemanları. Tamponda depolanan öğelerin tümü eşleşen bir veri özelliğine sahip olmalıdır. Yeniden yürütme arabelleği veri toplama için kullanıldığında, belirtim aracının veri toplama özelliğidir.

Tampon oluşturma:

Bir oluşturmak için TFUniformReplayBuffer biz geçmek:

  1. arabelleğin depolayacağı veri öğelerinin özelliği
  2. batch size tamponu yığın büyüklüğüne karşıt
  3. max_length toplu kesimi başına elemanların sayısı

Burada oluşturma örneğidir TFUniformReplayBuffer örnek veri özellikleri ile batch_size 32 ve max_length 1000 civarındadır.

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)

tampona yazma:

Tekrar tampon elemanları eklemek için, kullandığımız add_batch(items) yöntemi items öğe toplu temsil tensörlerinin bir liste / demet / yuva tamponuna ilave edilir. Her unsuru items bir dış boyuta eşit olmalıdır batch_size ve kalan boyutları (tekrar tampon yapıcıya iletilen veri özellikleri ile aynı) ürünün veri spec uymalıdır.

İşte toplu öğe eklemeye bir örnek

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)

tampondan okuma

Veri okumak için üç yolu vardır TFUniformReplayBuffer :

  1. get_next() - döner tampon bir numune. Örnek parti boyutu ve döndürülen zaman adımları sayısı, bu yöntemin bağımsız değişkenleri aracılığıyla belirtilebilir.
  2. as_dataset() - bir şekilde tekrar tampon döner tf.data.Dataset . Daha sonra bir veri kümesi yineleyicisi oluşturulabilir ve arabellekteki öğelerin örnekleri arasında yinelenebilir.
  3. gather_all() - şekli ile döner bir Tensörün tamponun tüm öğeleri [batch, time, data_spec]

Aşağıda, bu yöntemlerin her birini kullanarak yeniden oynatma arabelleğinden nasıl okunacağına ilişkin örnekler verilmiştir:

# 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 /tmp/ipykernel_15476/1348928897.py: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.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/tensorflow/python/data/experimental/ops/counter.py:66: scan (from tensorflow.python.data.experimental.ops.scan_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.data.Dataset.scan(...) 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 /tmp/ipykernel_15476/1348928897.py: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 aynı fonksiyonel olarak var TFUniformReplayBuffer yerine tf değişkenler, veri numpy diziler depolanır. Bu arabellek, grafik dışı veri toplama için kullanılabilir. Yedekleme deposunun numpy'de olması, bazı uygulamaların Tensorflow değişkenlerini kullanmadan veri işlemeyi (öncelikleri güncellemek için dizin oluşturma gibi) yapmasını kolaylaştırabilir. Ancak bu uygulama, Tensorflow ile grafik optimizasyonlarının avantajına sahip olmayacak.

Aşağıda başlatmasını bir örnektir PyUniformReplayBuffer ajanın politikası yörünge specs:

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

Eğitim sırasında tekrar arabelleklerini kullanma

Artık bir tekrar arabelleği oluşturmayı, ona öğeler yazmayı ve ondan okuma yapmayı bildiğimize göre, aracılarımızın eğitimi sırasında yörüngeleri depolamak için kullanabiliriz.

Veri toplama

İlk olarak, veri toplama sırasında tekrar arabelleğinin nasıl kullanılacağına bakalım.

TF-Agents biz bir kullanma Driver bir ortamda toplama deneyimine (diğer ayrıntılar için Sürücü öğretici bakınız). Bir kullanmak için Driver , biz belirtmek Observer için bir işlevdir Driver bir yörünge aldığında yürütülecek.

Bu nedenle, tekrar tampon yörünge elemanları eklemek için, biz aramaları bu bir gözlemci eklemek add_batch(items) tekrar tampon öğelerin bir toplu ekleyin.

Aşağıda bu bir örnektir TFUniformReplayBuffer . Önce bir ortam, bir ağ ve bir aracı oluşturuyoruz. Sonra bir oluşturmak TFUniformReplayBuffer . Yeniden yürütme arabelleğindeki yörünge öğelerinin özelliklerinin, aracının veri toplama özelliğine eşit olduğuna dikkat edin. Sonra onun set add_batch veriler eğitim sırasında toplamak yapacak sürücü için gözlemci olarak yöntemini:

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

Bir tren adımı için veri okuma

Yeniden yürütme arabelleğine yörünge öğeleri ekledikten sonra, bir tren adımı için giriş verileri olarak kullanmak üzere yeniden yürütme arabelleğinden yörünge yığınlarını okuyabiliriz.

Bir eğitim döngüsünde tekrar arabelleğinden yörüngeler üzerinde nasıl eğitileceğine dair bir örnek:

# 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.7/site-packages/tensorflow/python/util/dispatch.py:206: 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))