Gépi tanulási kísérletek konvertálása éles Python-kódra

A KÖVETKEZŐKRE VONATKOZIK:Python SDK azureml v1

Ebből az oktatóanyagból megtudhatja, hogyan konvertálhat Jupyter-notebookokat Python-szkriptekké, hogy az MLOpsPython kódsablon és az Azure Machine Learning használatával tesztelhetővé és automatizálhatóvá tegye azokat. Ezt a folyamatot általában arra használják, hogy kísérletezési/betanítási kódot készítsenek egy Jupyter-notebookból, és Python-szkriptekké alakítsák. Ezek a szkriptek ezután tesztelést és CI/CD-automatizálást használhatnak az éles környezetben.

A gépi tanulási projektekhez kísérletezni kell, ahol a hipotéziseket olyan agilis eszközökkel tesztelik, mint a Jupyter Notebook valós adatkészletek használatával. Ha a modell készen áll az éles használatra, a modellkódot egy éles kódtárba kell helyezni. Bizonyos esetekben a modellkódot Python-szkriptekké kell konvertálni, hogy az éles kódtárba kerüljenek. Ez az oktatóanyag a kísérletezési kód Python-szkriptekbe való exportálásának ajánlott megközelítését ismerteti.

Eben az oktatóanyagban az alábbiakkal fog megismerkedni:

  • Nem lényeges kód törlése
  • Kód újrabontása Jupyter Notebook függvényekbe
  • Python-szkriptek létrehozása kapcsolódó feladatokhoz
  • Egységtesztek létrehozása

Előfeltételek

  • Hozza létre az MLOpsPython sablont, és használja a és experimentation/Diabetes Ridge Regression Scoring.ipynb a experimentation/Diabetes Ridge Regression Training.ipynb jegyzetfüzetet. Ezek a jegyzetfüzetek példaként szolgálnak a kísérletezésből éles környezetbe való konvertálásra. Ezeket a jegyzetfüzeteket itt találja: https://github.com/microsoft/MLOpsPython/tree/master/experimentation.
  • Telepítse a(z) nbconvert rendszert. Csak az nbconvert telepítése szakaszban található telepítési utasításokat kövesse a Telepítés oldalon.

Az összes nem lényeges kód eltávolítása

A kísérletezés során írt egyes kódok csak feltáró jellegűek. Ezért a kísérleti kód éles kóddá konvertálásának első lépése ennek a nem lényeges kódnak a eltávolítása. A nem lényeges kód eltávolítása a kódot is karbantarthatóbbá teszi. Ebben a szakaszban eltávolítja a kódot a experimentation/Diabetes Ridge Regression Training.ipynb jegyzetfüzetből. A és az alakját és y a cellahívást Xfeatures.describe kinyomtató utasítások csak adatfeltárásra használhatók, és eltávolíthatók. A nem lényeges kód experimentation/Diabetes Ridge Regression Training.ipynb eltávolítása után a következő kódhoz hasonlóan kell kinéznie markdown nélkül:

from sklearn.datasets import load_diabetes
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
import joblib
import pandas as pd

sample_data = load_diabetes()

df = pd.DataFrame(
    data=sample_data.data,
    columns=sample_data.feature_names)
df['Y'] = sample_data.target

X = df.drop('Y', axis=1).values
y = df['Y'].values

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=0)
data = {"train": {"X": X_train, "y": y_train},
        "test": {"X": X_test, "y": y_test}}

args = {
    "alpha": 0.5
}

reg_model = Ridge(**args)
reg_model.fit(data["train"]["X"], data["train"]["y"])

preds = reg_model.predict(data["test"]["X"])
mse = mean_squared_error(preds, y_test)
metrics = {"mse": mse}
print(metrics)

model_name = "sklearn_regression_model.pkl"
joblib.dump(value=reg, filename=model_name)

Kód újrabontása függvényekké

