ai-center
2024.10
true
UiPath logo, featuring letters U and I in white

Guía del usuario de AI Center

Automation CloudAutomation SuiteStandalone
Última actualización 11 de nov. de 2024

Cargar archivo

Creación de paquetes ML

Los científicos de datos construyen modelos preentrenados utilizando Python o utilizando una plataforma AutoML. Los desarrolladores de RPA son los que consumirán estos modelos dentro de un flujo de trabajo.

Estructurar paquetes ML

Un paquete debe cumplir con un pequeño conjunto de requisitos. Estos requisitos se dividen entre los componentes necesarios para servir un modelo y los componentes necesarios para entrenar un modelo.

Servicio de componentes

Un paquete debe proporcionar al menos lo siguiente:
  • Una carpeta que contenga un archivo main.py en la raíz de esta carpeta.
  • En este archivo, una clase llamada Main que implemente al menos dos funciones:
    • __init__(self): no tiene argumento y carga tu modelo y los datos locales para el modelo (por ejemplo, inserción de palabras).
    • predict(self, input): una función a la que se llamará en el momento del servicio del modelo y que devuelve una cadena.
  • Un archivo denominado requirements.txt con las dependencias necesarias para ejecutar el modelo.
Piensa en el componente de servicio de un paquete como el modelo en el momento de la inferencia. En el momento del servicio, se crea una imagen de contenedor, utilizando el archivo requirements.txt, y la función predict se usa como punto final al modelo.

Componente de entrenamiento y evaluación

Además de la inferencia, un paquete puede utilizarse de forma opcional para entrenar un modelo de aprendizaje automático. Esta tarea se lleva a cabo proporcionando lo siguiente:
  • En la misma carpeta raíz con el archivo main.py, proporciona un archivo denominado train.py.
  • En este archivo, establece una clase llamada Main que implemente al menos cuatro funciones. Todas las siguientes funciones excepto _init_, son opcionales, pero limitan el tipo de procesos que pueden ejecutarse con el paquete correspondiente.
    • __init__(self): no tiene argumento y carga tu modelo y los datos para el modelo (por ejemplo, inserción de palabras).
    • train(self, training_directory): toma como input un directorio con datos estructurados de forma arbitraria; ejecuta todo el código necesario para entrenar un modelo. Esta función se llama cuando se ejecuta un proceso de entrenamiento.
    • evaluate(self, evaluation_directory): toma como input un directorio con datos estructurados de forma arbitraria; ejecuta todo el código necesario para evaluar un modo y devuelve una única puntuación para esa evaluación. Esta función se llama cuando se ejecuta un proceso de evaluación.
    • save(self): no tiene argumento. Esta función se llama después de cada llamada de la función train para mantener tu modelo.
    • process_data(self, input_directory): toma un input input_directory con datos estructurados de forma arbitraria. Esta función solo se llama cuando se ejecuta un proceso completo. En la ejecución de un proceso completo, esta función puede realizar transformaciones de datos arbitrarias y puede dividir datos. En concreto, cualquier dato guardado en la ruta a la que apunta la variable de entorno training_data_directory es el input a la función train, y cualquier dato guardado en la ruta a la que apunta la variable de entorno evaluation_data_directory es el input a la función evaluation anterior.

Gestión de tipos de datos

Para que UiPath® AI Center sea más fácil de usar dentro de un flujo de trabajo RPA, el paquete puede indicarse para que tenga uno de los tres tipos de entrada: Cadena, Archivo y Archivos (establecidos durante el tiempo de carga del paquete).

Datos de String

Esta es una secuencia de caracteres. Cualquier dato que pueda ser serializado puede utilizarse con un paquete. Si se utilizan dentro de un flujo de trabajo de RPA, los datos pueden ser serializados por el UiPath Robot (por ejemplo, utilizando una actividad personalizada) y enviados como una cadena. El cargador de paquetes debe haber seleccionado JSON como tipo de input del paquete.
La deserialización de los datos se realiza en la función predict. A continuación se muestran varios ejemplos útiles para deserializar los datos en Python:
Robot sends raw string to ML Skill Activity
# E.g. skill_input='a customer complaint'`
def predict(self, skill_input):
  example = skill_input  # No extra processing
    
