思考ノイズ

無い知恵を絞りだす。無理はしない。

<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 を以下のように変更することで動くことは確認しました。ただ、この結果が目的に合っているかの検証はできていません。ぶっちゃけ、これ書いている今もスクリプトぶん回している最中です。

  1. fn_framework.py 255行あたり - writer関数内
        with self.writer.as_default():
            tf.summary.scalar(name, value, index)
        self.writer.flush()
  1. 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()

はてさて、これでエラーを出さずに回すことができたのですが、この修正がどこまで正しいのかは検証できていません。