Másodszor, a Jupyter-kódot újra kell bontani függvényekké. A kód függvényekbe való újrabontása megkönnyíti az egységtesztelést, és karbantarthatóbbá teszi a kódot. Ebben a szakaszban a következőt fogja újrabontásra:

  • The Diabetes Ridge Regression Training notebook(experimentation/Diabetes Ridge Regression Training.ipynb)
  • The Diabetes Ridge Regression Scoring notebook(experimentation/Diabetes Ridge Regression Scoring.ipynb)

A Diabetes Ridge regressziós betanítási jegyzetfüzetének újrabontása függvényekbe

A fájlban experimentation/Diabetes Ridge Regression Training.ipynbhajtsa végre a következő lépéseket:

  1. Hozzon létre egy nevű split_data függvényt az adatkeret tesztelési és betanítási adatokra való felosztásához. A függvénynek az adatkeretet df kell paraméterként használnia, és egy szótárat kell visszaadnia, amely tartalmazza a és testa kulcsokattrain.

    Helyezze át az Adatok felosztása a Betanítási és érvényesítési készletek fejléc alatti kódot a split_data függvénybe, és módosítsa úgy, hogy visszaadja az data objektumot.

  2. Hozzon létre egy nevű train_modelfüggvényt, amely a paramétereket data veszi fel, és args egy betanított modellt ad vissza.

    Helyezze át a betanítási készlet betanítási modellje alatti kódot a train_model függvénybe, és módosítsa úgy, hogy visszaadja az reg_model objektumot. Távolítsa el a args szótárt, az értékek a args paraméterből származnak.

  3. Hozzon létre egy nevű get_model_metricsfüggvényt, amely a és dataa paramétereket reg_model veszi fel, majd kiértékeli a modellt, majd visszaadja a betanított modell metrikáinak szótárát.

    Helyezze át a Modell érvényesítése érvényesítési készleten fejléc alatti kódot a get_model_metrics függvénybe, és módosítsa úgy, hogy visszaadja az metrics objektumot.

A három függvénynek a következőnek kell lennie:

# Split the dataframe into test and train data
def split_data(df):
    X = df.drop('Y', axis=1).values
    y = df['Y'].values

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=0)
    data = {"train": {"X": X_train, "y": y_train},
            "test": {"X": X_test, "y": y_test}}
    return data


# Train the model, return the model
def train_model(data, args):
    reg_model = Ridge(**args)
    reg_model.fit(data["train"]["X"], data["train"]["y"])
    return reg_model


# Evaluate the metrics for the model
def get_model_metrics(reg_model, data):
    preds = reg_model.predict(data["test"]["X"])
    mse = mean_squared_error(preds, data["test"]["y"])
    metrics = {"mse": mse}
    return metrics

A fájlban experimentation/Diabetes Ridge Regression Training.ipynbtovábbra is hajtsa végre a következő lépéseket:

  1. Hozzon létre egy nevű új függvényt main, amely nem vesz fel paramétereket, és nem ad vissza semmit.

  2. Helyezze át az "Adatok betöltése" fejléc alatti kódot a main függvénybe.

  3. Adja hozzá az újonnan írt függvények meghívásait a main függvényhez:

    # Split Data into Training and Validation Sets
    data = split_data(df)
    
    # Train Model on Training Set
    args = {
        "alpha": 0.5
    }
    reg = train_model(data, args)
    
    # Validate Model on Validation Set
    metrics = get_model_metrics(reg, data)
    
  4. Helyezze át a "Modell mentése" fejléc alatti kódot a main függvénybe.

A main függvénynek a következő kódhoz hasonlóan kell kinéznie:

def main():
    # Load Data
    sample_data = load_diabetes()

    df = pd.DataFrame(
        data=sample_data.data,
        columns=sample_data.feature_names)
    df['Y'] = sample_data.target

    # Split Data into Training and Validation Sets
    data = split_data(df)

    # Train Model on Training Set
    args = {
        "alpha": 0.5
    }
    reg = train_model(data, args)

    # Validate Model on Validation Set
    metrics = get_model_metrics(reg, data)

    # Save Model
    model_name = "sklearn_regression_model.pkl"

    joblib.dump(value=reg, filename=model_name)

