Hak Cipta 2021 The TF-Agents Authors.
Lihat di TensorFlow.org | Jalankan di Google Colab | Lihat sumber di GitHub | Unduh buku catatan |
pengantar
Algoritme pembelajaran penguatan menggunakan buffer replay untuk menyimpan lintasan pengalaman saat menjalankan kebijakan di suatu lingkungan. Selama pelatihan, buffer replay ditanyai untuk subset lintasan (baik subset berurutan atau sampel) untuk "memutar ulang" pengalaman agen.
Dalam colab ini, kami mengeksplorasi dua jenis buffer replay: didukung python dan didukung tensorflow, berbagi API umum. Di bagian berikut, kami menjelaskan API, masing-masing implementasi buffer, dan cara menggunakannya selama pelatihan pengumpulan data.
Mempersiapkan
Instal tf-agents jika Anda belum melakukannya.
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
Replay Buffer API
Kelas Replay Buffer memiliki definisi dan metode berikut:
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"""
Perhatikan bahwa ketika objek ulangan penyangga diinisialisasi, itu membutuhkan data_spec
dari unsur-unsur yang akan menyimpan. Ini sesuai spesifikasi dengan TensorSpec
elemen lintasan yang akan ditambahkan ke buffer. Spec ini biasanya diperoleh dengan melihat agen ini agent.collect_data_spec
yang mendefinisikan bentuk, jenis, dan struktur yang diharapkan oleh agen ketika pelatihan (lebih pada nanti).
TFUniformReplayBuffer
TFUniformReplayBuffer
adalah ulangan penyangga paling umum digunakan di TF-Agen, dengan demikian kita akan menggunakannya dalam tutorial kami di sini. Dalam TFUniformReplayBuffer
dukungan penyimpanan buffer dilakukan oleh variabel tensorflow dan dengan demikian merupakan bagian dari grafik menghitung.
Toko penyangga batch elemen dan memiliki kapasitas maksimum max_length
elemen per segmen batch. Dengan demikian, total kapasitas buffer batch_size
x max_length
elemen. Semua elemen yang disimpan dalam buffer harus memiliki spesifikasi data yang cocok. Ketika buffer replay digunakan untuk pengumpulan data, spesifikasinya adalah spesifikasi pengumpulan data agen.
Membuat penyangga:
Untuk membuat TFUniformReplayBuffer
kita lulus di:
- spesifikasi elemen data yang akan disimpan buffer
- yang
batch size
sesuai dengan ukuran batch buffer - yang
max_length
jumlah elemen per segmen angkatan
Berikut adalah contoh dari menciptakan TFUniformReplayBuffer
dengan spesifikasi data sampel, batch_size
32 dan 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)
Menulis ke buffer:
Untuk menambahkan elemen ke buffer replay, kami menggunakan add_batch(items)
metode di mana items
adalah daftar / tupel / sarang tensor mewakili batch barang yang akan ditambahkan ke buffer. Setiap elemen dari items
harus memiliki dimensi yang sama luar batch_size
dan dimensi yang tersisa harus mematuhi spesifikasi data item (sama seperti spesifikasi data yang diberikan kepada replay penyangga konstruktor).
Berikut ini contoh menambahkan sekumpulan item
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)
Membaca dari buffer
Ada tiga cara untuk membaca data dari TFUniformReplayBuffer
:
-
get_next()
- kembali satu sampel dari buffer. Ukuran kumpulan sampel dan jumlah langkah waktu yang dikembalikan dapat ditentukan melalui argumen ke metode ini. -
as_dataset()
- mengembalikan buffer ulangan sebagaitf.data.Dataset
. Satu kemudian dapat membuat iterator dataset dan beralih melalui sampel item dalam buffer. -
gather_all()
- kembali semua item dalam buffer sebagai Tensor dengan bentuk[batch, time, data_spec]
Di bawah ini adalah contoh cara membaca dari buffer replay menggunakan masing-masing metode ini:
# 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
memiliki functionaly sama dengan TFUniformReplayBuffer
tapi bukannya variabel tf, data disimpan dalam array numpy. Buffer ini dapat digunakan untuk pengumpulan data di luar grafik. Memiliki penyimpanan cadangan dalam numpy dapat mempermudah beberapa aplikasi untuk melakukan manipulasi data (seperti pengindeksan untuk memperbarui prioritas) tanpa menggunakan variabel Tensorflow. Namun, implementasi ini tidak akan mendapatkan manfaat dari pengoptimalan grafik dengan Tensorflow.
Di bawah ini adalah contoh dari instantiating PyUniformReplayBuffer
dari spesifikasi lintasan kebijakan agen:
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))
Menggunakan buffer replay selama pelatihan
Sekarang kita tahu cara membuat buffer replay, menulis item ke sana dan membaca darinya, kita dapat menggunakannya untuk menyimpan lintasan selama pelatihan agen kita.
Pengumpulan data
Pertama, mari kita lihat bagaimana menggunakan buffer replay selama pengumpulan data.
Dalam TF-Agen kami menggunakan Driver
(lihat Driver tutorial untuk lebih jelasnya) pengalaman mengumpulkan di lingkungan. Untuk menggunakan Driver
, kita menentukan Observer
yang merupakan fungsi untuk Driver
untuk mengeksekusi ketika menerima lintasan.
Dengan demikian, untuk menambahkan elemen lintasan ke buffer replay, kita menambahkan pengamat bahwa panggilan add_batch(items)
untuk menambahkan batch item pada buffer replay.
Di bawah ini adalah contoh dari ini dengan TFUniformReplayBuffer
. Kami pertama-tama membuat lingkungan, jaringan, dan agen. Kemudian kita buat TFUniformReplayBuffer
. Perhatikan bahwa spesifikasi elemen lintasan dalam buffer replay sama dengan spesifikasi pengumpulan data agen. Kami kemudian menetapkan nya add_batch
metode sebagai pengamat untuk driver yang akan melakukan pengumpulan data selama pelatihan kami:
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()
Membaca data untuk langkah kereta
Setelah menambahkan elemen lintasan ke buffer replay, kita dapat membaca kumpulan lintasan dari buffer replay untuk digunakan sebagai data input untuk langkah kereta.
Berikut adalah contoh cara melatih lintasan dari buffer replay dalam loop pelatihan:
# 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))