Bienvenido, les saluda Miguel y en esta ocasión les traigo este nuevo tutorial.
Índice
Introducción
Dentro de muchos lenguajes de desarrollo, existe un paradigma popular de usar matrices N-Dimensionales
. Le permiten escribir código numérico que de otro modo requeriría muchos niveles de bucles anidados en solo unas pocas operaciones simples.
Debido a la capacidad de paralelizar, a menudo se ejecuta incluso más rápido que el bucle estándar . Esta es ahora una práctica estándar en muchos campos, como la ciencia de datos, los gráficos y el aprendizaje profundo, pero puede usarse en aplicaciones mucho más allá de esto.
En Python, la biblioteca estándar para NDArrays se llama NumPy. Sin embargo, no existe una biblioteca estándar equivalente en Java. Una oferta para los desarrolladores de Java interesados en trabajar con NDArrays es AWS Biblioteca Deep Java (DJL).
Aunque también contiene Deep Learning, el núcleo es un poderoso NDArray sistema que se puede utilizar por sí solo para llevar este paradigma a Java. Con soporte para varios marcos de aprendizaje profundo (PyTorch, TensorFlow, MXNet), DJL puede permitir que las operaciones de NDArray se ejecuten a gran escala y en múltiples plataformas.
No importa si está ejecutando en CPU o GPU, PC o Android, simplemente funciona.
En este tutorial, veremos cómo puede aprovechar la NDArray de DJL para escribir su código NumPy en Java y aplicar NDArray en una aplicación del mundo real.
Configuración
Puede usar la siguiente configuración en un proyecto de Gradle. O puede omitir la configuración e intentarlo directamente en nuestro consola online interactiva.
plugins id 'java' repositories jcenter() dependencies implementation "ai.djl:api:0.6.0" // PyTorch runtimeOnly "ai.djl.pytorch:pytorch-engine:0.6.0" runtimeOnly "ai.djl.pytorch:pytorch-native-auto:1.5.0"
Eso es todo, ahora podemos comenzar nuestra implementación.
Operación básica
Primero creemos un bloque try
para crear un alcance para nuestro código (si está utilizando la consola interactiva, puede omitir este paso):
try(NDManager manager = NDManager.newBaseManager())
NDManager ayuda a administrar el uso de memoria del NDArrays. Los crea y ayuda a eliminarlos también. Una vez que termine de usar un NDManager, también borrará todos los NDArrays que se crearon dentro de su alcance.
NDManager ayuda al sistema en general a utilizar la memoria de manera eficiente mediante el seguimiento del uso de NDArray.
A modo de comparación, veamos cómo se ve el código en NumPy de Python también. Comenzaremos importando la biblioteca NumPy con el alias estándar.
import NumPy as np
En las siguientes secciones, vamos a comparar la implementación y el resultado entre NumPy y NDArray de DJL.
Creación de NDArray
Ones
es una operación para generar una matriz N-dim
rellena con 1
.
NumPy
nd = np.ones((2, 3)) ``` [[1. 1. 1.] [1. 1. 1.]] ```
NDArray
NDArray nd = manager.ones(new Shape(2, 3)); /* ND: (2, 3) cpu() float32 [[1., 1., 1.], [1., 1., 1.], ] */
También puede probar la generación aleatoria. Por ejemplo, generaremos datos uniformes aleatorios de 0
a 1
.
NumPy
nd = np.random.uniform(0, 1, (1, 1, 4)) # [[[0.7034806 0.85115891 0.63903668 0.39386125]]]
NDArray
NDArray nd = manager.randomUniform(0, 1, new Shape(1, 1, 4)); /* ND: (1, 1, 4) cpu() float32 [[[0.932 , 0.7686, 0.2031, 0.7468], ], ] */
Esta es solo una demostración rápida de algunas funciones de uso común. El NDManager ahora ofrece más de 20 métodos de creación de NDArray que cubren la mayoría de los métodos disponibles en NumPy.
Operación matemática
También podemos probar algunas operaciones matemáticas usando NDArrays. Supongamos que estamos tratando de hacer una transponer y agregue un número a cada elemento del NDArray. Podemos lograr esto haciendo lo siguiente:
NumPy
nd = np.arange(1, 10).reshape(3, 3) nd = nd.transpose() nd = nd + 10 ``` [[11 14 17] [12 15 18] [13 16 19]] ```
NDArray
NDArray nd = manager.arange(1, 10).reshape(3, 3); nd = nd.transpose(); nd = nd.add(10); /* ND: (3, 3) cpu() int32 [[11, 14, 17], [12, 15, 18], [13, 16, 19], ] */
DJL ahora admite más de 60 métodos matemáticos diferentes de NumPy cubriendo la mayoría de las funciones matemáticas básicas y avanzadas.
Obtener y configurar
Una de las características más poderosas de NDArray es su indexación de datos flexible inspirada en una característica similar en NumPy.
Supongamos que nos gustaría filtrar todos los valores en una matriz que son menores que 10
.
NumPy
nd = np.arange(5, 14) nd = nd[nd >= 10] # [10 11 12 13]
NDArray:
NDArray nd = manager.arange(5, 14); nd = nd.get(nd.gte(10)); /* ND: (4) cpu() int32 [10, 11, 12, 13] */
Ahora intentemos hacer algo más complicado. Suponga que tenemos una matriz de 3x3
y nos gustaría multiplicar la segunda columna por 2
.
NumPy
nd = np.arange(1, 10).reshape(3, 3) nd[:, 1] *= 2 ``` [[ 1 4 3] [ 4 10 6] [ 7 16 9]] ```
NDArray
NDArray nd = manager.arange(1, 10).reshape(3, 3); nd.set(new NDIndex(":, 1"), array -> array.mul(2)); /* ND: (3, 3) cpu() int32 [[ 1, 4, 3], [ 4, 10, 6], [ 7, 16, 9], ] */
En el ejemplo anterior, presentamos un concepto en Java llamado NDIndex. Refleja la mayoría de las funcionalidades get / set
de NDArray que admite NumPy.
Simplemente pasando una representación de cadena, los desarrolladores pueden realizar todo tipo de manipulaciones de matrices sin problemas en Java.
Aplicación al mundo real
Estas operaciones son realmente útiles cuando necesitamos manipular un gran conjunto de datos. Repasemos un caso de uso específico: Clasificación de tokens.
En este caso, los desarrolladores intentaban realizar un análisis de opinión sobre la información de texto que recopilaron de los usuarios mediante la aplicación de un algoritmo de aprendizaje profundo.
Las operaciones de NDArray se aplicaron en el preprocesamiento y posprocesamiento para codificar y decodificar información.
Tokenización
Antes de introducir los datos en un NDArray, convertimos el texto de entrada en números. los tokenizer
en el bloque de código a continuación hay un Map<String, Integer>
que sirve como vocabulario para convertir texto en un vector correspondiente.
String text = "The rabbit cross the street and kick the fox"; String[] tokens = text.toLowerCase().split(" "); int[] vector = new int[tokens.length]; /* String[9] "the", "rabbit", "cross", "the", "street", "and", "kick", "the", "fox" */ for (int i = 0; i < tokens.length; i++) vector[i] = tokenizer.get(tokens[i]); vector /* int[9] 1, 6, 5, 1, 3, 2, 8, 1, 12 */
Procesando
Después de eso, creamos un NDArray
. Para continuar, necesitamos crear un lote de tokens y aplicarles algunas transformaciones.
NDArray array = manager.create(vector); array = array.reshape(new Shape(vector.length, 1)); // form a batch array = array.div(10.0); /* ND: (9, 1) cpu() float64 [[0.1], [0.6], [0.5], [0.1], [0.3], [0.2], [0.8], [0.1], [1.2], ] */
Luego, podemos enviar estos datos a un modelo de aprendizaje profundo. Para lograr lo mismo en Java puro, se requeriría mucho más trabajo.
Si estamos tratando de implementar la función de remodelación anterior, necesitamos crear una matriz N-dimensional
en Java que se vea así: List<List<List<...List<Float>...>>>
para cubrir todas las diferentes dimensiones.
Entonces tendríamos que insertar dinámicamente un nuevo List<Float>
que contiene los elementos para construir la estructura de datos resultante.
¿Por qué debería usar NDArray?
Con el tutorial anterior, debería tener una experiencia básica con NDArray en Java. Para resumir, estas son las tres ventajas clave de su uso:
- Fácil: acceso a más de
60
operadores en Java con una entrada simple y la misma salida. - Rápido: soporte completo para los marcos de aprendizaje profundo más utilizados, incluidos TensorFlow, PyTorch y MXNet. Ahora, puede acelerar su cálculo con MKLDNN en CPU, CUDA en GPU y mucho más.
- Preparado para aprendizaje profundo: admite matrices de alta dimensión y entradas dispersas de NDArray *. Puede aplicar este kit de herramientas en todas las plataformas, incluidas Apache Spark y Apache Beam, para el procesamiento de datos a gran escala. Es una herramienta perfecta para el preprocesamiento y posprocesamiento de datos.
* Sparse actualmente solo cubre COO en PyTorch y CSR / Row_Sparse
en MXNet.
Acerca de NDArray y DJL
Después de probar la creación y operación de NDArray, es posible que se pregunte cómo DJL implementa NDArray para lograr estos comportamientos. En esta sección, veremos brevemente la arquitectura de NDArray.
Arquitectura NDArray
Como se muestra arriba, hay tres capas clave para el NDArray.
La capa de interfaz contiene NDArray, es una interfaz Java que define cómo debería verse el NDArray. Lo evaluamos cuidadosamente e hicimos que la firma de todas las funciones fuera lo suficientemente general y fácil de usar.
En la capa EngineProvider, hay una implementación de motor diferente a la de NDArray. Esta capa sirvió como capa de interpretación que asigna el comportamiento específico del motor al comportamiento de NumPy.
Como resultado, todas las implementaciones de motores se comportan de la misma manera que NumPy.
En la capa C ++
, construimos JNI y JNA que exponen los métodos C ++
para que Java los llame. Aseguraría que tengamos suficientes métodos para construir toda la pila NDArray.
También asegura el mejor rendimiento llamando directamente desde Java a C ++
ya que todos los motores están implementados en C / C ++
.
Sobre DJL
Biblioteca Deep Java (DJL) es un marco de aprendizaje profundo escrito en Java, que admite tanto la formación como la inferencia. DJL está construido sobre los marcos modernos de Deep Learning (TenserFlow, PyTorch, MXNet, etc.).
Puede usar DJL fácilmente para entrenar su modelo o implementar sus modelos favoritos desde una variedad de motores sin ninguna conversión adicional.
Contiene un poderoso diseño ModelZoo que le permite administrar modelos entrenados y cargarlos en una sola línea. El ModelZoo integrado admite actualmente más de 70 modelos pre-entrenados
y listos para usar de GluonCV, HuggingFace, TorchHub y Keras.
La adición de NDArray convierte a DJL en el mejor kit de herramientas en Java para ejecutar su aplicación de aprendizaje profundo. Puede identificar automáticamente la plataforma en la que se está ejecutando y determinar si debe aprovechar la GPU para ejecutar su aplicación.
Desde la versión más reciente, DJL 0.6.0 es compatible oficialmente con MXNet 1.7.0, PyTorch 1.5.0 y TensorFlow 2.2.0. También tenemos soporte experimental para PyTorch en Android.
Gracias por leer este tutorial.
Añadir comentario