Почему PyTorch в 2 раза медленнее, чем Keras для идентичной модели и гиперпараметров? - PullRequest
6 голосов
/ 02 февраля 2020

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

Я перенес точную архитектуру в Keras и TF2 с нетерпеливым режимом так:

model = keras.models.Sequential([ keras.layers.Conv2D(32, (3, 3) , input_shape=(28,28,1), activation='relu'),
                                 keras.layers.Conv2D(64, (3, 3)),
                                 keras.layers.MaxPool2D((2, 2)),
                                 keras.layers.Dropout(0.25),
                                 keras.layers.Flatten(),
                                 keras.layers.Dense(128, activation='relu'),
                                 keras.layers.Dropout(0.5),
                                 keras.layers.Dense(10, activation='softmax')]
                                )

model.summary()

model.compile(optimizer=keras.optimizers.Adadelta(), loss=keras.losses.sparse_categorical_crossentropy, metrics=['accuracy'])

model.fit(train_data,train_labels,batch_size=64,epochs=30,shuffle=True, max_queue_size=1)

Обучение l oop в PyTorch:

def train(args, model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()

Со мной время каждой эпохи примерно так:

for epoch in range(1, args.epochs + 1):
    since = time.time()
    train(args, model, device, train_loader, optimizer, epoch)
    # test(args, model, device, test_loader)
    # scheduler.step()
    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))

Я проверил, что:

  • Обе версии используют один и тот же оптимизатор (AdaDelta)
  • Обе версии имеют примерно столько же обучаемых параметров (1,2 миллиона)
  • Я удалил нормализацию в dataLoader, оставив только вызов toTensor ().
  • pin_memory установлен в True, а num_workers установлен в 1 для кода PyTorch.
  • По предложению Timbus Calin Я установил max_queue_size в 1 и результаты идентичны.

Версия Keras работает на около 4-5 секунд на эпоху, в то время как версия PyTorch работает примерно на 9-10 секунд на эпоху.

Почему это так и как я могу улучшить это время?

1 Ответ

4 голосов
/ 02 февраля 2020

Я думаю, что есть небольшая разница, которая должна быть принята во внимание; Моя лучшая ставка / предчувствие заключается в следующем: это не само время обработки для каждого графического процессора, а параметр max_queue_size=10, по умолчанию 10 в Керасе.

Поскольку по умолчанию в обычном для -l oop в PyTorch данные не ставятся в очередь; очередь, которую выигрывает Keras, позволяет быстрее передавать данные из CPU в GPU; по сути, гораздо меньше времени затрачивается на подачу графического процессора, поскольку он потребляет быстрее из этой внутренней очереди / сокращаются накладные расходы на передачу данных с процессора на графический процессор.

Помимо моего предыдущего наблюдения, я не вижу любая другая видимая разница, возможно, другие люди могут указать на новые открытия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...