- Versionshinweise
- Bevor Sie beginnen
- Erste Schritte
- Projekte
- Datasets
- ML-Pakete
- Pipelines
- ML-Skills
- ML-Protokolle
- Document Understanding im AI Center
- Lizenzierung
- Anleitungen zu …
- Grundlegende Anleitung zur Fehlerbehebung
Die Data Scientists erstellen vortrainierte Modelle mit Python oder einer AutoML-Plattform. Diese Modelle werden von RPA-Entwicklern innerhalb eines Workflows verwendet.
ML-Pakete strukturieren
Ein Paket muss ein paar Voraussetzungen erfüllen. Diese Voraussetzungen werden in Komponenten unterteilt, die für die Ausgabe eines Modells erforderlich sind, und Komponenten, die für das Training eines Modells erforderlich sind.
Ausgebende Komponente
Ein Paket muss mindestens Folgendes enthalten:
- Ein Ordner, der eine main.py-Datei im Stammverzeichnis dieses Ordners enthält.
- In dieser Datei eine Klasse mit dem Namen Main, die mindestens zwei Funktionen implementiert:
__init__(self): Akzeptiert kein Argument und lädt Ihr Modell und/oder lokale Daten für das Modell (z. B. Worteinbettungen).predict(self, input): eine Funktion, die zum Zeitpunkt der Modellausgabe aufgerufen wird und einen String zurückgibt.
- Eine Datei mit dem Namen requirements.txt mit Abhängigkeiten, die zum Ausführen des Modells erforderlich sind.
Stellen Sie sich die ausgebende Komponente eines Pakets als Modell zur Inferenzzeit vor. Bei der Ausgabe wird ein Container-Image mit der bereitgestellten requirements.txt-Datei erstellt und die Funktion predict wird als Endpunkt des Modells verwendet.
Trainings- und Auswertungskomponente
Zusätzlich zur Inferenz kann optional ein Paket zum Trainieren eines Machine Learning-Modells verwendet werden. Dies geschieht, indem Folgendes bereitgestellt wird:
- Stellen Sie im gleichen Stammordner mit der main.py-Datei eine Datei mit dem Namen train.py bereit.
- Geben Sie in dieser Datei eine Klasse mit dem Namen Main an, die mindestens vier Funktionen implementiert. Alle folgenden Funktionen mit Ausnahme von
__init__sind optional, beschränken jedoch den Typ der Pipelines, die mit dem entsprechenden Paket ausgeführt werden können.__init__(self): Akzeptiert kein Argument und lädt Ihr Modell und/oder Daten für das Modell (z. B. Worteinbettungen).train(self, training_directory): Nimmt als Eingabe ein Verzeichnis mit beliebig strukturierten Daten und führt den gesamten Code aus, der zum Trainieren eines Modells erforderlich ist. Diese Funktion wird aufgerufen, wenn eine Trainingspipeline ausgeführt wird.evaluate(self, evaluation_directory): Nimmt als Eingabe ein Verzeichnis mit beliebig strukturierten Daten, führt den gesamten Code aus, der zum Auswerten eines Modus erforderlich ist, und gibt eine einzelne Punktzahl für diese Bewertung zurück. Diese Funktion wird aufgerufen, wenn eine Auswertungspipeline ausgeführt wird.save(self): Akzeptiert kein Argument. Diese Funktion wird nach jedem Aufruf dertrain-Funktion aufgerufen, um Ihr Modell beizubehalten.process_data(self, input_directory): Nimmt eineinput_directory-Eingabe mit beliebig strukturierten Daten. Diese Funktion wird nur aufgerufen, wenn eine vollständige Pipeline ausgeführt wird. Bei der Ausführung einer vollständigen Pipeline kann diese Funktion beliebige Datentransformationen durchführen und Daten aufteilen. Insbesondere sind alle Daten, die in dem Pfad gespeichert werden, auf den die Umgebungsvariabletraining_data_directoryverweist, die Eingabe dertrain-Funktion und alle Daten, die in dem Pfad gespeichert werden, auf den die Umgebungsvariableevaluation_data_directoryverweist, sind die Eingabe derevaluation-Funktion oben.
Umgang mit Datentypen
To make AI Center easier to use within an RPA workflow, the package can be denoted to have one of three input types: String,File and Files (set during package upload time).
String-Daten
Dies ist eine Abfolge von Zeichen. Alle Daten, die serialisiert werden können, können mit einem Paket verwendet werden. Wenn sie innerhalb eines RPA-Workflows verwendet werden, können die Daten vom Roboter serialisiert (z. B. mit einer benutzerdefinierten Aktivität) und als Zeichenfolge gesendet werden. Der Paket-Uploader muss json als Eingabetyp des Pakets ausgewählt haben.
Die Deserialisierung von Daten erfolgt in der Funktion predict. Im Folgenden finden Sie eine Handvoll Beispiele für die Deserialisierung von Daten in 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)
Dateidaten
Dadurch wird der Aktivität ML Skill, die dieses Modell aufruft, mitgeteilt, einen Pfad zu einer Datei zu erwarten. Insbesondere liest die Aktivität die Datei aus dem Dateisystem und sendet sie an die predict -Funktion als serialisierte Bytezeichenfolge. So kann der RPA-Entwickler einen Pfad zu einer Datei übergeben, anstatt die Datei im Workflow selbst lesen und serialisieren zu müssen.
Innerhalb des Workflows ist die Eingabe der Aktivität nur der Pfad zur Datei. Die Aktivität liest die Datei, serialisiert sie und sendet die Dateibytes an die Funktion predict. Die Deserialisierung von Daten erfolgt auch in der Funktion predict, im Allgemeinen werden Bytes nur direkt in ein dateiähnliches Objekt gelesen, wie unten:
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)
Das Lesen der serialisierten Bytes wie oben entspricht dem Öffnen einer Datei mit aktiviertem Flag für binäres lesen. Um das Modell lokal zu testen, lesen Sie eine Datei als Binärdatei. Im folgenden Beispiel wird eine Bilddatei gelesen und lokal getestet:
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))
Das folgende Beispiel zeigt das Lesen einer csv-Datei und die Verwendung eines pandas Dataframe in der Funktion 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))
Dateidaten
Dadurch wird das AI Center darüber informiert, dass die Aktivität ML Skill, die dieses Modell aufruft, eine Liste von Dateipfaden erwartet. Wie im vorherigen Fall liest und serialisiert die Aktivität jede Datei und sendet eine Liste von Byte-Strings an die Funktion predict .
Eine Liste von Dateien kann an eine Fähigkeit gesendet werden. Innerhalb des Workflows ist die Eingabe der Aktivität eine Zeichenfolge mit Pfaden zu den Dateien, die durch ein Komma getrennt sind.
Beim Hochladen eines Pakets wählt der Datenspezialist eine Liste von Dateien als Eingabetyp aus. Der Datenexperte muss dann jede der gesendeten Dateien deserialisieren (wie oben erläutert). Die Eingabe der Funktion predict ist eine Liste von Bytes, bei denen jedes Element in der Liste die Bytezeichenfolge der Datei ist.
Beibehalten beliebiger Daten
In train.py kann jede ausgeführte Pipeline beliebige Daten beibehalten, die als Pipelineausgabe bezeichnet werden. Alle Daten, die aus den Artefakten der Umgebungsvariablen in den Verzeichnispfad geschrieben werden, werden beibehalten und können jederzeit angezeigt werden, indem Sie zur Seite Pipelinedetails navigieren. In der Regel kann jede Art von Diagrammen, Statistiken der Trainings-/Auswertungsaufträge im Verzeichnis artifacts gespeichert werden und am Ende der Pipelineausführung über die Benutzeroberfläche aufgerufen werden.
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))
...
Verwenden von TensorFlow
Während der Modellentwicklung muss das TensorFlow-Diagramm in denselben Thread geladen werden, der auch zur Ausgabe verwendet wird. Dazu muss das Standarddiagramm verwendet werden.
Im Folgenden finden Sie ein Beispiel mit den erforderlichen Änderungen:
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():
...
Informationen zur GPU-Nutzung
When GPU is enabled at skill creation time, it is deployed on an image with NVIDIA GPU driver 418, CUDA Toolkit 10.0 and CUDA Deep Neural Network Library (cuDNN) 7.6.5 runtime library.
Beispiele
Einfaches Ready-to-Serve-ML-Modell ohne Training
In diesem Beispiel erfordert das Geschäftsproblem kein erneutes Training des Modells, daher muss das Paket das serialisierte Modell IrisClassifier.sav enthalten, das zur Verfügung gestellt wird.
-
Anfängliche Projektstruktur (ohne main.py und requirements.txt):
IrisClassifier/ - IrisClassifier.savIrisClassifier/ - IrisClassifier.sav -
Beispielhafte main.py, die dem Stammordner hinzugefügt werden soll:
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()) -
requirements.txt hinzufügen:
scikit-learn==0.19.0scikit-learn==0.19.0Hinweis:There are some constraints that need to be respected on pip libraries. Make sure that you can install libraries under the following constraint files:
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.0Um dies zu testen, können Sie den folgenden Befehl in einer neuen Umgebung verwenden und sicherstellen, dass alle Bibliotheken ordnungsgemäß installiert sind:
pip install -r requirements.txt -c constraints.txtpip install -r requirements.txt -c constraints.txt -
Endgültige Ordnerstruktur:
IrisClassifier/ - IrisClassifier.sav - main.py - requirements.txtIrisClassifier/ - IrisClassifier.sav - main.py - requirements.txt
Simple ready-to-serve model with training enabled
In diesem Beispiel erfordert das Geschäftsproblem, dass das Modell neu trainiert wird. Aufbauend auf dem oben beschriebenen Paket haben Sie möglicherweise Folgendes:
-
Anfängliche Projektstruktur (Paket ,das nur ausgibt):
IrisClassifier/ - IrisClassifier.sav - main.py - requirements.txtIrisClassifier/ - IrisClassifier.sav - main.py - requirements.txt -
Beispielcode für train.py, der dem Stammordner hinzugefügt werden sollte:
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 -
Bearbeiten Sie requirements.txt, falls erforderlich:
pandas==1.0.1 scikit-learn==0.19.0pandas==1.0.1 scikit-learn==0.19.0 -
Endgültige Ordnerstruktur (Paket):
IrisClassifier/ - IrisClassifier.sav - main.py - requirements.txt - train.pyIrisClassifier/ - IrisClassifier.sav - main.py - requirements.txt - train.pyHinweis:Dieses Modell kann jetzt zuerst bereitgestellt werden, und da neue Datenpunkte über den Roboter oder Human-in-the-Loop in das System kommen, können Trainings- und Auswertungspipelines erstellt werden, die train.py nutzen.
- ML-Pakete strukturieren
- Ausgebende Komponente
- Trainings- und Auswertungskomponente
- Umgang mit Datentypen
- String-Daten
- Dateidaten
- Dateidaten
- Beibehalten beliebiger Daten
- Verwenden von TensorFlow
- Informationen zur GPU-Nutzung
- Beispiele
- Einfaches Ready-to-Serve-ML-Modell ohne Training
- Einfaches Ready-to-Serve-Modell mit aktiviertem Training