Объект tenensflow. python .framework.ops.EagerTensor не имеет атрибута _in_graph_mode. - PullRequest
1 голос
/ 12 апреля 2020

Я пытаюсь визуализировать фильтры CNN, оптимизируя случайное «изображение», чтобы оно вызывало активацию среднего значения для этого фильтра, что как-то похоже на алгоритм передачи нейронного стиля.

Для этой цели я Я использую TensorFlow == 2.2.0-r c. Но в процессе оптимизации возникает ошибка: 'tensorflow.python.framework.ops.EagerTensor' object has no attribute '_in_graph_mode'. Я попытался отладить его, и он как-то работает, когда я не использую opt.apply_gradients() и вместо этого применяю его градиент вручную, как img = img - lr * grads, но я хочу использовать оптимизатор "Адам", а не простой SGD.

Вот мой код для части оптимизации

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]))

1 Ответ

0 голосов
/ 25 апреля 2020

Причина ошибки заключается в том, что оптимизаторы tf.keras применяют градиенты к переменным объектам (типа tf.Variable), в то время как вы пытаетесь применить градиенты к тензорам (типа tf.Tensor). Тензорные объекты не являются изменяемыми в TensorFlow, поэтому оптимизатор не может применять к нему градиенты.

Вы должны инициализировать переменную 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 нужны тензоры в качестве входных данных, а не переменные (ошибка или особенность?).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...