ホーム » 強化学習 » TF-Agents 0.4 : Tutorials : ポリシー

TF-Agents 0.4 : Tutorials : ポリシー

TF-Agents 0.4 Tutorials : ポリシー (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/19/2020 (0.4)

* 本ページは、TF Agents の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

ポリシー

イントロダクション

強化学習の用語では、ポリシーは環境からの観測をアクションかアクションに渡る分布にマップします。TF-Agents では、環境からの観測は名前付きタプル TimeStep(‘step_type’, ‘discount’, ‘reward’, ‘observation’) に含まれて、そしてポリシーは時間ステップをアクションかアクションに渡る分布にマップします。殆どのポリシーは timestep.observation を利用し、幾つかのポリシーは timestep.step_type を利用します (e.g. ステートフル・ポリシーでエピソードの始まりで状態をリセットするため) が、timestep.discount と timestep.reward は通常は無視されます。

ポリシーは次のような方法で TF-Agents で他のコンポーネントに関係します。殆どのポリシーはアクション and/or TimeSteps からのアクションに渡る分布を計算するためにニューラルネットワークを持ちます。エージェントは異なる目的のために 1 つまたはそれ以上のポリシーを含むことができます、e.g. 配備のために訓練される主要ポリシー、そしてデータ収集のための noisy ポリシー。ポリシーはセーブ/リストアできて、データコレクション、評価等のためにエージェントとは無関係に使用できます。

幾つかのポリシーは TensorFlow で書くことがより容易です (e.g. ニューラルネットワークを持つもの)、他は Python で書くことが容易であることに反して (e.g. アクションのスクリプトに従っている)。そこで TF agents では、Python と TensorFlow ポリシーの両者を許容します。更に、TensorFlow で書かれたポリシーは Python 環境で使用されなければならないかもしれません、or vice versa、e.g. TensorFlow ポリシーは訓練のために使用されますが後で製品 python 環境で配備されます。これを容易にするために、python と TensorFlow ポリシーの間で変換するためのラッパーを提供します。

ポリシーのもう一つの興味深いクラスはポリシー・ラッパーです、これは与えられたポリシーをある方法で変更します、e.g. 特定のタイプのノイズを追加する、確率的ポリシーの greedy or epsilon-greedy 版を作成する、ランダムにマルチポリシーをミックスする等。

 

セットアップ

まだ tf-agents をインストールしていないのであれば、以下を実行します :

!pip install --upgrade tensorflow-probability
!pip install tf-agents
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 ポリシー

Python ポリシーのためのインターフェイスは policies/py_policy.Base で定義されます。主要なメソッドは :

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

  @abc.abstractmethod
  def copy(self):
    # return a copy of self.
    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

最も重要なメソッドは action(time_step) です、これは環境からの観測を含む time_step を以下の属性を含む PolicyStep 名前付きタプルにマップします :

  • action: 環境に適用されるアクション。
  • state: アクションへの次の呼び出しで供給されるポリシーの状態 (e.g. RNN 状態)。
  • info: アクション対数確率のようなオプションの副次情報。

time_step_spec と action_spec は入力時間ステップと出力アクションのための仕様です。ポリシーはまたリセット関数を持ちます、これは典型的にはステートフル・ポリシーの状態をリセットするために使用されます。copy 関数は自身のコピーを返しそして update(new_policy) 関数は自身を new_policy に向けて更新します。

今は、python ポリシーの 2, 3 のサンプルを見ましょう。

 

サンプル 1: ランダム Python ポリシー

PyPolicy の単純なサンプルは RandomPyPolicy で、これは離散/連続な与えられた action_spec のためのランダムアクションを生成します。入力 time_step は無視されます。

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)

 

サンプル 2: Scripted Python ポリシー

script ポリシーは (num_repeats, action) タプルのリストとして表されたアクションのスクリプトをプレイバックします。action 関数が呼び出されるたびに、それは反復の指定回数が成されるまでリストから次のアクションを返し、それからリストの次のアクションに進みます。reset メソッドはリストの最初から実行を開始するために呼び出すことができます。

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_repeates` 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)

 

TensorFlow ポリシー

TensorFlow ポリシーは Python ポリシーと同じインターフェイスに従います。2, 3 のサンプルを見ましょう。

 

Example 1: Random TF ポリシー

RandomTFPolicy は与えられた離散/連続な action_spec に従ってランダムアクションを生成するために使用できます。入力 time_step は無視されます。

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)

 

サンプル 2: Actor ポリシー

actor ポリシーは time_steps をアクションにマップするネットワークか、time_steps をアクションに渡る分散にマップするネットワークを使用して作成できます。

 
アクションネットワークを使用する

ネットワークを次のように定義しましょう :


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 では殆どのネットワーク層はバッチ演算のために設計されていますので、入力 time_steps はバッチ処理されてネットワーク出力もバッチ処理されることを想定します。ネットワークはまた与えられた action_spec の正しい範囲でアクションを生成する責任も負います。これは慣習的に e.g. [-1, 1] のアクションを生成するために最終層のための tanh 活性を使用してからこれを入力 action_spec として正しい範囲にスケールしてシフトすることにより成されます (e.g. tf_agents/agents/ddpg/networks.actor_network() 参照)。

今は、上のネットワークを使用して actor ポリシーを作成できます。

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)

それを time_step_spec に従う time_steps の任意のバッチに適用できます :

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)

上のサンプルで、アクション tensor を生成するアクション・ネットワークを使用してポリシーを作成しました。この場合、policy.distribution(time_step) は policy.action(time_step) の出力回りの決定論的 (delta) 分布です。確率的ポリシーを生成する一つの方法は actor ポリシーをアクションに noise を追加するポリシー・ラッパーでラップすることです。もう一つの方法は下で示されるようにアクションネットワークの代わりにアクション分布ネットワークを使用して actor ポリシーを作成することです。

 
アクション分布ネットワークを使用する

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.Normal(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)

上で、アクションは与えられたアクション spec [-1, 1] の範囲にクリップされることに注意してください。これはデフォルトで ActorPolicy のコンストラクタ引数 clip=True であるためです。これを false に設定することはネットワークにより生成されるクリップされないアクションを返します。

確率的ポリシーは例えば、GreedyPolicy ラッパーを使用して決定論的ポリシーに変換できます、これはそのアクションとして stochastic_policy.distribution().mode() を、そしてその distribution() としてこの greedy アクション回りの決定論的/delta 分布を選択します。

 

サンプル 3: Q ポリシー

Q ポリシーは DQN のようなエージェントで使用されて、各離散アクションのための Q 値を予測する Q ネットワークに基づきます。与えられた時間ステップについて、Q ポリシーのアクション分布はロジットとして q 値を使用して作成される categorical 分布です。

input_tensor_spec = tensor_spec.TensorSpec((4,), tf.float32)
time_step_spec = ts.time_step_spec(input_tensor_spec)
action_spec = tensor_spec.BoundedTensorSpec((1,),
                                            tf.int32,
                                            minimum=-1,
                                            maximum=1)
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)

 

ポリシー・ラッパー

ポリシー・ラッパーは与えられたポリシー, e.g. add noise をラップして変更するために使用できます。ポリシー・ラッパーは Policy (Python/TensorFlow) のサブクラスで従ってちょうど任意の他のポリシーのように使用できます。

 

サンプル: Greedy ポリシー

greedy ラッパーは distribution() を実装する任意の TensorFlow ポリシーをラップするために使用できます。GreedyPolicy.action() は wrapped_policy.distribution().mode() を返してそして GreedyPolicy.distribution() は GreedyPolicy.action() 回りの決定論的/delta 分布です :


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)
 

以上






AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com