Bản quyền 2021 Các tác giả TF-Agents.
Xem trên TensorFlow.org | Chạy trong Google Colab | Xem nguồn trên GitHub | Tải xuống sổ ghi chép |
Giới thiệu
Trong thuật ngữ Học tăng cường, các chính sách ánh xạ một quan sát từ môi trường đến một hành động hoặc sự phân bổ qua các hành động. Trong TF-Đại lý, quan sát từ môi trường được chứa trong một tuple tên TimeStep('step_type', 'discount', 'reward', 'observation')
, và chính sách bản đồ timesteps đến những hành động hoặc các bản phân phối qua hành động. Hầu hết các chính sách sử dụng timestep.observation
, một số chính sách sử dụng timestep.step_type
(ví dụ để thiết lập lại trạng thái ở phần đầu của một tập phim trong chính sách stateful), nhưng timestep.discount
và timestep.reward
thường bị bỏ qua.
Các chính sách có liên quan đến các thành phần khác trong TF-Agents theo cách sau. Hầu hết các chính sách đều có mạng nơ-ron để tính toán các hành động và / hoặc phân phối qua các hành động từ TimeSteps. Tác nhân có thể chứa một hoặc nhiều chính sách cho các mục đích khác nhau, ví dụ: chính sách chính đang được đào tạo để triển khai và chính sách ồn ào để thu thập dữ liệu. Các chính sách có thể được lưu / khôi phục và có thể được sử dụng một cách bí mật của tác nhân để thu thập dữ liệu, đánh giá, v.v.
Một số chính sách dễ viết hơn trong Tensorflow (ví dụ: những chính sách có mạng nơron), trong khi những chính sách khác dễ viết hơn bằng Python (ví dụ: theo một tập lệnh các hành động). Vì vậy, trong các tác nhân TF, chúng tôi cho phép cả chính sách Python và Tensorflow. Hơn nữa, các chính sách được viết bằng TensorFlow có thể phải được sử dụng trong môi trường Python hoặc ngược lại, ví dụ: chính sách TensorFlow được sử dụng để đào tạo nhưng sau đó được triển khai trong môi trường Python sản xuất. Để làm cho việc này dễ dàng hơn, chúng tôi cung cấp các trình bao bọc để chuyển đổi giữa các chính sách Python và TensorFlow.
Một loại chính sách thú vị khác là trình bao bọc chính sách, nó sửa đổi một chính sách nhất định theo một cách nhất định, ví dụ: thêm một loại nhiễu cụ thể, tạo phiên bản tham lam hoặc tham lam của chính sách ngẫu nhiên, kết hợp ngẫu nhiên nhiều chính sách, v.v.
Thành lập
Nếu bạn chưa cài đặt tf-agent, hãy chạy:
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
Chính sách Python
Giao diện cho các chính sách Python được định nghĩa trong policies/py_policy.PyPolicy
. Các phương pháp chính là:
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
Phương pháp quan trọng nhất là action(time_step)
mà bản đồ một time_step
chứa một quan sát từ môi trường đến một tuple PolicyStep tên có chứa các thuộc tính sau:
-
action
: Hành động được áp dụng đối với môi trường. -
state
: Trạng thái của chính sách (ví dụ như nhà nước RNN) được đưa vào các cuộc gọi tiếp theo để hành động. -
info
: Thông tin bên bắt buộc như xác suất log hành động.
Các time_step_spec
và action_spec
là thông số kỹ thuật cho lần bước đầu vào và đầu ra hành động. Chính sách này cũng có một reset
chức năng mà thường được sử dụng để đặt lại nhà nước trong chính sách stateful. Các update(new_policy)
chức năng cập nhật self
đối với new_policy
.
Bây giờ, chúng ta hãy xem xét một vài ví dụ về các chính sách Python.
Ví dụ 1: Chính sách Python ngẫu nhiên
Một ví dụ đơn giản của một PyPolicy
là RandomPyPolicy
mà tạo ra những hành động ngẫu nhiên cho rời rạc / action_spec được liên tục. Các đầu vào time_step
được bỏ qua.
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=())
Ví dụ 2: Chính sách Python được tập lệnh
Một vở kịch chính sách kịch bản sao lưu một kịch bản hành động thể hiện dưới dạng một danh sách (num_repeats, action)
tuples. Mỗi lần các action
hàm được gọi, nó sẽ trả về các hành động tiếp theo trong danh sách cho đến khi số quy định của lặp đi lặp lại được thực hiện, và sau đó chuyển sang các hành động tiếp theo trong danh sách. Các reset
phương pháp có thể được gọi để bắt đầu thực hiện từ đầu danh sách.
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=())
Chính sách TensorFlow
Các chính sách TensorFlow tuân theo giao diện giống như các chính sách Python. Chúng ta hãy xem xét một vài ví dụ.
Ví dụ 1: Chính sách TF ngẫu nhiên
Một RandomTFPolicy thể được sử dụng để tạo ra những hành động ngẫu nhiên theo một rời rạc cho / liên tục action_spec
. Các đầu vào time_step
được bỏ qua.
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)
Ví dụ 2: Chính sách Tác nhân
Một chính sách diễn viên có thể được tạo ra bằng cách sử dụng một mạng lưới mà các bản đồ time_steps
để hành động hoặc một mạng lưới mà các bản đồ time_steps
để phân phối qua hành động.
Sử dụng mạng hành động
Hãy để chúng tôi xác định một mạng như sau:
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
Trong TensorFlow, hầu hết các lớp mạng được thiết kế cho các hoạt động hàng loạt, vì vậy chúng tôi mong đợi các bước thời gian đầu vào sẽ được thực hiện theo từng đợt và đầu ra của mạng cũng sẽ được thực hiện theo từng đợt. Ngoài ra, mạng chịu trách nhiệm tạo ra các hành động trong phạm vi chính xác của action_spec đã cho. Đây là thông thường thực hiện bằng ví dụ một tanh kích hoạt cho các lớp cuối cùng để hành động sản trong [-1, 1] và sau đó mở rộng quy mô và thay đổi này đến phạm vi đúng như action_spec đầu vào (ví dụ thấy tf_agents/agents/ddpg/networks.actor_network()
).
Bây giờ, chúng ta có thể tạo chính sách tác nhân bằng cách sử dụng mạng trên.
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)
Chúng tôi có thể áp dụng nó cho bất kỳ lô thời gian nào tuân theo 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)
Trong ví dụ trên, chúng tôi đã tạo chính sách bằng cách sử dụng mạng hành động tạo ra một bộ căng hành động. Trong trường hợp này, policy.distribution(time_step)
là một xác định (đồng bằng) phân phối xung quanh đầu ra của policy.action(time_step)
. Một cách để tạo ra chính sách ngẫu nhiên là bao bọc chính sách tác nhân trong một trình bao bọc chính sách để tạo thêm nhiễu cho các hành động. Một cách khác là tạo chính sách tác nhân bằng cách sử dụng mạng phân phối hành động thay vì mạng hành động như hình dưới đây.
Sử dụng mạng phân phối hành động
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)
Lưu ý rằng trong phần trên, các hành động được cắt theo phạm vi của thông số hành động đã cho [-1, 1]. Điều này là do một đối số phương thức khởi tạo của ActorPolicy clip = True theo mặc định. Đặt giá trị này thành false sẽ trả về các hành động không liên quan do mạng tạo ra.
Chính sách Stochastic có thể được chuyển đổi sang chính sách xác định sử dụng, ví dụ, một wrapper GreedyPolicy mà chọn stochastic_policy.distribution().mode()
như hành động của nó, và một bản phân phối / đồng bằng xác định xung quanh hành động tham lam này như nó distribution()
.
Ví dụ 3: Chính sách Q
Chính sách AQ được sử dụng trong các đại lý như DQN và dựa trên mạng Q dự đoán giá trị Q cho mỗi hành động rời rạc. Đối với một bước thời gian nhất định, phân phối hành động trong Chính sách Q là một phân phối phân loại được tạo bằng cách sử dụng các giá trị q làm logits.
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)
Trình gói chính sách
Một trình bao bọc chính sách có thể được sử dụng để bao bọc và sửa đổi một chính sách nhất định, ví dụ như thêm nhiễu. Trình bao bọc chính sách là một lớp con của Chính sách (Python / TensorFlow) và do đó có thể được sử dụng giống như bất kỳ chính sách nào khác.
Ví dụ: Chính sách tham lam
Một wrapper tham lam có thể được sử dụng để quấn bất kỳ chính sách TensorFlow rằng dụng cụ distribution()
. GreedyPolicy.action()
sẽ trở lại wrapped_policy.distribution().mode()
Và GreedyPolicy.distribution()
là một phân phối / đồng bằng xác định xung quanh 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)