Вторая часть полного обсуждения того, как выполнять распределенное глубокое обучение с Apache Spark. Я полностью сосредоточусь на библиотеке конвейеров DL и на том, как использовать ее с нуля. Одна из вещей, которые вы увидите, - это перенос обучения на простом конвейере, как использовать предварительно обученные модели для работы с «небольшими» объемами данных и возможность предсказывать вещи и многое другое.

Всем привет и добро пожаловать обратно в учебу :). В этой статье я продолжу обсуждение глубокого обучения с помощью Apache Spark. Первую часть вы можете увидеть здесь.

В этой части я полностью сосредоточусь на библиотеке конвейеров DL и на том, как использовать ее с нуля.

Хронология Apache Spark

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

Скоро я напишу статью с описанием для этой временной шкалы, но если вы думаете, что чего-то не хватает, дайте мне знать :)

Конвейеры глубокого обучения

Deep Learning Pipelines - это библиотека с открытым исходным кодом, созданная Databricks, которая предоставляет высокоуровневые API-интерфейсы для масштабируемого глубокого обучения на Python с Apache Spark.



Это потрясающая работа, и скоро она будет объединена с официальным API, поэтому стоит взглянуть на нее.

Некоторые из преимуществ этой библиотеки по сравнению с теми, которые объединяют Spark с DL:

  • В духе Spark и Spark MLlib он предоставляет простые в использовании API-интерфейсы, которые обеспечивают глубокое обучение в очень небольшом количестве строк кода.
  • Он ориентирован на простоту использования и интеграции без ущерба для производительности.
  • Он создан создателями Apache Spark (которые также являются основными участниками), поэтому вероятность его объединения в качестве официального API выше, чем у других.
  • Он написан на Python, поэтому он будет интегрирован со всеми своими известными библиотеками, и прямо сейчас он использует возможности TensorFlow и Keras, двух основных библиотек на данный момент для DL.

Deep Learning Pipelines основывается на конвейерах машинного обучения Apache Spark для обучения, а также на Spark DataFrames и SQL для развертывания моделей. Он включает высокоуровневые API-интерфейсы для общих аспектов глубокого обучения, поэтому их можно эффективно реализовать с помощью нескольких строк кода:

  • Загрузка изображения
  • Применение предварительно обученных моделей в качестве преобразователей в конвейере Spark ML
  • Передача обучения
  • Масштабное применение моделей глубокого обучения
  • Распределенная настройка гиперпараметров (следующая часть)
  • Развертывание моделей в DataFrames и SQL

Я подробно опишу каждую из этих функций на примерах. Эти примеры взяты из официальной записной книжки от Databricks.

Apache Spark на Deep Cognition

Для запуска и тестирования кодов из этой статьи вам необходимо создать учетную запись в Deep Cognition.

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

Теперь просто нажмите на левую часть, кнопку «Блокнот»:

И вы будете в Jupyter Notebook со всеми установленными пакетами :). Ой! Примечание: Spark Notebook (DLS SPARK) - это предстоящая функция, которая будет выпущена для публики где-то в следующем месяце и сообщит, что она все еще находится в частной бета-версии (только для этого сообщения).

Вы можете скачать полную версию Блокнота здесь, чтобы увидеть весь код:

Https://github.com/FavioVazquez/deep-learning-pyspark

Загрузка изображения

Первый шаг к применению глубокого обучения к изображениям - это возможность загружать изображения. Deep Learning Pipelines включает служебные функции, которые могут загружать миллионы изображений в DataFrame и автоматически декодировать их в распределенном режиме, позволяя манипулировать в любом масштабе. Новая версия spark (2.3.0) также имеет эту возможность, но мы будем использовать библиотеку sparkdl.

Мы будем использовать архив лицензионных фотографий цветов Creative Commons, созданный TensorFlow, чтобы проверить это. Чтобы получить набор фотографий цветов, запустите эти команды из записной книжки (мы также создадим папку-образец):

Давайте скопируем несколько фотографий из папок с тюльпанами и ромашками, чтобы создать небольшой образец фотографий.

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

Вы должны это увидеть

