¿No te gusta Java? ¡Sí, no sabes cómo cocinarlo! Mani Sarkar nos invita a conocer la herramienta Valohai, que le permite realizar investigaciones modelo en Java.

Descargo de responsabilidad del traductorEspero que esta no sea una publicación publicitaria. No estoy afiliado a Valohai. Acabo de traducir el artículo al que remito el enlace. Si se traduce torpemente, patee PM. Si es necesario, puedo eliminar enlaces y mencionar otros recursos externos. Gracias por su comprensión
Introduccion
Hace algún tiempo, me encontré con un servicio en la nube llamado Valohai, y estaba satisfecho con su interfaz de usuario y la simplicidad del diseño y el diseño. Pedí el servicio de uno de los miembros de Valohai y recibí una versión demo. Antes de eso, escribí una tubería simple usando GNU Parallel, JavaScript, Python y Bash, y otra que usa solo GNU Parallel y Bash.
También pensé en usar herramientas de administración de tareas / flujo de trabajo listas para usar como Jenkins X, Jenkins Pipeline, Concourse o Airflow, pero por varias razones decidí no hacerlo.
Noté que muchos ejemplos y documentación de Valohai se basan en Python y R y sus respectivos marcos y bibliotecas. Decidí no perder la oportunidad y quiero corregir la falta de ejemplos y documentación.
Valohai me presionó para implementar algo usando la famosa biblioteca de Java llamada
DL4J - Deep Learning for Java .
Mi primera experiencia con Valohai me causó una buena impresión después de sentirme a través de su diseño, diseño y flujo de trabajo. Los creadores ya han tenido en cuenta varios aspectos tanto de los flujos de trabajo como de la infraestructura del desarrollador. En nuestro mundo, el proceso de desarrollo de infraestructura está controlado principalmente por los equipos DevOps o SysOps, y conocemos los matices y los puntos débiles asociados con él.
¿Qué necesitamos y cómo?
En cualquier proyecto de aprendizaje automático, hay dos componentes importantes (desde un punto de vista de alto nivel): un código que funcionará con el modelo y un código que funcionará con la infraestructura, en la que se ejecutará todo el ciclo de vida del proyecto.
Por supuesto, habrá pasos y componentes necesarios antes, durante y después, pero para simplificar, digamos, necesitamos código e infraestructura.
Código
Para el código, elegí un ejemplo complejo usando DL4J, este es un
proyecto MNist con un conjunto de capacitación de 60,000 imágenes y un conjunto de prueba de 10,000 imágenes de dígitos escritos a mano. Este conjunto de datos está disponible a través de la biblioteca DL4J (al igual que Keras).
Antes de comenzar, le recomendamos que eche un vistazo al código fuente que usaremos. La clase principal de Java se llama
org.deeplearning4j.feedforward.mnist.MLPMnistSingleLayerRunner .
La infraestructura
Decidimos probar el ejemplo de Java utilizando Valohai como nuestra infraestructura para realizar experimentos (capacitación y evaluación de modelos). Valohai reconoce los repositorios git y se conecta directamente a ellos, lo que nos permite ejecutar nuestro código independientemente de la plataforma o el idioma, así que veremos cómo funciona. También significa que si usa GitOps o Infrastructure-As-Code, todo funcionará para usted también.
Para hacer esto, solo necesitamos una cuenta en Valohai. Después de crear una cuenta gratuita, tenemos acceso a varias instancias de varias configuraciones. Para lo que nos gustaría hacer, Free-Tier es más que suficiente.
Aprendizaje profundo para Java y Valohai
Proporcionaremos todas las dependencias a la imagen de Docker y la usaremos para compilar nuestra aplicación Java, entrenar el modelo y evaluarlo en la plataforma Valohai usando un simple archivo
valohai.yaml ubicado en la carpeta raíz del repositorio del proyecto.
Aprendizaje profundo para Java: DL4J
La parte mas simple. No tenemos que hacer mucho, solo recolecte el jar y cargue el conjunto de datos en el contenedor Docker. Tenemos una imagen Docker pre-creada que contiene todas las dependencias necesarias para crear una aplicación Java. Ponemos esta imagen en el Docker Hub, y puede encontrarla buscando dl4j-mnist-single-layer (usaremos una etiqueta especial como se define en el archivo YAML). Decidimos utilizar GraalVM 19.1.1 como nuestro entorno Java de compilación y tiempo de ejecución para este proyecto, y está integrado en la imagen de Docker.
Cuando se llama al uber jar desde la línea de comandos, creamos la clase MLPMnistSingleLayerRunner, que nos dice la acción deseada, dependiendo de los parámetros pasados a:
public static void main(String[] args) throws Exception { MLPMnistSingleLayerRunner mlpMnistRunner = new MLPMnistSingleLayerRunner(); JCommander.newBuilder() .addObject(mlpMnistRunner) .build() .parse(args); mlpMnistRunner.execute(); }
Los parámetros pasados a uber jar son aceptados por esta clase y procesados por el método execute ().
Podemos crear un modelo usando el parámetro --action train y evaluar el modelo creado usando el parámetro --action Evaluation pasado a la aplicación Java.
Las partes principales de la aplicación Java que hace este trabajo se pueden encontrar en las dos clases Java mencionadas en las secciones a continuación.
Entrenamiento modelo
Llamar
./runMLPMnist.sh --action train --output-dir ${VH_OUTPUTS_DIR} or java -Djava.library.path="" \ -jar target/MLPMnist-1.0.0-bin.jar \ --action train --output-dir ${VH_OUTPUTS_DIR}
Este comando crea un modelo llamado mlpmnist-single-layer.pb en la carpeta especificada por el parámetro --output-dir pasado al inicio de la ejecución. Desde el punto de vista de Valohai, debe colocarse en $ {VH_OUTPUTS_DIR}, lo cual hacemos (ver el archivo
valohai.yaml ).
Para el código fuente, vea la clase
MLPMNistSingleLayerTrain.java .
Evaluación modelo
Llamar
./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
Se supone que el modelo (creado durante la fase de entrenamiento) con el nombre mlpmnist-single-layer.pb estará presente en la carpeta especificada en el parámetro --input-dir pasado cuando se llamó a la aplicación.
Para el código fuente, vea la clase
MLPMNistSingleLayerEvaluate.java .
Espero que esta breve ilustración aclare cómo funciona una aplicación Java que enseña y evalúa un modelo.
Esto es todo lo que se requiere de nosotros, pero no dude en jugar con el resto de las
fuentes (junto con los
scripts README.md y bash) y satisfacer su curiosidad y comprensión de cómo se hace.
Valohai
Valohai nos permite vincular libremente nuestro tiempo de ejecución, código y conjunto de datos, como puede ver en la estructura de archivos YAML a continuación. Por lo tanto, varios componentes pueden desarrollarse independientemente uno del otro. En consecuencia, solo los componentes de ensamblaje y tiempo de ejecución se empaquetan en nuestro contenedor Docker.
En tiempo de ejecución, recolectamos el UAR JAR en un contenedor Docker, lo cargamos en un almacenamiento interno o externo, y luego usamos el otro paso de ejecución para cargar el UAR JAR y el conjunto de datos del almacenamiento (u otro lugar) para comenzar el entrenamiento. Por lo tanto, los dos pasos de ejecución están desconectados; Por ejemplo, podemos compilar una jarra una vez y completar cientos de pasos de entrenamiento en una sola jarra. Debido a que los entornos de ensamblaje y tiempo de ejecución no tienen que cambiar con tanta frecuencia, podemos almacenarlos en caché, y el código, los conjuntos de datos y los modelos pueden ser accesibles dinámicamente en tiempo de ejecución.
valohai.yamlLa parte principal de la integración de nuestro proyecto Java con la infraestructura de Valohai es determinar el orden de los pasos de Ejecución en el archivo valohai.yaml ubicado en la raíz de la carpeta de su proyecto. Nuestro valohai.yaml se ve así:
--- - 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 ie 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 ie 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
Cómo funciona Build-dl4j-mnist-single-layer-java-app
Desde el archivo YAML, vemos que definimos este paso, primero usando la imagen de Docker y luego ejecutando el script para construir el JAR de Uber. Nuestra imagen acoplable tiene personalización de dependencias del entorno de compilación (por ejemplo, GraalVM JDK, Maven, etc.) para crear una aplicación Java. No proporcionamos ninguna entrada o parámetro, ya que esta es la fase de ensamblaje. Una vez que la compilación es exitosa, copiamos el archivo uber llamado MLPMnist-1.0.0-bin.jar (nombre original) a la carpeta / valohai / salidas (representada como $ {VH_OUTPUTS_DIR}). Todo en esta carpeta se guarda automáticamente en el almacenamiento de su proyecto, por ejemplo, en la papelera de reciclaje de AWS S3. Finalmente, definimos nuestro trabajo para AWS.
NotaLa cuenta gratuita de Valohai no tiene acceso a la red desde el contenedor Docker (esto está deshabilitado de forma predeterminada), comuníquese con el soporte para habilitar esta opción (tuve que hacer lo mismo), de lo contrario no podremos descargar nuestro Maven y otras dependencias durante el montaje
Cómo funciona Run-dl4j-mnist-single-layer-train-model
La semántica de la definición es similar al paso anterior, excepto que especificamos dos entradas: una para uber jar (MLPMnist-1.0.0.jar) y la otra para el conjunto de datos (desempaquetado en la carpeta $ {HOME} /. Deeplearning4j). Pasaremos dos parámetros: --action train y --output-dir / valohai / salidas. El modelo creado en este paso está integrado en / valohai / salidas / model (representado como $ {VH_OUTPUTS_DIR} / model).
NotaEn los campos de entrada en la pestaña Ejecutar de la interfaz web de Valohai, podemos seleccionar la salida de ejecuciones anteriores usando el número de ejecución, es decir, # 1 o # 2, además de usar el datum: // o http: / URLs /, ingresar algunas letras del nombre del archivo también ayuda a buscar en toda la lista.
Cómo funciona Run-dl4j-mnist-single-layer -valu-model
Nuevamente, este paso es similar al paso anterior, excepto que pasaremos dos parámetros: evaluación de acción y --input-dir / valohai / inputs / model. Además, nuevamente indicamos en la entrada: las secciones definidas en el archivo YAML con el nombre dl4j-java-app y el modelo sin el valor predeterminado para ambos. Esto nos permitirá seleccionar el uber jar y el modelo que queremos evaluar, que fue creado usando el paso Run-dl4j-mnist-single-layer-train-model usando la interfaz web.
Espero que esto explique los pasos en el archivo de definición anterior, pero si necesita más ayuda, no dude en ver la
documentación y los
tutoriales .
Interfaz web Valohai
Después de recibir la cuenta, podemos iniciar sesión y continuar creando el proyecto con el nombre mlpmnist-single-layer y asociar git repo
github.com/valohai/mlpmnist-dl4j-example con el proyecto y guardar el proyecto.
¡Ahora puedes completar el paso y ver cómo resulta!
Construir una aplicación Java DL4J
Vaya a la pestaña "Ejecución" en la interfaz web y copie la ejecución existente o cree una nueva con el botón [Crear ejecución]. Se completarán todos los parámetros predeterminados necesarios. Seleccione Step Build-dl4j-mnist-single-layer-java-app.
Para el
entorno, seleccioné AWS eu-west-1 g2.2xlarge y hice clic en el botón [Crear ejecución] en la parte inferior de la página para ver el inicio de la ejecución.

Entrenamiento modelo
Vaya a la pestaña "Ejecución" en la interfaz web y haga lo mismo que en el paso anterior, y seleccione Ejecutar-dl4j-mnist-single-layer-train-model. Deberá seleccionar la aplicación Java (solo ingrese jar en el campo) creada en el paso anterior. El conjunto de datos ya se ha rellenado previamente utilizando el archivo valohai.yaml:

Haga clic en [Crear ejecución] para comenzar.

Verá el resultado en la consola:
[<--- 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 --->]
Los modelos creados se pueden encontrar en la pestaña "Salidas" de la pestaña principal "Ejecución" durante y después de la ejecución:

Puede observar varios artefactos en la subpestaña Salidas. Esto se debe a que mantenemos puntos de control al final de cada era. Veamos esto en los registros:
[<--- snipped --->] 11:17:14 odolCheckpointListener - Model checkpoint saved: epoch 0, iteration 469, path: /valohai/outputs/checkpoint_0_MultiLayerNetwork.zip [<--- snipped --->]
El punto de control contiene el estado del modelo en tres archivos:
configuration.json coefficients.bin updaterState.bin
Modelo de entrenamiento. Metadatos
Es posible que haya notado estas entradas en los registros de ejecución:
[<--- 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 odolCheckpointListener - Model checkpoint saved: epoch 0, iteration 469, path: /valohai/outputs/checkpoint_0_MultiLayerNetwork.zip [<--- snipped --->]
Estos datos le permiten a Valohai obtener estos valores (en formato JSON), que se utilizarán para crear las métricas que se pueden ver durante y después de la ejecución en la pestaña Metadatos adicional en la pestaña principal Ejecuciones:

Pudimos hacer esto conectando la clase ValohaiMetadataCreator al modelo, para que Valohai se refiera a esta clase durante el entrenamiento. En el caso de esta clase, derivamos varias eras, el número de iteraciones y la puntuación (valor de la función de pérdida). Aquí hay un fragmento de código de la clase:
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) ); } }
Evaluación modelo
Una vez que el modelo se haya creado con éxito en el paso anterior, debe evaluarse. Creamos una nueva Ejecución de la misma manera que antes, pero esta vez seleccione el paso Run-dl4j-mnist-single-layer -valu-model. Tendremos que seleccionar la aplicación Java (MLPMnist-1.0.0.jar) y el modelo creado (mlpmnist-single-layer.pb) nuevamente antes de comenzar la ejecución (como se muestra a continuación):

