Politikalar

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Tanıtım

Reinforcement Learning terminolojisinde politikalar, çevreden gelen bir gözlemi bir eyleme veya eylemler üzerindeki bir dağılıma eşler. TF-Ajanlar olarak, çevreden gözlemler adlandırılmış tanımlama grubu içinde bulunan TimeStep('step_type', 'discount', 'reward', 'observation') , ve politikaları eylemleri üzerinde eylem veya dağılımları dilimler map. Çoğu politikaları kullanmak timestep.observation bazı politikalar kullanın timestep.step_type (örn durum bilgisi politikalarında bir bölüm başlangıcında durumunu sıfırlamak için), ancak timestep.discount ve timestep.reward genellikle göz ardı edilir.

Politikalar, TF-Agent'lardaki diğer bileşenlerle aşağıdaki şekilde ilişkilidir. Çoğu ilke, TimeSteps'ten gelen eylemler üzerinden eylemleri ve/veya dağıtımları hesaplamak için bir sinir ağına sahiptir. Aracılar farklı amaçlar için bir veya daha fazla ilke içerebilir, örneğin dağıtım için eğitilen bir ana ilke ve veri toplama için gürültülü bir ilke. Politikalar kaydedilebilir/geri yüklenebilir ve veri toplama, değerlendirme vb. için aracıdan bağımsız olarak kullanılabilir.

Bazı politikaların Tensorflow'ta yazılması daha kolaydır (ör. sinir ağı olanlar), diğerlerinin Python'da yazılması daha kolaydır (ör. bir eylem komut dosyasının ardından). Dolayısıyla TF aracılarında hem Python hem de Tensorflow politikalarına izin veriyoruz. Ayrıca, TensorFlow'da yazılan ilkelerin bir Python ortamında kullanılması gerekebilir veya bunun tersi de olabilir; örneğin, eğitim için bir TensorFlow ilkesi kullanılır, ancak daha sonra bir üretim Python ortamında devreye alınır. Bunu kolaylaştırmak için Python ve TensorFlow ilkeleri arasında dönüştürme için sarmalayıcılar sağlıyoruz.

Bir başka ilginç politika sınıfı, belirli bir politikayı belirli bir şekilde değiştiren, örneğin belirli bir gürültü türü ekleyen, stokastik bir politikanın açgözlü veya epsilon-açgözlü bir versiyonunu yapan, birden fazla politikayı rastgele karıştıran vb.

Kurmak

Henüz tf-agent'ları yüklemediyseniz, şunu çalıştırın:

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

Python Politikaları

Python politikaları için arabirim tanımlanan policies/py_policy.PyPolicy . Ana yöntemler şunlardır:

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

En önemli yöntem action(time_step) bir harita time_step aşağıdaki özellikleri içeren bir PolicyStep adlı başlığın çevreden bir gözlem içerir:

  • action : aksiyon ortamına uygulanacak.
  • state : politikası (örneğin RNN durumu) durumu eylem sonraki çağrı içine beslenecek.
  • info : İsteğe bağlı yan bilgi işlem günlüğü olasılıkları gibi.

time_step_spec ve action_spec giriş zamanı adımı ve çıkış eylem için özellikleri vardır. Politikalar ayrıca sahip reset tipik durum bilgisi politikalarında devlet sıfırlamak için kullanılır işlevi. update(new_policy) işlevi günceller self doğru new_policy .

Şimdi birkaç Python politikası örneğine bakalım.

Örnek 1: Rastgele Python Politikası

Bir basit bir örnek PyPolicy olan RandomPyPolicy kesikli / sürekli verilen action_spec rasgele işlemleri oluşturur. Giriş time_step göz ardı edilir.

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=())

Örnek 2: Komut Dosyalı Python Politikası

Metne dayalı bir politika oynar listesi olarak temsil eylemlerin bir komut dosyası geri (num_repeats, action) küpe. Her zaman action fonksiyonu denir, bu tekrarların belirtilen sayıda yapılana kadar listeden sonraki eylem verir ve sonra listedeki bir sonraki eyleme geçer. reset yöntemi listenin başından yürütmeye başlamak üzere çağrılabilir.

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=())

