Хабрахабр

[Перевод] Deep Learning теперь на Java

Не любите Java? Да вы не умеете ее готовить! Mani Sarkar предлагает нам познакомиться с инструментом Valohai, позволяющим проводить исследования модели на Java.

Дисклеймер от переводчика

Я не связан с Valohai. Я надеюсь, это не является рекламной публикацией. Если коряво перевел — пинайте в личку. Я лишь перевел статью, на которую указываю ссылку. Спасибо за понимание.
Если будет нужно — могу удалить ссылки и упоминание других внешних ресурсов.

Введение

Некоторое время назад я столкнулся с облачным сервисом под названием Valohai, и меня порадовал его пользовательский интерфейс и простота дизайна и компоновки. Я попросил об услуге одного из членов Valohai и получил демо-версию. До этого я написал простой конвейер с использованием GNU Parallel, JavaScript, Python и Bash — и еще один, использующий только GNU Parallel и Bash.

Я также думал об использовании готовых к использованию инструментов управления задачами / рабочими процессами, таких как Jenkins X, Jenkins Pipeline, Concourse или Airflow, но по разным причинам я решил этого не делать.

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

Valohai подтолкнул меня к тому, чтобы реализовать что-то, используя известную библиотеку Java под названием DL4J — Deep Learning for Java.

Создатели уже приняли во внимание различные аспекты как рабочих процессов разработчика, так и инфраструктуры. Мой первый опыт работы с Valohai уже произвел на меня хорошее впечатление после прощупывания его дизайна, компоновки и рабочего процесса. В нашем мире процесс разработки инфраструктуры в основном управляется командами DevOps или SysOps, и мы знаем нюансы и болевые точки, связанные с ним.

Что нам нужно и как?

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

Конечно, будут шаги и компоненты, необходимые до, во время и после, но для простоты, скажем, нам нужен код и инфраструктура.

Код

Для кода я выбрал сложный пример с использованием DL4J, это проект MNist с обучающим набором из 60000 изображений и тестовым набором из 10000 изображений рукописных цифр. Этот набор данных доступен через библиотеку DL4J (точно так же, как и Keras).

Основной класс Java называется org.deeplearning4j.feedforward.mnist. Прежде чем начать, рекомендуется взглянуть на исходный код, который мы будем использовать. MLPMnistSingleLayerRunner.

Инфраструктура

Мы решили попробовать пример Java с использованием Valohai в качестве нашей инфраструктуры для проведения экспериментов (обучение и оценка модели). Valohai распознает git-репозитории и напрямую подключается к ним, позволяя выполнять наш код независимо от платформы или языка — так что мы увидим, как это работает. Это также означает, что если вы используете GitOps или Infrastructure-As-Code, у вас также все будет работать.

После создания бесплатной учетной записи получаем доступ к нескольким экземплярам различных конфигураций. Для этого нам просто нужна учетная запись в Valohai. Для того, что мы хотели бы сделать, Free-Tier более чем достаточно.

Deep Learning для Java и Valohai

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

Deep Learning для Java: DL4J

Самая простая часть. Нам не нужно много делать, просто соберите jar и загрузите набор данных в контейнер Docker. У нас есть предварительно созданный образ Docker, который содержит все зависимости, необходимые для создания приложения Java. Мы поместили этот образ в Docker Hub, и вы можете найти его, выполнив поиск dl4j-mnist-single-layer (мы будем использовать специальный тег, как определено в файле YAML). Мы решили использовать GraalVM 19.1.1 в качестве нашей сборочной и выполняемой среды Java для этого проекта, и она встроена в образ Docker.

Когда uber jar вызывается из командной строки, мы создаем класс MLPMnistSingleLayerRunner, который указывает нам предполагаемое действие в зависимости от параметров, передаваемых в:

public static void main(String[] args) throws Exception { MLPMnistSingleLayerRunner mlpMnistRunner = new MLPMnistSingleLayerRunner(); JCommander.newBuilder() .addObject(mlpMnistRunner) .build() .parse(args); mlpMnistRunner.execute();
}