Ebben a szakaszban nem lehet olyan kód a jegyzetfüzetben, amely nem szerepel egy függvényben, kivéve az első cellában lévő importálási utasításokat.

Adjon hozzá egy utasítást, amely meghívja a függvényt main .

main()

Az újrabontás experimentation/Diabetes Ridge Regression Training.ipynb után a következő kódhoz hasonlóan kell kinéznie markdown nélkül:

from sklearn.datasets import load_diabetes
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
import pandas as pd
import joblib


# Split the dataframe into test and train data
def split_data(df):
    X = df.drop('Y', axis=1).values
    y = df['Y'].values

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=0)
    data = {"train": {"X": X_train, "y": y_train},
            "test": {"X": X_test, "y": y_test}}
    return data


# Train the model, return the model
def train_model(data, args):
    reg_model = Ridge(**args)
    reg_model.fit(data["train"]["X"], data["train"]["y"])
    return reg_model


# Evaluate the metrics for the model
def get_model_metrics(reg_model, data):
    preds = reg_model.predict(data["test"]["X"])
    mse = mean_squared_error(preds, data["test"]["y"])
    metrics = {"mse": mse}
    return metrics


def main():
    # Load Data
    sample_data = load_diabetes()

    df = pd.DataFrame(
        data=sample_data.data,
        columns=sample_data.feature_names)
    df['Y'] = sample_data.target

    # Split Data into Training and Validation Sets
    data = split_data(df)

    # Train Model on Training Set
    args = {
        "alpha": 0.5
    }
    reg = train_model(data, args)

    # Validate Model on Validation Set
    metrics = get_model_metrics(reg, data)

    # Save Model
    model_name = "sklearn_regression_model.pkl"

    joblib.dump(value=reg, filename=model_name)

main()

A Diabetes Ridge regressziós pontozási jegyzetfüzetének újrabontása függvényekbe

A fájlban experimentation/Diabetes Ridge Regression Scoring.ipynbhajtsa végre a következő lépéseket:

  1. Hozzon létre egy nevű új függvényt init, amely nem vesz fel paramétereket, és nem ad vissza semmit.
  2. Másolja a "Modell betöltése" fejléc alatti kódot a init függvénybe.

A init függvénynek a következő kódhoz hasonlóan kell kinéznie:

def init():
    model_path = Model.get_model_path(
        model_name="sklearn_regression_model.pkl")
    model = joblib.load(model_path)

init A függvény létrehozása után cserélje le a "Modell betöltése" fejléc alatti kódot egyetlen hívásra init az alábbiak szerint:

init()

A fájlban experimentation/Diabetes Ridge Regression Scoring.ipynbhajtsa végre a következő lépéseket:

  1. Hozzon létre egy nevű új függvénytrun, amely a és request_headers a paramétert használjaraw_data, és az eredmények szótárát adja vissza az alábbiak szerint:

    {"result": result.tolist()}
    
  2. Másolja az "Adatok előkészítése" és az "Adatok pontozása" fejléc alatti kódot a run függvénybe.

    A run függvénynek a következő kódhoz hasonlóan kell kinéznie (ne felejtse el eltávolítani a változókat raw_datarequest_headersbeállítva és a utasítást tartalmazó utasításokat, amelyeket a run függvény meghívásakor később fog használni):

    def run(raw_data, request_headers):
        data = json.loads(raw_data)["data"]
        data = numpy.array(data)
        result = model.predict(data)
    
        return {"result": result.tolist()}
    

run A függvény létrehozása után cserélje le az "Adatok előkészítése" és az "Adatok pontozása" fejléc alatti kódot a következő kódra:

