Набор данных TensorFlow 2.0.__iter__() поддерживается только при включенном активном выполнении

#python #tensorflow #tensorflow-datasets #tensorflow2.0

#python #tensorflow #tensorflow-datasets #tensorflow2.0

Вопрос:

Я использую следующий пользовательский обучающий код в TensorFlow 2:

 def parse_function(filename, filename2):
    image = read_image(fn)
    def ret1(): return image, read_image(fn2), 0
    def ret2(): return image, preprocess(image), 1
    return tf.case({tf.less(tf.random.uniform([1])[0], tf.constant(0.5)): ret2}, default=ret1)

dataset = tf.data.Dataset.from_tensor_slices((train,shuffled_train))
dataset = dataset.shuffle(len(train))
dataset = dataset.map(parse_function, num_parallel_calls=4)
dataset = dataset.batch(1)
dataset = dataset.prefetch(buffer_size=4)

@tf.function
def train(model, dataset, optimizer):
    for x1, x2, y in enumerate(dataset):
        with tf.GradientTape() as tape:
            left, right = model([x1, x2])
            loss = contrastive_loss(left, right, tf.cast(y, tf.float32))
        gradients = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))

siamese_net.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-3))
train(siamese_net, dataset, tf.keras.optimizers.RMSprop(learning_rate=1e-3))
  

Этот код выдает ошибку:

 dataset.__iter__() is only supported when eager execution is enabled.
  

Однако это в TensorFlow 2.0, поэтому по умолчанию включен eager.
tf.executing_eagerly() также возвращает ‘True’.

Комментарии:

1. Я думаю, что вы используете неправильный порядок в этой строке for x1, x2, y in enumerate(dataset): , итератор перечисления идет первым, поэтому в вашем случае это должно быть y, x1, x2, left, right = model([x1, x2])

2. Я не уверен, что понимаю ваше изменение. x1, x2 и y — это два изображения и метка, возвращаемые набором данных. Я использовал это в качестве ссылки: tensorflow.org/alpha/guide/keras/… Я также добавил parse_function

3. вставьте print(x1) сразу после for x1, x2, y in enumerate(dataset): того, как вы получите 0 вместо фактического значения из dataset. В этом случае x1 не является значением, это счетчик перечисления

4. Хорошо, здесь две проблемы. Вы правильно указали перечисление. Это должно быть: для шага, (x1, x2, y) в enumerate (dataset) . Во-вторых, по какой-то причине я должен удалить строку @tf.function . Я не уверен, почему этого не может быть здесь, поскольку он часто используется в примерах документации, которые я нашел, но в этом случае он прерывает итерацию набора данных. Он вообще не работает с этой строкой и просто выдает эту ошибку.

Ответ №1:

Я исправил это, включив быстрое выполнение после импорта tensorflow:

 import tensorflow as tf

tf.enable_eager_execution()
  

Ссылка: Tensorflow

Комментарии:

1. Обратите внимание, что вы должны включить его в начале программы

2. Как я упоминал в сообщении, этот код уже выполнялся с нетерпением, поскольку он был TF2, и tf.executing_eagerly() вернул True . Опубликованная вами ссылка на документацию подтверждает это. Возможно, это помогло бы с другой версией tensorflow. Мое исправление, приведенное ниже, в конечном итоге сработало для меня.

3. @emrepun но что, если я хочу выполнить итерацию по набору данных не в режиме ожидания?

4. Я полагаю, что ошибка указывает на то, что такая вещь невозможна без режима ожидания. Это означает, что мы не можем выполнить итерацию, __iter__() но, возможно, есть другое решение, когда активированный режим отключен. К сожалению, я не знаю, как это сделать. @404pio

Ответ №2:

В случае, если вы используете Jupyter notebook после

 import tensorflow as tf

tf.enable_eager_execution()
  

Вам нужно перезапустить ядро, и оно заработает

Ответ №3:

Я исправил это, изменив функцию train на следующую:

 def train(model, dataset, optimizer):
    for step, (x1, x2, y) in enumerate(dataset):
        with tf.GradientTape() as tape:
            left, right = model([x1, x2])
            loss = contrastive_loss(left, right, tf.cast(y, tf.float32))
        gradients = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  

Два изменения — удаление @tf.function и исправление перечисления.

Комментарии:

1. Возможно, @tf.function будет работать без перечисления набора данных