Параметры, переданные в uber jar, принимаются этим классом и обрабатываются методом execute().

Мы можем создать модель с помощью параметра --action train и оценить созданную модель с помощью параметра --action evaluate переданного в приложение Java.

Основные части приложения Java, которое выполняет эту работу, можно найти в двух классах Java, упомянутых в разделах ниже.

Обучение модели

Вызовем

./runMLPMnist.sh --action train --output-dir $
or
java -Djava.library.path="" \ -jar target/MLPMnist-1.0.0-bin.jar \ --action train --output-dir ${VH_OUTPUTS_DIR}

Эта команда создает модель с именем mlpmnist-single-layer.pb в папке, указанной параметром --output-dir переданным в начале выполнения. С точки зрения Valohai, он должен быть помещен в $ {VH_OUTPUTS_DIR}, что мы и делаем (см. файл valohai.yaml).

в классе MLPMNistSingleLayerTrain.java. Исходный код см.

Оценка модели

Вызовем

./runMLPMnist.sh --action evaluate --input-dir ${VH_INPUTS_DIR}/model
or
java -Djava.library.path="" \ -jar target/MLPMnist-1.0.0-bin.jar \ --action evaluate --input-dir ${VH_INPUTS_DIR}/model

Предполагается, что модель (созданная на этапе обучения) с именем mlpmnist-single-layer.pb будет присутствовать в папке, указанной в параметре --input-dir переданном при вызове приложения.

в классе MLPMNistSingleLayerEvaluate.java. Исходный код см.

Я надеюсь, что эта короткая иллюстрация прояснит, как работает приложение Java, которое обучает и оценивает модель.

Это все, что от нас требуется, но не стесняйтесь поиграть с остальными исходниками (вместе с README.md и скриптами bash) и удовлетворить свое любопытство и понимание того, как это делается!

Valohai

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

Таким образом, два шага выполнения разъединяются; например, мы можем скомпилировать jar один раз и выполнить сотни тренировочных шагов на одном jar. Во время выполнения мы собираем Uber JAR в контейнере Docker, загружаем его в какое-либо внутреннее или внешнее хранилище, а затем с помощью другого шага выполнения загружаем Uber JAR и набор данных из хранилища (или другого места) для запуска обучения. Поскольку среды сборки и среды выполнения не должны изменяться так часто, мы можем их кэшировать, а код, набор данных и модели могут быть динамически доступны во время выполнения.

Наш valohai.yaml выглядит так: valohai.yaml
Главной частью интеграции нашего Java-проекта с инфраструктурой Valohai является определение порядка шагов Execution в файле valohai.yaml, расположенном в корне папки вашего проекта.