# Robot sends json formatted string to ML Skill Activity
# E.g skill_input='{'email': a customer complaint', 'date': 'mm:dd:yy'}'
def predict(self, skill_input):
  import json
  example = json.loads(skill_input)
  
# Robot sends json formatted string with number array to ML Skill Activity
# E.g. skill_input='[10, 15, 20]'
def predict(self, skill_input):
  import json
  import numpy as np
  example = np.array(json.loads(skill_input))
  
# Robot sends json formmatted pandas dataframe
# E.g. skill_input='{"row 1":{"col 1":"a","col 2":"b"},
#                    "row 2":{"col 1":"c","col 2":"d"}}'
def predict(self, skill_input):
  import pandas as pd
  example = pd.read_json(skill_input)Robot sends raw string to ML Skill Activity
# E.g. skill_input='a customer complaint'`
def predict(self, skill_input):
  example = skill_input  # No extra processing
    
# Robot sends json formatted string to ML Skill Activity
# E.g skill_input='{'email': a customer complaint', 'date': 'mm:dd:yy'}'
def predict(self, skill_input):
  import json
  example = json.loads(skill_input)
  
# Robot sends json formatted string with number array to ML Skill Activity
# E.g. skill_input='[10, 15, 20]'
def predict(self, skill_input):
  import json
  import numpy as np
  example = np.array(json.loads(skill_input))
  
# Robot sends json formmatted pandas dataframe
# E.g. skill_input='{"row 1":{"col 1":"a","col 2":"b"},
#                    "row 2":{"col 1":"c","col 2":"d"}}'
def predict(self, skill_input):
  import pandas as pd
  example = pd.read_json(skill_input)

Datos de File

Esto informa a la actividad de la habilidad ML que realiza llamadas a este modelo que espere una ruta a un archivo. En concreto, la actividad lee el archivo desde el sistema de archivos y lo envía a la función predict como una cadena de bytes serializada. Así, el desarrollador de RPA puede pasar una ruta a un archivo, en lugar de tener que leer y serializar el archivo en el propio flujo de trabajo.
Dentro del flujo de trabajo, el input a la actividad es solo la ruta al archivo. La actividad lee el archivo, lo serializa y envía los bytes del archivo a la función predict. La deserialización de los datos también se realiza en la función predict: el caso general es simplemente leer los bytes directamente en un objeto similar a un archivo de la siguiente manera:
ML Package has been uploaded with *file* as input type. The ML Skill Activity
# expects a file path. Any file type can be passed as input and it will be serialized.
def predict(self, skill_input):
  import io
  file_like = io.BytesIO(skill_input)ML Package has been uploaded with *file* as input type. The ML Skill Activity
# expects a file path. Any file type can be passed as input and it will be serialized.
def predict(self, skill_input):
  import io
  file_like = io.BytesIO(skill_input)

La lectura de los bytes serializados como se ve anteriormente es equivalente a abrir un archivo con la marca binaria de lectura activada. Para probar el modelo localmente, lee un archivo como archivo binario. A continuación, se muestra un ejemplo de lectura de un archivo de imagen y su prueba de forma local:

main.py where model input is an image
class Main(object):
   ...
    
   def predict(self, skill_input): 
      import io
      from PIL import Image
      image = Image.open(io.BytesIO(skill_input))
   ...
  
if__name__ == '_main_':
   # Test the ML Package locally
   with open('./image-to-test-locally.png', 'rb') as input_file:
      file_bytes = input_file.read()
     m = Main()
     print(m.predict(file bytes))main.py where model input is an image
class Main(object):
   ...
    
   def predict(self, skill_input): 
      import io
      from PIL import Image
      image = Image.open(io.BytesIO(skill_input))
   ...
  
if__name__ == '_main_':
   # Test the ML Package locally
   with open('./image-to-test-locally.png', 'rb') as input_file:
      file_bytes = input_file.read()
     m = Main()
     print(m.predict(file bytes))
A continuación, se muestra un ejemplo de lectura de un archivo csv y la utilización de una trama de datos Pandas en la función predict:
main.py where model input is a csv file
class Main(object):
   ...
   def predict(self, skill_input): 
      import pandas as pd
      data frame = pd.read_csv(io.BytesIO(skill_input))
      ...
      
