تاریخ را ذخیره کنید! Google I / O 18-20 مه بازمی گردد اکنون ثبت نام کنید
این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

آموزش راهزنان چند مسلح با ویژگی های هر بازو

شروع کنید

مشاهده در TensorFlow.org در Google Colab اجرا کنید مشاهده منبع در GitHub دانلود دفترچه یادداشت

این آموزش یک راهنمای گام به گام در مورد چگونگی استفاده از کتابخانه TF-Agents برای مشکلات راهزنان زمینه ای است که در آن اقدامات (بازوها) دارای ویژگی های خاص خود هستند ، مانند لیستی از فیلم های ارائه شده توسط ویژگی ها (ژانر ، سال انتشار ، ...)

پيش نياز

فرض بر این است که خواننده تا حدودی با کتابخانه Bandit TF-Agents آشنا است ، به ویژه قبل از خواندن این آموزش از طریق آموزش Bandits in TF-Agents کار کرده است .

راهزنان چند مسلح با ویژگی های بازو

در تنظیم "کلاسیک" راهزنان چند مسلح زمینه ای ، یک عامل در هر مرحله بردار زمینه ای (مشاهدات مستعار) را دریافت می کند و مجبور است از مجموعه محدودی از اعمال عددی (بازوها) انتخاب کند تا پاداش تجمعی خود را به حداکثر برساند.

حال سناریویی را در نظر بگیرید که یک نماینده فیلم بعدی را برای تماشای آن به کاربر پیشنهاد می کند. هر وقت تصمیم گیری باید انجام شود ، نماینده بعنوان زمینه برخی از اطلاعات مربوط به کاربر (سابقه تماشا ، اولویت ژانر و غیره ...) و همچنین لیست فیلم هایی را که انتخاب می کند ، دریافت می کند.

ما می توانیم سعی کنیم این مشکل را با در نظر گرفتن اطلاعات کاربر به عنوان زمینه و بازوهای movie_1, movie_2, ..., movie_K ، movie_1, movie_2, ..., movie_K ، اما این رویکرد دارای کاستی های متعددی است:

  • تعداد کنش ها باید همه فیلم های موجود در سیستم باشد و افزودن یک فیلم جدید دست و پا گیر است.
  • نماینده باید برای تک تک فیلم ها یک مدل یاد بگیرد.
  • شباهت بین فیلم ها در نظر گرفته نمی شود.

به جای شماره گذاری فیلم ها ، می توانیم کاری بصری تر انجام دهیم: ما می توانیم فیلم هایی را با مجموعه ای از ویژگی ها از جمله ژانر ، طول ، بازیگران ، رتبه بندی ، سال و ... نشان دهیم. مزایای این روش چندین برابر است:

  • تعمیم در بین فیلم ها.
  • نماینده فقط یک عملکرد پاداش را یاد می گیرد که مدل آن را با ویژگی های کاربر و فیلم پاداش می دهد.
  • حذف یا معرفی فیلم های جدید به سیستم آسان است.

در این تنظیم جدید ، لازم نیست تعداد اقدامات در هر مرحله زمانی یکسان باشد.

راهزنان Per-Arm در TF-Agents

مجموعه Bandit TF-Agents به گونه ای ساخته شده است که می توان از آن برای قاب بازو نیز استفاده کرد. محیط های هر بازو وجود دارد و همچنین بسیاری از سیاست ها و عوامل می توانند در حالت بازو عمل کنند.

قبل از اینکه ما در یک کدگذاری یک مثال غوطه ور شویم ، به کالاهای وارداتی نیاز داریم.

نصب و راه اندازی

pip install -q tf-agents

واردات

import functools
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf

from tf_agents.bandits.agents import lin_ucb_agent
from tf_agents.bandits.environments import stationary_stochastic_per_arm_py_environment as p_a_env
from tf_agents.bandits.metrics import tf_metrics as tf_bandit_metrics
from tf_agents.drivers import dynamic_step_driver
from tf_agents.environments import tf_py_environment
from tf_agents.replay_buffers import tf_uniform_replay_buffer
from tf_agents.specs import tensor_spec
from tf_agents.trajectories import time_step as ts

# Clear any leftover state from previous colabs run.
# (This is not necessary for normal programs.)
tf.compat.v1.reset_default_graph()