---
- step: name: Build-dl4j-mnist-single-layer-java-app image: neomatrix369/dl4j-mnist-single-layer:v0.5 command: - cd ${VH_REPOSITORY_DIR} - ./buildUberJar.sh - echo "~~~ Copying the build jar file into ${VH_OUTPUTS_DIR}" - cp target/MLPMnist-1.0.0-bin.jar ${VH_OUTPUTS_DIR}/MLPMnist-1.0.0.jar - ls -lash ${VH_OUTPUTS_DIR} environment: aws-eu-west-1-g2-2xlarge
- step: name: Run-dl4j-mnist-single-layer-train-model image: neomatrix369/dl4j-mnist-single-layer:v0.5 command: - echo "~~~ Unpack the MNist dataset into ${HOME} folder" - tar xvzf ${VH_INPUTS_DIR}/dataset/mlp-mnist-dataset.tgz -C ${HOME} - cd ${VH_REPOSITORY_DIR} - echo "~~~ Copying the build jar file from ${VH_INPUTS_DIR} to current location" - cp ${VH_INPUTS_DIR}/dl4j-java-app/MLPMnist-1.0.0.jar . - echo "~~~ Run the DL4J app to train model based on the the MNist dataset" - ./runMLPMnist.sh {parameters} inputs: - name: dl4j-java-app description: DL4J Java app file (jar) generated in the previous step 'Build-dl4j-mnist-single-layer-java-app' - name: dataset default: https://github.com/neomatrix369/awesome-ai-ml-dl/releases/download/mnist-dataset-v0.1/mlp-mnist-dataset.tgz description: MNist dataset needed to train the model parameters: - name: --action pass-as: '--action {v}' type: string default: train description: Action to perform i.e. train or evaluate - name: --output-dir pass-as: '--output-dir {v}' type: string default: /valohai/outputs/ description: Output directory where the model will be created, best to pick the Valohai output directory environment: aws-eu-west-1-g2-2xlarge
- step: name: Run-dl4j-mnist-single-layer-evaluate-model image: neomatrix369/dl4j-mnist-single-layer:v0.5 command: - cd ${VH_REPOSITORY_DIR} - echo "~~~ Copying the build jar file from ${VH_INPUTS_DIR} to current location" - cp ${VH_INPUTS_DIR}/dl4j-java-app/MLPMnist-1.0.0.jar . - echo "~~~ Run the DL4J app to evaluate the trained MNist model" - ./runMLPMnist.sh {parameters} inputs: - name: dl4j-java-app description: DL4J Java app file (jar) generated in the previous step 'Build-dl4j-mnist-single-layer-java-app' - name: model description: Model file generated in the previous step 'Run-dl4j-mnist-single-layer-train-model' parameters: - name: --action pass-as: '--action {v}' type: string default: evaluate description: Action to perform i.e. train or evaluate - name: --input-dir pass-as: '--input-dir {v}' type: string default: /valohai/inputs/model description: Input directory where the model created by the previous step can be found created environment: aws-eu-west-1-g2-2xlarge

Как работает Build-dl4j-mnist-single-layer-java-app

Из файла YAML мы видим, что мы определяем этот шаг, сначала используя образ Docker, а затем запускаем скрипт для сборки Uber JAR. Наш образ докера имеет настройку зависимостей среды сборки (например, GraalVM JDK, Maven и т. д.) для создания приложения Java. Мы не указываем какие-либо входные данные или параметры, так как это этап сборки. Как только сборка будет успешной, мы копируем uber jar с именем MLPMnist-1.0.0-bin.jar (оригинальное имя) в папку /valohai/outputs (представленную как ${VH_OUTPUTS_DIR} ). Все в этой папке автоматически сохраняется в хранилище вашего проекта, например, в корзине AWS S3. Наконец, мы определяем нашу работу для работы в среде AWS.

Примечание

Бесплатная учетная запись Valohai не имеет доступа к сети из контейнера Docker (по умолчанию это отключено), пожалуйста, свяжитесь со службой поддержки, чтобы включить эту опцию (я должен был сделать то же самое), иначе мы не сможем загрузить наш Maven и другие зависимости во время сборки.

Как работает Run-dl4j-mnist-single-layer-train-model

Семантика определения аналогична предыдущему шагу, за исключением того, что мы указываем два ввода: один для uber jar ( MLPMnist-1.0.0.jar ), а другой — для набора данных (распаковывается в папку ${HOME}/.deeplearning4j ). Мы будем передавать два параметра — --action train и --output-dir /valohai/outputs. Модель, созданная на этом шаге, собирается в /valohai/outputs/model (представлена ​​в виде ${VH_OUTPUTS_DIR}/model ).

Примечание

е. В полях ввода на вкладке «Выполнение» веб-интерфейса Valohai мы можем выбрать выходные данные из предыдущих выполнений, используя номер выполнения, т. #1 или #2, в дополнение к использованию URL-адресов datum: // или http: //, ввод в несколько букв имени файла также помогает искать по всему списку.