TensorFlow Politikaları

TensorFlow ilkeleri, Python ilkeleriyle aynı arabirimi izler. Birkaç örneğe bakalım.

Örnek 1: Rastgele TF Politikası

Bir RandomTFPolicy belirli bir ayrık / sürekli uygun rastgele işlemleri üretmek için kullanılabilir action_spec . Giriş time_step göz ardı edilir.

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)

Örnek 2: Aktör Politikası

Bir aktör politikası eşleyen bir ağ kullanılarak oluşturulabilir time_steps eylemlere ya eşleştiren bir şebekeyi time_steps eylemleri üzerinde dağılımları.

Bir eylem ağı kullanma

Bir ağı aşağıdaki gibi tanımlayalım:

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

TensorFlow'da ağ katmanlarının çoğu toplu işlemler için tasarlanmıştır, bu nedenle girdi time_steps'in toplu hale getirilmesini ve ağın çıktısının da toplu hale getirilmesini bekleriz. Ayrıca ağ, verilen action_spec'in doğru aralığında eylemler üretmekten sorumludur. Bu geleneksel [-1, 1] ve daha sonra ölçekleme ve (giriş action_spec olarak doğru aralığa bu kaydırılmasında üretmek eylemleri son kat için, örneğin bir tanh aktivasyonu kullanılarak yapılır bakınız örneğin tf_agents/agents/ddpg/networks.actor_network() ).

Şimdi yukarıdaki ağı kullanarak bir aktör politikası oluşturabiliriz.

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)

Bunu, time_step_spec'i izleyen herhangi bir time_steps grubuna uygulayabiliriz:

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)

Yukarıdaki örnekte, eylem tensörü üreten bir eylem ağı kullanarak politikayı oluşturduk. Bu durumda, policy.distribution(time_step) çıkışında yaklaşık deterministik (ö) dağılımı policy.action(time_step) . Stokastik bir ilke üretmenin bir yolu, aktör ilkesini, eylemlere gürültü ekleyen bir ilke sarmalayıcıya sarmaktır. Diğer bir yol, aşağıda gösterildiği gibi bir eylem ağı yerine bir eylem dağıtım ağı kullanarak aktör politikasını oluşturmaktır.

Bir eylem dağıtım ağı kullanma

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)

Yukarıda, eylemlerin verilen eylem özelliğinin [-1, 1] aralığına kırpıldığını unutmayın. Bunun nedeni, varsayılan olarak ActorPolicy clip=True yapıcı argümanının olmasıdır. Bunu false olarak ayarlamak, ağ tarafından üretilen kırpılmamış eylemleri döndürür.

Stokastik politikaları örneğin kullanılarak belirleyici politikaları, seçen bir GreedyPolicy sargı dönüştürülebilir stochastic_policy.distribution().mode() kendi etki olarak, ve bu hırslı eylem etrafında deterministik / üçgen dağılımı distribution() .

Örnek 3: Q Politikası

AQ ilkesi, DQN gibi aracılarda kullanılır ve her ayrı eylem için bir Q değeri öngören bir Q ağına dayanır. Belirli bir zaman adımı için, Q Politikasındaki eylem dağılımı, logit olarak q değerleri kullanılarak oluşturulan kategorik bir dağılımdır.

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)

İlke Paketleyiciler

Belirli bir ilkeyi sarmak ve değiştirmek için bir ilke sarmalayıcı kullanılabilir, örneğin gürültü eklemek. İlke sarmalayıcılar, İlkenin (Python/TensorFlow) bir alt sınıfıdır ve bu nedenle diğer herhangi bir ilke gibi kullanılabilir.

Örnek: Açgözlü Politika

Bir hırslı sarıcı bu uygulayan bir TensorFlow ilkesi sarmak için kullanılabilir distribution() . GreedyPolicy.action() döndürecektir wrapped_policy.distribution().mode() Ve GreedyPolicy.distribution() etrafında bir deterministik / delta dağıtımıdır 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)