Machine learning-pijplijnen maken en uitvoeren met Azure Machine Learning SDK
VAN TOEPASSING OP: Python SDK azureml v1
In dit artikel leert u hoe u machine learning-pijplijnen maakt en uitvoert met behulp van de Azure Machine Learning SDK. Gebruik ML-pijplijnen om een werkstroom te maken waarmee verschillende ML-fasen worden samengevoegd. Publiceer die pijplijn vervolgens voor latere toegang of delen met anderen. Houd ML-pijplijnen bij om te zien hoe uw model presteert in de echte wereld en om gegevensdrift te detecteren. ML-pijplijnen zijn ideaal voor batchgewijs scorescenario's, waarbij verschillende berekeningen worden gebruikt, stappen opnieuw worden gebruikt in plaats van ze opnieuw uit te voeren en ML-werkstromen met anderen te delen.
Dit artikel is geen zelfstudie. Zie zelfstudie: Een Azure Machine Learning-pijplijn bouwen voor batchgewijs scoren of geautomatiseerde ML gebruiken in een Azure Machine Learning-pijplijn in Python voor hulp bij het maken van uw eerste pijplijn.
Hoewel u een andere soort pijplijn kunt gebruiken, een Azure-pijplijn voor CI/CD-automatisering van ML-taken, wordt dat type pijplijn niet opgeslagen in uw werkruimte. Vergelijk deze verschillende pijplijnen.
De ML-pijplijnen die u maakt, zijn zichtbaar voor de leden van uw Azure Machine Learning-werkruimte.
ML-pijplijnen worden uitgevoerd op rekendoelen (zie Wat zijn rekendoelen in Azure Machine Learning). Pijplijnen kunnen gegevens lezen en schrijven naar en van ondersteunde Azure Storage-locaties .
Als u geen Azure-abonnement hebt, maakt u een gratis account voordat u begint. Probeer de gratis of betaalde versie van Azure Machine Learning.
Vereisten
Een Azure Machine Learning-werkruimte. Werkruimtebronnen maken.
Configureer uw ontwikkelomgeving om de Azure Machine Learning SDK te installeren of gebruik een Azure Machine Learning-rekenproces met de SDK die al is geïnstalleerd.
Begin met het koppelen van uw werkruimte:
import azureml.core
from azureml.core import Workspace, Datastore
ws = Workspace.from_config()
Resources voor machine learning instellen
Maak de resources die nodig zijn om een ML-pijplijn uit te voeren:
Stel een gegevensarchief in dat wordt gebruikt voor toegang tot de gegevens die nodig zijn in de pijplijnstappen.
Configureer een
Dataset
object om te verwijzen naar permanente gegevens die zich in een gegevensarchief bevinden of toegankelijk zijn in. Configureer eenOutputFileDatasetConfig
object voor tijdelijke gegevens die worden doorgegeven tussen pijplijnstappen.Stel de rekendoelen in waarop uw pijplijnstappen worden uitgevoerd.
Een gegevensarchief instellen
In een gegevensarchief worden de gegevens voor de pijplijn opgeslagen voor toegang. Elke werkruimte heeft een standaardgegevensarchief. U kunt meer gegevensarchieven registreren.
Wanneer u uw werkruimte maakt, worden Azure Files en Azure Blob Storage gekoppeld aan de werkruimte. Er wordt een standaardgegevensarchief geregistreerd om verbinding te maken met de Azure Blob-opslag. Zie Bepalen wanneer u Azure Files, Azure Blobs of Azure Disks gebruikt voor meer informatie.
# Default datastore
def_data_store = ws.get_default_datastore()
# Get the blob storage associated with the workspace
def_blob_store = Datastore(ws, "workspaceblobstore")
# Get file storage associated with the workspace
def_file_store = Datastore(ws, "workspacefilestore")
Stappen verbruiken doorgaans gegevens en produceren uitvoergegevens. Een stap kan gegevens maken, zoals een model, een map met model- en afhankelijke bestanden of tijdelijke gegevens. Deze gegevens zijn vervolgens beschikbaar voor andere stappen verderop in de pijplijn. Zie de artikelen How to Access Data and How to Register Datasets (Gegevenssets registreren) voor meer informatie over het verbinden van uw pijplijn met uw gegevens.
Gegevens configureren met Dataset
en OutputFileDatasetConfig
objecten
De voorkeursmethode voor het leveren van gegevens aan een pijplijn is een gegevenssetobject . Het Dataset
object verwijst naar gegevens in of zijn toegankelijk vanuit een gegevensarchief of op een web-URL. De Dataset
klasse is abstract, dus u maakt een exemplaar van een (verwijzend naar een FileDataset
of meer bestanden) of een TabularDataset
exemplaar dat is gemaakt door een of meer bestanden met gescheiden kolommen met gegevens.
U maakt een Dataset
using-methode, zoals from_files of from_delimited_files.
from azureml.core import Dataset
my_dataset = Dataset.File.from_files([(def_blob_store, 'train-images/')])
Tussenliggende gegevens (of uitvoer van een stap) worden vertegenwoordigd door een OutputFileDatasetConfig-object . output_data1
wordt geproduceerd als uitvoer van een stap. Deze gegevens kunnen eventueel als gegevensset worden geregistreerd door aan te roepen register_on_complete
. Als u een OutputFileDatasetConfig
in één stap maakt en deze gebruikt als invoer voor een andere stap, maakt die gegevensafhankelijkheid tussen stappen een impliciete uitvoeringsvolgorde in de pijplijn.
OutputFileDatasetConfig
objecten retourneren een map en schrijven standaard uitvoer naar het standaardgegevensarchief van de werkruimte.
from azureml.data import OutputFileDatasetConfig
output_data1 = OutputFileDatasetConfig(destination = (datastore, 'outputdataset/{run-id}'))
output_data_dataset = output_data1.register_on_complete(name = 'prepared_output_data')
Belangrijk
Tussenliggende gegevens die worden opgeslagen met behulp OutputFileDatasetConfig
van, worden niet automatisch verwijderd door Azure.
U moet tussenliggende gegevens aan het einde van een pijplijnuitvoering programmatisch verwijderen, een gegevensarchief gebruiken met een kort beleid voor gegevensretentie of regelmatig handmatig opschonen.
Tip
Upload alleen bestanden die relevant zijn voor de huidige taak. Wijzigingen aan bestanden in de gegevensmap worden gezien als een reden om de stap opnieuw uit te voeren de volgende keer dat de pijplijn wordt uitgevoerd, zelfs als opnieuw gebruiken is opgegeven.
Een rekendoel instellen
In Azure Machine Learning verwijst de term compute (of rekendoel) naar de machines of clusters die de rekenkundige stappen in uw machine learning-pijplijn uitvoeren. Zie rekendoelen voor modeltraining voor een volledige lijst met rekendoelen en rekendoelen maken voor het maken en koppelen van deze doelen aan uw werkruimte. Het proces voor het maken en koppelen van een rekendoel is hetzelfde, ongeacht of u een model traint of een pijplijnstap uitvoert. Nadat u het rekendoel hebt gemaakt en gekoppeld, gebruikt u het ComputeTarget
object in de pijplijnstap.
Belangrijk
Het uitvoeren van beheerbewerkingen op rekendoelen wordt niet ondersteund vanuit externe taken. Omdat machinelearning-pijplijnen als een externe taak worden verzonden, mag u geen beheerbewerkingen op rekendoelen gebruiken vanuit de pijplijn.
Azure Machine Learning-rekenproces
U kunt een Azure Machine Learning-rekenproces maken voor het uitvoeren van uw stappen. De code voor andere rekendoelen is vergelijkbaar, met iets andere parameters, afhankelijk van het type.
from azureml.core.compute import ComputeTarget, AmlCompute
compute_name = "aml-compute"
vm_size = "STANDARD_NC6"
if compute_name in ws.compute_targets:
compute_target = ws.compute_targets[compute_name]
if compute_target and type(compute_target) is AmlCompute:
print('Found compute target: ' + compute_name)
else:
print('Creating a new compute target...')
provisioning_config = AmlCompute.provisioning_configuration(vm_size=vm_size, # STANDARD_NC6 is GPU-enabled
min_nodes=0,
max_nodes=4)
# create the compute target
compute_target = ComputeTarget.create(
ws, compute_name, provisioning_config)
# Can poll for a minimum number of nodes and for a specific timeout.
# If no min node count is provided it will use the scale settings for the cluster
compute_target.wait_for_completion(
show_output=True, min_node_count=None, timeout_in_minutes=20)
# For a more detailed view of current cluster status, use the 'status' property
print(compute_target.status.serialize())
De omgeving van de trainingsuitvoering configureren
De volgende stap zorgt ervoor dat de uitvoering van de externe training alle afhankelijkheden bevat die nodig zijn voor de trainingsstappen. Afhankelijkheden en de runtimecontext worden ingesteld door een RunConfiguration
object te maken en te configureren.
from azureml.core.runconfig import RunConfiguration
from azureml.core.conda_dependencies import CondaDependencies
from azureml.core import Environment
aml_run_config = RunConfiguration()
# `compute_target` as defined in "Azure Machine Learning compute" section above
aml_run_config.target = compute_target
USE_CURATED_ENV = True
if USE_CURATED_ENV :
curated_environment = Environment.get(workspace=ws, name="AzureML-sklearn-0.24-ubuntu18.04-py37-cpu")
aml_run_config.environment = curated_environment
else:
aml_run_config.environment.python.user_managed_dependencies = False
# Add some packages relied on by data prep step
aml_run_config.environment.python.conda_dependencies = CondaDependencies.create(
conda_packages=['pandas','scikit-learn'],
pip_packages=['azureml-sdk', 'azureml-dataset-runtime[fuse,pandas]'],
pin_sdk_version=False)
De bovenstaande code bevat twee opties voor het verwerken van afhankelijkheden. Zoals u ziet, USE_CURATED_ENV = True
is de configuratie gebaseerd op een gecureerde omgeving. Gecureerde omgevingen zijn 'vooraf gedefinieerd' met gemeenschappelijke interafhankelijke bibliotheken en kunnen sneller online worden gebracht. Gecureerde omgevingen hebben vooraf gemaakte Docker-installatiekopieën in het Microsoft Container Registry. Zie voor meer informatie gecureerde Azure Machine Learning-omgevingen.
Het pad dat wordt genomen als u het False
patroon wijzigt USE_CURATED_ENV
voor het expliciet instellen van uw afhankelijkheden. In dat scenario wordt een nieuwe aangepaste Docker-installatiekopieën gemaakt en geregistreerd in een Azure Container Registry binnen uw resourcegroep (zie Inleiding tot persoonlijke Docker-containerregisters in Azure). Het bouwen en registreren van deze afbeelding kan enkele minuten duren.
Je pijplijnstappen maken
Zodra u de rekenresource en -omgeving hebt gemaakt, kunt u de stappen van uw pijplijn definiëren. Er zijn veel ingebouwde stappen beschikbaar via de Azure Machine Learning SDK, zoals u kunt zien in de referentiedocumentatie voor het azureml.pipeline.steps
pakket. De meest flexibele klasse is PythonScriptStep, waarmee een Python-script wordt uitgevoerd.
from azureml.pipeline.steps import PythonScriptStep
dataprep_source_dir = "./dataprep_src"
entry_point = "prepare.py"
# `my_dataset` as defined above
ds_input = my_dataset.as_named_input('input1')
# `output_data1`, `compute_target`, `aml_run_config` as defined above
data_prep_step = PythonScriptStep(
script_name=entry_point,
source_directory=dataprep_source_dir,
arguments=["--input", ds_input.as_download(), "--output", output_data1],
compute_target=compute_target,
runconfig=aml_run_config,
allow_reuse=True
)
De bovenstaande code toont een typische eerste pijplijnstap. Uw gegevensvoorbereidingscode bevindt zich in een submap (in dit voorbeeld "prepare.py"
in de map "./dataprep.src"
). Als onderdeel van het proces voor het maken van de pijplijn wordt deze map gezipt en geüpload naar de compute_target
map en wordt het script uitgevoerd dat is opgegeven als de waarde voor script_name
.
De arguments
waarden geven de invoer en uitvoer van de stap op. In het bovenstaande voorbeeld zijn de basislijngegevens de my_dataset
gegevensset. De bijbehorende gegevens worden gedownload naar de rekenresource omdat de code deze opgeeft als as_download()
. Het script prepare.py
voert alle taken voor gegevenstransformatie uit die geschikt zijn voor de taak die bij de hand is en voert de gegevens uit naar output_data1
, van het type OutputFileDatasetConfig
. Zie Gegevens verplaatsen naar en tussen ML-pijplijnstappen (Python) voor meer informatie.
De stap wordt uitgevoerd op de computer die is gedefinieerd met compute_target
behulp van de configuratie aml_run_config
.
Hergebruik van eerdere resultaten (allow_reuse
) is belangrijk bij het gebruik van pijplijnen in een samenwerkingsomgeving, omdat het elimineren van onnodige nieuwe uitvoeringen flexibiliteit biedt. Hergebruik is het standaardgedrag wanneer de script_name, invoer en de parameters van een stap hetzelfde blijven. Wanneer hergebruik is toegestaan, worden de resultaten van de vorige uitvoering onmiddellijk verzonden naar de volgende stap. Als allow_reuse
deze optie is ingesteld False
, wordt er altijd een nieuwe uitvoering gegenereerd voor deze stap tijdens het uitvoeren van de pijplijn.
Het is mogelijk om een pijplijn met één stap te maken, maar bijna altijd kiest u ervoor om uw algehele proces in verschillende stappen te splitsen. U hebt bijvoorbeeld stappen voor gegevensvoorbereiding, training, modelvergelijking en implementatie. U kunt zich bijvoorbeeld voorstellen dat na de data_prep_step
bovenstaande opgegeven stap de volgende stap training kan zijn:
train_source_dir = "./train_src"
train_entry_point = "train.py"
training_results = OutputFileDatasetConfig(name = "training_results",
destination = def_blob_store)
train_step = PythonScriptStep(
script_name=train_entry_point,
source_directory=train_source_dir,
arguments=["--prepped_data", output_data1.as_input(), "--training_results", training_results],
compute_target=compute_target,
runconfig=aml_run_config,
allow_reuse=True
)
De bovenstaande code is vergelijkbaar met de code in de stap voor gegevensvoorbereiding. De trainingscode bevindt zich in een map die losstaat van die van de gegevensvoorbereidingscode. De OutputFileDatasetConfig
uitvoer van de stap voor gegevensvoorbereiding wordt output_data1
gebruikt als invoer voor de trainingsstap. Er wordt een nieuw OutputFileDatasetConfig
object training_results
gemaakt voor het opslaan van de resultaten voor een latere vergelijkings- of implementatiestap.
Zie voor andere codevoorbeelden hoe u een ML-pijplijn met twee stappen bouwt en hoe u gegevens terugschrijft naar gegevensarchieven wanneer de uitvoering is voltooid.
Nadat u de stappen hebt gedefinieerd, bouwt u de pijplijn met behulp van een of meer van deze stappen.
Notitie
Er worden geen bestanden of gegevens geüpload naar Azure Machine Learning wanneer u de stappen definieert of de pijplijn bouwt. De bestanden worden geüpload wanneer u Experiment.submit() aanroept.
# list of steps to run (`compare_step` definition not shown)
compare_models = [data_prep_step, train_step, compare_step]
from azureml.pipeline.core import Pipeline
# Build the pipeline
pipeline1 = Pipeline(workspace=ws, steps=[compare_models])
Een gegevensset gebruiken
Gegevenssets die zijn gemaakt op basis van Azure Blob Storage, Azure Files, Azure Data Lake Storage Gen1, Azure Data Lake Storage Gen2, Azure SQL Database en Azure Database for PostgreSQL kunnen worden gebruikt als invoer voor elke pijplijnstap. U kunt uitvoer schrijven naar een DataTransferStep, DatabricksStep of als u gegevens naar een specifiek gegevensarchief wilt schrijven, gebruikt u OutputFileDatasetConfig.
Belangrijk
Het schrijven van uitvoergegevens naar een gegevensarchief met behulp van OutputFileDatasetConfig
wordt alleen ondersteund voor gegevensarchieven van Azure Blob, Azure-bestandsshare, ADLS Gen 1 en Gen 2.
dataset_consuming_step = PythonScriptStep(
script_name="iris_train.py",
inputs=[iris_tabular_dataset.as_named_input("iris_data")],
compute_target=compute_target,
source_directory=project_folder
)
Vervolgens haalt u de gegevensset in uw pijplijn op met behulp van de Run.input_datasets woordenlijst.
# iris_train.py
from azureml.core import Run, Dataset
run_context = Run.get_context()
iris_dataset = run_context.input_datasets['iris_data']
dataframe = iris_dataset.to_pandas_dataframe()
De lijn Run.get_context()
is de moeite waard om te markeren. Met deze functie wordt een Run
weergave opgehaald van de huidige experimentele uitvoering. In het bovenstaande voorbeeld gebruiken we deze om een geregistreerde gegevensset op te halen. Een ander veelvoorkomend gebruik van het Run
object is het ophalen van zowel het experiment zelf als de werkruimte waarin het experiment zich bevindt:
# Within a PythonScriptStep
ws = Run.get_context().experiment.workspace
Zie Gegevens verplaatsen naar en tussen ML-pijplijnstappen (Python) voor meer informatie, waaronder alternatieve manieren om gegevens door te geven en te openen.
Opslaan in cache en opnieuw gebruiken
Als u het gedrag van uw pijplijnen wilt optimaliseren en aanpassen, kunt u een aantal dingen doen in de cache en opnieuw gebruiken. U kunt bijvoorbeeld het volgende doen:
- Schakel het standaardgebruik van de uitvoer van de stapuitvoering uit door deze in te stellen
allow_reuse=False
tijdens de stapdefinitie. Hergebruik is belangrijk bij het gebruik van pijplijnen in een samenwerkingsomgeving, omdat onnodige uitvoeringen overbodige uitvoeringen elimineren flexibiliteit biedt. U kunt zich echter afmelden voor hergebruik. - Uitvoerregeneratie afdwingen voor alle stappen in een uitvoering met
pipeline_run = exp.submit(pipeline, regenerate_outputs=True)
allow_reuse
Voor stappen is standaard ingeschakeld en wordt de source_directory
opgegeven in de stapdefinitie gehasht. Dus als het script voor een bepaalde stap hetzelfde blijft (script_name
invoer en de parameters), en niets anders in de source_directory
stap is gewijzigd, wordt de uitvoer van een vorige stap opnieuw gebruikt, wordt de taak niet verzonden naar de berekening en zijn de resultaten van de vorige uitvoering onmiddellijk beschikbaar voor de volgende stap.
step = PythonScriptStep(name="Hello World",
script_name="hello_world.py",
compute_target=aml_compute,
source_directory=source_directory,
allow_reuse=False,
hash_paths=['hello_world.ipynb'])
Notitie
Als de namen van de gegevensinvoer veranderen, wordt de stap opnieuw uitgevoerd, zelfs als de onderliggende gegevens niet worden gewijzigd. U moet het name
veld met invoergegevens (data.as_input(name=...)
) expliciet instellen. Als u deze waarde niet expliciet instelt, wordt het name
veld ingesteld op een willekeurige guid en worden de resultaten van de stap niet opnieuw gebruikt.
De pijplijn indienen
Wanneer u de pijplijn verzendt, controleert Azure Machine Learning de afhankelijkheden voor elke stap en uploadt u een momentopname van de bronmap die u hebt opgegeven. Als er geen bronmap is opgegeven, wordt de huidige lokale map geüpload. De momentopname wordt ook opgeslagen als onderdeel van het experiment in uw werkruimte.
Belangrijk
Als u wilt voorkomen dat onnodige bestanden worden opgenomen in de momentopname, maakt u een genegeerd bestand (.gitignore
of .amlignore
) in de map. Voeg de bestanden en mappen toe die u wilt uitsluiten van dit bestand. Zie de syntaxis en patronen voor .gitignore
meer informatie over de syntaxis die in dit bestand moet worden gebruikt. Het .amlignore
bestand gebruikt dezelfde syntaxis. Als beide bestanden bestaan, wordt het .amlignore
bestand gebruikt en wordt het .gitignore
bestand niet gebruikt.
Zie Momentopnamen voor meer informatie.
from azureml.core import Experiment
# Submit the pipeline to be run
pipeline_run1 = Experiment(ws, 'Compare_Models_Exp').submit(pipeline1)
pipeline_run1.wait_for_completion()
Wanneer u een pijplijn voor het eerst uitvoert, azure Machine Learning:
Hiermee downloadt u de momentopname van het project naar het rekendoel vanuit de Blob-opslag die aan de werkruimte is gekoppeld.
Hiermee bouwt u een Docker-installatiekopieën die overeenkomen met elke stap in de pijplijn.
Hiermee downloadt u de Docker-installatiekopieën voor elke stap naar het rekendoel uit het containerregister.
Hiermee configureert u de toegang tot
Dataset
enOutputFileDatasetConfig
objecten. Vooras_mount()
de toegangsmodus wordt FUSE gebruikt om virtuele toegang te bieden. Als koppelen niet wordt ondersteund of als de gebruiker toegang heeft opgegeven alsas_upload()
, worden de gegevens in plaats daarvan gekopieerd naar het rekendoel.Hiermee wordt de stap uitgevoerd in het rekendoel dat is opgegeven in de stapdefinitie.
Maakt artefacten, zoals logboeken, stdout en stderr, metrische gegevens en uitvoer die door de stap is opgegeven. Deze artefacten worden vervolgens geüpload en bewaard in het standaardgegevensarchief van de gebruiker.
Zie de naslaginformatie over experimentklassen voor meer informatie.
Pijplijnparameters gebruiken voor argumenten die tijdens deductietijd veranderen
Soms hebben de argumenten voor afzonderlijke stappen binnen een pijplijn betrekking op de ontwikkelings- en trainingsperiode: zaken zoals trainingssnelheden en momentum, of paden naar gegevens of configuratiebestanden. Wanneer een model wordt geïmplementeerd, wilt u echter dynamisch de argumenten doorgeven waarop u deductie uitvoert (dat wil zeggen de query die u hebt gemaakt om het model te beantwoorden).) U moet deze typen pijplijnparameters voor argumenten maken. Als u dit in Python wilt doen, gebruikt u de azureml.pipeline.core.PipelineParameter
klasse, zoals wordt weergegeven in het volgende codefragment:
from azureml.pipeline.core import PipelineParameter
pipeline_param = PipelineParameter(name="pipeline_arg", default_value="default_val")
train_step = PythonScriptStep(script_name="train.py",
arguments=["--param1", pipeline_param],
target=compute_target,
source_directory=project_folder)
Hoe Python-omgevingen werken met pijplijnparameters
Zoals eerder is besproken in de omgeving, omgevingsstatus en Python-bibliotheekafhankelijkheden van de trainingsuitvoering configureren, worden opgegeven met behulp van een Environment
object. Over het algemeen kunt u een bestaande Environment
opgeven door te verwijzen naar de naam en, optioneel, een versie:
aml_run_config = RunConfiguration()
aml_run_config.environment.name = 'MyEnvironment'
aml_run_config.environment.version = '1.0'
Als u er echter voor kiest om tijdens runtime variabelen dynamisch in te PipelineParameter
stellen voor uw pijplijnstappen, kunt u deze techniek niet gebruiken om naar een bestaande Environment
te verwijzen. Als u objecten wilt gebruiken PipelineParameter
, moet u het environment
veld van het RunConfiguration
object instellen op een Environment
object. Het is uw verantwoordelijkheid om ervoor te zorgen dat een dergelijk pakket Environment
afhankelijk is van externe Python-pakketten.
Resultaten van een pijplijn weergeven
Bekijk de lijst met al uw pijplijnen en de bijbehorende uitvoeringsdetails in de studio:
Meld u aan bij Azure Machine Learning Studio.
Selecteer aan de linkerkant Pijplijnen om alle pijplijnuitvoeringen weer te geven.
Selecteer een specifieke pijplijn om de uitvoeringsresultaten weer te geven.
Git-tracering en -integratie
Wanneer u een trainingsuitvoering start waarbij de bronmap een lokale Git-opslagplaats is, wordt informatie over de opslagplaats opgeslagen in de uitvoeringsgeschiedenis. Zie Git-integratie voor Azure Machine Learning voor meer informatie.
Volgende stappen
- Als u uw pijplijn wilt delen met collega's of klanten, raadpleegt u Machine Learning-pijplijnen publiceren
- Gebruik deze Jupyter-notebooks op GitHub om machine learning-pijplijnen verder te verkennen
- Raadpleeg de SDK-referentiehulp voor het pakket azureml-pipelines-core en het pakket azureml-pipelines-steps
- Zie de instructies voor tips over foutopsporing en probleemoplossing voor pijplijnen=
- Informatie over het uitvoeren van notebooks vindt u in het artikel Use Jupyter notebooks to explore this service (Jupyter Notebooks gebruiken om deze service te verkennen).