<Pythonで学ぶ強化学習> DQNサンプルコードでつまづいて、なんとなく解決したメモ
*追記 結局、Tensorflow 2.0への活用は諦めて、Tensorflow 1.15へバージョンを戻すことでサンプルコードが走ったことを確認しました。まだ僕の実力ではこのバージョンアップの改変は早すぎたようです。もう少し精進しますー :)
本屋で衝動買いしたこの本ですが、強化学習について分かりやすくかかれた良本であり、かつサンプルコードなどもGIT HUBにまとめられており、再現も簡単にできて素敵!・・・と思っていたのですが、進めていくうちにバージョン互換性と思われるエラーがでてきました。それを本当に正しいかどうかはわからないのですが、何となく解決した時のメモとなります。問題は次の2つ。それぞれを順番に見ていきます。
- ValueError: Tried to convert 'y' to a tensor and failed. Error: None values not supported.
- AttributeError: 'ResourceSummaryWriter' object has no attribute 'add_summary'
著者様のGIT HUB GitHub - icoxfog417/baby-steps-of-rl-ja: Pythonで学ぶ強化学習 -入門から実践まで- サンプルコード
ValueError: Tried to convert 'y' to a tensor and failed. Error: None values not supported.
サンプルコードをとりあえず実行してみたけど次のエラーメッセージが。
Traceback (most recent call last): File "dqn_agent.py", line 214, in <module> main(args.play, args.test) File "dqn_agent.py", line 203, in main trainer.train(obs, test_mode=is_test) File "dqn_agent.py", line 143, in train observe_interval) File "C:\Users\ore\Documents\python\github\dqn\baby-steps-of-rl-ja\FN\fn_framework.py", line 127, in train_loop self.step(i, step_count, agent, e) File "dqn_agent.py", line 159, in step self.loss += agent.update(batch, self.gamma) File "dqn_agent.py", line 66, in update loss = self.model.train_on_batch(states, estimateds) File "C:\Users\ore\AppData\Local\Continuum\anaconda3\envs\rl-book\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 1017, in train_on_batch self._make_train_function() File "C:\Users\ore\AppData\Local\Continuum\anaconda3\envs\rl-book\lib\site-packages\tensorflow_core\python\keras\engine\training.py", line 2116, in _make_train_function params=self._collected_trainable_weights, loss=self.total_loss) File "C:\Users\ore\AppData\Local\Continuum\anaconda3\envs\rl-book\lib\site-packages\tensorflow_core\python\keras\optimizers.py", line 476, in get_updates grads = self.get_gradients(loss, params) File "C:\Users\ore\AppData\Local\Continuum\anaconda3\envs\rl-book\lib\site-packages\tensorflow_core\python\keras\optimizers.py", line 92, in get_gradients if None in grads: File "C:\Users\ore\AppData\Local\Continuum\anaconda3\envs\rl-book\lib\site-packages\tensorflow_core\python\ops\math_ops.py", line 1336, in tensor_equals return gen_math_ops.equal(self, other) File "C:\Users\ore\AppData\Local\Continuum\anaconda3\envs\rl-book\lib\site-packages\tensorflow_core\python\ops\gen_math_ops.py", line 3626, in equal name=name) File "C:\Users\ore\AppData\Local\Continuum\anaconda3\envs\rl-book\lib\site-packages\tensorflow_core\python\framework\op_def_library.py", line 545, in _apply_op_helper (input_name, err)) ValueError: Tried to convert 'y' to a tensor and failed. Error: None values not supported.
解決方法は git に記載していました。
tensorflow.python.kerasをtensorflow.kerasに変更 · Issue #37 · icoxfog417/baby-steps-of-rl-ja · GitHub
Tensorflow のバージョンが2.0にあがったことにより、Karasのライブラリを変更する必要があるようです。よかった、これで解決。。。と思ったのですが。
AttributeError: 'ResourceSummaryWriter' object has no attribute 'add_summary'
上の変更をおこなった後、次のエラーが出てしまいました。
Traceback (most recent call last): File "dqn_agent.py", line 214, in <module> main(args.play, args.test) File "dqn_agent.py", line 203, in main trainer.train(obs, test_mode=is_test) File "dqn_agent.py", line 143, in train observe_interval) File "C:\Users\ore\Documents\project\dqn\FN\fn_framework.py", line 132, in train_loop self.episode_end(i, step_count, agent) File "dqn_agent.py", line 166, in episode_end self.logger.write(self.training_count, "loss", self.loss) File "C:\Users\ore\Documents\project\dqn\FN\fn_framework.py", line 254, in write self.writer.add_summary(summary, index) AttributeError: 'ResourceSummaryWriter' object has no attribute 'add_summary'
ここの解決には時間がかかりました。結局原因をしっかりとつかむことはできなかったのですが、予想としては最初の問題と同じようにTensorBoardのバージョン 2.0 の互換性が関係しているのかと思ってます。Tensorboardは実行したデータを表示するための機能ではあるので、機械学習の本質的には影響しないのですが、ビジュアルを使った評価がなくてはより正確な機械学習の最適化はできなさそうなので、必須といっても過言ではないでしょう。
とりあえず、fn_framework.py を以下のように変更することで動くことは確認しました。ただ、この結果が目的に合っているかの検証はできていません。ぶっちゃけ、これ書いている今もスクリプトぶん回している最中です。
- fn_framework.py 255行あたり - writer関数内
with self.writer.as_default(): tf.summary.scalar(name, value, index) self.writer.flush()
- fn_framework.py 275行あたり - write_image関数内
def write_image(self, index, name, frames): # Deal with a 'frames' as a list of sequential gray scaled image. last_frames = [f[:, :, -1] for f in frames] height, width = last_frames[-1].shape if np.min(last_frames[-1]) < 0: scale = 127 / np.abs(last_frames[-1]).max() offset = 128 else: scale = 255 / np.max(last_frames[-1]) offset = 0 channel = 1 # gray scale tag = "frames_at_training_{}".format(index) values = [] images = [] with self.writer.as_default(): tf.summary.image(name, tf.reshape(last_frames, [len(last_frames), height, width, channel]), index) self.writer.flush()
はてさて、これでエラーを出さずに回すことができたのですが、この修正がどこまで正しいのかは検証できていません。