tf.compat.v1.enable_resource_variables()
tf.compat.v1.enable_v2_behavior()
nest = tf.compat.v2.nest

پارامترها - به راحتی بازی کنید

# The dimension of the global features.
GLOBAL_DIM = 40 
# The elements of the global feature will be integers in [-GLOBAL_BOUND, GLOBAL_BOUND).
GLOBAL_BOUND = 10 
# The dimension of the per-arm features.
PER_ARM_DIM = 50 
# The elements of the PER-ARM feature will be integers in [-PER_ARM_BOUND, PER_ARM_BOUND).
PER_ARM_BOUND = 6 
# The variance of the Gaussian distribution that generates the rewards.
VARIANCE = 100.0 
# The elements of the linear reward parameter will be integers in [-PARAM_BOUND, PARAM_BOUND).
PARAM_BOUND = 10 

NUM_ACTIONS = 70 
BATCH_SIZE = 20 

# Parameter for linear reward function acting on the
# concatenation of global and per-arm features.
reward_param = list(np.random.randint(
      -PARAM_BOUND, PARAM_BOUND, [GLOBAL_DIM + PER_ARM_DIM]))

یک محیط ساده برای بازو

محیط تصادفی ثابت ، که در آموزش دیگر توضیح داده شده است ، دارای یک نمونه مشابه از هر بازو است.

برای مقداردهی اولیه محیط هر بازو ، باید توابع تولید شده را تعریف کرد

  • ویژگی های global و per-arm : این توابع هیچ پارامتر ورودی ندارند و در صورت فراخوانی یک بردار ویژگی واحد (global یا per-arm) ایجاد می کنند.
  • پاداش ها : این تابع به هم پیوستن یک بردار ویژگی جهانی و یک ویژگی برای هر بازو را می گیرد و پاداش ایجاد می کند. اساساً این عملکردی است که نماینده باید "حدس" بزند. در اینجا شایان ذکر است که در مورد هر بازو ، عملکرد پاداش برای هر بازو یکسان است. این یک تفاوت اساسی با مورد راهزن کلاسیک است ، جایی که عامل باید توابع پاداش را برای هر بازو به طور مستقل تخمین بزند.
def global_context_sampling_fn():
  """This function generates a single global observation vector."""
  return np.random.randint(
      -GLOBAL_BOUND, GLOBAL_BOUND, [GLOBAL_DIM]).astype(np.float32)

def per_arm_context_sampling_fn():
  """"This function generates a single per-arm observation vector."""
  return np.random.randint(
      -PER_ARM_BOUND, PER_ARM_BOUND, [PER_ARM_DIM]).astype(np.float32)

def linear_normal_reward_fn(x):
  """This function generates a reward from the concatenated global and per-arm observations."""
  mu = np.dot(x, reward_param)
  return np.random.normal(mu, VARIANCE)

اکنون ما مجهز شده ایم تا محیط خود را آغاز کنیم.

per_arm_py_env = p_a_env.StationaryStochasticPerArmPyEnvironment(
    global_context_sampling_fn,
    per_arm_context_sampling_fn,
    NUM_ACTIONS,
    linear_normal_reward_fn,
    batch_size=BATCH_SIZE
)
per_arm_tf_env = tf_py_environment.TFPyEnvironment(per_arm_py_env)

در زیر می توانیم بررسی کنیم که این محیط چه چیزی تولید می کند.

print('observation spec: ', per_arm_tf_env.observation_spec())
print('\nAn observation: ', per_arm_tf_env.reset().observation)

action = tf.zeros(BATCH_SIZE, dtype=tf.int32)
time_step = per_arm_tf_env.step(action)
print('\nRewards after taking an action: ', time_step.reward)
observation spec:  {'global': TensorSpec(shape=(40,), dtype=tf.float32, name=None), 'per_arm': TensorSpec(shape=(70, 50), dtype=tf.float32, name=None)}

