AI Center
Plus récente (Latest)
False
Image de fond de la bannière
AI Center
Dernière mise à jour 18 avr. 2024

Télécharger le fichier

Construire des paquets ML

Les data scientists créent des modèles pré-entraînés à l’aide de Python ou d’une plate-forme AutoML. Ces modèles sont utilisés par les développeurs RPA dans un workflow.

Structurer les paquets ML

Tout package doit respecter un petit ensemble d'exigences. Ces exigences sont divisées entre les composants nécessaires pour servir un modèle et les composants nécessaires pour entraîner un modèle.

Composant de service

Un package doit fournir au moins les éléments suivants :
  • Un dossier contenant un fichier main.py à la racine de ce dossier.
  • Dans ce fichier, une classe appelée Main implémente au moins deux fonctions :
    • __init__(self) : ne prend aucun argument et charge votre modèle et/ou les données locales du modèle (par exemple intégrations de mots).
    • predict(self, input) : une fonction à appeler au moment de la diffusion du modèle et qui renvoie une valeur String.
  • Un fichier nommé requirements.txt avec les dépendances nécessaires pour exécuter le modèle.
Considérez le composant de service d'un package comme le modèle au moment de l'inférence. Au moment du service, une image de conteneur est créée à l'aide du fichier requirements.txt fourni, et la fonction predict est utilisée comme point de terminaison du modèle.

Composant d'entraînement et d'évaluation

Outre l'inférence, un package peut éventuellement être utilisé pour entraîner un modèle d'apprentissage automatique. Cela s'effectue en fournissant les éléments suivants :
  • Dans le même dossier racine que le fichier main.py, fournissez un fichier nommé train.py.
  • Dans ce fichier, fournissez une classe appelée Main qui implémente au moins deux fonctions : Toutes les fonctions ci-dessous, à l'exception de _init_, sont facultatives, mais limitent le type de pipelines pouvant être exécutés avec le package correspondant.
    • __init__(self) : ne prend aucun argument et charge votre modèle et/ou les données du modèle (par exemple intégrations de mots).
    • train(self, training_directory) : prend en tant qu'entrée un répertoire avec des données arbitrairement structurées, et exécute tout le code nécessaire pour entraîner un modèle. Cette fonction est appelée chaque fois qu'un pipeline d'entraînement est exécuté.
    • c. evaluate(self, evaluation_directory) : prend en tant qu'entrée un répertoire avec des données arbitrairement structurées, exécute tout le code nécessaire pour évaluer un mode, et renvoie un score unique pour cette évaluation. Cette fonction est appelée chaque fois qu'un pipeline d'évaluation est exécuté.
    • save(self) : ne prend aucun argument. Cette fonction est appelée après chaque appel de la fonction train pour conserver votre modèle.
    • process_data(self, input_directory) : prend une entrée input_directory avec des données arbitrairement structurées. Cette fonction n'est appelée que lorsqu'un pipeline complet est exécuté. Dans l'exécution d'un pipeline complet, cette fonction peut effectuer des transformations de données arbitraires et peut fractionner les données. Plus précisément, toutes les données enregistrées dans le chemin indiqué par la variable d'environnement training_data_directory seront l'entrée de la fonction train, et toutes les données enregistrées dans le chemin indiqué par la variable d'environnement evaluation_data_directory seront l'entrée de la fonction evaluation ci-dessus.

Gérer les types de données

Pour faciliter l'utilisation d'AI Center dans un workflow RPA, le package peut être défini comme ayant l'un de ces trois types d'entrées : Chaîne (String), Fichier (File) et Fichiers (Files) (défini au moment du téléchargement du package).

Données de la chaîne

Il s'agit d'une séquence de caractères. Toutes les données pouvant être sérialisées peuvent être utilisées avec un package. Si elles sont utilisées dans un workflow RPA, les données peuvent être sérialisées par le Robot (par exemple à l'aide d'une activité personnalisée) et envoyées sous forme de chaîne. Le téléchargeur du package doit avoir sélectionné JSON comme type d'entrée du package.
La désérialisation des données se fait dans la fonction predict. Vous trouverez ci-dessous quelques exemples de désérialisation de données 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)

Données du fichier

