#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 будет работать без перечисления набора данных