An observation:  {'global': <tf.Tensor: shape=(20, 40), dtype=float32, numpy=
array([[ -2.,   6.,  -7.,  -9.,   5.,   1.,   3.,  -1.,   1.,   1.,  -9.,
         -9.,  -7.,  -2.,   3.,   1.,  -7.,   2.,  -5.,   5.,   0.,   8.,
          9.,   5.,   3.,   1.,   5.,  -6.,   7.,   7.,  -9.,   0.,   7.,
         -2.,   9.,  -5.,   5.,   1.,  -1.,  -9.],
       [  4.,  -3.,   4.,  -7.,   5.,   7.,   4.,  -9.,  -9.,  -2.,  -3.,
         -9.,   0.,  -5.,  -5., -10.,  -7.,  -2.,   4.,  -6.,   6.,   2.,
          1.,   8.,   4.,   8.,   2.,   2.,   5.,   9.,  -3.,  -5.,  -8.,
          7.,   8.,  -5.,  -9.,   9.,   7.,  -8.],
       [  3.,   6., -10.,   0.,  -8.,  -5.,   8.,  -1.,  -2.,  -2.,  -8.,
          7.,   7.,   2.,  -6.,   8.,   8.,   4.,  -1.,   7.,   7.,   7.,
         -7.,  -3.,   3.,  -9.,   7.,   4.,   7.,   3.,   6., -10.,  -2.,
          1.,  -8.,   0.,  -5.,   5.,  -3.,   0.],
       [-10.,  -9.,   1.,   9.,   9., -10.,  -6.,   1.,   0.,  -7.,   1.,
          0.,   1.,   2.,   6.,  -5., -10.,  -5.,   9.,   3.,   0.,   4.,
          6.,  -6.,   4.,  -5.,  -6.,  -8.,  -5.,   2.,  -2.,  -9.,  -2.,
         -6.,   4.,  -5.,  -8.,  -9., -10.,  -1.],
       [ -6.,  -1.,  -3.,   4.,   6.,   6.,  -2.,   1.,   2.,   6.,   2.,
          3.,   7.,  -7.,   2.,   0.,  -3.,   0.,   6.,   3.,   0.,   0.,
         -7.,  -7.,   0.,   8.,   4.,   1., -10.,  -8.,  -4.,  -3.,  -6.,
         -9.,   3.,  -8.,   8.,   1.,  -4.,   6.],
       [  2.,  -8.,   5.,  -8.,   1.,  -9.,   9.,  -2.,  -9., -10.,  -8.,
         -2.,   7.,  -5.,   8.,   6., -10.,   7.,   5.,   7.,  -6.,  -8.,
         -9.,   6.,  -2.,  -1., -10.,  -5.,  -1.,  -2.,   1.,  -8.,   8.,
          6.,  -2.,   4.,  -5.,  -5.,  -6.,   8.],
       [  8.,   4.,   9.,   9.,  -9.,  -3.,  -5.,   5.,   1.,   3.,   9.,
         -7.,  -3.,  -7.,  -7.,   8.,   9.,  -8.,  -7.,   5.,  -3.,  -5.,
         -8., -10.,   9.,   4.,   9.,   1.,   2.,  -3.,   2.,  -5., -10.,
         -4.,  -9.,  -5.,  -5.,   6.,   2.,  -9.],
       [ -2.,  -4.,  -4.,  -5.,  -7.,  -1.,  -8.,   1.,   2., -10.,  -6.,
          2.,   4.,   4.,  -3.,  -5.,   0.,   1.,  -5.,   9.,  -5.,   8.,
         -2.,   6.,  -4.,  -8.,  -8.,   2.,   2.,   9.,   2.,  -9.,   7.,
         -1.,   4.,  -1.,   8.,   5.,  -3.,  -7.],
       [ -8.,   4.,   0.,   1.,  -1.,   4.,  -5.,  -8.,  -1.,   7.,  -2.,
         -4.,  -4.,   8.,   2.,   5.,  -7.,   8.,   8.,  -6.,  -2.,  -2.,
         -9., -10.,  -8.,  -8.,   2.,  -8.,   3.,  -9.,   8.,  -7.,   0.,
         -1.,  -7.,   2.,   1.,   4.,   8.,   2.],
       [ -7.,  -2.,  -1.,  -4.,  -2.,  -4.,   0.,  -5.,   2.,  -3.,  -9.,
         -5.,  -5.,   9.,   3.,   4.,   4.,  -9.,  -9.,  -8.,   1.,  -2.,
         -3., -10.,  -9.,   0.,   9.,   1.,   3.,  -4.,   9.,   1.,  -7.,
          1.,   2.,   8.,  -2.,  -5.,   8.,  -4.],
       [-10.,  -2.,   6.,  -2.,   9.,  -9.,  -7.,   3.,  -9.,  -2.,   2.,
         -8.,  -7.,  -6.,   3.,  -2.,   8.,   2.,  -3., -10.,   5.,   1.,
         -4.,  -4.,   3.,  -5.,   8.,  -3.,  -8.,   6.,  -8.,  -6.,   4.,
         -7.,  -5.,   7.,  -6.,   1.,   3.,  -2.],
       [ -6.,  -6.,  -6.,  -7.,  -6.,   9.,  -9.,  -1.,  -3.,   0.,  -5.,
         -4.,   9.,   1.,  -9.,  -8.,  -1.,  -2., -10., -10.,   1.,  -1.,
          0.,  -6.,   5.,   0.,   7.,   2.,   6.,   8.,  -5.,   2.,  -2.,
          6.,  -2.,  -3.,   5.,  -3.,   2.,   1.],
       [ -9.,   6.,   0.,   8.,   4.,  -6.,   1.,  -4.,  -9.,  -6.,  -6.,
         -9.,  -3.,   0.,  -1.,   7.,   4.,   5.,   5., -10.,  -1., -10.,
          4.,   0.,  -1.,  -6.,  -6.,   6.,   3.,   4.,   6.,  -7.,   5.,
        -10.,   9.,  -1.,   2.,  -7.,  -7.,   2.],
       [ -5., -10.,   4.,  -3.,  -3.,  -1.,  -9.,   4., -10.,   7.,   9.,
         -9.,  -4.,   7.,   4.,   9.,  -8.,  -9.,  -6.,  -5.,   4.,   6.,
          7.,   0.,  -6.,  -4.,  -1.,   7.,   4.,  -5.,  -9.,   6.,  -5.,
          7.,   2.,   4.,   5.,  -7., -10.,   2.],
       [ -2.,   7.,   9.,   1.,  -5.,  -4.,  -7.,   2.,   4.,   8.,  -9.,
          0.,  -8.,   2.,  -4.,  -9.,  -9.,  -6.,  -7.,   8.,  -6.,   2.,
          8.,  -5.,  -1.,   9.,  -4.,   2.,  -4.,  -9.,  -2.,  -9.,   4.,
          8.,  -5.,  -3.,  -9.,  -5.,  -7.,   3.],
       [  9.,   8.,   1.,   2.,   5.,   6., -10.,  -2.,  -3.,   4.,  -7.,
          7.,   8.,   3.,   0.,  -1.,  -8.,   8.,  -8.,  -1., -10.,   4.,
          1., -10.,  -8.,   3.,   3.,   5.,   2.,   3.,   3.,  -9.,  -7.,
          2.,   4.,  -9.,   6., -10.,  -7.,   1.],
       [  7.,  -2.,  -9.,   8.,  -6.,  -5.,  -1.,  -6.,  -3.,  -3.,   8.,
          4.,   5.,  -1.,  -9.,   0.,   8.,   1.,   0.,   7.,   9.,   7.,
         -3., -10.,  -4.,   5.,   7.,  -2.,  -3.,  -3.,   7.,   7.,   7.,
          8.,  -7.,   5.,  -6.,  -4.,  -7.,   4.],
       [ -6.,  -9.,  -1.,  -5., -10.,  -9.,  -3.,   2.,  -6.,   3.,   0.,
         -4.,  -6., -10.,   2.,   2.,  -3.,   0.,   9.,   6.,  -9.,   7.,
          5.,   3.,  -8.,  -9., -10.,   9.,  -8.,   8.,   9.,   8.,  -6.,
          0.,   9.,  -8.,   8.,  -7., -10.,  -3.],
       [ -8.,   5.,  -8., -10.,  -3.,  -1.,   9.,  -4.,  -9.,  -5.,   2.,
         -5.,   9.,   0.,   2.,  -6.,  -9.,   3.,   1., -10.,   8.,   2.,
         -7.,  -5.,   1.,   1.,   7.,   7.,   4.,   4.,   8.,  -1.,  -2.,
         -4.,  -9.,  -9.,   0.,   5.,   6.,   5.],
       [ -2.,   3.,   0.,   8.,   8.,  -7.,  -7.,  -4.,  -4.,  -1.,   7.,
          6.,   6.,  -2., -10.,  -5.,  -3.,   5.,  -7.,  -1., -10.,   8.,
          8.,  -7.,   1.,  -1.,   9.,  -1.,   1.,  -3.,  -3.,  -5.,   3.,
         -2.,  -8.,  -5.,   1.,  -9.,  -5.,   3.]], dtype=float32)>, 'per_arm': <tf.Tensor: shape=(20, 70, 50), dtype=float32, numpy=
array([[[ 5.,  4., -1., ...,  5., -2.,  2.],
        [-3., -4.,  1., ...,  2.,  1.,  3.],
        [ 5.,  5.,  1., ..., -3.,  1., -3.],
        ...,
        [-4., -5.,  2., ..., -3.,  2., -4.],
        [-6., -2., -1., ...,  0., -3., -2.],
        [ 0., -1.,  0., ..., -5.,  5.,  5.]],

       [[ 1.,  0., -6., ...,  0., -6.,  5.],
        [-1.,  3.,  4., ..., -6.,  2.,  2.],
        [ 4.,  4., -3., ...,  3.,  4., -1.],
        ...,
        [ 4.,  5.,  5., ...,  3., -4., -5.],
        [-4.,  4., -4., ...,  0.,  0., -2.],
        [ 3.,  3., -2., ...,  5., -4.,  1.]],

       [[ 3.,  0.,  3., ...,  3., -5., -5.],
        [ 2., -6.,  2., ..., -3.,  1., -5.],
        [-3.,  0.,  3., ...,  5.,  4.,  1.],
        ...,
        [ 5., -2.,  4., ..., -1.,  1., -5.],
        [-6., -5., -5., ..., -2.,  2., -2.],
        [-3.,  4., -3., ..., -6., -2., -5.]],

       ...,

       [[-1.,  3., -5., ...,  5.,  0., -6.],
        [-2., -3.,  5., ..., -1., -3., -6.],
        [-5., -2., -6., ...,  2., -1., -1.],
        ...,
        [ 5.,  5.,  3., ..., -2., -6.,  4.],
        [ 3., -2.,  5., ..., -2.,  1., -3.],
        [ 0., -4.,  0., ..., -2., -5.,  3.]],

       [[ 4.,  0., -1., ...,  1., -5.,  1.],
        [ 3., -1.,  1., ...,  3.,  2., -3.],
        [-3.,  5., -3., ..., -5., -2., -2.],
        ...,
        [ 2.,  2.,  0., ..., -4., -3.,  1.],
        [-2., -1., -6., ...,  5.,  2., -1.],
        [ 5., -5., -4., ...,  0.,  0.,  2.]],

       [[ 2., -5., -3., ...,  4.,  1.,  5.],
        [-6., -3.,  0., ...,  0., -6.,  0.],
        [-4.,  5.,  4., ..., -2., -6., -2.],
        ...,
        [-5.,  2., -3., ...,  2.,  2., -1.],
        [ 3.,  1.,  2., ..., -3.,  4., -2.],
        [-4., -6.,  0., ...,  1.,  4., -3.]]], dtype=float32)>}