Cela indique à l'activité de compétence ML effectuant des appels vers ce modèle de s'attendre à un chemin d'accès vers un fichier. Plus précisément, l'activité lit le fichier à partir du système de fichiers et l'envoie à la fonction predict sous la forme d'une chaîne d'octets sérialisée. Ainsi, le RPA Developer peut définir un chemin d'accès vers un fichier, au lieu d'avoir à lire et à sérialiser le fichier dans le workflow même.
Dans le workflow, l'entrée de l'activité sera simplement le chemin d'accès au fichier. L'activité lit le fichier, le sérialise et envoie les octets du fichier à la fonction predict. La désérialisation des données se fait également dans la fonction predict, le cas général consistant simplement à lire les octets directement dans un objet de type fichier tel que ci-dessous :
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)

Lire les octets sérialisés comme ci-dessus équivaut à ouvrir un fichier en activant l'indicateur de lecture binaire. Pour tester le modèle localement, lisez un fichier en tant que fichier binaire. Voici un exemple de lecture d'un fichier image et de test local de ce fichier :

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))
Ce qui suit est un exemple de lecture d'un fichier csv et d'utilisation d'un cadre de données pandas dans la fonction 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))

Données du fichier

Cela informe AI Center que l'activité de Compétence ML effectuant des appels vers ce modèle attend une liste de chemins de fichiers. Comme dans le cas précédent, l'activité lit et sérialise chaque fichier, puis envoie une liste de chaînes d'octets à la fonction predict.

Une liste de fichiers peut être envoyée à une compétence. Dans le workflow, l'entrée de l'activité est une chaîne avec des chemins d'accès aux fichiers séparés par une virgule.

Lors du téléchargement d'un package, le scientifique des données sélectionne une liste de fichiers comme type d'entrées. Le scientifique des données doit alors désérialiser chacun des fichiers envoyés (comme expliqué ci-dessus). L'entrée de la fonction predict est une liste d'octets dans laquelle chaque élément est la chaîne d'octets du fichier.

Données arbitraires persistantes

Dans train.py, tout pipeline exécuté peut conserver des données arbitraires appelées sortie de pipeline. Toutes les données écrites dans le chemin du répertoire à partir d'artefacts de variables d'environnement sont conservées et peuvent être affichées à tout moment en accédant à la Page Détails du Pipeline. En règle générale, tout type de graphique et de statistique des tâches d'entraînement/évaluation peut être enregistré dans le répertoire artifacts et est accessible depuis l'interface utilisateur à la fin de l'exécution du pipeline.
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))
...

Utilisation de TensorFlow

Lors du développement du modèle, le graphique TensorFlow doit être chargé sur le même thread que celui utilisé pour le service. Pour ce faire, le graphique par défaut doit être utilisé.

Voici un exemple incorporant les modifications nécessaires :

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():
      ...

Informations sur l'utilisation du GPU

Lorsque le GPU est activé au moment de la création de la compétence, il est déployé sur une image avec le pilote NVIDIA GPU 418, CUDA Toolkit 10.0 et la bibliothèque d'exécution CUDA Deep Neural Network Library (cuDNN) 7.6.5.

Exemples

Modèle de ML simple et prêt à l'emploi sans entraînement

Dans cet exemple, le problème métier ne nécessite pas de réentraînement du modèle ; le package doit donc contenir le modèle sérialisé IrisClassifier.sav qui sera servi.
  1. Arborescence initiale du projet (sans main.py et requirements.txt) :
    IrisClassifier/
      - IrisClassifier.savIrisClassifier/
      - IrisClassifier.sav
  2. Exemple de main.py à ajouter au dossier racine :
    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. Ajouter requirements.txt :
    scikit-learn==0.19.0scikit-learn==0.19.0
Remarque : certaines contraintes doivent être respectées sur les bibliothèques pip. Assurez-vous que vous pouvez installer les bibliothèques sous les fichiers de contraintes suivants :
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

Pour tester cela, vous pouvez utiliser la commande suivante dans un nouvel environnement et vous assurer que toutes les bibliothèques s'installent correctement :

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

4. Structure finale des dossiers :

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

Modèle simple et prêt à l'emploi avec entraînement activé