raw_data = '{"data":[[1,2,3,4,5,6,7,8,9,10],[10,9,8,7,6,5,4,3,2,1]]}'
request_header = {}
prediction = run(raw_data, request_header)
print("Test result: ", prediction)

Az előző kód beállítja a változókat és a változókatraw_data, meghívja a függvényt a run és request_headera raw_data használatával, és kinyomtatja az előrejelzéseket.request_header

Az újrabontás experimentation/Diabetes Ridge Regression Scoring.ipynb után a következő kódhoz hasonlóan kell kinéznie markdown nélkül:

import json
import numpy
from azureml.core.model import Model
import joblib

def init():
    model_path = Model.get_model_path(
        model_name="sklearn_regression_model.pkl")
    model = joblib.load(model_path)

def run(raw_data, request_headers):
    data = json.loads(raw_data)["data"]
    data = numpy.array(data)
    result = model.predict(data)

    return {"result": result.tolist()}

init()
test_row = '{"data":[[1,2,3,4,5,6,7,8,9,10],[10,9,8,7,6,5,4,3,2,1]]}'
request_header = {}
prediction = run(test_row, {})
print("Test result: ", prediction)

Harmadszor, a kapcsolódó függvényeket Python-fájlokba kell egyesíteni, hogy jobban segíthesse a kód újrafelhasználását. Ebben a szakaszban Python-fájlokat fog létrehozni a következő jegyzetfüzetekhez:

  • The Diabetes Ridge Regression Training notebook(experimentation/Diabetes Ridge Regression Training.ipynb)
  • The Diabetes Ridge Regression Scoring notebook(experimentation/Diabetes Ridge Regression Scoring.ipynb)

Python-fájl létrehozása a Diabetes Ridge Regression Training jegyzetfüzethez

Konvertálja a jegyzetfüzetet végrehajtható szkriptté a következő utasítás parancssorban való futtatásával, amely a nbconvert csomagot és az elérési útját experimentation/Diabetes Ridge Regression Training.ipynbhasználja:

jupyter nbconvert "Diabetes Ridge Regression Training.ipynb" --to script --output train

A jegyzetfüzet átalakítása train.pyután távolítsa el a nem kívánt megjegyzéseket. Cserélje le a fájl végén lévő hívását main() egy feltételes hívásra, például az alábbi kódra:

if __name__ == '__main__':
    main()

A train.py fájlnak a következő kódhoz hasonlóan kell kinéznie:

from sklearn.datasets import load_diabetes
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
import pandas as pd
import joblib


# Split the dataframe into test and train data
def split_data(df):
    X = df.drop('Y', axis=1).values
    y = df['Y'].values

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=0)
    data = {"train": {"X": X_train, "y": y_train},
            "test": {"X": X_test, "y": y_test}}
    return data


# Train the model, return the model
def train_model(data, args):
    reg_model = Ridge(**args)
    reg_model.fit(data["train"]["X"], data["train"]["y"])
    return reg_model


# Evaluate the metrics for the model
def get_model_metrics(reg_model, data):
    preds = reg_model.predict(data["test"]["X"])
    mse = mean_squared_error(preds, data["test"]["y"])
    metrics = {"mse": mse}
    return metrics


def main():
    # Load Data
    sample_data = load_diabetes()

    df = pd.DataFrame(
        data=sample_data.data,
        columns=sample_data.feature_names)
    df['Y'] = sample_data.target

    # Split Data into Training and Validation Sets
    data = split_data(df)

    # Train Model on Training Set
    args = {
        "alpha": 0.5
    }
    reg = train_model(data, args)

    # Validate Model on Validation Set
    metrics = get_model_metrics(reg, data)

    # Save Model
    model_name = "sklearn_regression_model.pkl"

    joblib.dump(value=reg, filename=model_name)

if __name__ == '__main__':
    main()

train.py most már meghívható egy terminálból a parancs futtatásával python train.py. A függvények más train.py fájlokból is meghívhatók.