Rewards after taking an action:  tf.Tensor(
[ 331.55225   218.48183    12.477335  187.16455   589.95874   763.1056
 -626.69977    84.7426    236.88188  -534.37384  -574.7208   -109.05664
 -275.17267  -658.0759    190.7286    636.0466    430.8289    476.09213
 -191.11966    47.453167], shape=(20,), dtype=float32)

می بینیم که مشخصات مشاهده یک فرهنگ لغت با دو عنصر است:

  • یکی با کلید 'global' : این قسمت زمینه جهانی است که شکل با پارامتر GLOBAL_DIM .
  • یکی با کلید 'per_arm' : این متن برای هر بازو است و شکل آن [NUM_ACTIONS, PER_ARM_DIM] . این قسمت محل نگهداری ویژگی های بازو برای هر بازو در یک گام زمانی است.

نماینده LinUCB

عامل LinUCB الگوریتم Bandit با نام مشابه را پیاده سازی می کند ، که پارامتر تابع پاداش خطی را تخمین می زند و در عین حال بیضی اعتماد به نفس را در مورد برآورد حفظ می کند. با فرض اینکه پارامتر در بیضوی اطمینان باشد ، نماینده بازویی را انتخاب می کند که بالاترین پاداش پیش بینی شده را داشته باشد.

