Tensorflow tf.набор данных.перемешивание очень медленное

#python #tensorflow #machine-learning #tensorflow-datasets

Вопрос:

Я тренирую модель VAE с 9100 изображениями (каждое размером 256 x 64). Я тренирую модель с помощью Nvidia RTX 3080. Сначала я загружаю все изображения в массив numpy размером 9100 x 256 x 64 под названием traindata . Затем, чтобы сформировать набор данных для обучения, я использую

 train_dataset = (tf.data.Dataset.from_tensor_slices(traindata).shuffle(len(traindata)).batch(batch_size))
 

Здесь я использую batch_size цифру 65. В основном у меня есть 2 вопроса о том, что я вижу во время тренировок:

Вопрос 1:

Согласно документам, весь набор данных перетасовывается заново для каждой эпохи. Однако таким образом обучение проходит очень медленно (около 50 секунд за эпоху). Я провел сравнение с обучением без перетасовки, не вызывая .shuffle(len(traindata)) при создании набора данных, и обучение происходит намного быстрее (около 20 с/эпоха). Мне интересно, почему .shuffle() операция выполняется так медленно и есть ли какие-либо методы, чтобы сделать ее быстрее? Согласно этой теме StatsSE, перетасовка очень важна для обучения, и именно поэтому я включаю операцию перетасовки.

Вопрос 2:

Когда я звонил .shuffle() при создании набора данных, Tensorflow всегда выдает следующее сообщение

 I tensorflow/core/platform/windows/subprocess.cc:308] SubProcess ended with return code: 4294967295
 

Я пытаюсь искать в Интернете, но все еще не могу понять, что за этим кроется. Означает ли это, что произошла какая-то ошибка или это просто предупреждение, которое я могу игнорировать?

Ответ №1:

Это связано с тем, что хранение всех элементов вашего набора данных в буфере обходится дорого. Если вам абсолютно не нужна идеальная случайность, вам следует использовать меньшую buffer_size . Все элементы в конечном итоге будут взяты, но более детерминированным образом.

Вот что произойдет с меньшим buffer_size , скажем, 3. Буфер-это скобки, и Tensorflow выбирает случайное значение в этой скобке. Тот, который был выбран случайным образом, это ^

 1) [1 2 3]4 5 6 7 8 9 
      ^
2) [1 3 4]5 6 7 8
        ^
3) [1 3 5]6 7 8
        ^
4) [1 3 6]7 8
    ^
5) [3 6 7]8
 

И т.д.

Таким образом, более ранние значения будут взяты в начале вашей эпохи, но вам все равно придется немного перетасовать, и все образцы в конечном итоге будут взяты.

tl;dr buffer_size значительно сокращается