Az train_aml.py MLOpsPython-adattár könyvtárában diabetes_regression/training található fájl meghívja az Azure Machine Learning-kísérletfeladat kontextusában train.py definiált függvényeket. A függvények az útmutató későbbi részében ismertetett egységtesztekben is meghívhatók.

Python-fájl létrehozása a Diabetes Ridge regressziós pontozási jegyzetfüzetéhez

Konvertálja a jegyzetfüzetet végrehajtható szkriptté a következő utasítás futtatásával egy parancssorban, amely a nbconvert csomagot és az elérési útját experimentation/Diabetes Ridge Regression Scoring.ipynbhasználja:

jupyter nbconvert "Diabetes Ridge Regression Scoring.ipynb" --to script --output score

A jegyzetfüzet átalakítása score.pyután távolítsa el a nem kívánt megjegyzéseket. A score.py fájlnak a következő kódhoz hasonlóan kell kinéznie:

import json
import numpy
from azureml.core.model import Model
import joblib

def init():
    model_path = Model.get_model_path(
        model_name="sklearn_regression_model.pkl")
    model = joblib.load(model_path)

def run(raw_data, request_headers):
    data = json.loads(raw_data)["data"]
    data = numpy.array(data)
    result = model.predict(data)

    return {"result": result.tolist()}

init()
test_row = '{"data":[[1,2,3,4,5,6,7,8,9,10],[10,9,8,7,6,5,4,3,2,1]]}'
request_header = {}
prediction = run(test_row, request_header)
print("Test result: ", prediction)

A model változónak globálisnak kell lennie, hogy látható legyen a szkriptben. Adja hozzá a következő utasítást a függvény elejéhez init :

global model

Az előző utasítás hozzáadása után a függvénynek a init következő kódhoz hasonlóan kell kinéznie:

def init():
    global model

    # load the model from file into a global object
    model_path = Model.get_model_path(
        model_name="sklearn_regression_model.pkl")
    model = joblib.load(model_path)

Egységtesztek létrehozása minden Python-fájlhoz

Negyedszer hozzon létre egységteszteket a Python-függvényekhez. Az egységtesztek megvédik a kódot a funkcionális regresszióktól, és megkönnyítik a karbantartást. Ebben a szakaszban egységteszteket fog létrehozni a függvényekhez a következőben train.py: .

train.py több függvényt tartalmaz, de ebben az oktatóanyagban csak egyetlen egységtesztet hozunk létre a train_model függvényhez a Pytest-keretrendszer használatával. Nem a Pytest az egyetlen Python-egységtesztelési keretrendszer, de ez az egyik leggyakrabban használt keretrendszer. További információért látogasson el a Pytest webhelyre.

Az egységteszt általában három fő műveletet tartalmaz:

  • Objektum elrendezése – a szükséges objektumok létrehozása és beállítása
  • Művelet egy objektumon
  • A várt érték megadása

Az egységteszt train_model meghív néhány szigorúan kódolt adatot és argumentumot, és az eredményül kapott betanított modell használatával ellenőrzi train_model a várt módon működő adatokat, és összehasonlítja az előrejelzést egy várt értékkel.

import numpy as np
from code.training.train import train_model


def test_train_model():
    # Arrange
    X_train = np.array([1, 2, 3, 4, 5, 6]).reshape(-1, 1)
    y_train = np.array([10, 9, 8, 8, 6, 5])
    data = {"train": {"X": X_train, "y": y_train}}

    # Act
    reg_model = train_model(data, {"alpha": 1.2})

    # Assert
    preds = reg_model.predict([[1], [2]])
    np.testing.assert_almost_equal(preds, [9.93939393939394, 9.03030303030303])

Következő lépések

Most, hogy megismerte, hogyan konvertálhat egy kísérletből éles kódra, további információkért és a következő lépésekért tekintse meg az alábbi hivatkozásokat: