Тесты платформы глубокого обучения (TensorFlow/Caffe/MXNet/Keras/PyTorch)

TensorFlow Keras API модульный тест
Тесты платформы глубокого обучения (TensorFlow/Caffe/MXNet/Keras/PyTorch)

深度学习框架哪家强:TensorFlow?Caffe?MXNet?Keras?PyTorch?

对于这几大框架在运行各项深度任务时的性能差异如何,各位读者不免会有所好奇。

微软数据科学家Ilia Karmanov最新测试的结果显示,亚马逊MXNet在CNN、RNN与NLP情感分析任务上性能强劲,而TensorFlow仅擅长于特征提取。
测试详情更新在Ilia Karmanov的GitHub项目DeepLearningFrameworks(https://github.com/ilkarman/DeepLearningFrameworks)内。

不过作者表示,项目内的测试代码并非专门为深度学习性能而编写,目的仅在于简单比较一下各框架之间的性能差异。
以下为该项目的详情,have fun!

Перевод | Лю Чанг

Редактор | Донна


Мы составили этот список для развлечения, поэтому многие важные части сравнения были опущены. Например: справка и поддержка, пользовательские слои (можно ли создать капсульную сеть?), загрузчики данных, отладка, поддержка разных платформ, распределенное обучение и т. д.

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

Например, создайте CNN в Python с помощью Caffe2, затем реплицируйте эту сеть в Julia с помощью KNet или попробуйте создать RNN в PyTorch и воспроизвести ее в Tensorflow. Вы можете выполнить извлечение некоторых признаков в Chainer, а затем воспроизвести эту операцию в CNTK.

Поскольку платформа на виртуальной машине глубокого обучения Microsoft Azure NC6 была обновлена ​​до последней версии, код ноутбуков был выбран для работы на ней, используя только половину производительности графического процессора Nvidia K80 GPU.

тестовая цель

Rosetta Stone, создающая фреймворки глубокого обучения, позволяет специалистам по данным легко переносить свой опыт с одного фреймворка на другой (путем перевода, а не обучения с нуля) . Кроме того, чтобы сделать сравнение более прозрачным с точки зрения времени обучения модели и параметров по умолчанию.

Во многих онлайн-учебниках используются очень низкоуровневые API-интерфейсы, которые, хотя и очень подробные, не имеют особого смысла для большинства случаев использования, поскольку в большинстве случаев доступны помощники более высокого уровня. Здесь мы просто игнорируем конфликтующие значения по умолчанию и пытаемся использовать API самого высокого уровня для упрощения сравнения между фреймворками.

Приведенные ниже результаты демонстрируют, что после использования высокоуровневого API структура кода становится очень похожей и может быть грубо выражена следующим образом:

  • загрузить данные; x_train, x_test, y_train, y_test = cifar_for_library(channel_first=?, one_hot=?)

  • Создание сетевой структуры CNN/RNN (обычно не активируется на последнем уровне)

  • Укажите функцию потерь (перекрестная энтропия указывается с помощью softmax), оптимизатор и инициализируйте веса сети + сеансы

  • Обучайте тренировочный набор в мини-пакетах и ​​используйте собственные итераторы (все фреймворки используют общую базу данных).

  • Делайте прогнозы на мини-партии тестового набора

  • Рассчитать точность

По сути, мы сравниваем ряд детерминированных математических операций (хотя и инициализированных случайным образом), поэтому сравнивать точность разных фреймворков бессмысленно. Вместо этого он предлагает нам проверить желаемое совпадение (?), чтобы убедиться, что мы сравниваем одну и ту же архитектуру модели.


Результаты испытаний (24 ноября 2017 г.)

Обучите сеть CNN (тип VGG) на наборе данных CIFAR-10.

Сравнение производительности — распознавание изображений

Входными данными для модели является стандартный набор данных CIFAR-10, который содержит пятьдесят тысяч обучающих изображений и десять тысяч тестовых изображений, равномерно распределенных по 10 классам. Каждое изображение размером 32x32 пикселя преобразуется в форму тензора (3, 32, 32) со значениями пикселей, нормализованными от 0-255 до 0-1. Например: соответствующий параметр y=(0,1,0,0,0,0,0,0,0,0) изображения автомобиля, его метка = [самолет, автомобиль, птица, кошка, олень, собака , лягушка, лошадь, лодка, грузовик]

Обучите RNN (GRU, Gated Recurrent Unit) на наборе данных IMDB

Сравнение производительности — обработка естественного языка (анализ тональности)

Входными данными для этой модели является стандартный набор данных обзоров фильмов IMDB, который содержит 25 000 обучающих обзоров и 25 000 тестовых обзоров, равномерно разделенных на 2 уровня (положительный/отрицательный). Загруженный комментарий уже является тензором словесных индексов, например (если вам нравятся комедийные комиксы для взрослых, такие как Южный парк), он будет представлен как (1 2 3 4 5 6 3 7 8).

Следуя подходу платформы Keras, где начальный символ устанавливается равным 1, а словарь вне словаря (с использованием словаря размером 30 000) представляется как 2, поэтому индекс слова начинается с 3. Сократите размер каждого комментария до 150 слов с помощью нулевого заполнения/усечения.

Там, где это возможно, я бы попытался оптимизировать RNN способом cudnn (управляемым переключателем CUDNN=True), поскольку у нас есть простая RNN, которую можно легко свести к уровню CuDNN. Например, для CNTK вместо функции Recurrence(LSTM()) мы используем оптимизированный_rnnstack. Хотя он менее гибкий, он намного быстрее.

Например, с CNTK мы больше не можем использовать более сложные переменные, такие как нормализация слоя. В PyTorch это включено по умолчанию. Но для MXNet я не могу найти такую ​​функцию RNN, но использую немного более медленную функцию Fused RNN.

Keras совсем недавно получил поддержку cudnn, но доступен только бэкэнд Tensorflow (а не бэкенд CNTK). У Tensorflow есть много вариантов RNN, включая их собственные ядра. Вот хороший бенчмарк, попробую обновить пример с помощью CudnnLSTM вместо текущего метода.

Примечание. Фреймворк CNTK поддерживает динамические оси, что означает, что нам не нужно дополнять ввод до 150 слов, мы можем печатать как есть, но, поскольку я не смог найти способ сделать это с другими фреймворками, я В любом случае, я собираюсь с отступами Методы. Это немного несправедливо по отношению к фреймворку CNTK, потому что он недооценивает его возможности.

Модель классификации создает матрицу встраивания размером (150x125), затем берет 100 вентильных рекуррентных единиц и принимает конечный результат (не выходную последовательность и не скрытое состояние) в качестве вывода.

Сравнение производительности логического вывода ResNet-50 (извлечение признаков)

Загрузите предварительно обученную модель ResNet50 и усеките ее в вектор (7,7) после окончания avg_pooling и выведите 2048-мерный вектор. Сюда можно вставить слой softmax или другой классификатор, например дерево возбуждения для трансферного обучения. Здесь подсчитывается время прямого прохода к уровню avg_pool как на ЦП, так и на ГП.


Что я узнал из этого?

О Си-Эн-Эн

Ниже приведены некоторые сведения о сравнении точности тестов в разных средах после просмотра проблем, поднятых на github.

1. Приведенные выше примеры (кроме Keras) для сравнения пытаются использовать один и тот же уровень API, поэтому все они используют одну и ту же функцию генератора. Для MXNet и CNTK я попробовал API более высокого уровня, где я использовал функцию генератора поездов фреймворка. В этом примере прирост скорости незначителен, потому что весь набор данных загружается в ОЗУ в виде массива NumPy, а данные рандомизируются для каждой итерации при обработке. Я подозреваю, что генератор фреймворка делает рандом асинхронно.

Как ни странно, рандомизация структуры, по-видимому, выполняется на уровне партии, а не на уровне наблюдения, что немного снижает точность тестирования (по крайней мере, после 10 итераций). Пользовательские генераторы окажут большее влияние на производительность операций ввода и вывода, которые мы будем выполнять, и, возможно, предварительной обработки и увеличения данных на лету.

2. Разрешить CuDNN автоматически настраивать/исчерпывающие параметры поиска (которые могут выбрать наиболее эффективный алгоритм CNN для фиксации размера изображения) может значительно улучшить производительность. Все четыре фреймворка, Chainer, Caffe2, PyTorch и Theano, должны запускать его вручную. Три фреймворка CNTK, MXNet и Tensorflow по умолчанию включают CuDNN.

Цзя Янцин упомянул улучшение производительности между cudnnGet (по умолчанию) и cudnnFind. Однако на графических процессорах TitanX разница намного меньше.

Теперь кажется,Новый cudnn, принятый на K80+, делает проблему различий в производительности еще более заметной. Поскольку запуск cudnnFind на комбинации изображений различных размеров для обнаружения целей приведет к значительному падению производительности, алгоритм полного поиска не следует использовать для задачи обнаружения целей..

3.При использовании Keras важно выбрать порядок [NCHW], который соответствует внутренней структуре.. CNTK - это каналы в первую очередь, я однажды неправильно настроил Keras, поскольку каналы в последнюю очередь. Это должно было бы изменить его порядок в каждой партии, что привело бы к серьезному падению производительности. В общем, [NHWC] используется по умолчанию для большинства фреймворков (например, Tensorflow), а [NCHW] — лучший порядок, который можно использовать при обучении с cuDNN на графических процессорах NVIDIA.

4. Tensorflow, PyTorch, Caffe2 и Theano — всем четырем платформам требуется логическое значение, предоставляемое слою исключения, чтобы указать, тренируемся мы или нет, поскольку это оказывает большое влияние на точность тестового набора, 72 против 77%. следовательно,В этом случае Dropout не следует использовать для тестирования..

5. При использовании платформы Tensorflow требуются два изменения: включение TF_ENABLE_WINOGRAD_NONFUSED, а также изменение размера, предоставляемого для канала первым, а не последним (data_format = 'channels_first'). Включение WINOGRAD для операций свертки естественным образом изменяет keras на TF в качестве серверной части.

6.Слой Softmax обычно используется с функцией cross_entropy_loss() для большинства функций, вам нужно проверить, хотите ли вы активировать последний полносвязный слой, чтобы сэкономить время на его двойное использование.

7. Инициализаторы ядра для разных фреймворков могут различаться и влиять на точность на ±1%. Я указываю xavier/glorot как можно единообразно без слишком многословной инициализации ядра.

8. Для реализации типа импульса в SGD-импульсе пришлось отключить unit_gain. Потому что он по умолчанию отключен в фреймворке CNTK, чтобы соответствовать реализации других фреймворков.

9,Caffe2 выполняет дополнительные оптимизации на первом слое сети (no_gradient_to_input = 1), что может дать небольшой прирост скорости, не вычисляя градиент ввода.. Возможно, в Tensorflow и MXNet это уже включено по умолчанию. Вычисление этого градиента полезно для исследований и сетей, таких как глубокий сон.

10. Использование активаций ReLU после максимального объединения означает, что вы выполняете вычисления только после уменьшения размерности, что экономит несколько секунд. Это может сократить время выполнения на 3 секунды с помощью MXNet framework.

11. Некоторые дополнительные проверки, которые могут быть полезны:

  • Становится ли указанное ядро ​​(3) симметричным кортежем (3,3) или одномерной сверткой (3,1)?

  • Шаг (в максимальном пуле) по умолчанию равен (1, 1) или равен ядру (что делает Keras)?

  • Заполнение по умолчанию обычно выключено (0, 0) или допустимо, но полезно проверить, что оно не включено/'то же самое'

  • Является ли активация по умолчанию для сверточных слоев «Нет» или «ReLu»

  • Инициализация значения смещения может быть невозможной (иногда значение смещения отсутствует)

  • Градиентный спуск и обработка бесконечных значений или NaN могут различаться в зависимости от фреймворка.

  • Некоторые фреймворки поддерживают разреженные метки вместо прямого типа кодирования (например, в Tensorflow, который я использую, есть функция f.nn.sparse_softmax_cross_entropy_with_logits)

  • Предположения о типах данных могут быть разными — например, я однажды пытался инициализировать X и Y типами float32 и int32. Но в факеле Y нужны данные типа double (чтобы их можно было использовать в функции torch.LongTensor(y).cuda)

  • Если фреймворк имеет API немного более низкого уровня, убедитесь, что градиенты не вычисляются, установив training=False во время тестирования.

12. Говорят, что немного сложно установить Caffe2, который поддерживает версию python3.5. Итак, я делюсь сценарием здесь

О RNN

1. В большинстве фреймворков (например, Tensorflow) существует несколько реализаций/ядер RNN; после понижения до уровня cudnn LSTM/GRU скорость выполнения становится максимальной. Однако эта реализация менее гибкая (например, может потребоваться нормализация уровня) и может быть проблематичной, если затем выполнять вывод на ЦП.

2. На уровне cuDNN время выполнения большинства фреймворков очень похоже. В этом посте в блоге Nvidia написано о нескольких интересных подходах для cuDNN-оптимизации рекуррентных нейронных сетей, например, слияние — «объединить вычисление множества маленьких матриц с вычислением больших матриц, и как можно больше выполнять потоковое вычисление, увеличивая отношение к памяти I /O вычислений, что приводит к повышению производительности графического процессора».

Автор | Илья Карманов

Оригинальный адрес: https://github.com/ilkarman/DeepLearningFrameworks