حق چاپ 2021 نویسندگان TF-Agents.
مشاهده در TensorFlow.org | در Google Colab اجرا شود | مشاهده منبع در GitHub | دانلود دفترچه یادداشت |
معرفی
الگوریتمهای یادگیری تقویتی از بافرهای پخش مجدد برای ذخیره مسیرهای تجربه هنگام اجرای سیاست در یک محیط استفاده میکنند. در طول آموزش، بافرهای پخش مجدد برای زیرمجموعه ای از مسیرها (یا یک زیرمجموعه متوالی یا یک نمونه) جستجو می شوند تا تجربه عامل "بازپخش" شود.
در این colab، ما دو نوع بافر پخش مجدد را بررسی میکنیم: پشتیبان پایتون و پشتوانه تنسورفلو، که یک API مشترک دارند. در بخشهای بعدی، API، هر یک از پیادهسازیهای بافر و نحوه استفاده از آنها در طول آموزش جمعآوری دادهها را توضیح میدهیم.
برپایی
اگر قبلاً نصب نکرده اید، tf-agents را نصب کنید.
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
کلاس Replay Buffer دارای تعریف و روش های زیر است:
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"""
توجه داشته باشید که هنگامی که شی بافر پخش مقداردهی اولیه شده است، آن نیاز به data_spec
از عناصر است که آن را ذخیره خواهد کرد. این مربوط به تنظیمات TensorSpec
از عناصر مسیر خواهد شد که به بافر اضافه شده است. این مشخصه است که معمولا با نگاه کردن به یک عامل را به دست آورد agent.collect_data_spec
تعریف می کند که اشکال، انواع و ساختارهای انتظار می رود توسط عامل در هنگام آموزش (بیشتر در بعد).
TFUniformReplayBuffer
TFUniformReplayBuffer
شایع ترین استفاده از بافر پخش در TF-نمایندگی است، بنابراین ما آن را در آموزش ما در اینجا استفاده خواهد کرد. در TFUniformReplayBuffer
ذخیره سازی بافر حمایت توسط متغیرهای tensorflow انجام می شود و در نتیجه بخشی از نمودار محاسبه است.
فروشگاه بافر دسته از عناصر و دارای حداکثر ظرفیت max_length
عناصر در بخش دسته ای. بنابراین، ظرفیت بافر کل است batch_size
X max_length
عناصر. عناصر ذخیره شده در بافر همگی باید دارای مشخصات داده منطبق باشند. هنگامی که بافر پخش مجدد برای جمع آوری داده ها استفاده می شود، مشخصات، مشخصات جمع آوری داده های عامل است.
ایجاد بافر:
برای ایجاد یک TFUniformReplayBuffer
ما در عبور:
- مشخصات عناصر داده ای که بافر ذخیره می کند
-
batch size
مربوط به اندازه دسته ای از بافر -
max_length
تعدادی از عناصر در بخش دسته ای
اینجا یک مثال از ایجاد یک است TFUniformReplayBuffer
با مشخصات داده های نمونه، batch_size
32 و 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)
نوشتن در بافر:
برای اضافه کردن عناصر به بافر پخش، ما استفاده از add_batch(items)
روش که در آن items
یک لیست / تاپل / لانه تانسورها به نمایندگی از دسته ای از اقلام به به بافر اضافه شده است. هر عنصر از items
باید یک بعد برابر بیرونی batch_size
و ابعاد باقی مانده باید به مشخصات داده از آیتم (همان مشخصات داده به تصویب رسید به پخش سازنده بافر) پایبند است.
در اینجا نمونه ای از افزودن دسته ای از آیتم ها آورده شده است
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)
خواندن از بافر
سه راه برای خواندن داده ها از وجود دارد TFUniformReplayBuffer
:
-
get_next()
- بازده یک نمونه از بافر شده است. اندازه دسته نمونه و تعداد گام های زمانی بازگشتی را می توان از طریق آرگومان های این روش مشخص کرد. -
as_dataset()
- بازگرداندن بافر پخش به عنوان یکtf.data.Dataset
. سپس میتوان یک تکرارکننده مجموعه داده ایجاد کرد و از طریق نمونههای آیتمهای موجود در بافر تکرار کرد. -
gather_all()
- بازده تمام موارد در بافر به عنوان یک تانسور با شکل[batch, time, data_spec]
در زیر نمونه هایی از نحوه خواندن از بافر پخش مجدد با استفاده از هر یک از این روش ها آورده شده است:
# 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
است functionaly همان TFUniformReplayBuffer
اما به جای متغیرهای TF، اطلاعات آن در آرایه نامپای ذخیره می شود. این بافر می تواند برای جمع آوری داده های خارج از نمودار استفاده شود. داشتن حافظه پشتیبان در numpy ممکن است انجام دستکاری داده ها (مانند نمایه سازی برای به روز رسانی اولویت ها) را برای برخی از برنامه ها بدون استفاده از متغیرهای Tensorflow آسان تر کند. با این حال، این پیاده سازی از مزایای بهینه سازی نمودار با Tensorflow برخوردار نخواهد بود.
در زیر یک مثال از نمونه گذاری است PyUniformReplayBuffer
از مشخصات مسیر سیاست عامل:
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))
استفاده از بافرهای پخش مجدد در طول تمرین
اکنون که می دانیم چگونه یک بافر پخش مجدد ایجاد کنیم، موارد را در آن بنویسیم و از روی آن بخوانیم، می توانیم از آن برای ذخیره مسیرها در طول آموزش عوامل خود استفاده کنیم.
جمع آوری داده ها
ابتدا، بیایید نحوه استفاده از بافر پخش مجدد در طول جمع آوری داده ها را بررسی کنیم.
در TF-نمایندگی ما با استفاده از Driver
(آموزش درایور برای اطلاعات بیشتر ببینید) به تجربه جمع آوری در یک محیط. برای استفاده از یک Driver
، ما یک مشخص Observer
است که یک تابع برای Driver
به اجرا هنگامی که آن را به یک مسیر دریافت می کند.
بنابراین، برای اضافه کردن عناصر مسیر به بافر پخش، ما یک ناظر که تماس اضافه add_batch(items)
به اضافه کردن یک دسته ای از موارد در بافر پخش.
در زیر یک مثال از این با TFUniformReplayBuffer
. ابتدا یک محیط، یک شبکه و یک عامل ایجاد می کنیم. سپس ما ایجاد TFUniformReplayBuffer
. توجه داشته باشید که مشخصات عناصر مسیر در بافر پخش مجدد با مشخصات جمع آوری داده های عامل برابر است. ما پس از آن خود را تنظیم کنید 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()
خواندن داده ها برای یک پله قطار
پس از افزودن عناصر مسیر به بافر پخش مجدد، میتوانیم دستههایی از مسیرها را از بافر پخش مجدد بخوانیم تا به عنوان داده ورودی برای مرحله قطار استفاده کنیم.
در اینجا مثالی از نحوه تمرین روی مسیرها از بافر پخش مجدد در یک حلقه آموزشی آورده شده است:
# 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))