Ladění modelu pomocí Azure Machine Learning

automatizujte efektivní ladění parametrů pomocí Azure Machine Learning balíčku HyperDrive. naučte se, jak provést kroky potřebné k optimalizaci parametrů s Azure Machine Learning SDK:

  1. Definice hledaného prostoru parametrů
  2. Určení primární metriky k optimalizaci
  3. Zadat zásady prvotního ukončení pro nízkoúrovňové spouštění
  4. Vytváření a přiřazování prostředků
  5. Spustit experiment s definovanou konfigurací
  6. Vizualizace školicích běhů
  7. Vyberte nejlepší konfiguraci pro váš model.

Co je ladění parametrů?

V parametrech jsou seřiditelné parametry, které umožňují řídit proces školení modelu. Například u neuronové sítí určíte počet skrytých vrstev a počet uzlů v jednotlivých vrstvách. Výkon modelu závisí silně na parametrech.

Ladění parametrů, označované také jako optimalizace s parametry, je proces hledání konfigurace parametrů, jejichž výsledkem je nejlepší výkon. Tento proces je obvykle výpočetně nákladný a ruční.

Azure Machine Learning umožňuje automatizovat optimalizaci parametrů a paralelně spouštět experimenty, aby bylo možné efektivně optimalizovat parametry.

Definování prostoru pro hledání

Vyladěním parametrů můžete prozkoumat rozsah hodnot definovaných pro každý parametr.

Parametry mohou být diskrétní nebo souvislé a mají distribuci hodnot popsaných výrazem parametru.

Samostatné parametry

Diskrétní parametry jsou zadány jako choice mezi diskrétní hodnoty. choice může být:

  • jedna nebo více hodnot oddělených čárkami
  • rangeobjekt
  • libovolný list objekt
    {
        "batch_size": choice(16, 32, 64, 128)
        "number_of_hidden_layers": choice(range(1,5))
    }

V tomto případě batch_size jedna z hodnot [16, 32, 64, 128] a number_of_hidden_layers přebírá jednu z hodnot [1, 2, 3, 4].