if name == '_main_':
   # Test the ML Package locally
   with open('./csv—to—test—locally.csv', 'rb') as input_file:
      bytes = input_file.read()
   m = Main()
   print(m.predict(bytes))main.py where model input is a csv file
class Main(object):
   ...
   def predict(self, skill_input): 
      import pandas as pd
      data frame = pd.read_csv(io.BytesIO(skill_input))
      ...
      
if name == '_main_':
   # Test the ML Package locally
   with open('./csv—to—test—locally.csv', 'rb') as input_file:
      bytes = input_file.read()
   m = Main()
   print(m.predict(bytes))

Datos de Files

Esto informa a AI Center de que la actividad de la habilidad ML que hace llamadas a este modelo espera una lista de rutas de archivos. Como en el caso anterior, la actividad lee y serializa cada archivo, además de enviar una lista de cadenas de bytes a la función predict.

Puede enviarse una lista de archivos a una habilidad. Dentro del flujo de trabajo, el input a la actividad es una cadena con rutas a los archivos, separadas por una coma.

Al cargar un paquete, el científico de datos selecciona la lista de archivos como tipo de input. A continuación, el científico de datos debe deserializar cada uno de los archivos enviados (como se explica anteriormente). El input de la función predict es una lista de bytes en los que cada elemento de la lista es la cadena de bytes del archivo.

Datos arbitrarios persistentes

En train.py, cualquier proceso ejecutado puede generar datos arbitrarios, llamados output del proceso. Cualquier dato que se escriba en la ruta del directorio desde los artefactos de la variable de entorno persiste y puede emerger en cualquier momento yendo a la página Detalles del proceso. Normalmente, cualquier tipo de gráfico, estadísticas de los trabajos de entrenamiento/evaluación, puede guardarse en el directorio artifacts y se puede acceder a ello desde la IU al final de la ejecución del proceso.
train.py where some historical plot are saved in ./artifacts directory during Full Pipeline execution
# Full pipeline (using process_data) will automatically split data.csv in 2/3 train.csv (which will be in the directory passed to the train function) and 1/3 test.csv
import pandas as pd
from sklearn.model_selection import train_test_split
class Main(object):
   ...
   def process_data(self, data_directory):
     d = pd.read_csv(os.path.join(data_directory, 'data.csv')) 
     d = self.clean_data(d)
     d_train, d_test = train_test_split(d, test_size=0.33, random_state=42)
     d_train.to_csv(os.path.join(data_directory , 'training', 'train.csv'), index=False)
     d_test.to_csv (os.path.join(data__directory , 'test' , 'test.csv'), index=False)
     self.save_artifacts(d_train, 'train_hist.png', os.environ["artifacts"])
     self.save_artifacts(d_test, 'test_hist.png', os.environ["artifacts"])
  ...
  
   def save_artifacts(self, data, file_name, artifact_directory):
      plot = data.hist() 
      fig = plot[0][0].get_figure()
      fig.savefig(os.path.join(artifact_directory, file_name))
...train.py where some historical plot are saved in ./artifacts directory during Full Pipeline execution
# Full pipeline (using process_data) will automatically split data.csv in 2/3 train.csv (which will be in the directory passed to the train function) and 1/3 test.csv
import pandas as pd
from sklearn.model_selection import train_test_split
class Main(object):
   ...
   def process_data(self, data_directory):
     d = pd.read_csv(os.path.join(data_directory, 'data.csv')) 
     d = self.clean_data(d)
     d_train, d_test = train_test_split(d, test_size=0.33, random_state=42)
     d_train.to_csv(os.path.join(data_directory , 'training', 'train.csv'), index=False)
     d_test.to_csv (os.path.join(data__directory , 'test' , 'test.csv'), index=False)
     self.save_artifacts(d_train, 'train_hist.png', os.environ["artifacts"])
     self.save_artifacts(d_test, 'test_hist.png', os.environ["artifacts"])
  ...
  
   def save_artifacts(self, data, file_name, artifact_directory):
      plot = data.hist() 
      fig = plot[0][0].get_figure()
      fig.savefig(os.path.join(artifact_directory, file_name))
...

