Tf.data API не может распечатать все партии

Я самоучусь по tf.data API. Я использую набор данных MNIST для двоичной классификации. Данные для обучения x и y заархивированы вместе в полном наборе train_dataset. Вместе с этим методом zip сначала связан метод набора данных batch(). данные сгруппированы с размером пакета 30. Поскольку размер моего обучающего набора составляет 11623, с размером пакета 128 у меня будет 91 пакет. Размер последней партии будет 103, и это нормально, так как это LSTM. Дополнительно использую выпадение. Когда я вычисляю точность партии, я отключаю выпадение.

Полный код приведен ниже:

#Ignore the warnings
import warnings
warnings.filterwarnings("ignore")

import pandas as pd
import tensorflow as tf
import numpy as np

import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (8,7)

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/")

Xtrain = mnist.train.images[mnist.train.labels < 2]
ytrain = mnist.train.labels[mnist.train.labels < 2]

print(Xtrain.shape)
print(ytrain.shape)

#Data parameters
num_inputs = 28
num_classes = 2
num_steps=28

# create the training dataset
Xtrain = tf.data.Dataset.from_tensor_slices(Xtrain).map(lambda x: tf.reshape(x,(num_steps, num_inputs)))
# apply a one-hot transformation to each label for use in the neural network
ytrain = tf.data.Dataset.from_tensor_slices(ytrain).map(lambda z: tf.one_hot(z, num_classes))
# zip the x and y training data together and batch and Prefetch data for faster consumption
train_dataset = tf.data.Dataset.zip((Xtrain, ytrain)).batch(128).prefetch(128)

iterator = tf.data.Iterator.from_structure(train_dataset.output_types,train_dataset.output_shapes)
X, y = iterator.get_next()

training_init_op = iterator.make_initializer(train_dataset)


#### model is here ####

#Network parameters
num_epochs = 2
batch_size = 128
output_keep_var = 0.5

with tf.Session() as sess:
    init.run()

    print("Initialized")
    # Training cycle
    for epoch in range(0, num_epochs):
        num_batch = 0
        print ("Epoch: ", epoch)
        avg_cost = 0.
        avg_accuracy =0
        total_batch = int(11623 / batch_size + 1)
        sess.run(training_init_op)
       while True:
            try:
                _, miniBatchCost = sess.run([trainer, loss], feed_dict = {output_keep_prob: output_keep_var})
                miniBatchAccuracy = sess.run(accuracy, feed_dict = {output_keep_prob: 1.0})
               print('Batch %d: loss = %.2f, acc = %.2f' % (num_batch, miniBatchCost, miniBatchAccuracy * 100))
                num_batch +=1
            except tf.errors.OutOfRangeError:
                break

Когда я запускаю этот код, кажется, что он работает и печатает:

Batch 0: loss = 0.67276, acc = 0.94531
Batch 1: loss = 0.65672, acc = 0.92969
Batch 2: loss = 0.65927, acc = 0.89062
Batch 3: loss = 0.63996, acc = 0.99219
Batch 4: loss = 0.63693, acc = 0.99219
Batch 5: loss = 0.62714, acc = 0.9765
......
......
Batch 39: loss = 0.16812, acc = 0.98438
Batch 40: loss = 0.10677, acc = 0.96875
Batch 41: loss = 0.11704, acc = 0.99219
Batch 42: loss = 0.10592, acc = 0.98438
Batch 43: loss = 0.09682, acc = 0.97656
Batch 44: loss = 0.16449, acc = 1.00000

Однако, как легко увидеть, что-то не так. Напечатано всего 45 партий, а не 91, и я не знаю, почему это происходит. Я так много пробовал и думаю, что что-то упускаю.

Я могу использовать функцию repeat(), но я не хочу этого, потому что у меня есть избыточные наблюдения для последних пакетов, и я хочу, чтобы LSTM справился с этим.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
163
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это досадная ловушка при определении модели, основанной непосредственно на выходных данных get_next() итератора tf.data. В вашем цикле у вас есть два вызова sess.run, из которых оба продвинет итератор на один шаг. Это означает, что каждая итерация цикла фактически потребляет два пакета (а также ваши расчеты потерь и точности вычисляются для разных пакетов).

Не совсем уверен, есть ли "канонический" способ исправить это, но вы можете

  • вычислить точность в том же вызове run, что и на этапе стоимости / обучения. Это означало бы, что на расчет точности также влияет маска исключения, но поскольку это приблизительное значение, основанное только на одной партии, это не должно быть большой проблемой.
  • вместо этого определите свою модель на основе заполнителя и в каждой итерации цикла run самой операции get_next, а затем загрузите полученные массивы numpy (то есть пакет) в вычисления потерь / точности.

Да, вообще-то я пробовал оба подхода. Для второго подхода я особенно не хотел использовать заполнители, потому что следующим моим шагом будет использование API tf.data с SQL-запросом, и я хочу избежать использования feed_dict для потребления данных, потому что результат этого SQL-запроса большой. После того, как я задал этот вопрос, я понял, что не могу выполнить два вызова ses.run, поэтому я поставил точность в тот же вызов run, что и этап затрат / обучения, поскольку это первый подход, который вы упомянули, и он работает. Я думаю, что этот подход более осуществим, и я могу рассчитать точность каждой партии для модели с выпадением

ARAT 23.11.2018 21:42

Каковы другие подходы к использованию API tf.data для определения модели? он либо назначает вывод итератора tf.data каждому аргументу определения модели, либо использует feed_dict для использования вывода sess.run([X,y]) (или sess.run(next_batch)), как указано в здесь или здесь.

ARAT 23.11.2018 21:46

Я не думаю, что есть какой-либо другой «прямой» способ, поскольку в конце концов итераторы tf.data просто возвращают тензоры, а операция get_next будет продвигаться каждый раз, когда она вызывается ... Одним из вариантов может быть определение настраиваемого набора данных, который возвращает каждый элемент дважды (или k раза, что может быть указано в качестве параметра) перед продвижением. Это могло бы, например, быть достигнуто с помощью набора данных from_generator.

xdurch0 24.11.2018 11:31

Другие вопросы по теме