Pomocí distribuce lze také zadat následující pokročilé samostatné parametry:

  • quniform(low, high, q) -Vrátí hodnotu, třeba Round (Uniform (nízká, High)/q) * q.
  • qloguniform(low, high, q) -Vrátí hodnotu jako Round (EXP (Uniform (nízká, High)/q) * q.
  • qnormal(mu, sigma, q) -Vrátí hodnotu, jako je Round (normální (mu, Sigma)/q) * q.
  • qlognormal(mu, sigma, q) -Vrátí hodnotu, jako je Round (EXP (normální (mu, Sigma))/q) * q

Souvislé parametry

Průběžné parametry jsou zadány jako distribuce pro souvislý rozsah hodnot:

  • uniform(low, high) -Vrátí hodnotu rovnoměrně distribuovanou mezi dolní a vysokou hodnotou.
  • loguniform(low, high) -Vrátí hodnotu vykreslenou podle EXP (Uniform (Low, High)), aby byl logaritmus návratové hodnoty stejnoměrně distribuován.
  • normal(mu, sigma) – Vrátí reálnou hodnotu, která je normálně distribuována se středníky a směrodatnou odchylkou Sigma.
  • lognormal(mu, sigma) -Vrátí hodnotu vykreslenou podle EXP (Normal (mu, Sigma)), aby byl standardně distribuován logaritmus návratové hodnoty.

Příklad definice prostoru parametrů:

    {    
        "learning_rate": normal(10, 3),
        "keep_probability": uniform(0.05, 0.1)
    }

Tento kód definuje prostor pro hledání se dvěma parametry – learning_rate a keep_probability . learning_rate má normální distribuci s střední hodnotou 10 a směrodatnou odchylku 3. keep_probability má jednotnou distribuci s minimální hodnotou 0,05 a maximální hodnotou 0,1.

Vzorkování prostoru s parametrem

Zadejte metodu vzorkování parametrů, která se má použít v prostoru s parametrem. Azure Machine Learning podporuje následující metody:

  • Náhodný výběr
  • Vzorkování mřížky
  • Bayesovské vzorkování

Náhodný výběr

Náhodné vzorkování podporuje diskrétní a souvislé parametry. Podporuje předčasné ukončení běhu s nízkým výkonem. Někteří uživatelé provedou počáteční vyhledávání s náhodným vzorkováním a pak upřesníte prostor pro hledání za účelem zlepšení výsledků.

V případě náhodného vzorkování jsou hodnoty s parametry náhodně vybrány z definovaného prostoru hledání.

from azureml.train.hyperdrive import RandomParameterSampling
from azureml.train.hyperdrive import normal, uniform, choice
param_sampling = RandomParameterSampling( {
        "learning_rate": normal(10, 3),
        "keep_probability": uniform(0.05, 0.1),
        "batch_size": choice(16, 32, 64, 128)
    }
)

Vzorkování mřížky

Vzorkování mřížky podporuje samostatné parametry. Vzorkování mřížky použijte v případě, že můžete rozpočtovat do vyčerpání prostoru pro hledání. Podporuje předčasné ukončení běhu s nízkým výkonem.

Vzorkování mřížky provádí jednoduché hledání v mřížce přes všechny možné hodnoty. Vzorkování mřížky lze použít pouze s choice parametry. Například následující místo má šest vzorků:

from azureml.train.hyperdrive import GridParameterSampling
from azureml.train.hyperdrive import choice
param_sampling = GridParameterSampling( {
        "num_hidden_layers": choice(1, 2, 3),
        "batch_size": choice(16, 32)
    }
)

Bayesovské vzorkování

Vzorkování bayesovského rozhodování je založené na algoritmu optimalizace bayesovského rozhodování. Vybírá ukázky na základě předchozích vzorků, takže nové ukázky zlepšují primární metriku.

Vzorkování bayesovského rozhodování se doporučuje, pokud máte dostatečný rozpočet na prozkoumání prostoru s parametrem. Pro dosažení nejlepších výsledků doporučujeme maximální počet spuštění, který je větší nebo roven 20, počtu vyladěných parametrů.

Počet souběžných spuštění má vliv na efektivitu procesu optimalizace. Menší počet souběžných spuštění může vést k lepší konvergenci vzorkování, protože menší stupeň paralelismu zvyšuje počet spuštění s výhodou dříve dokončených spuštění.

Vzorkování bayesovského rozhodování podporuje jenom choice uniform distribuce, a v quniform prostoru pro hledání.

from azureml.train.hyperdrive import BayesianParameterSampling
from azureml.train.hyperdrive import uniform, choice
param_sampling = BayesianParameterSampling( {
        "learning_rate": uniform(0.05, 0.1),
        "batch_size": choice(16, 32, 64, 128)
    }
)

Zadat primární metriku

Určete primární metriku , která má optimalizovat laděním parametrů. U každého výukového běhu se vyhodnocuje primární metrika. Zásady prvotního ukončení používají primární metriku k identifikaci spuštění s nízkým výkonem.

Zadejte následující atributy pro primární metriku:

  • primary_metric_name: Název primární metriky musí přesně odpovídat názvu metriky zaznamenané školicím skriptem.
  • primary_metric_goal: Může být buď PrimaryMetricGoal.MAXIMIZE nebo PrimaryMetricGoal.MINIMIZE , a určuje, zda bude primární metrika maximalizována nebo minimalizována při vyhodnocování spuštění.
primary_metric_name="accuracy",
primary_metric_goal=PrimaryMetricGoal.MAXIMIZE

Tato ukázka maximalizuje přesnost.

Metriky protokolu pro ladění parametrů

Školicí skript pro váš model musí během školení modelu protokolovat primární metriku, aby k nim Hyperdrive měl přístup pro ladění pomocí parametrů.

Zaprotokolujte primární metriku ve školicím skriptu pomocí následujícího ukázkového fragmentu kódu:

from azureml.core.run import Run
run_logger = Run.get_context()
run_logger.log("accuracy", float(val_accuracy))

Školicí skript vypočítá val_accuracy a zaznamená jako přesnost primární metriky. Pokaždé, když se metrika zaznamená, obdrží ji služba pro ladění pomocí parametrů. Můžete určit četnost generování sestav.

další informace o hodnotách protokolování v běhu školicích kurzů najdete v tématu povolení protokolování ve službě Azure ML školicích běhů.

Zadat zásady prvotního ukončení

Automatické ukončení nedostatečně výkonného spuštění se zásadami předčasného ukončení. Předčasné ukončení vylepšuje výpočetní efektivitu.

Můžete nakonfigurovat následující parametry, které řídí, kdy se zásada použije:

  • evaluation_interval: frekvence použití zásad. Pokaždé, když školicí skript zaznamená primární metriku, počítá se jako jeden interval. V případě evaluation_interval 1 bude zásada použita pokaždé, když skript školení ohlásí primární metriku. U evaluation_interval 2 se zásada použije kdykoli. Pokud není zadán, evaluation_interval je ve výchozím nastavení nastaveno na hodnotu 1.
  • delay_evaluation: zpoždění prvního vyhodnocení zásad pro zadaný počet intervalů. Toto je volitelný parametr, který brání předčasnému ukončení školicích běhů tím, že umožňuje spuštění všech konfigurací v případě minimálního počtu intervalů. Když se tato zásada zadá, uplatní se všechny násobky evaluation_interval, které jsou větší nebo rovny delay_evaluation.

Azure Machine Learning podporuje následující zásady prvotního ukončení:

Zásady Bandit

Zásada Bandit je založená na rozsahu časové rezervy/rezervy a intervalu vyhodnocení. Bandit se spustí, když primární metrika není v rámci zadaného faktoru časové rezervy nebo časové rezervy z úspěšného spuštění.

Poznámka

Vzorkování bayesovského rozhodování nepodporuje předčasné ukončení. Při použití vzorkování bayesovského rozhodování nastavte early_termination_policy = None .

Zadejte následující parametry konfigurace:

  • slack_factor nebo slack_amount : časová rezerva povolená s ohledem na nejlepší provádění školicích běhů. slack_factor Určuje povolenou časovou rezervu jako poměr. slack_amount Určuje povolenou časovou rezervu jako absolutní hodnotu namísto poměru.

    Představte si třeba zásady Bandit použité v intervalu 10. Předpokládejme, že nejlepší provádění v intervalu 10 oznámilo primární metriku je 0,8 s cílem maximalizovat primární metriku. Pokud zásada specifikuje slack_factor 0,2, budou všechny školicí běhy, jejichž nejlepší metrika v intervalu 10 je nižší než 0,66 (0,8/(1 + slack_factor )), budou ukončeny.

  • evaluation_interval: (volitelné) frekvence použití zásad

  • delay_evaluation: (volitelné) odloží první vyhodnocení zásad pro zadaný počet intervalů.

from azureml.train.hyperdrive import BanditPolicy
early_termination_policy = BanditPolicy(slack_factor = 0.1, evaluation_interval=1, delay_evaluation=5)

V tomto příkladu se zásada prvotního ukončení používá v každém intervalu při hlášení metrik počínaje v intervalu vyhodnocení 5. Jakékoli spuštění, jejichž nejlepší metrika je menší než (1/(1 + 0,1) nebo 91% nejlepšího spuštění, se ukončí.

Medián – zastavení zásad

Medián při zastavení je zásada předčasného ukončení založená na běžících průměrech primárních metrik, které běhy oznámily. Tato zásada vypočítá průměry na všech školicích běhů a zastaví spuštění, jejichž primární hodnota metriky je horší než střední hodnota průměrů.

Tato zásada přijímá následující konfigurační parametry:

  • evaluation_interval: frekvence použití zásad (volitelného parametru).
  • delay_evaluation: zpoždění prvního vyhodnocení zásad pro zadaný počet intervalů (volitelný parametr).
from azureml.train.hyperdrive import MedianStoppingPolicy
early_termination_policy = MedianStoppingPolicy(evaluation_interval=1, delay_evaluation=5)

V tomto příkladu se zásady prvotního ukončení aplikují v intervalu vyhodnocení 5 v každém intervalu. Běh se zastavil v intervalu 5, pokud je jeho nejlepší primární metrika horší než střední hodnota průměrů spuštěných v intervalech 1:5 v rámci všech školicích běhů.

Zásada výběru zkrácení

Výběr zkrácení zruší procento nejnižších běhů běhu v každém intervalu vyhodnocení. Běhy se porovnávají s použitím primární metriky.

Tato zásada přijímá následující konfigurační parametry:

  • truncation_percentage: procento nejnižších běhů běhu pro ukončení v každém intervalu vyhodnocení. Celočíselná hodnota v rozmezí od 1 do 99.
  • evaluation_interval: (volitelné) frekvence použití zásad
  • delay_evaluation: (volitelné) odloží první vyhodnocení zásad pro zadaný počet intervalů.
from azureml.train.hyperdrive import TruncationSelectionPolicy
early_termination_policy = TruncationSelectionPolicy(evaluation_interval=1, truncation_percentage=20, delay_evaluation=5)

V tomto příkladu se zásady prvotního ukončení aplikují v intervalu vyhodnocení 5 v každém intervalu. Spuštění skončí v intervalu 5, pokud je jeho výkon v intervalu 5 v nejnižší 20% výkonu všech běhů v intervalu 5.

Žádné zásady ukončení (výchozí)

Pokud není zadána žádná zásada, bude služba ladění u parametrů nastavena na dokončení všech školicích běhů.

policy=None

Vybírání zásad prvotního ukončení

  • Pro konzervativní zásadu, která poskytuje úspory bez ukončení přislíbení úloh, zvažte střední zastavování zásad s evaluation_interval 1 a delay_evaluation 5. Jedná se o konzervativní nastavení, které může poskytovat přibližně 25 až 35% úspory bez ztráty primární metriky (na základě našich zkušebních údajů).
  • Pro efektivnější úspory použijte zásady Bandit s menší povolenou časovou rezervou nebo zkrácenými zásadami výběru s větším procentem zkrácení.

Vytváření a přiřazování prostředků

Určete svůj rozpočet prostředků zadáním maximálního počtu běhů cvičení.

  • max_total_runs: Maximální počet běhů cvičení. Musí být celé číslo v rozmezí od 1 do 1000.
  • max_duration_minutes: (volitelné) maximální doba trvání experimentu ladění parametrů v řádu minut. Spustí se po zrušení této doby.

Poznámka

Pokud max_total_runs max_duration_minutes jsou zadány oba a, experiment ladění s parametry se ukončí při dosažení prvního z těchto dvou mezních hodnot.

Navíc můžete zadat maximální počet běhů cvičení, které mají být spuštěny souběžně během vyhledávání laděním parametrů.

  • max_concurrent_runs: (volitelné) maximální počet spuštění, který může běžet souběžně. Pokud tento parametr nezadáte, spustí se všechny spuštění paralelně. Je-li tento parametr zadán, musí být celé číslo v rozmezí od 1 do 100.

Poznámka

Počet souběžných spuštění je gated u prostředků, které jsou k dispozici v zadaném cíli výpočtu. Ujistěte se, že cíl výpočtů má dostupné prostředky pro požadovanou souběžnost.

max_total_runs=20,
max_concurrent_runs=4

Tento kód nakonfiguruje experiment vyladěním parametrů, aby používal maximálně 20 spuštění celkem, současně se čtyřmi konfiguracemi.

Konfigurovat experiment s optimalizací parametrů

Chcete-li nakonfigurovat experiment s optimalizací parametrů , zadejte následující:

  • Definovaný prostor pro hledání parametrů
  • Zásady předčasného ukončení
  • Primární metrika
  • Nastavení přidělení prostředků
  • ScriptRunConfig script_run_config

ScriptRunConfig je školicí skript, který se spustí s ukázkovými parametry. Definuje prostředky na úlohu (jeden nebo víc uzlů) a výpočetní cíl, který se má použít.

Poznámka

Cílový výpočetní výkon, který se používá v nástroji, script_run_config musí mít dostatek prostředků pro uspokojení vaší úrovně souběžnosti. Další informace o ScriptRunConfig najdete v tématu Konfigurace školicích běhů.

Konfigurace experimentu ladění vašich parametrů:

from azureml.train.hyperdrive import HyperDriveConfig
from azureml.train.hyperdrive import RandomParameterSampling, BanditPolicy, uniform, PrimaryMetricGoal

param_sampling = RandomParameterSampling( {
        'learning_rate': uniform(0.0005, 0.005),
        'momentum': uniform(0.9, 0.99)
    }
)

early_termination_policy = BanditPolicy(slack_factor=0.15, evaluation_interval=1, delay_evaluation=10)

hd_config = HyperDriveConfig(run_config=script_run_config,
                             hyperparameter_sampling=param_sampling,
                             policy=early_termination_policy,
                             primary_metric_name="accuracy",
                             primary_metric_goal=PrimaryMetricGoal.MAXIMIZE,
                             max_total_runs=100,
                             max_concurrent_runs=4)

HyperDriveConfigNastaví parametry předané do ScriptRunConfig script_run_config . script_run_configZase předává parametry do skriptu pro školení. Výše uvedený fragment kódu je pořízen z ukázkového výukového poznámkového bloku , pomocí ladění a nasazení pomocí PyTorch. V této ukázce learning_rate momentum budou vyladěny parametry a. Předčasné zastavování spuštění bude určeno pomocí BanditPolicy , což zastaví běh, jehož primární metrika spadá mimo slack_factor (viz Referenční dokumentace třídy BanditPolicy).

Následující kód z ukázky ukazuje, jak jsou přiladěny hodnoty přijímány, analyzovány a předány funkci školicího skriptu fine_tune_model :

# from pytorch_train.py
def main():
    print("Torch version:", torch.__version__)

    # get command-line arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--num_epochs', type=int, default=25,
                        help='number of epochs to train')
    parser.add_argument('--output_dir', type=str, help='output directory')
    parser.add_argument('--learning_rate', type=float,
                        default=0.001, help='learning rate')
    parser.add_argument('--momentum', type=float, default=0.9, help='momentum')
    args = parser.parse_args()

    data_dir = download_data()
    print("data directory is: " + data_dir)
    model = fine_tune_model(args.num_epochs, data_dir,
                            args.learning_rate, args.momentum)
    os.makedirs(args.output_dir, exist_ok=True)
    torch.save(model, os.path.join(args.output_dir, 'model.pt'))

Důležité

Každý parametr spustí restart od začátku, včetně opětovného sestavení modelu a všech datových zavaděčů. tyto náklady můžete minimalizovat pomocí Azure Machine Learningho kanálu nebo ručního procesu k tomu, abyste mohli co nejvíce připravit data před spuštěním vašich školicích kurzů.

Odeslat experiment s optimalizací parametrů

Po definování konfigurace ladění vašich parametrů odešlete experiment:

from azureml.core.experiment import Experiment
experiment = Experiment(workspace, experiment_name)
hyperdrive_run = experiment.submit(hd_config)

Rychlé spuštění ladění parametrů (volitelné)

Hledání nejlepších hodnot parametrů pro váš model může být iterativní proces. Pokud chcete zrychlit ladění parametrů, můžete znovu použít znalostní bázi z pěti předchozích běhů.

Zahřívání od začátku se zpracovává jinak v závislosti na metodě vzorkování:

  • Vzorkování bayesovského rozhodování: pro výběr nových ukázek a pro zlepšení primární metriky se používají zkušební verze předchozího běhu jako předchozí znalosti.
  • Náhodný odběr vzorkování nebo mřížky: předčasné ukončení používá k určení nedostatečně výkonného spuštění znalosti z předchozích spuštění.

Zadejte seznam nadřazených spuštění, ze kterých chcete začít zahřívání.

from azureml.train.hyperdrive import HyperDriveRun

warmstart_parent_1 = HyperDriveRun(experiment, "warmstart_parent_run_ID_1")
warmstart_parent_2 = HyperDriveRun(experiment, "warmstart_parent_run_ID_2")
warmstart_parents_to_resume_from = [warmstart_parent_1, warmstart_parent_2]

Pokud se zruší experimentování s laděním parametrů, můžete pokračovat v školicích běhůch z posledního kontrolního bodu. Školicí skript však musí zpracovat logiku kontrolního bodu.

Školicí běh musí používat stejnou konfiguraci parametrů a připojit složky výstupy. Školicí skript musí souhlasit s resume-from argumentem, který obsahuje soubor kontrolního bodu nebo soubory modelu, ze kterých se má pokračovat v běhu školení. Můžete obnovit jednotlivé běhy školení pomocí následujícího fragmentu kódu:

from azureml.core.run import Run

resume_child_run_1 = Run(experiment, "resume_child_run_ID_1")
resume_child_run_2 = Run(experiment, "resume_child_run_ID_2")
child_runs_to_resume = [resume_child_run_1, resume_child_run_2]

Experiment ladění vašich parametrů můžete nakonfigurovat tak, aby začal začínat od předchozího experimentu, nebo obnovit jednotlivé školicí běhy pomocí volitelných parametrů resume_from a resume_child_runs v konfiguraci:

from azureml.train.hyperdrive import HyperDriveConfig

hd_config = HyperDriveConfig(run_config=script_run_config,
                             hyperparameter_sampling=param_sampling,
                             policy=early_termination_policy,
                             resume_from=warmstart_parents_to_resume_from,
                             resume_child_runs=child_runs_to_resume,
                             primary_metric_name="accuracy",
                             primary_metric_goal=PrimaryMetricGoal.MAXIMIZE,
                             max_total_runs=100,
                             max_concurrent_runs=4)

Vizualizace spuštění laděním parametrů

pomocí widgetu poznámkového bloku můžete vizualizovat vaše běhy ladění vašich parametrů v Azure Machine Learning studiu.

Studio

v Azure Machine Learning studiumůžete vizualizovat všechna spuštění ladění vašich parametrů. Další informace o tom, jak zobrazit experiment na portálu, najdete v tématu zobrazení záznamů spuštění v nástroji Studio.

  • Graf metrik: Tato vizualizace sleduje metriky zaznamenané pro každou podřízenou položku Hyperdrive, která se spouští po dobu trvání ladění parametrů. Každý řádek představuje podřízený běh a každý bod měří primární hodnotu metriky v této iteraci modulu runtime.

    Graf metrik ladění parametrů

  • Graf paralelních souřadnic: Tato vizualizace zobrazuje korelaci mezi primárním výkonem metriky a hodnotami jednotlivých parametrů. Graf je interaktivní pohybem os (kliknutím a přetažením podle popisku osy) a zvýrazněním hodnot na jedné ose (kliknutím a přetažením svisle podél jedné osy zvýrazněte rozsah požadovaných hodnot). Graf paralelních souřadnic obsahuje osu na pravé většině částí grafu, která vykresluje nejlepší hodnotu metriky odpovídající hyperparametrům nastaveným pro danou instanci spuštění. Tato osa je k dispozici pro zobrazení legendy přechodu grafu na data čitelným způsobem.

    Graf paralelních souřadnic ladění hyperparametrů

  • 2dimenzionální bodový graf: Tato vizualizace ukazuje korelaci mezi libovolnými dvěma jednotlivými hyperparametry a jejich přidruženou primární hodnotou metriky.

    Dvourozměrný bodový graf pro ladění parametrů

  • Trojrozměrný bodový graf: Tato vizualizace je stejná jako 2D, ale umožňuje tři rozměry hyperparametrů korelace s hodnotou primární metriky. Také můžete kliknutím a přetažením změnit orientaci grafu a zobrazit různé korelace ve 3D prostoru.

    Trojrozměrný bodový graf pro ladění parametrů

Widget poznámkového bloku

Pomocí widgetu Poznámkový blok můžete vizualizovat průběh trénování. Následující fragment kódu vizualizovat všechna vaše ladění hyperparametrů běží na jednom místě v poznámkovém bloku Jupyter:

from azureml.widgets import RunDetails
RunDetails(hyperdrive_run).show()

Tento kód zobrazí tabulku s podrobnostmi o spuštěních trénování pro každou konfiguraci hyperparametrů.

Tabulka ladění hyperparametrů

Při trénování můžete také vizualizovat výkon jednotlivých spuštění.

Vyhledání nejlepšího modelu

Po dokončení všech spuštění ladění hyperparametrů identifikujte hodnoty konfigurace s nejlepším výkonu a hyperparametrů:

best_run = hyperdrive_run.get_best_run_by_primary_metric()
best_run_metrics = best_run.get_metrics()
parameter_values = best_run.get_details()['runDefinition']['arguments']

print('Best Run Id: ', best_run.id)
print('\n Accuracy:', best_run_metrics['accuracy'])
print('\n learning rate:',parameter_values[3])
print('\n keep probability:',parameter_values[5])
print('\n batch size:',parameter_values[7])

Ukázkový poznámkový blok

Projděte si poznámkové bloky train-hyperparameter-* v této složce:

Postupujte podle pokynů v článku věnovaném využití poznámkových bloků Jupyter k prozkoumání této služby a zjistěte, jak provozovat poznámkové bloky.

Další kroky