Utilizando TensorFlow

Durante el desarrollo del modelo, el gráfico de TensorFlow debe cargarse en el mismo hilo que se utilizó para el servicio. Para ello, debe utilizarse el gráfico predeterminado.

A continuación se muestra un ejemplo con las modificaciones necesarias:

import tensorflow as tf
class Main(object):
  def __init__(self):
    self.graph = tf.get_default_graph() # Add this line
    ...
    
  def predict(self, skill_input):
    with self.graph.as_default():
      ...import tensorflow as tf
class Main(object):
  def __init__(self):
    self.graph = tf.get_default_graph() # Add this line
    ...
    
  def predict(self, skill_input):
    with self.graph.as_default():
      ...

Información sobre el uso de la GPU

Cuando la GPU se habilita en el momento de la creación de la habilidad, se implementa en una imagen con el controlador de GPU NVIDIA 418, CUDA Toolkit 10.0 y la biblioteca de runtime CUDA Deep Neural Network Library (cuDNN) 7.6.5.

Ejemplos

Modelo ML simple listo para servir sin entrenamiento

En este ejemplo, el problema de la empresa no requiere reentrenamiento de modelos, por lo que el paquete debe contener el modelo IrisClassifier.sav serializado que se servirá.
  1. Árbol de proyecto inicial (sin main.py y requirements.txt):
    IrisClassifier/
      - IrisClassifier.savIrisClassifier/
      - IrisClassifier.sav
  2. main.py de muestra que se añadirá a la carpeta raíz:
    from sklearn.externals import joblib 
    import json
    class Main(object):
       def __init__(self):
          self.model = joblib.load('IrisClassifier.sav')
       def predict(self, X):
          X = json.loads(X)
          result = self.model.predict_proba(X)
          return json.dumps(result.tolist())from sklearn.externals import joblib 
    import json
    class Main(object):
       def __init__(self):
          self.model = joblib.load('IrisClassifier.sav')
       def predict(self, X):
          X = json.loads(X)
          result = self.model.predict_proba(X)
          return json.dumps(result.tolist())
  3. Añade requirements.txt:
    scikit-learn==0.19.0scikit-learn==0.19.0
Nota: hay algunas restricciones que deben respetarse en las bibliotecas pip. Asegúrese de que puede instalar bibliotecas con los siguientes archivos de restricción:
itsdangerous<2.1.0
Jinja2<3.0.5
Werkzeug<2.1.0
click<8.0.0itsdangerous<2.1.0
Jinja2<3.0.5
Werkzeug<2.1.0
click<8.0.0

Para probar esto, puedes usar el siguiente comando en un entorno nuevo y asegurarte de que todas las bibliotecas se están instalando correctamente:

pip install -r requirements.txt -c constraints.txtpip install -r requirements.txt -c constraints.txt

4. Estructura final de carpetas:

IrisClassifier/
  - IrisClassifier.sav
  - main.py
  - requirements.txtIrisClassifier/
  - IrisClassifier.sav
  - main.py
  - requirements.txt

Modelo simple listo para servir con entrenamiento habilitado