ایجاد یک عامل نیاز به دانش مشاهده و مشخصات عمل دارد. هنگام تعریف عامل ، پارامتر boolean accepts_per_arm_features روی True تنظیم می کنیم.

observation_spec = per_arm_tf_env.observation_spec()
time_step_spec = ts.time_step_spec(observation_spec)
action_spec = tensor_spec.BoundedTensorSpec(
    dtype=tf.int32, shape=(), minimum=0, maximum=NUM_ACTIONS - 1)

agent = lin_ucb_agent.LinearUCBAgent(time_step_spec=time_step_spec,
                                     action_spec=action_spec,
                                     accepts_per_arm_features=True)

جریان داده های آموزش

در این بخش نگاهی اجمالی به مکانیک می اندازد که چگونه ویژگی های هر بازو از سیاست به آموزش می رسد. در صورت تمایل به قسمت بعدی بروید (تعریف متاسف برای حسرت) و در صورت تمایل بعداً به اینجا برگردید.

ابتدا اجازه دهید نگاهی به مشخصات داده در عامل بیندازیم. training_data_spec صفت مشخص عامل چه عناصر و ساختار داده های آموزشی باید داشته باشد.

print('training data spec: ', agent.training_data_spec)
training data spec:  Trajectory(step_type=TensorSpec(shape=(), dtype=tf.int32, name='step_type'), observation=DictWrapper({'global': TensorSpec(shape=(40,), dtype=tf.float32, name=None)}), action=BoundedTensorSpec(shape=(), dtype=tf.int32, name=None, minimum=array(0, dtype=int32), maximum=array(69, dtype=int32)), policy_info=PerArmPolicyInfo(log_probability=(), predicted_rewards_mean=(), predicted_rewards_optimistic=(), predicted_rewards_sampled=(), bandit_policy_type=(), chosen_arm_features=TensorSpec(shape=(50,), dtype=tf.float32, name=None)), next_step_type=TensorSpec(shape=(), dtype=tf.int32, name='step_type'), reward=TensorSpec(shape=(), dtype=tf.float32, name='reward'), discount=BoundedTensorSpec(shape=(), dtype=tf.float32, name='discount', minimum=array(0., dtype=float32), maximum=array(1., dtype=float32)))

اگر نگاه دقیق تری به قسمت observation مشخصات داشته باشیم ، می بینیم که این ویژگی شامل ویژگی های هر بازو نیست!

print('observation spec in training: ', agent.training_data_spec.observation)
observation spec in training:  {'global': TensorSpec(shape=(40,), dtype=tf.float32, name=None)}

چه اتفاقی برای ویژگی های هر بازو افتاد؟ برای پاسخ به این س firstال ، ابتدا توجه داشته باشیم که وقتی عامل LinUCB تمرین می کند ، به ویژگی های بازو برای همه بازوها نیاز ندارد ، بلکه فقط به بازوی انتخابی نیاز دارد. از این رو ، منطقی است که تنسور شکل [BATCH_SIZE, NUM_ACTIONS, PER_ARM_DIM] ، زیرا بسیار هدر دهنده است ، مخصوصاً اگر تعداد اقدامات زیاد باشد.

اما هنوز ، ویژگی های هر بازو بازوی انتخاب شده باید در جایی باشد! برای این منظور ، اطمینان حاصل می کنیم که خط مشی LinUCB ویژگی های بازوی انتخاب شده را در قسمت policy_info داده های آموزش ذخیره می کند:

print('chosen arm features: ', agent.training_data_spec.policy_info.chosen_arm_features)
chosen arm features:  TensorSpec(shape=(50,), dtype=tf.float32, name=None)

