Bir sorunuz mu var? TensorFlow Forum Ziyaret Forumunda toplulukla bağlantı kurun

Politikalar

TensorFlow.org'da görüntüleyin Google Colab'de çalıştırın Kaynağı GitHub'da görüntüleyin Defteri indirin

Giriş

Reinforcement Learning terminolojisinde, politikalar çevreden gelen bir gözlemi bir eyleme veya eylemler üzerinden bir dağıtıma eşler. TF-Agent'larda, ortamdan gelen gözlemler, adlandırılmış bir TimeStep('step_type', 'discount', 'reward', 'observation') içinde yer alır ve politikalar, eylemlere veya eylemlere göre dağılımlara zaman akışlarını eşler. Çoğu politika timestep.observation kullanır, bazı politikalar timestep.step_type kullanır (örneğin, durum bilgisi olan politikalarda bir bölümün başlangıcındaki durumu sıfırlamak için), ancak timestep.discount ve timestep.reward genellikle göz ardı edilir.

İlkeler, TF-Aracılar'daki diğer bileşenlerle aşağıdaki şekilde ilişkilidir. Çoğu politika, TimeSteps'ten gelen eylemler üzerinden eylemleri ve / veya dağılı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. İçin temsilciden bağımsız olarak kullanılabilir.

Bazı politikaların Tensorflow'da (örneğin bir sinir ağına sahip olanlar) yazılması daha kolayken, diğerlerinin Python'da yazılması daha kolaydır (örneğin, bir eylemler komut dosyasının izlenmesi). Dolayısıyla, TF aracılarında hem Python hem de Tensorflow politikalarına izin veriyoruz. Dahası, TensorFlow'da yazılan politikaların bir Python ortamında kullanılması gerekebilir veya bunun tersi olabilir, örneğin eğitim için bir TensorFlow politikası kullanılır, ancak daha sonra bir Python üretim ortamında dağıtılır. Bunu kolaylaştırmak için Python ve TensorFlow politikaları 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 oluşturan, birden fazla politikayı rastgele karıştıran vb. Politika sarmalayıcılardır.

Kurulum

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

pip install -q 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

tf.compat.v1.enable_v2_behavior()

Python Politikaları

Python politikaları için arayüz, policies/py_policy.PyPolicy tanımlanmıştır. Ana yöntemler:

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) gelen bir time_step içeren bir zaman_adımını aşağıdaki öznitelikleri içeren PolicyStep adlı bir tuple ile eşleyen action(time_step) :

  • action : Ortama uygulanacak eylem.
  • state : Bir sonraki harekete geçirici mesaja beslenecek politikanın durumu (örneğin, RNN durumu).
  • info : Eylem günlüğü olasılıkları gibi isteğe bağlı yan bilgiler.

time_step_spec ve action_spec , girdi zaman adımı ve çıktı eylemi için özelliklerdir. İlkelerin ayrıca, durum bilgisi olan ilkelerde durumu sıfırlamak için kullanılan bir reset işlevi de vardır. update(new_policy) işlevi self new_policy doğru günceller.

Ş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. Girilen time_step yok sayılır.

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([-6,  2], dtype=int32), state=(), info=())
PolicyStep(action=array([-7,  7], dtype=int32), state=(), info=())

Örnek 2: Komut Dosyalı Python Politikası

Komut dosyası yazılmış bir ilke, (num_repeats, action) tuplelar listesi olarak temsil edilen bir eylemler komut dosyasını oynatır. action işlevi her çağrıldığında, belirtilen sayıda yineleme yapılana kadar listeden sonraki eylemi döndürür ve ardından listedeki sonraki eyleme geçer. reset yöntemi, yürütmeyi listenin başından başlatmak için ç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 politikaları, Python politikalarıyla aynı arayüzü izler. Birkaç örneğe bakalım.

Örnek 1: Rastgele TF Politikası

Bir RandomTFPolicy, belirli bir ayrık / sürekli action_spec göre rastgele eylemler oluşturmak için kullanılabilir. Girilen time_step yok sayılır.

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([ 1.8538141  -0.95033884], shape=(2,), dtype=float32)

Örnek 2: Aktör Politikası

Bir aktör politikası, time_steps adımlarını eylemlerle eşleştiren bir ağ veya eylemler üzerindeki dağıtımlarla time_steps adımlarını eşleştiren bir ağ kullanılarak oluşturulabilir.

Bir eylem ağı kullanmak

Bir ağı şu şekilde 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 çoğu ağ katmanı toplu işlemler için tasarlanmıştır, bu nedenle girdi zaman_adımlarının gruplanmasını ve ağın çıktısının da toplu olarak işlenmesini bekliyoruz. Ayrıca ağ, verilen eylem_specinin doğru aralığında eylemler üretmekten sorumludur. Bu, geleneksel olarak, örneğin [-1, 1] 'de eylemler üretmek için son katman için bir tanh aktivasyonu kullanılarak ve ardından bunu giriş eylem_specisi olarak doğru aralığa ölçeklendirip kaydırarak yapılır (örn. 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 takip eden herhangi bir zaman_adımı 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.06422257  0.6671298   0.734995  ]
 [-0.06422257  0.6671298   0.734995  ]], shape=(2, 3), dtype=float32)
Action distribution:
tfp.distributions.Deterministic("Deterministic", batch_shape=[2, 3], event_shape=[], dtype=float32)

Yukarıdaki örnekte, bir 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 politika üretmenin bir yolu, aktör politikasını, eylemlere gürültü ekleyen bir politika sarmalayıcısıyla sarmalamaktı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.

Eylem dağıtım ağı kullanmak

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(
[[ 1.         1.        -0.810334 ]
 [-0.5075199  1.         0.1654225]], 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 spesifikasyonu [-1, 1] aralığına kırpıldığını unutmayın. Bunun nedeni, varsayılan olarak ActorPolicy clip = True yapıcı bağımsız değişkenidir. Bunu yanlış 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 politikası, DQN gibi aracılarda kullanılır ve her ayrı eylem için bir Q değerini tahmin eden 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([0 2], shape=(2,), dtype=int32)
Action distribution:
tfp.distributions.Categorical("Categorical", batch_shape=[2], event_shape=[], dtype=int32)

Politika Sarmalayıcılar

Bir politika sarıcı, belirli bir politikayı sarmak ve değiştirmek, örneğin gürültü eklemek için kullanılabilir. Politika sarmalayıcılar, Politikanın (Python / TensorFlow) bir alt sınıfıdır ve bu nedenle, diğer herhangi bir politika gibi kullanılabilir.

Örnek: Açgözlü Politika

distribution() uygulayan herhangi bir TensorFlow ilkesini sarmak için açgözlü bir sarmalayıcı kullanılabilir. GreedyPolicy.action() , wrapped_policy.distribution().mode() GreedyPolicy.distribution() ve GreedyPolicy.distribution() , GreedyPolicy.action() etrafında bir deterministik / delta dağılımıdır:

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([0 0], shape=(2,), dtype=int32)
Action distribution:
tfp.distributions.DeterministicWithLogProb("Deterministic", batch_shape=[2], event_shape=[], dtype=int32)