ลิขสิทธิ์ 2021 The TF-Agents Authors.
ดูบน 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
เล่นซ้ำบัฟเฟอร์ 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"""
ทราบว่าเมื่อ replay บัฟเฟอร์วัตถุที่จะเริ่มต้นก็ต้อง 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
นี้เป็นรายการ / tuple / รังของเทนเซอร์ที่เป็นตัวแทนของชุดของรายการที่จะเพิ่มการบัฟเฟอร์ องค์ประกอบของแต่ละ items
จะต้องมีมิติด้านนอกเท่ากับ batch_size
และมิติที่เหลือต้องเป็นไปตามสเปคข้อมูลของรายการ (เช่นเดียวกับรายละเอียดข้อมูลที่ส่งผ่านไปยังตัวสร้าง replay บัฟเฟอร์)
นี่คือตัวอย่างการเพิ่มชุดรายการ
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()
- ผลตอบแทนบัฟเฟอร์ replay เป็นtf.data.Dataset
จากนั้นคุณสามารถสร้างตัววนซ้ำชุดข้อมูลและวนซ้ำตัวอย่างของรายการในบัฟเฟอร์ -
gather_all()
- ผลตอบแทนทุกรายการในบัฟเฟอร์เป็น Tensor มีรูปร่าง[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 สำหรับรายละเอียดเพิ่มเติม) เพื่อประสบการณ์การเก็บในสภาพแวดล้อมที่ หากต้องการใช้ 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))