En este ejemplo, el problema de la empresa requiere que el modelo se reentrene. Al desarrollar sobre el paquete descrito anteriormente, es posible que experimentes lo siguiente:

  1. Árbol de proyecto inicial (paquete solo de servicio):
    IrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txtIrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txt
  2. train.py de muestra para añadir a la carpeta raíz:
    import pandas as pd 
    import joblib
    class Main(object): 
       def __init__(self):
           self.model_path = './IrisClassifier.sav' 
           self.model = joblib.load(self.model_path)
          
       def train(self, training_directory):
           (X,y) = self.load_data(os.path.join(training_directory, 'train.csv'))
           self.model.fit(X,y)
       def evaluate(self, evaluation_directory):
           (X,y) = self.load_data(os.path.join(evaluation_directory, 'evaluate.csv'))
           return self.model.score(X,y)
       def save(self):
           joblib.dump(self.model, self.model_path)
       def load_data(self, path):
           # The last column in csv file is the target column for prediction.
           df = pd.read_csv(path)
           X = df.iloc[:, :-1].get_values()
           y = df.iloc[:, 'y'].get_values()
           return X,yimport pandas as pd 
    import joblib
    class Main(object): 
       def __init__(self):
           self.model_path = './IrisClassifier.sav' 
           self.model = joblib.load(self.model_path)
          
       def train(self, training_directory):
           (X,y) = self.load_data(os.path.join(training_directory, 'train.csv'))
           self.model.fit(X,y)
       def evaluate(self, evaluation_directory):
           (X,y) = self.load_data(os.path.join(evaluation_directory, 'evaluate.csv'))
           return self.model.score(X,y)
       def save(self):
           joblib.dump(self.model, self.model_path)
       def load_data(self, path):
           # The last column in csv file is the target column for prediction.
           df = pd.read_csv(path)
           X = df.iloc[:, :-1].get_values()
           y = df.iloc[:, 'y'].get_values()
           return X,y
  3. Edita requirements.txt si es necesario:
    pandas==1.0.1
    scikit-learn==0.19.0pandas==1.0.1
    scikit-learn==0.19.0
  4. Estructura de carpeta final (paquete):
    IrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txt
      - train.pyIrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txt
      - train.py
    Aviso: Este modelo ahora puede servirse primero y, conforme van entrando al sistema nuevos puntos de datos a través del UiPath Robot o "persona en el ciclo", los procesos de entrenamiento y de evaluación pueden crearse aprovechando train.py.

Cargar archivo zip

Importante:

Antes de cargar paquetes, asegúrate de que se crean como se especifica aquí.

Al crear un paquete ML en AI Center, no se puede nombrar utilizando ninguna palabra clave reservada de Python, como class, break, from, finally, global, None, etc. Asegúrate de elegir otro nombre. Los ejemplos enumerados no están completos, ya que el nombre del paquete se utiliza para class <pkg-name> y import <pck-name>.

Sigue estos pasos para cargar un paquete ya creado:

  1. En la página Paquetes ML, haz clic en el botón Cargar archivo zip. Se mostrará así la página Crear nuevo paquete.
  2. En la página Crear nuevo paquete, escribe un nombre para tu paquete.
  3. Haz clic en Cargar paquete para seleccionar el archivo .zip deseado o arrastra y suelta el archivo .zip del paquete en el campo Cargar paquete.
  4. (Opcional) Proporciona una descripción clara del modelo.

    La descripción se mostrará al implementar una nueva habilidad basada en este modelo, así como en la página Paquetes ML.

  5. Selecciona el tipo de input en el menú desplegable. Las opciones son:
    • JSON
    • .xml
    • .csv
  6. Opcional: Escribe una descripción clara de la entrada esperada por el modelo.
  7. Opcional: Escribe una descripción clara del output mostrado por el modelo.
    Estas descripciones son visibles para los desarrolladores de RPA que utilicen la actividad de la habilidad ML en UiPath Studio. Como buena práctica, se recomienda mostrar un ejemplo de los formatos de input y output para facilitar la comunicación entre los científicos de datos y los desarrolladores.
  8. Selecciona el lenguaje del desarrollo del modelo en el menú desplegable. Las opciones son:
    • Python 3.7
    • Python 3.8
    • Python 3.8 OpenCV
  9. Selecciona si el modelo de aprendizaje automático requiere una GPU (de forma predeterminada se establece en No). Esta información emerge como sugerencia cuando se crea una habilidad a partir de este paquete.
  10. Selecciona si habilitas el entrenamiento para tu modelo. Esto es lo que sucede si lo habilitas:
    • El paquete puede utilizarse en cualquier proceso.
    • El paso de validación comprueba si el archivo train.py se implementa en el paquete; de lo contrario, la validación falla.
  11. Haz clic en Crear para cargar el paquete o en Cancelar para abortar el proceso. Se cerrará la ventana Crear nuevo paquete y el paquete se cargará y mostrará junto con sus detalles en la página Paquetes ML > [Nombre del paquete ML]. Puede tardar unos minutos antes de que tu carga se propague.

¿Te ha resultado útil esta página?

Obtén la ayuda que necesitas
RPA para el aprendizaje - Cursos de automatización
Foro de la comunidad UiPath
Uipath Logo White
Confianza y seguridad
© 2005-2024 UiPath. Todos los derechos reservados.