Теперь давайте воспользуемся Spark, чтобы загрузить эти изображения как DataFrame. Метод spark.readImage позволяет считывать изображения в обычных форматах (jpg, png и т. Д.) Из хранилища HDFS в DataFrame. Каждое изображение хранится в виде строки в формате imageSchema. Рекурсивная опция позволяет вам читать изображения из подпапок, например, для образцов с положительной и отрицательной метками. Параметр sampleRatio позволяет поэкспериментировать с меньшей выборкой изображений перед обучением модели с полными данными.

Если мы посмотрим на этот фрейм данных, мы увидим, что он создал один столбец под названием «изображение».

image_df.show()
+--------------------+
|               image|
+--------------------+
|[file:/Users/favi...|
|[file:/Users/favi...|
|[file:/Users/favi...|
+--------------------+

Столбец изображения содержит строковый столбец, содержащий структуру изображения со схемой == ImageSchema.

Передача обучения

Deep Learning Pipelines предоставляет утилиты для выполнения переноса обучения на изображениях, что является одним из самых быстрых (с точки зрения кода и времени выполнения) способов начать использовать глубокое обучение. Используя Deep Learning Pipelines, это можно сделать всего несколькими строками кода.

Deep Learning Pipelines обеспечивает быструю передачу обучения с помощью концепции Featurizer. В следующем примере сочетаются модель InceptionV3 и логистическая регрессия в Spark, чтобы адаптировать InceptionV3 к нашему конкретному домену. DeepImageFeaturizer автоматически отделяет последний слой предварительно обученной нейронной сети и использует выходные данные всех предыдущих слоев в качестве функций для алгоритма логистической регрессии. Поскольку логистическая регрессия - это простой и быстрый алгоритм, это обучение с переносом обучения может быстро сходиться с использованием гораздо меньшего количества изображений, чем обычно требуется для обучения модели глубокого обучения с нуля.

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

А теперь обучим модель

Посмотрим, насколько хороша модель:

Test set accuracy = 0.9753086419753086

Не так уж и плохо для примера и вообще без тюнинга!

Мы можем посмотреть, где мы делаем ошибки:

Масштабное применение моделей глубокого обучения

Deep Learning Pipelines поддерживает запуск предварительно обученных моделей распределенным образом с помощью Spark, доступный как для пакетной обработки, так и для потоковой обработки данных.

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

Помимо использования встроенных моделей, пользователи могут подключить модели Keras и графики TensorFlow в конвейер прогнозирования Spark. Это превращает любые одноузловые модели в одноузловых инструментах в модель, которую можно применять распределенным образом к большому количеству данных.

Следующий код создает конвейер прогнозирования Spark с использованием InceptionV3, современной модели сверточной нейронной сети (CNN) для классификации изображений, и прогнозирует, какие объекты находятся в изображениях, которые мы только что загрузили.

Давайте посмотрим на фрейм данных прогнозов:

predictions_df.select("predicted_labels").show(truncate=False,n=3)
+----------------+
|predicted_labels|                                                                                                                                                                                                                                                                                                                                            |                |
+----------------+
|[[n03930313, picket_fence, 0.1424783], [n11939491, daisy, 0.10951301], [n03991062, pot, 0.04505], [n02206856, bee, 0.03734662], [n02280649, cabbage_butterfly, 0.019011213], [n13133613, ear, 0.017185668], [n02219486, ant, 0.014198389], [n02281406, sulphur_butterfly, 0.013113698], [n12620546, hip, 0.012272579], [n03457902, greenhouse, 0.011370744]]            |
|[[n11939491, daisy, 0.9532104], [n02219486, ant, 6.175268E-4], [n02206856, bee, 5.1203516E-4], [n02190166, fly, 4.0093894E-4], [n02165456, ladybug, 3.70687E-4], [n02281406, sulphur_butterfly, 3.0587992E-4], [n02112018, Pomeranian, 2.9011074E-4], [n01795545, black_grouse, 2.5667972E-4], [n02177972, weevil, 2.4875381E-4], [n07745940, strawberry, 2.3729511E-4]]|
|[[n11939491, daisy, 0.89181453], [n02219486, ant, 0.0012404523], [n02206856, bee, 8.13047E-4], [n02190166, fly, 6.03804E-4], [n02165456, ladybug, 6.005444E-4], [n02281406, sulphur_butterfly, 5.32096E-4], [n04599235, wool, 4.6653638E-4], [n02112018, Pomeranian, 4.625338E-4], [n07930864, cup, 4.400617E-4], [n02177972, weevil, 4.2434104E-4]]                    |
+----------------+
only showing top 3 rows

Обратите внимание, что столбец predicted_labels показывает «маргаритка» как класс с высокой вероятностью для всех образцов цветов, использующих эту базовую модель, по какой-то причине тюльпан был ближе к забору из штакетника, чем к цветку (возможно, из-за фона фото).

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

Посмотрим, насколько хорошо наша модель распознает тип цветка:

Для пользователей Keras

Для распределенного применения моделей Keras с использованием Spark KerasImageFileTransformer работает с моделями Keras, поддерживаемыми TensorFlow. Это

  • Внутренне создает DataFrame, содержащий столбец изображений, применяя указанную пользователем функцию загрузки и обработки изображений к входному DataFrame, содержащему столбец URI изображений.
  • Загружает модель Keras из заданного пути к файлу модели
  • Применяет модель к изображению DataFrame

Чтобы использовать преобразователь, нам сначала нужно сохранить модель Keras в виде файла. Для этого блокнота мы просто сохраним модель InceptionV3, встроенную в Keras, вместо учебной.

Теперь мы создадим преобразователь Keras, но сначала мы предварительно обработаем изображения для работы с ним.

Теперь мы прочитаем изображения и загрузим их в Spark Dataframe, и они будут использовать наш преобразователь для применения модели к изображениям:

Если мы посмотрим на этот фрейм данных с прогнозами, мы увидим много информации, и это всего лишь вероятность каждого класса в модели InceptionV3.

Работа с общими тензорами

Deep Learning Pipelines также предоставляет способы применения моделей с тензорными входными данными (до двух измерений), записанными в популярных библиотеках глубокого обучения:

  • Графики TensorFlow
  • Модели Keras

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

final_df.show()
+-------------+--------------------+
|  predictions|            features|
+-------------+--------------------+
| [0.86104786]|[-0.76344526, 0.2...|
| [0.21693115]|[0.41084298, 0.93...|
|[0.057743043]|[0.062970825, 0.3...|
| [0.43409333]|[-0.43408343, -1....|
| [0.43690935]|[-0.89413625, 0.8...|
| [0.49984664]|[-0.82052463, -0....|
|  [0.6204273]|[-0.5075533, 0.54...|
|  [0.2285336]|[0.016106872, -0....|
| [0.37478408]|[-1.6756374, 0.84...|
|  [0.2997861]|[-0.34952268, 1.2...|
|  [0.3885377]|[0.1639214, -0.22...|
|  [0.5006814]|[0.91551965, -0.3...|
| [0.20518135]|[-1.2620118, -0.4...|
| [0.18882117]|[-0.14812712, 0.8...|
| [0.49993372]|[1.4617485, -0.33...|
| [0.42390883]|[-0.877813, 0.603...|
|  [0.5232896]|[-0.031451378, -1...|
| [0.45858437]|[0.9310042, -1.77...|
| [0.49794272]|[-0.37061003, -1....|
|  [0.2543479]|[0.41954428, 1.88...|
+-------------+--------------------+
only showing top 20 rows

Развертывание моделей в SQL

Один из способов создания модели - развернуть ее как определяемую пользователем функцию Spark SQL, которая позволяет использовать ее любому, кто знает SQL. Конвейеры глубокого обучения предоставляют механизмы для использования модели глубокого обучения и регистрации пользовательской функции Spark SQL (UDF). В частности, Deep Learning Pipelines 0.2.0 добавляет поддержку для создания пользовательских функций SQL из моделей Keras, которые работают с данными изображений.

Результирующий UDF принимает столбец (отформатированный как структура изображения «SpImage») и производит вывод данной модели Keras; например для Inception V3 он создает реальный вектор оценок по категориям объектов ImageNet.

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

После регистрации UDF его можно использовать в запросе SQL:

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

sparkdl.registerKerasUDF("awesome_dl_model", "/mymodels/businessmodel.h5")

Затем любой пользователь в организации может применить прогнозирование в SQL:

SELECT image, awesome_dl_model(image) label FROM images 
WHERE contains(label, “Product”)

В следующей части я расскажу о настройке распределенных гиперпараметров с помощью Spark и попробую новые модели и примеры :).

Если вы хотите связаться со мной, обязательно подпишитесь на меня в твиттере:



и LinkedIn: