Hak Cipta 2021 The TF-Agents Authors.
Lihat di TensorFlow.org | Jalankan di Google Colab | Lihat sumber di GitHub | Unduh buku catatan |
pengantar
Dalam terminologi Reinforcement Learning, kebijakan memetakan pengamatan dari lingkungan ke suatu tindakan atau distribusi atas tindakan. Dalam TF-Agen, pengamatan dari lingkungan yang terkandung dalam tuple bernama TimeStep('step_type', 'discount', 'reward', 'observation')
, dan kebijakan peta timesteps tindakan atau distribusi atas tindakan. Kebanyakan kebijakan menggunakan timestep.observation
, beberapa kebijakan menggunakan timestep.step_type
(misalnya untuk me-reset negara pada awal sebuah episode dalam kebijakan stateful), tapi timestep.discount
dan timestep.reward
biasanya diabaikan.
Kebijakan terkait dengan komponen lain di TF-Agents dengan cara berikut. Sebagian besar kebijakan memiliki jaringan saraf untuk menghitung tindakan dan/atau distribusi melalui tindakan dari TimeSteps. Agen dapat berisi satu atau lebih kebijakan untuk tujuan yang berbeda, misalnya kebijakan utama yang sedang dilatih untuk penerapan, dan kebijakan noise untuk pengumpulan data. Kebijakan dapat disimpan/dipulihkan, dan dapat digunakan secara mandiri oleh agen untuk pengumpulan data, evaluasi, dll.
Beberapa kebijakan lebih mudah ditulis dalam Tensorflow (misalnya, yang memiliki jaringan saraf), sedangkan yang lain lebih mudah ditulis dengan Python (misalnya, mengikuti skrip tindakan). Jadi di agen TF, kami mengizinkan kebijakan Python dan Tensorflow. Selain itu, kebijakan yang ditulis dalam TensorFlow mungkin harus digunakan di lingkungan Python, atau sebaliknya, misalnya kebijakan TensorFlow digunakan untuk pelatihan tetapi kemudian diterapkan di lingkungan produksi Python. Untuk mempermudah ini, kami menyediakan pembungkus untuk mengonversi antara kebijakan Python dan TensorFlow.
Kelas kebijakan lain yang menarik adalah pembungkus kebijakan, yang memodifikasi kebijakan tertentu dengan cara tertentu, misalnya menambahkan jenis kebisingan tertentu, membuat versi serakah atau epsilon-rakus dari kebijakan stokastik, mencampur beberapa kebijakan secara acak, dll.
Mempersiapkan
Jika Anda belum menginstal tf-agents, jalankan:
pip install tf-agents
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import abc
import tensorflow as tf
import tensorflow_probability as tfp
import numpy as np
from tf_agents.specs import array_spec
from tf_agents.specs import tensor_spec
from tf_agents.networks import network
from tf_agents.policies import py_policy
from tf_agents.policies import random_py_policy
from tf_agents.policies import scripted_py_policy
from tf_agents.policies import tf_policy
from tf_agents.policies import random_tf_policy
from tf_agents.policies import actor_policy
from tf_agents.policies import q_policy
from tf_agents.policies import greedy_policy
from tf_agents.trajectories import time_step as ts
Kebijakan Python
Antarmuka untuk kebijakan Python didefinisikan dalam policies/py_policy.PyPolicy
. Metode utamanya adalah:
class Base(object):
@abc.abstractmethod
def __init__(self, time_step_spec, action_spec, policy_state_spec=()):
self._time_step_spec = time_step_spec
self._action_spec = action_spec
self._policy_state_spec = policy_state_spec
@abc.abstractmethod
def reset(self, policy_state=()):
# return initial_policy_state.
pass
@abc.abstractmethod
def action(self, time_step, policy_state=()):
# return a PolicyStep(action, state, info) named tuple.
pass
@abc.abstractmethod
def distribution(self, time_step, policy_state=()):
# Not implemented in python, only for TF policies.
pass
@abc.abstractmethod
def update(self, policy):
# update self to be similar to the input `policy`.
pass
@property
def time_step_spec(self):
return self._time_step_spec
@property
def action_spec(self):
return self._action_spec
@property
def policy_state_spec(self):
return self._policy_state_spec
Metode yang paling penting adalah action(time_step)
yang memetakan sebuah time_step
mengandung pengamatan dari lingkungan ke PolicyStep bernama tuple yang berisi atribut berikut:
-
action
: Tindakan yang harus diterapkan untuk lingkungan. -
state
: Negara bagian kebijakan (misalnya negara RNN) untuk dimasukkan ke dalam panggilan berikutnya untuk bertindak. -
info
: Informasi sisi opsional seperti probabilitas tindakan log.
The time_step_spec
dan action_spec
adalah spesifikasi untuk input langkah waktu dan tindakan output. Kebijakan juga memiliki reset
fungsi yang biasanya digunakan untuk mereset negara dalam kebijakan stateful. The update(new_policy)
fungsi update self
terhadap new_policy
.
Sekarang, mari kita lihat beberapa contoh kebijakan Python.
Contoh 1: Kebijakan Python Acak
Contoh sederhana dari PyPolicy
adalah RandomPyPolicy
yang menghasilkan tindakan acak untuk diskrit / kontinu action_spec diberikan. Input time_step
diabaikan.
action_spec = array_spec.BoundedArraySpec((2,), np.int32, -10, 10)
my_random_py_policy = random_py_policy.RandomPyPolicy(time_step_spec=None,
action_spec=action_spec)
time_step = None
action_step = my_random_py_policy.action(time_step)
print(action_step)
action_step = my_random_py_policy.action(time_step)
print(action_step)
PolicyStep(action=array([10, -4], dtype=int32), state=(), info=()) PolicyStep(action=array([7, 6], dtype=int32), state=(), info=())
Contoh 2: Kebijakan Python Berskrip
Sebuah drama kebijakan scripted kembali naskah tindakan direpresentasikan sebagai daftar (num_repeats, action)
tupel. Setiap kali action
fungsi disebut, ia mengembalikan tindakan selanjutnya dari daftar sampai jumlah tertentu mengulangi dilakukan, dan kemudian pindah ke tindakan berikutnya dalam daftar. The reset
metode dapat dipanggil untuk mulai menjalankan dari awal daftar.
action_spec = array_spec.BoundedArraySpec((2,), np.int32, -10, 10)
action_script = [(1, np.array([5, 2], dtype=np.int32)),
(0, np.array([0, 0], dtype=np.int32)), # Setting `num_repeats` to 0 will skip this action.
(2, np.array([1, 2], dtype=np.int32)),
(1, np.array([3, 4], dtype=np.int32))]
my_scripted_py_policy = scripted_py_policy.ScriptedPyPolicy(
time_step_spec=None, action_spec=action_spec, action_script=action_script)
policy_state = my_scripted_py_policy.get_initial_state()
time_step = None
print('Executing scripted policy...')
action_step = my_scripted_py_policy.action(time_step, policy_state)
print(action_step)
action_step= my_scripted_py_policy.action(time_step, action_step.state)
print(action_step)
action_step = my_scripted_py_policy.action(time_step, action_step.state)
print(action_step)
print('Resetting my_scripted_py_policy...')
policy_state = my_scripted_py_policy.get_initial_state()
action_step = my_scripted_py_policy.action(time_step, policy_state)
print(action_step)
Executing scripted policy... PolicyStep(action=array([5, 2], dtype=int32), state=[0, 1], info=()) PolicyStep(action=array([1, 2], dtype=int32), state=[2, 1], info=()) PolicyStep(action=array([1, 2], dtype=int32), state=[2, 2], info=()) Resetting my_scripted_py_policy... PolicyStep(action=array([5, 2], dtype=int32), state=[0, 1], info=())
Kebijakan TensorFlow
Kebijakan TensorFlow mengikuti antarmuka yang sama dengan kebijakan Python. Mari kita lihat beberapa contoh.
Contoh 1: Kebijakan TF Acak
Sebuah RandomTFPolicy dapat digunakan untuk menghasilkan tindakan acak menurut diskrit / kontinu diberikan action_spec
. Input time_step
diabaikan.
action_spec = tensor_spec.BoundedTensorSpec(
(2,), tf.float32, minimum=-1, maximum=3)
input_tensor_spec = tensor_spec.TensorSpec((2,), tf.float32)
time_step_spec = ts.time_step_spec(input_tensor_spec)
my_random_tf_policy = random_tf_policy.RandomTFPolicy(
action_spec=action_spec, time_step_spec=time_step_spec)
observation = tf.ones(time_step_spec.observation.shape)
time_step = ts.restart(observation)
action_step = my_random_tf_policy.action(time_step)
print('Action:')
print(action_step.action)
Action: tf.Tensor([-0.9448042 1.9039011], shape=(2,), dtype=float32)
Contoh 2: Kebijakan Aktor
Kebijakan aktor dapat dibuat baik menggunakan jaringan yang memetakan time_steps
tindakan atau jaringan yang memetakan time_steps
untuk distribusi atas tindakan.
Menggunakan jaringan aksi
Mari kita definisikan jaringan sebagai berikut:
class ActionNet(network.Network):
def __init__(self, input_tensor_spec, output_tensor_spec):
super(ActionNet, self).__init__(
input_tensor_spec=input_tensor_spec,
state_spec=(),
name='ActionNet')
self._output_tensor_spec = output_tensor_spec
self._sub_layers = [
tf.keras.layers.Dense(
action_spec.shape.num_elements(), activation=tf.nn.tanh),
]
def call(self, observations, step_type, network_state):
del step_type
output = tf.cast(observations, dtype=tf.float32)
for layer in self._sub_layers:
output = layer(output)
actions = tf.reshape(output, [-1] + self._output_tensor_spec.shape.as_list())
# Scale and shift actions to the correct range if necessary.
return actions, network_state
Di TensorFlow sebagian besar lapisan jaringan dirancang untuk operasi batch, jadi kami berharap input time_steps di-batch, dan output dari jaringan juga akan di-batch. Juga jaringan bertanggung jawab untuk menghasilkan tindakan dalam rentang yang benar dari action_spec yang diberikan. Ini secara konvensional dilakukan dengan menggunakan misalnya tanh aktivasi untuk lapisan akhir tindakan produksi di [-1, 1] dan kemudian scaling dan pergeseran ini untuk rentang yang benar sebagai action_spec input (misalnya lihat tf_agents/agents/ddpg/networks.actor_network()
).
Sekarang, kita dapat membuat kebijakan aktor menggunakan jaringan di atas.
input_tensor_spec = tensor_spec.TensorSpec((4,), tf.float32)
time_step_spec = ts.time_step_spec(input_tensor_spec)
action_spec = tensor_spec.BoundedTensorSpec((3,),
tf.float32,
minimum=-1,
maximum=1)
action_net = ActionNet(input_tensor_spec, action_spec)
my_actor_policy = actor_policy.ActorPolicy(
time_step_spec=time_step_spec,
action_spec=action_spec,
actor_network=action_net)
Kami dapat menerapkannya ke kumpulan time_steps apa pun yang mengikuti time_step_spec:
batch_size = 2
observations = tf.ones([2] + time_step_spec.observation.shape.as_list())
time_step = ts.restart(observations, batch_size)
action_step = my_actor_policy.action(time_step)
print('Action:')
print(action_step.action)
distribution_step = my_actor_policy.distribution(time_step)
print('Action distribution:')
print(distribution_step.action)
Action: tf.Tensor( [[0.9318627 0.7770741 0.8645338] [0.9318627 0.7770741 0.8645338]], shape=(2, 3), dtype=float32) Action distribution: tfp.distributions.Deterministic("Deterministic", batch_shape=[2, 3], event_shape=[], dtype=float32)
Pada contoh di atas, kami membuat kebijakan menggunakan jaringan tindakan yang menghasilkan tensor tindakan. Dalam hal ini, policy.distribution(time_step)
adalah deterministik (delta) distribusi di seluruh output dari policy.action(time_step)
. Salah satu cara untuk menghasilkan kebijakan stokastik adalah dengan membungkus kebijakan aktor dalam pembungkus kebijakan yang menambahkan noise pada tindakan. Cara lain adalah membuat kebijakan aktor menggunakan jaringan distribusi tindakan alih-alih jaringan tindakan seperti yang ditunjukkan di bawah ini.
Menggunakan jaringan distribusi aksi
class ActionDistributionNet(ActionNet):
def call(self, observations, step_type, network_state):
action_means, network_state = super(ActionDistributionNet, self).call(
observations, step_type, network_state)
action_std = tf.ones_like(action_means)
return tfp.distributions.MultivariateNormalDiag(action_means, action_std), network_state
action_distribution_net = ActionDistributionNet(input_tensor_spec, action_spec)
my_actor_policy = actor_policy.ActorPolicy(
time_step_spec=time_step_spec,
action_spec=action_spec,
actor_network=action_distribution_net)
action_step = my_actor_policy.action(time_step)
print('Action:')
print(action_step.action)
distribution_step = my_actor_policy.distribution(time_step)
print('Action distribution:')
print(distribution_step.action)
Action: tf.Tensor( [[ 0.96731853 1. 1. ] [ 0.94488937 -0.29294527 1. ]], shape=(2, 3), dtype=float32) Action distribution: tfp.distributions.MultivariateNormalDiag("ActionNet_MultivariateNormalDiag", batch_shape=[2], event_shape=[3], dtype=float32)
Perhatikan bahwa dalam contoh di atas, tindakan dijepit ke kisaran spesifikasi tindakan yang diberikan [-1, 1]. Ini karena argumen konstruktor dari ActorPolicy clip=True secara default. Menyetel ini ke false akan mengembalikan tindakan tidak terpotong yang dihasilkan oleh jaringan.
Kebijakan Stochastic dapat dikonversi ke kebijakan deterministik menggunakan, misalnya, pembungkus GreedyPolicy yang memilih stochastic_policy.distribution().mode()
sebagai aksinya, dan distribusi / delta deterministik sekitar tindakan serakah ini sebagai yang distribution()
.
Contoh 3: Kebijakan Q
Kebijakan AQ digunakan di agen seperti DQN dan didasarkan pada jaringan Q yang memprediksi nilai Q untuk setiap tindakan diskrit. Untuk langkah waktu tertentu, distribusi tindakan dalam Kebijakan Q adalah distribusi kategorikal yang dibuat menggunakan nilai q sebagai logit.
input_tensor_spec = tensor_spec.TensorSpec((4,), tf.float32)
time_step_spec = ts.time_step_spec(input_tensor_spec)
action_spec = tensor_spec.BoundedTensorSpec((),
tf.int32,
minimum=0,
maximum=2)
num_actions = action_spec.maximum - action_spec.minimum + 1
class QNetwork(network.Network):
def __init__(self, input_tensor_spec, action_spec, num_actions=num_actions, name=None):
super(QNetwork, self).__init__(
input_tensor_spec=input_tensor_spec,
state_spec=(),
name=name)
self._sub_layers = [
tf.keras.layers.Dense(num_actions),
]
def call(self, inputs, step_type=None, network_state=()):
del step_type
inputs = tf.cast(inputs, tf.float32)
for layer in self._sub_layers:
inputs = layer(inputs)
return inputs, network_state
batch_size = 2
observation = tf.ones([batch_size] + time_step_spec.observation.shape.as_list())
time_steps = ts.restart(observation, batch_size=batch_size)
my_q_network = QNetwork(
input_tensor_spec=input_tensor_spec,
action_spec=action_spec)
my_q_policy = q_policy.QPolicy(
time_step_spec, action_spec, q_network=my_q_network)
action_step = my_q_policy.action(time_steps)
distribution_step = my_q_policy.distribution(time_steps)
print('Action:')
print(action_step.action)
print('Action distribution:')
print(distribution_step.action)
Action: tf.Tensor([2 2], shape=(2,), dtype=int32) Action distribution: tfp.distributions.Categorical("Categorical", batch_shape=[2], event_shape=[], dtype=int32)
Pembungkus Kebijakan
Pembungkus kebijakan dapat digunakan untuk membungkus dan memodifikasi kebijakan yang diberikan, misalnya menambahkan noise. Pembungkus kebijakan adalah subkelas dari Kebijakan (Python/TensorFlow) dan oleh karena itu dapat digunakan sama seperti kebijakan lainnya.
Contoh: Kebijakan Greedy
Sebuah wrapper serakah dapat digunakan untuk membungkus setiap kebijakan TensorFlow yang mengimplementasikan distribution()
. GreedyPolicy.action()
akan kembali wrapped_policy.distribution().mode()
Dan GreedyPolicy.distribution()
adalah distribusi / delta deterministik sekitar GreedyPolicy.action()
:
my_greedy_policy = greedy_policy.GreedyPolicy(my_q_policy)
action_step = my_greedy_policy.action(time_steps)
print('Action:')
print(action_step.action)
distribution_step = my_greedy_policy.distribution(time_steps)
print('Action distribution:')
print(distribution_step.action)
Action: tf.Tensor([1 1], shape=(2,), dtype=int32) Action distribution: tfp.distributions.DeterministicWithLogProb("Deterministic", batch_shape=[2], event_shape=[], dtype=int32)