Применить dataset.repeat предварительно извлеченного набора данных

Я пытаюсь реализовать алгоритм квантования АдаРаунд, и мне нужно тренировать свои слои один за другим.

Я использую набор данных с 1024 с размером пакета 32, и мне нужно выполнить итерацию по набору данных примерно 312 эпох (или 10 000 итераций по пакетному набору данных), я заметил, что данные копируются с хоста на устройство каждую итерацию и что данные не кэшируются на графическом процессоре (несмотря на повторное использование одних и тех же данных) - графический процессор простаивает 30–40% процентов времени

Процент бездействия графического процессора

Данные по-прежнему копируются с хоста на устройство в расширенных итерациях:

Чанк memcpyH2D за одну итерацию

я пытался использовать

tf.data.experimental.prefetch_to_device

tf.data.experimental.copy_to_device

но когда я перебираю данные после prefetch_to_device или copy_to_device, тензоры сохраняются на графическом процессоре, но если я использую повтор для просмотра набора данных, тензоры сохраняются на ЦП

Я пытался использовать model.fit без dataset.repeat, но с несколькими эпохами, но получаю похожее поведение.

Я также пытался использовать model.fit с тензорами, которые хранятся на графическом процессоре, но подгонка модели преобразует его в набор данных, который возвращает данные обратно в процессор.

Фрагмент кода для воссоздания проблемы:

input_shape = (56, 56, 64)
output_shape = (54, 54, 64)
conv = tf.keras.layers.Conv2D(64, (3, 3))
mock_input = tf.keras.layers.Input(input_shape)
mock_output = conv(mock_input)
train_model = tf.keras.Model(inputs=mock_input, outputs=mock_output)

input_data = np.random.rand(1024, *input_shape)
output_data = np.random.rand(1024, *output_shape)

input_dataet = tf.data.Dataset.from_tensor_slices(input_data)
output_dataset = tf.data.Dataset.from_tensor_slices(output_data)

train_model.compile(
    optimizer='adam',
    loss='mse'
)
train_data = tf.data.Dataset.zip((input_dataet, output_dataset))
batched_train_data = train_data.batch(32).cache()
fetched_train_data = batched_train_data.prefetch(tf.data.AUTOTUNE).repeat()
with tf.profiler.experimental.Profile('logs'):
    train_model.fit(fetched_train_data, steps_per_epoch=1024, epochs=1)

Есть ли способ применить операцию dataset.repeat к графическому процессору?

  • Я использую тензорный поток 2.5.2 с питоном 3.6.9.
Udacity Nanodegree Capstone Project: Классификатор пород собак
Udacity Nanodegree Capstone Project: Классификатор пород собак
Вы можете ознакомиться со скриптами проекта и данными на github .
1
0
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Подробный ответ

У nvidia есть пакет с именем Nvidia ДАЛИ, этот пакет предлагает эффективную оболочку для набора данных tensorflow (и многое другое, но это важная функция, которую я использовал здесь), мне пришлось установить 2 пакета — nvidia-dali-cuda110, nvidia-dali-tf- plugin-cuda110 (подробное руководство по установке можно найти здесь)

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

одна итерация при использовании правильно инициализированного DALIDataset

Фрагмент кода:

from nvidia.dali.plugin.tf import DALIDataset
from nvidia.dali import pipeline_def, fn

def prep_dataset_dali(dir1, dir2, batch_size):
    @pipeline_def(batch_size=batch_size, num_threads=3, device_id=0)
    def pipe(path1, path2):
        data1 = fn.readers.numpy(device='cpu', file_root=path1, file_filter='*.npy')
        data2 = fn.readers.numpy(device='cpu', file_root=path2, file_filter='*.npy')
        return data1.gpu(), data2.gpu()
    my_pipe = pipe(dir1, dir2)
    my_pipe.build()
    return DALIDataset(my_pipe, output_dtypes=(tf.float32, tf.float32), output_shapes=((None, 56, 56, 64), (None, 56, 56, 64)))

Примечание:

внешний конвейер не работает с DALIDataset, но может работать с Класс DALIDatasetWithInputs из экспериментального раздела

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