Después de seleccionar el modelo deseado como entrada, haga clic en el botón [Crear ejecución]. Se ejecutará más rápido que el anterior, y veremos el siguiente resultado:

Vemos que nuestro "hola mundo" condujo a un modelo cuya precisión es aproximadamente del 97% basada en un conjunto de datos de prueba. La matriz de confusión ayuda a encontrar casos en los que un dígito se predijo incorrectamente como otro dígito.
La pregunta permanece (y más allá del alcance de esta publicación): ¿qué tan bueno es el modelo cuando se enfrenta a datos reales?
Para clonar un repositorio de git, esto es lo que debe hacer:
$ git clone https://github.com/valohai/mlpmnist-dl4j-example
Luego, necesitamos vincular nuestro proyecto Valohai, creado a través de la interfaz web en la sección anterior, con el proyecto almacenado en nuestra máquina local (la que acabamos de clonar). Ejecute los siguientes comandos para hacer esto:
$ cd mlpmnist-dl4j-example $ vh project --help ### to see all the project-specific options we have for Valohai $ vh project link
Se le mostrará algo como esto:
[ 1] mlpmnist-single-layer ... Which project would you like to link with /path/to/mlpmnist-dl4j-example? Enter [n] to create a new project.:
Seleccione 1 (o el que más le convenga) y debería ver este mensaje:
Success! Linked /path/to/mlpmnist-dl4j-example to mlpmnist-single-layer.
Una cosa más, antes de continuar, asegúrese de que su proyecto Valohai esté sincronizado con el último proyecto git haciendo esto:
$ vh project fetch