Как работает Run-dl4j-mnist-single-layer -valu-model

Опять же, этот шаг аналогичен предыдущему шагу, за исключением того, что мы будем передавать два параметра --action evaluate и --input-dir /valohai/inputs/model. Кроме того, мы снова указали в вводе: разделы, определенные в файле YAML с именем dl4j-java-app и model без заданного по умолчанию для них обоих. Это позволит нам выбрать uber jar и модель, которую мы хотим оценить — которая была создана с помощью шага Run-dl4j-mnist-single-layer-train-model, используя веб-интерфейс.

Я надеюсь, что это объясняет шаги в приведенном выше файле определения, но если вам требуется дополнительная помощь, пожалуйста, не стесняйтесь просматривать документацию и туториалы.

Веб-интерфейс Valohai

Получив учетную запись, мы можем войти и продолжить создание проекта с именем mlpmnist-single-layer и связать git repo github.com/valohai/mlpmnist-dl4j-example с проектом и сохранить проект.

Теперь вы можете выполнить шаг и посмотреть, как это получится!

Сборка Java-приложения DL4J

Перейдите на вкладку «Execution» в веб-интерфейсе и либо скопируйте существующее execution, либо создайте новое с помощью кнопки [Create execution]. Все необходимые параметры по умолчанию будут заполнены. Выберите Step Build-dl4j-mnist-single-layer-java-app.

2xlarge и щелкнул по кнопке [Create execution] внизу страницы, чтобы увидеть начало выполнения. Для Окружения я выбрал AWS eu-west-1 g2.

Обучение модели

Перейдите на вкладку «Execution» в веб-интерфейсе и сделайте то же, что и на предыдущем шаге, и выберите Run-dl4j-mnist-single-layer-train-model. Вам нужно будет выбрать приложение Java (просто введите jar в поле), созданное на предыдущем шаге. Набор данных уже был предварительно заполнен с помощью файла valohai.yaml:

Нажмите [Create Execution], чтобы начать.

Вы увидите результат в консоли:

[<--- snipped --->]
11:17:05 =======================================================================
11:17:05 LayerName (LayerType) nIn,nOut TotalParams ParamsShape
11:17:05 =======================================================================
11:17:05 layer0 (DenseLayer) 784,1000 785000 W:{784,1000}, b:{1,1000}
11:17:05 layer1 (OutputLayer) 1000,10 10010 W:{1000,10}, b:{1,10}
11:17:05 -----------------------------------------------------------------------
11:17:05 Total Parameters: 795010
11:17:05 Trainable Parameters: 795010
11:17:05 Frozen Parameters: 0
11:17:05 =======================================================================
[<--- snipped --->]

Созданные модели можно найти на вкладке «Outputs» главной вкладки «Execution» во время и после выполнения:

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

[<--- snipped --->]
11:17:14 o.d.o.l.CheckpointListener - Model checkpoint saved: epoch 0, iteration 469, path: /valohai/outputs/checkpoint_0_MultiLayerNetwork.zip
[<--- snipped --->]

Чекпоинт содержит состояние модели в трех файлах:

configuration.json
coefficients.bin
updaterState.bin

Обучение модели. Метаданные

Возможно, вы заметили эти записи в журналах выполнения:

[<--- snipped --->]
11:17:05 {"epoch": 0, "iteration": 0, "score (loss function)": 2.410047}
11:17:07 {"epoch": 0, "iteration": 100, "score (loss function)": 0.613774}
11:17:09 {"epoch": 0, "iteration": 200, "score (loss function)": 0.528494}
11:17:11 {"epoch": 0, "iteration": 300, "score (loss function)": 0.400291}
11:17:13 {"epoch": 0, "iteration": 400, "score (loss function)": 0.357800}
11:17:14 o.d.o.l.CheckpointListener - Model checkpoint saved: epoch 0, iteration 469, path: /valohai/outputs/checkpoint_0_MultiLayerNetwork.zip
[<--- snipped --->]

Эти данные позволяют Valohai получить эти значения (в формате JSON), которые будут использоваться для построения метрики, которые можно увидеть во время и после выполнения на дополнительной вкладке «Metadata» на главной вкладке «Executions»:

В случае этого класса мы выводим несколько эпох, количество итераций и Score (значение функции loss). Мы смогли сделать это, подключив класс ValohaiMetadataCreator к модели, так что во время обучения Valohai обращается к этому классу. Вот фрагмент кода из класса:

public void iterationDone(Model model, int iteration, int epoch) { if (printIterations <= 0) printIterations = 1; if (iteration % printIterations == 0) { double score = model.score(); System.out.println(String.format( "{\"epoch\": %d, \"iteration\": %d, \"score (loss function)\": %f}", epoch, iteration, score) ); } }

Оценка модели

Как только модель была успешно создана на предыдущем этапе, следует ее оценить. Мы создаем новое Execution точно так же, как и ранее, но на этот раз выбираем шаг Run-dl4j-mnist-single-layer -valu-model. Нам нужно будет снова выбрать приложение Java (MLPMnist-1.0.0.jar) и созданную модель (mlpmnist-single-layer.pb), прежде чем начинать выполнение (как показано ниже):

Оно быстрее исполнится, чем предыдущее, и мы увидим следующий результат: После выбора нужной модели в качестве входных данных нажмите кнопку [Create execution].

Confusion matrix помогает найти случаи, когда цифра была неправильно предсказана как другая цифра. Мы видим, что наш «hello world» привел к получению модели, точность которой составляет около 97% на основе тестового набора данных.

Остается вопрос (и выходящий за рамки этого поста) — насколько хороша модель, когда сталкиваешься с реальными данными?

Чтобы клонировать репозиторий git, то вот что нужно сделать:

$ git clone https://github.com/valohai/mlpmnist-dl4j-example

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

$ cd mlpmnist-dl4j-example
$ vh project --help ### to see all the project-specific options we have for Valohai
$ vh project link

Вам будет показано что-то вроде этого:

[ 1] mlpmnist-single-layer
...
Which project would you like to link with /path/to/mlpmnist-dl4j-example?
Enter [n] to create a new project.:

Выберите 1 (или подходящий вам вариант), и вы должны увидеть это сообщение:

Success! Linked /path/to/mlpmnist-dl4j-example to mlpmnist-single-layer.

Еще кое-что, прежде чем идти дальше, убедитесь, что ваш проект Valohai синхронизирован с последним git-проектом, выполнив это:

$ vh project fetch

Теперь мы можем выполнить шаги из CLI с помощью:

$ vh exec run Build-dl4j-mnist-single-layer-java-app

После того, как Execution выполнено, мы можем проверить его с помощью:

$ vh exec info
$ vh exec logs
$ vh exec watch

Заключение

Как мы видели, очень удобно работать с DL4J и Valohai вместе. Кроме того, мы можем разрабатывать различные компоненты, из которых состоят наши эксперименты (исследования), то есть среду сборки / выполнения, код и набор данных, и интегрировать их в наш проект.

И вы можете использовать веб-интерфейс или интерфейс командной строки, чтобы выполнить свою работу с Valohai. Примеры шаблонов, использованные в этом посте, — хороший способ начать создавать более сложные проекты. С CLI вы также можете интегрировать его с вашими установками и сценариями (или даже с заданиями CRON или CI / CD).

Кроме того, ясно, что если я работаю над проектом, связанным с AI / ML / DL, мне не нужно заботиться о создании и поддержке сквозного конвейера (что пришлось сделать многим другим и мне в прошлом).

Ссылки

  1. Проект mlpmnist-dl4j-examples на GitHub
  2. Потрясающие ресурсы AI / ML / DL
  3. Ресурсы Java AI / ML / DL
  4. Deep Learning и ресурсы DL4J

Спасибо за внимание!

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»