Ниже приведен минимальный тестовый пример, в котором я создаю переменную v, которую я хочу инициализировать значением 777 (для упрощенного тестового примера).

Примечание. Я не могу инициализировать v обычным инициализатором, поскольку он зависит от константы нормализации, вычисленной для всех переменных (некоторые из которых еще не созданы в момент создания v).

Мое решение (ниже) состоит в том, чтобы создать логическую переменную full_init_cond, для которой я установил значение True, как только я однажды запустил несколько инициализационных / назначенных OP, и использую tf.cond, чтобы они выполнялись только один раз.

import tensorflow as tf

v = tf.Variable(0, trainable=False)
full_init_cond = tf.Variable(False, trainable=False, dtype=tf.bool)

with tf.control_dependencies([v]):
  tf.cond(
    full_init_cond,
    true_fn=lambda: [tf.no_op],
    false_fn=lambda: [tf.assign(v, 777), tf.assign(full_init_cond, True)]
  )

Я получаю следующую ошибку в строке tf.cond:

TypeError: Failed to convert object of type <class 'function'> to Tensor. Contents: <function no_op at 0x7f39abf51400>. Consider casting elements to a supported type.

Я не очень понимаю эту ошибку.


Обновить:

К моему удивлению, этот простой тест, похоже, дает правильный тензор:

tf.cond(full_init_cond, tf.no_op, tf.no_op)

Мысль эта не удалась:

tf.cond(full_init_cond, lambda: tf.no_op, lambda: tf.no_op)

Моя путаница продолжается ... Кстати, версия Tensorflow 1.5.

1
David Parks 14 Мар 2018 в 05:09

2 ответа

Лучший ответ

lambda: tf.no_op не работает, потому что вы передаете функцию, которая возвращает функцию.

tf.group необходим, чтобы структуры соответствовали списку и возвращению no_op.

Ниже приведен фрагмент кода в 1.11

import tensorflow as tf

v = tf.Variable(0, trainable=False)
full_init_cond = tf.Variable(False, trainable=False, dtype=tf.bool)

with tf.control_dependencies([v]):
  tf.cond(
    full_init_cond,
    true_fn=tf.no_op,
    false_fn=lambda: tf.group([tf.assign(v, 777), tf.assign(full_init_cond, True)])
  )
1
Anton 4 Дек 2018 в 09:18

Оказывается, ему не понравилось выражение tf.no_op.

tf.cond требует, чтобы вы возвращали одинаковое количество и тип операций для условий true | false. Поэтому вместо tf.no_op я заменил его операцией tf.identity в качестве подходящей замены для no_op:

import tensorflow as tf

v = tf.Variable(0, trainable=False)
full_init_cond = tf.Variable(False, trainable=False, dtype=tf.bool)

with tf.control_dependencies([v]):
  x = tf.cond(
    full_init_cond,
    true_fn=lambda: [tf.identity(v), tf.identity(full_init_cond)],
    false_fn=lambda: [tf.assign(v, 777), tf.assign(full_init_cond, True)]
  )

print(x)
0
David Parks 14 Мар 2018 в 16:47