Ahora podemos completar los pasos desde la CLI con:
$ vh exec run Build-dl4j-mnist-single-layer-java-app
Una vez realizada la ejecución, podemos verificarlo con:
$ vh exec info $ vh exec logs $ vh exec watch
Conclusión
Como hemos visto, es muy conveniente trabajar juntos con DL4J y Valohai. Además, podemos desarrollar los diversos componentes que componen nuestros experimentos (investigación), es decir, el entorno de compilación / tiempo de ejecución, el código y el conjunto de datos, e integrarlos en nuestro proyecto.
Las plantillas de muestra utilizadas en esta publicación son una buena manera de comenzar a crear proyectos más complejos. Y puede usar la interfaz web o de línea de comandos para hacer su trabajo con Valohai. Con la CLI, también puede integrarlo con sus instalaciones y scripts (o incluso con trabajos CRON o CI / CD).
Además, está claro que si estoy trabajando en un proyecto relacionado con AI / ML / DL, no necesito preocuparme por crear y mantener una tubería de extremo a extremo (que muchos otros tuvieron que hacer en el pasado).
Referencias
- El proyecto mlpmnist-dl4j-examples en GitHub
- Recursos impresionantes de AI / ML / DL
- Recursos Java AI / ML / DL
- Aprendizaje profundo y recursos DL4J
Gracias por su atencion!