header_2.png
Organisatie

Tutorial: begin met MLOps met MLFlow en DVC

Pieter Zijlstra
Pieter Zeilstra, MSc Leestijd Minuten

In deze tutorial bouwen we een basis machine learning (ML) pipeline met behulp van MLOps-principes. We maken gebruik van MLflow voor het bijhouden van experimenten, Git voor versiebeheer en DVC (Data Version Control) voor het beheren van datasets en modelbestanden. Voor ons voorbeeld gebruiken we de populaire scikit-learn bibliotheek om een eenvoudig classificatiemodel te maken op basis van de Wine dataset.

De voorbeeldrepository is te vinden op GitHub.

Wat is MLOps en waarom zou je het gebruiken?

MLOps is een set van praktijken en tools die het machine learning proces stroomlijnen en automatiseren, van het ontwikkelen van methoden tot het implementeren ervan en het onderhouden van modellen in productie. Figuur 1 toont dit proces, van het verzamelen en verwerken van data tot het monitoren van het model in productie. Voor een diepere duik in de interne werking van elk onderdeel van de MLOps levenscyclus, raden we aan de blogpost van Heck (2021) te bekijken, die hier beschikbaar is.

figure-1.png

Figuur 1: MLOps levenscyclus, overgenomen uit (Heck, 2021) (https://fontysblogt.nl/ai-engineering-and-mlops/)

Wat is MLFlow en hoe werkt het?

MLflow is een open-source platform dat is ontworpen om de end-to-end machine learning (ML) levenscyclus te beheren. Het biedt tools die helpen bij verschillende stadia, van het ontwikkelen en trainen van modellen tot het implementeren ervan en het bijhouden van modellen en bijbehorende experimenten. MLflow maakt het gehele proces van experimenteren, bijhouden en implementeren van modellen gemakkelijker, vooral wanneer er in teams gewerkt wordt of met een groot aantal modellen.

figure-2.png

Wat is DVC en hoe werkt het?

DVC (Data Version Control) is een tool die versiebeheer faciliteert voor machine learning pipelines, datasets en modellen. Dit maakt het makkelijker om deze te volgen tijdens het machine learning proces. DVC integreert goed met Git, waardoor data scientists hun code kunnen versiebeheer samen met hun data en machine learning elementen. Dit resulteert in betere samenwerkingsmogelijkheden en reproduceerbaarheid.

figure-3.png

Stap 1: Schrijf een basis ML pipeline

Voordat we de code induiken, moeten we de benodigde Python-pakketten installeren. We gebruiken pip voor de installatie. Voor de eenvoud is het een goed idee om een virtuele omgeving te maken. Je kunt hier instructies vinden.

Installeer vereiste pakketten
Voer de volgende opdrachten uit in je terminal:

pip install pandas

pip install matplotlib

pip install scikit-learn

pip install mlflow

pip install dvc

Stap 2: Initialiseer Git en DVC

Vervolgens maken we een Git-repository om wijzigingen bij te houden, aangezien dit ook als basis dient voor DVC. We negeren de mlruns-directory die door MLflow is gegenereerd, omdat we deze niet naar onze Git-repository willen pushen.

git init

dvc init

touch .gitignore

echo "mlruns/" >> .gitignore

Stap 3: Organiseer de structuur van je project

Het is belangrijk om meerdere Python-bestanden te maken, omdat dit het makkelijker maakt om een duidelijke en geautomatiseerde pipeline te bouwen. In deze tutorial maken we drie Python-bestanden, elk met een specifieke functie in onze pipeline:

create_dataset.py

train_model.py

eval_model.py


We maken ook een mappenstructuur om onze data- en modelbestanden op te slaan. De uiteindelijke structuur van de repository ziet er als volgt uit:

/your_repo

  • /models
    • /SVC
  • /data
  • create_dataset.py
  • train_model.py
  • eval_model.py

Maak het Dataset-bestand: create_dataset.py

De eerste stap is het maken van een dataset voor training en testen. De wijn-dataset wordt opgesplitst in training en testen, met een testgrootte van 0.2. De twee sets worden opgeslagen als een csv-bestand.

from sklearn.datasets import load_wine

from sklearn.model_selection import train_test_split

import pandas as pd

 

parameters = {'random_state': 42, 'test_size': 0.2}

# Laad de wijn-dataset

print("Dataset laden")

wine = load_wine()

# Verdeel de dataset in data en labels

wine_ds = pd.DataFrame(wine.data, columns=wine.feature_names)

wine_ds["label"] = wine.target

# Zorg ervoor dat je een getal in de random state zet, anders zullen de sets elke keer verschillend zijn.

train, test = train_test_split(wine_ds, test_size=parameters['test_size'], random_state=parameters['random_state'])

# Sla de wijn-dataset op (dit moet versiebeheer hebben via DVC)

print("Dataset opslaan")

train.to_csv('data/train.csv', index=False)

test.to_csv('data/test.csv', index=False)

# Sla de gebruikte parameters op

with open("data/dataset_parameters.yaml", "w") as f: f.write('\n'.join(f"{k}: {v}" for k, v in parameters.items()))

print("Klaar")

Voeg vervolgens de output toe als een stage aan DVC met het volgende commando:

dvc stage add -n create_dataset \

  -d create_dataset.py \

  -o data/train.csv \

  -o data/test.csv \

  -o data/dataset_parameters.yaml\

  python create_dataset.py

Het commando dvc stage in DVC (Data Version Control) wordt gebruikt om verschillende stadia van een datapipeline binnen een DVC-project te definiëren en te beheren. Elke stage vertegenwoordigt een afzonderlijke stap in je machine learning-workflow, zoals data preprocessing, modeltraining of evaluatie.

Gebruik dvc repro om de pipeline tot nu toe uit te voeren en te controleren of alles werkt.

Maak het Model-trainingsbestand: train_model.py

Een SVC-model met een RBF-kernel wordt getraind als voorbeeld op de trainingsset en de parameters worden direct opgeslagen in MLflow, zodat je deze later kunt controleren.

# Imports

from sklearn.svm import SVC

import pandas as pd

import mlflow

import mlflow.sklearn

import joblib

 

mlflow.set_experiment("SVC-model-training") # Maakt een nieuw experiment aan en stelt dit in

# schakel autologging in

mlflow.sklearn.autolog()

 

# Laad de dataset

print('Trainingsdataset laden')

train = pd.read_csv('data/train.csv')

X_train = train.drop('label', axis=1)

y_train = train.label

 

# Train het model

with mlflow.start_run() as run:

    print('Model trainen')

    clf = SVC(kernel='rbf', probability=True) # Als je extra parameters hebt gebruikt, sla deze dan ook op in een bestand

    clf.fit(X_train, y_train)

    print('Model opslaan')

    joblib.dump(clf, f"models/SVC/model")

    print('Parameters opslaan')

    # Sla de gebruikte parameters op

    run_id = run.info.run_id

    run_name = mlflow.get_run(run_id).data.tags["mlflow.runName"]

    parameters = {'run_id': run_id, 'run_name': run_name}

    with open("models/SVC/model_parameters.yaml", "w") as f: f.write('\n'.join(f"{k}: {v}" for k, v in parameters.items()))

print('Klaar')

Voeg dit ook toe als een stage met het commando dvc stage:

dvc stage add -n train_model\

    -d data/train.csv \

    -d train_model.py \

    -o models/SVC/model \

    -o models/SVC/model_parameters.yaml \

    python train_model.py

Start het MLflow-dashboard
Gebruik dvc repro om de pipeline tot nu toe uit te voeren en de resultaten te bekijken in de MLflow UI.

Start het MLflow-dashboard door het volgende commando in de directory van je repository uit te voeren:

mlflow ui

Als alles correct is ingesteld, zou je een URL moeten zien (bijvoorbeeld http://127.0.0.1:5000) waar je MLflow-dashboard wordt gehost.

figure-4.png

Figuur 2: Tabblad Experiments op MLFlow

figure-5.png

Figuur 3: Het klikken op een run toont de parameters en metriek

Evalueer het Modelbestand: eval_model.py

De prestaties van het model worden gemeten met verschillende statistieken, zoals nauwkeurigheid, precisie en recall. Ook wordt een verwarringsmatrix gemaakt.

Het model wordt geëvalueerd met de testset die in een eerdere stap is gemaakt. De prestatiebeoordelingen, verwarringsmatrix en een plot van de feature importanties worden allemaal opgeslagen in MLflow, zodat je deze later kunt raadplegen, bijvoorbeeld bij het vergelijken van verschillende modellen.

# Imports
import mlflow
import mlflow.sklearn
import joblib
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.inspection import permutation_importance
from sklearn.metrics import (
    accuracy_score,
    precision_score,
    recall_score,
    confusion_matrix,
    ConfusionMatrixDisplay
)
# mlflow.sklearn.autolog()
# We will not use auto logging this time but create our own parameters!
print("Loading test dataset")
test= pd.read_csv('data/test.csv')
X_test = test.drop('label', axis=1)
y_test = test.label
print("loading model")
clf = joblib.load("models/SVC/model")
mlflow.set_experiment("SVC-model-testing")

# Get model info
with open("models/SVC/model_parameters.yaml", "r") as f:
    run_info = {line.split(":")[0].strip(): line.split(":")[1].strip() for line in f}
print(f"Run info: {run_info}")

with mlflow.start_run() as run:
    # Set same runName so we can easily see it in MlFlow
    mlflow.set_tag("mlflow.runName", run_info.get("run_name"))
    print("Evaluating model")
    mlflow.sklearn.log_model(clf, "SVC")
    predictions = clf.predict(X_test)
    cm = confusion_matrix(y_test, predictions, labels=clf.classes_)
    disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=clf.classes_)
    disp.plot()
    # Save the confusion matrix, so that we can then save it in mlflow as an artifact
    plt.savefig('models/SVC/confusion_matrix.png')
    plt.close()

    # Determine the feature importances (how important each feature is for the final assessment)
    perm_importance = permutation_importance(clf, X_test, y_test)
    sorted_idx = perm_importance.importances_mean.argsort()
    features = X_test.columns
    plt.barh(features[sorted_idx], perm_importance.importances_mean[sorted_idx])
    plt.xlabel("Permutation Importance")
    plt.gcf().set_size_inches(20, 10)
    plt.savefig('models/SVC/feature_importances.png')
    plt.close()

    # Calculate the scores
    scores_acc = accuracy_score(y_test, predictions)
    scores_prec = precision_score(y_test, predictions, average='weighted')
    scores_recall = recall_score(y_test, predictions, average='weighted')
    # Provide an input example from the test data

    mlflow.log_metric("accuracy", scores_acc)
    mlflow.log_metric("precision", scores_prec)
    mlflow.log_metric("recall", scores_recall)
    mlflow.log_artifact('models/SVC/confusion_matrix.png')
    mlflow.log_artifact('models/SVC/feature_importances.png')
    # Save model ID and metrics to a text file
    metrics = mlflow.get_run(run.info.run_id).data.metrics
    print("Metrics", metrics)
    with open("models/SVC/metrics.yaml", "w") as f:
        f.write(f"Run ID: {run.info.run_id}\n")
        f.write("\n".join(f"{k}: {v}" for k, v in metrics.items()))
print("Done")

Stap 3: Maak de pipeline af door DVC toe te voegen als een stage

dvc stage add -n eval_model\

  -d eval_model.py \

  -d data/test.csv \

  -d models/SVC/model \

  -o models/SVC/metrics.yaml \

  -o models/SVC/confusion_matrix.png\

  -o models/SVC/feature_importances.png\

  python eval_model.py

Gebruik dvc repro om de pipeline opnieuw uit te voeren en bekijk de resultaten in de MLflow UI. We hebben nu een nieuw experiment genaamd: "SVC-model-testing".

figure-6.png

Figuur 4: Ga naar modelmetrics in de SVC-model-testing run om onze gelogde metrics te bekijken.

figure-7.png

Figuur 5: Klik op “Artifacts” om onze opgeslagen grafieken te zien.

Stap 4: Review de Pipeline Configuratie

Om de stages in je DVC-pipeline te bekijken, check het dvc.yaml bestand:

stages:

  create_dataset:

    cmd: python create_dataset.py

    deps:

    - create_dataset.py

    outs:

    - data/dataset_parameters.yaml

    - data/test.csv

    - data/train.csv

  train_model:

    cmd: python train_model.py

    deps:

    - data/train.csv

    - train_model.py

    outs:

    - models/SVC/model

    - models/SVC/model_parameters.yaml

  eval_model:

    cmd: python eval_model.py

    deps:

    - data/test.csv

    - eval_model.py

    - models/SVC/model

    outs:

    - models/SVC/confusion_matrix.png

    - models/SVC/feature_importances.png

    - models/SVC/metrics.yaml

Visualiseer en voer de pipeline uit
Om de pipeline te visualiseren, gebruik de volgende opdracht:

dvc dag  # Je kunt ook --outs toevoegen

Uitvoer:

             +----------------+      

             | create_dataset |

             +----------------+

              ***           ***

            **                 **

          **                     **

+-------------+                    **

| train_model |                  **

+-------------+                **

              ***           ***

                 **       **

                   **   **

               +------------+

               | eval_model |

               +------------+

Commit uiteindelijk je wijzigingen naar Git:

git add .  # Voeg alle wijzigingen toe, inclusief .dvc-bestanden

git commit -m "Setup mijn eerste ML-pipeline met DVC en MLFlow!"

Stap 5: Automatiseer met Git Hooks

Wijzig in het bestand create_dataset.py de random_state parameter naar een ander nummer (bijv. 43) en probeer te committen. DVC zal automatisch de pipeline opnieuw uitvoeren elke keer dat je wijzigingen commit!

dvc install --use-pre-commit

git commit -m "Extra ruimte toegevoegd aan eval_model.py"

Stap 6: Gebruik DVC en haal eerdere data + artifacts terug!

Stel je voor dat je wilt terugkeren naar een eerdere commit en ook de data wilt herstellen. Voer de volgende commando's uit:

git log

git checkout <commit-hash>

DVC zal de staat van het dvc.lock bestand bij die commit herkennen en ervoor zorgen dat je de juiste dataversie krijgt.

dvc pull

Probeer het zelf!

Verken de bovenstaande code in onze Github-repository en probeer het zelf uit!

Geïnteresseerd in meer?

We hebben ook een tool gemaakt om je te helpen het juiste MLOps-hulpmiddel voor je project en organisatie te kiezen! Lees meer hierover in deze post.

Vragen of feedback?

Als je vragen of suggesties hebt, neem dan gerust contact met ons op via onze Github-pagina. We horen graag je gedachten!

Over ons

Deze workshop werd ontwikkeld als onderdeel van onderzoek uitgevoerd bij de Ambient Intelligence-onderzoeksgroep, onderdeel van Saxion Hogeschool. Bij onze onderzoeksgroep voeren we vraaggestuurd onderzoek uit samen met partners uit de industrie en (toegepaste) universiteiten, met een focus op Connected Embedded Systems, Toegepaste Datawetenschap en Augmented Interaction. Verschillende domeinen worden behandeld, zoals veiligheid, sport en slimme industrieën.

Pieter Zijlstra

Pieter Zeilstra, MSc

Iris Heerlien 500x500.jpg

Iris Heerlien, MSc

Gerelateerde artikelen

header2.png Organisatie

AI Platform Guide - Welke ML tool past het best bij mij?

11 december 2024
Bram Ton promoveert: voorspelbaar spooronderhoud Onderzoek

Bram Ton promoveert: voorspelbaar spooronderhoud

18 november 2024
Lector Jeroen Linssen voor Saxion Deventer Onderzoek

Jeroen Linssen houdt zijn rede: ‘symbiose tussen mens en AI’