1. ホーム
  2. python

[解決済み] 'tensorflow.python.framework.ops.EagerTensor'オブジェクトには属性 '_in_graph_mode' がありません。

2022-02-28 12:22:35

質問

CNNフィルターを視覚化するために、ランダムな「画像」を最適化し、そのフィルターに高い平均活性化を生じさせようとしているが、これはニューロスタイル転送アルゴリズムと何らかの類似性がある。

そのために、TensorFlow==2.2.0-rc を使っています。しかし、最適化の過程で、以下のようなエラーが発生します。 'tensorflow.python.framework.ops.EagerTensor' object has no attribute '_in_graph_mode' . デバッグしてみると、どうやら opt.apply_gradients() のように手動でグラデーションを適用します。 img = img - lr * grads しかし、私は単純なSGDではなく、"Adam"オプティマイザを使いたいのです。

以下は、最適化部分のコードです。

opt = tf.optimizers.Adam(learning_rate=lr, decay = 1e-6)
for _ in range(epoch):
    with tf.GradientTape() as tape:
        tape.watch(img)
        y = model(img)[:, :, :, filter]
        loss = -tf.math.reduce_mean(y)
        grads = tape.gradient(loss, img)
        opt.apply_gradients(zip([grads], [img]))

解決方法は?

バグの原因は、tf.kerasのオプティマイザが変数オブジェクト(tf.Variable型)に勾配を適用し、あなたがテンソル(tf.Tensor型)に勾配を適用しようとすることにあります。TensorオブジェクトはTensorFlowではmutableではないので、オプティマイザはこれに勾配を適用することができない。

を初期化する必要があります。 img をtf.Variableとして使用します。これがあなたのコードのあり方です。

# NOTE: The original image is lost here. If this is not desired, then you can
# rename the variable to something like img_var.
img = tf.Variable(img)
opt = tf.optimizers.Adam(learning_rate=lr, decay = 1e-6)

for _ in range(epoch):
    with tf.GradientTape() as tape:
        tape.watch(img)
        y = model(img.value())[:, :, :, filter]
        loss = -tf.math.reduce_mean(y)

    grads = tape.gradient(loss, img)
    opt.apply_gradients(zip([grads], [img]))

また、グラデーションの計算はテープのコンテキストの外側で行うことを推奨します。これは、中に入れておくと、テープがグラデーションの計算自体をトラッキングしてしまい、メモリ使用量が多くなってしまうからです。これは、高次のグラジェントを計算したい場合にのみ望ましい。それらは必要ないので、外に置いてある。

なお、私は以下の行を変更しました。 y = model(img)[:, :, :, filter] から y = model(img.value())[:, :, :, filter] . これは、tf.kerasのモデルは変数ではなく、テンソルを入力として必要とするためです(バグ、あるいは特徴?)