از شکل می بینیم که فیلد chosen_arm_features فقط بردار ویژگی یک بازو را دارد و این بازوی انتخابی خواهد بود. توجه داشته باشید که policy_info و به همراه آن ویژگی chosen_arm_features ، بخشی از داده های آموزش است ، همانطور که از بازرسی مشخصات داده های آموزش مشاهده کردیم ، بنابراین در زمان آموزش در دسترس است.

تعریف متاسف پشیمانی

قبل از شروع حلقه آموزش ، برخی از توابع ابزار را تعریف می کنیم که به محاسبه حسرت نماینده ما کمک می کند. این توابع با توجه به مجموعه اقدامات (داده شده توسط ویژگیهای بازوی آنها) و پارامتر خطی که از عامل پنهان است ، به تعیین پاداش مطلوب مورد انتظار کمک می کنند.

def _all_rewards(observation, hidden_param):
  """Outputs rewards for all actions, given an observation."""
  hidden_param = tf.cast(hidden_param, dtype=tf.float32)
  global_obs = observation['global']
  per_arm_obs = observation['per_arm']
  num_actions = tf.shape(per_arm_obs)[1]
  tiled_global = tf.tile(
      tf.expand_dims(global_obs, axis=1), [1, num_actions, 1])
  concatenated = tf.concat([tiled_global, per_arm_obs], axis=-1)
  rewards = tf.linalg.matvec(concatenated, hidden_param)
  return rewards

def optimal_reward(observation):
  """Outputs the maximum expected reward for every element in the batch."""
  return tf.reduce_max(_all_rewards(observation, reward_param), axis=1)

regret_metric = tf_bandit_metrics.RegretMetric(optimal_reward)

اکنون ما برای شروع حلقه آموزش راهزن آماده هستیم. راننده زیر مراقبت از انتخاب اقدامات با استفاده از خط مشی ، ذخیره پاداش اقدامات انتخاب شده در بافر پخش ، محاسبه معیار پشیمانی از پیش تعیین شده و اجرای مرحله آموزش عامل است.

num_iterations = 20 # @param
steps_per_loop = 1 # @param

replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
    data_spec=agent.policy.trajectory_spec,
    batch_size=BATCH_SIZE,
    max_length=steps_per_loop)

observers = [replay_buffer.add_batch, regret_metric]

driver = dynamic_step_driver.DynamicStepDriver(
    env=per_arm_tf_env,
    policy=agent.collect_policy,
    num_steps=steps_per_loop * BATCH_SIZE,
    observers=observers)

regret_values = []

for _ in range(num_iterations):
  driver.run()
  loss_info = agent.train(replay_buffer.gather_all())
  replay_buffer.clear()
  regret_values.append(regret_metric.result())
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tf_agents/drivers/dynamic_step_driver.py:203: calling while_loop_v2 (from tensorflow.python.ops.control_flow_ops) with back_prop=False is deprecated and will be removed in a future version.
Instructions for updating:
back_prop=False is deprecated. Consider using tf.stop_gradient instead.
Instead of:
results = tf.while_loop(c, b, vars, back_prop=False)
Use:
results = tf.nest.map_structure(tf.stop_gradient, tf.while_loop(c, b, vars))
WARNING:tensorflow:From <ipython-input-1-3fff329da73f>:21: ReplayBuffer.gather_all (from tf_agents.replay_buffers.replay_buffer) is deprecated and will be removed in a future version.
Instructions for updating:
Use `as_dataset(..., single_deterministic_pass=True)` instead.

حالا بیایید نتیجه را ببینیم. اگر همه کارها را درست انجام دهیم ، نماینده می تواند عملکرد پاداش خطی را به خوبی تخمین بزند ، بنابراین سیاست می تواند اقداماتی را انتخاب کند که پاداش مورد انتظار آنها نزدیک به حد بهینه باشد. این با معیار پشیمانی تعریف شده در بالا نشان داده می شود ، که پایین می آید و به صفر می رسد.

plt.plot(regret_values)
plt.title('Regret of LinUCB on the Linear per-arm environment')
plt.xlabel('Number of Iterations')
_ = plt.ylabel('Average Regret')

png

بعدی چیست

مثال فوق در پایگاه کد ما پیاده سازی شده است که در آن شما می توانید عوامل دیگر را نیز انتخاب کنید ، از جمله عامل عصبی اپسیلون-حریص .