@popcorn0000

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

OpenAi倒立振子におけるエラー

解決したいこと

以下の本を用いて勉強しています。
https://www.ohmsha.co.jp/book/9784274226731/
提供されている倒立振子のDQNプログラムを実行した際にエラーが発生しました。解決方法が分かる方教えてもらいたいです。よろしくお願いします。
初心者なのでお手柔らかにお願いします。

発生している問題・エラー

TypeError: this __dict__ descriptor does not support '_DictWrapper' objects

該当するソースコード

'''
倒立振子のDQNプログラム
Copyright(c) 2020 Koji Makino and Hiromitsu Nishizaki All Rights Reserved.
'''
import tensorflow as tf
from tensorflow import keras

from tf_agents.environments import gym_wrapper, py_environment, tf_py_environment
from tf_agents.agents.dqn import dqn_agent
from tf_agents.networks import network
from tf_agents.replay_buffers import tf_uniform_replay_buffer
from tf_agents.policies import policy_saver
from tf_agents.trajectories import time_step as ts
from tf_agents.trajectories import trajectory
from tf_agents.specs import array_spec
from tf_agents.utils import common
from tf_agents.drivers import dynamic_step_driver, dynamic_episode_driver

import numpy as np
import random
import gym
#ネットワーククラスの設定
class MyQNetwork(network.Network):
  def __init__(self, observation_spec, action_spec, n_hidden_channels=50, name='QNetwork'):
    super(MyQNetwork, self).__init__(
      input_tensor_spec=observation_spec, 
      state_spec=(), 
      name=name
    )
    n_action = action_spec.maximum - action_spec.minimum + 1
    self.model = keras.Sequential(
      [
        keras.layers.Dense(n_hidden_channels, activation='tanh'),
        keras.layers.Dense(n_hidden_channels, activation='tanh'),
        keras.layers.Dense(n_action),
      ]
    )
  def call(self, observation, step_type=None, network_state=(), training=True):
    actions = self.model(observation, training=training)
    return actions, network_state

def main():
#環境の設定
  env_py = gym.make('CartPole-v0')
  env = tf_py_environment.TFPyEnvironment(gym_wrapper.GymWrapper(env_py))
#ネットワークの設定
  primary_network = MyQNetwork(env.observation_spec(),  env.action_spec())
#エージェントの設定
  n_step_update = 1
  agent = dqn_agent.DqnAgent(
    env.time_step_spec(),
    env.action_spec(),
    q_network=primary_network,
    optimizer=keras.optimizers.Adam(learning_rate=1e-3, epsilon=1e-2),
    n_step_update=n_step_update,
    epsilon_greedy=1.0,
    target_update_tau=1.0,
    target_update_period=100,
    gamma=0.99,
    td_errors_loss_fn = common.element_wise_squared_loss,
    train_step_counter = tf.Variable(0)
  )
  agent.initialize()
  agent.train = common.function(agent.train)
#行動の設定
  policy = agent.collect_policy
#データの保存の設定
  replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
    data_spec=agent.collect_data_spec,
    batch_size=env.batch_size,
    max_length=10**6
  )
  dataset = replay_buffer.as_dataset(
    num_parallel_calls=tf.data.experimental.AUTOTUNE,
    sample_batch_size=128,
    num_steps=n_step_update+1
  ).prefetch(tf.data.experimental.AUTOTUNE)
  iterator = iter(dataset)
#事前データの設定
  env.reset()
  driver = dynamic_episode_driver.DynamicEpisodeDriver(
    env, 
    policy, 
    observers=[replay_buffer.add_batch], 
    num_episodes = 100,
  )
  driver.run(maximum_iterations=10000)
  
  num_episodes = 200
  tf_policy_saver = policy_saver.PolicySaver(policy=agent.policy)#ポリシーの保存設定

  for episode in range(num_episodes+1):
    episode_rewards = 0#報酬の計算用
    episode_average_loss = []#lossの計算用
    policy._epsilon = 0.5 * (1 / (episode + 1))#ランダム行動の確率
    time_step = env.reset()#環境の初期化
  
    while True:
      if episode%10 == 0:#10回に1回だけ描画(高速に行うため)
        env_py.render('human')

      policy_step = policy.action(time_step)#状態から行動の決定
      next_time_step = env.step(policy_step.action)#行動による状態の遷移

      traj =  trajectory.from_transition(time_step, policy_step, next_time_step)#データの生成
      replay_buffer.add_batch(traj)#データの保存

      experience, _ = next(iterator)#学習用データの呼び出し
      loss_info = agent.train(experience=experience)#学習

      R = next_time_step.reward.numpy().astype('int').tolist()[0]#報酬
      episode_average_loss.append(loss_info.loss.numpy())#lossの計算
      episode_rewards += R#報酬の合計値の計算

      time_step = next_time_step#次の状態を今の状態に設定

      if next_time_step.is_last():#終了?(棒が倒れた場合)
        break
      if episode_rewards == 200:#報酬が200?(棒が一定時間立っていた場合)
        break

    print(f'Episode:{episode:4.0f}, R:{episode_rewards:3.0f}, AL:{np.mean(episode_average_loss):.4f}, PE:{policy._epsilon:.6f}')

  tf_policy_saver.save(export_dir='policy')#ポリシーの保存
  env.close()

if __name__ == '__main__':
  main()

自分で試したこと

エラーをコピペして検索しましたがよくわかりませんでした。

0 likes

1Answer

こちら同じエラーを再現することを確認しました.

質問に記載のコードが自身で書かれたものでないのであれば特にある話なのですが,バージョン違いによってエラーが出るようになることもあります.

Copyrightを見る感じ2020なので,機械学習とそのライブラリの世界からしたら昔過ぎる話なので,最新バージョンで動くものを探すか,ライブラリの変更点を洗い出して動くように書き換えるほかありません.

適当にググるだけでもTensorFlow 1系にダウングレードしたら治る.というような記載を複数見かけました.

エラーをコピペして検索しましたがよくわかりませんでした。

はあまりいただけないコメントということになりますね.

ひとまずプログラムを動かすには,エラーを生じさせているPolicySaver関連の2行をコメントアウトすることを推奨します.

0Like

Comments

  1. @popcorn0000

    Questioner

    回答ありがとうございます。
    ダウングレードなど試してみます。

Your answer might help someone💌