Dans cet exemple, le problème métier nécessite un réentraînement du modèle. En s'appuyant sur le package décrit ci-dessus, vous pouvez disposer des éléments suivants :

  1. Arborescence du projet initial (package de service uniquement) :
    IrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txtIrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txt
  2. Exemple de train.py à ajouter au dossier racine :
    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. Modifiez le fichier requirements.txt si nécessaire :
    pandas==1.0.1
    scikit-learn==0.19.0pandas==1.0.1
    scikit-learn==0.19.0
  4. Structure du dossier final (package) :
    IrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txt
      - train.pyIrisClassifier/
      - IrisClassifier.sav
      - main.py
      - requirements.txt
      - train.py
    Remarque : ce modèle peut désormais être servi en premier et, à mesure que de nouveaux points de données entrent dans le système via Robot ou Human-in-the-Loop, des pipelines d'entraînement et d'évaluation peuvent être créés grâce à train.py.

Charger le fichier zip

Important :
Lors de la création d'un paquet ML dans AI Center™, il ne peut pas être nommé à l'aide d'un mot clé réservé python, tel que class , break , from , finally , global , None , etc. Assurez-vous pour choisir un autre nom. Les exemples répertoriés ne sont pas complets car le nom du package est utilisé pour class <pkg-name> et import <pck-name>.

Suivez ces étapes pour télécharger un package déjà créé :

  1. Sur la page Paquets ML (Packages), cliquez sur le bouton Télécharger le fichier zip (Upload zip file). La page Créer un nouveau package (Create New Package) s'affiche.
  2. Dans la page Créer un nouveau package, saisissez un nom pour votre package.
  3. Cliquez sur Télécharger le package (Upload Package) pour sélectionner le .zip souhaité ou faites glisser et déposez le fichier .zip dans le champ Télécharger le package (Upload package).
  4. Facultatif : fournissez une description claire du modèle.

    La description s'affiche lors du déploiement d'une nouvelle compétence basée sur ce modèle, ainsi que sur la page Paquets ML (ML Packages).

  5. Sélectionnez le type d’entrée dans le menu déroulant. Les options possibles sont :
    • json
    • Fichier
    • Files
  6. Facultatif : saisissez une description claire de l'entrée attendue par le modèle.
  7. Facultatif : saisissez une description claire de la sortie renvoyée par le modèle.
    Ces descriptions sont visibles pour les développeurs RPA utilisant l'activité Compétence ML (ML Skill) dans UiPath Studio. Comme bonne pratique, nous avons recommandé de montrer un exemple des formats d'entrée et de sortie pour faciliter la communication entre les scientifiques des données et les développeurs.
  8. Sélectionnez le langage de développement du modèle dans la liste déroulante. Les options possibles sont :
    • Python 3.7
    • Python 3.8
    • Python 3.8 OpenCV
    • Python 3.9
  9. Sélectionnez si le modèle d'apprentissage automatique nécessite un GPU ; par défaut, il est défini sur No. Ces informations sont présentées comme une suggestion lorsqu'une compétence est créée à partir de ce package.
  10. Sélectionnez si vous souhaitez activer l'entraînement pour votre modèle. Voici ce qui se passe si vous l'activez :
    • Le package peut être utilisé dans n’importe quel pipeline.
    • L'étape de validation vérifie si le fichier train.py est implémenté dans le package, sinon, la validation échoue.


  11. Cliquez sur Créer (Create) pour télécharger le package ou sur Annuler (Cancel) pour abandonner le processus. La fenêtre Créer un nouveau package (Create New Package) se ferme et le package est téléchargé et affiché avec ses détails sur la page Packages ML > [Nom du paquet ML] (ML Packages > [ML Package Name]). La propagation de votre téléchargement peut prendre quelques minutes.


Remarque : pour plus d'informations sur la validation des packages, le contrôle de version et les détails, consultez la section Gestion des paquets ML.

Cette page vous a-t-elle été utile ?

Obtenez l'aide dont vous avez besoin
Formation RPA - Cours d'automatisation
Forum de la communauté UiPath
Logo Uipath blanc
Confiance et sécurité
© 2005-2024 UiPath. All rights reserved.