Amazon Web Services ブログ

Amazon SageMaker 自動モデルチューニングによる高精度なモデル、高速化

Amazon SageMaker では、このほど、機械学習モデルのハイパーパラメータ値を自動的に調整することで、より正確な予測を生成できる機能をリリースしました。ハイパーパラメータは、トレーニング中にアルゴリズムがどのように動作するかを示すユーザー定義の設定です。例としては、データを繰り返し処理する毎に、決定木のサイズを拡張する方法、セグメンテーションで必要なクラスタの数やニューラルネットワークの重み付けを更新する方法などがあります。

機械学習モデルに適したハイパーパラメータ値を選択することは、最終的な精度とパフォーマンスに大きな影響を与える可能性があるため重要です。しかしながら、ハイパーパラメータ値を設定するプロセスは難しい場合があります。正しいやり方はデータによって異なります。アルゴリズムによっては、調整が可能なさまざまなハイパーパラメータがあります。一部のハイパーパラメータは、選択した値に対して他のパラメータよりも敏感に反応します。ほとんどの場合、モデルフィットとハイパーパラメータ値の間には非線形の関係があります。

ハイパーパラメータ値を選択するためのさまざまな方策があります。一部のサイエンティストは、ドメイン知識、経験則、直感、または手動の実験を活用します。他のサイエンティストは力まかせ探索を使用します。いくつかのメタモデルを構築して、どのようなハイパーパラメータ値がうまくいくか予測します。このアプローチの詳細については、Shahriari et alを参照してください。(2016) 方法にかかわらず、ハイパーパラメータ値の選択によっては、新たな機械学習の問題を解決するための特殊なスキルセットを必要になる場合があります。

Amazon SageMaker 自動モデルチューニングを使えば、この作業が容易になります。 ガウス過程回帰 (Gaussian Process regression) を使用して、どのパラメータ値がフィットを改善するのに最も効果的かを予測します。また、ベイズ最適化を使用して、ハイパーパラメータの領域の探索と特定のハイパーパラメータ値の利用が適切な場合にバランスをとることができます。また、重要なポイントとして、Amazon SageMakerの組み込みアルゴリズム、あらかじめ構築された詳細な深層学習フレームワーク、独自アルゴリズムコンテナを使って、自動モデルチューニングを使用することができます。

本ブログ記事では、Amazon SageMakerでハイパーパラメータチューニングを実行し、2つの方法を比較する方法を紹介します。つまり、自動モデルチューニングとランダム検索です。 単純に無作為に選んだハイパーパラメータ値は、最終的なフィットとそれに到達するために必要なジョブの数の両方に適したベースラインとしてしばしば利用できます。最先端の方法にも匹敵する方法です。

問題の概要

本記事では、全体的なアプローチについて説明します。 詳細と完全なステップバイステップの使い方については、対応する例・ノート

使用するデータセットは、一般的なコンピュータビジョンベンチマークである CIFAR-10 画像データセット。 これは、60K 32×32 ピクセルのカラー画像 (50K トレイン、10Kテスト) で構成され、10 クラスに均等に分散しています。そのサイズは、ダウンロードするには十分に小さく、1つのインスタンスでトレーニングを行います。しかし、さまざまなアプローチの違いがハイライトされるので難しい作業です。

私たちは、Amazon SageMaker MXNetコンテナを使用して、ResNet-34 畳み込み画像分類ニューラルネットワークをトレーニングし、確率的勾配降下を使用してネットワークの重みを見つけます。すべてのジョブ実行に対して、単一の ml.p3.8xlarge インスタンスで、エポックを 50、ミニバッチサイズを 1,024 に修正します。私たちの目標は、ハイパーパラメータのチューニングを通してホールドアウトによる分類精度を向上させる方法と、各チューニング方法がどのように機能するかを示すことです。

この例をエンドツーエンドで実行すると約 400 USD の費用がかかります。

トレーニング

一度デフォルトのハイパーパラメータ値を使って、シンプルにモデルをトレーニングしてみましょう。 確率的勾配降下 (SGD) を使用して畳み込みニューラルネットワーク (CNN) をトレーニングしています。これは、トレーニング損失を改善するネットワーク重みを変更する方向を見つけることでトレーニング損失を最小限に抑える方法です。SGD はその方向の重みを少し更新して繰り返します。これらの3つのハイパーパラメータに焦点を当てます :

  • learning_rate: 重みに対して行う更新の大きさを制御します。
  • momentum: 前回の更新の方向からの情報を使い、現在の更新を知らせます。 デフォルト値 0 は、現在のバッチ内の情報のみに基づいて重みの更新が行われることを意味します。
  • wd: 重みが大きすぎると不利になります。 デフォルト値の 0 はペナルティなしを意味します。

Amazon SageMaker でトレーニングジョブを開始するには、MXNet エスティメーターを作成し、次のような情報を渡します。

  • トレーニングスクリプト (cifar10.py は、モデルを定義してトレーニングするための標準的な MXNet Gluon コード)
  • IAMロール
  • ハードウェア設定
  • ハイパーパラメータ (MXNetのSGD のデフォルト値)
from sagemaker.mxnet import MXNet

m = MXNet('cifar10.py',
          role=role,
          train_instance_count=1,
          train_instance_type='ml.p3.8xlarge',
          hyperparameters={'batch_size': 1024,
                           'epochs': 50,
                           'learning_rate': 0.01,
                           'momentum': 0.,
                           'wd': 0.})
m.fit('s3://sagemaker-<region>-<account>/data/DEMO-gluon-cifar10')

このトレーニングジョブのログでは、デフォルトのハイパーパラメータ値を使った場合、検証データセットで約 53% の精度しか得られないことが示されています。CIFAR-10 は難しいかもしれませんが、現状よりも精度を上げたいと思っています。

ランダム検索

非常にシンプルに実行できるハイパーパラメータチューニングの方法の1つは、設定範囲内でさまざまなランダムなハイパーパラメータ値で独立したトレーニングジョブセットを試すことです。私たちのユースケースでは、これを実行するためにヘルパースクリプト random_tuner.py を作成しました。raw code で詳細を確認できますが、その核となる部分には次のものを提供する必要があります。

  • つまり、ジョブ名とハイパーパラメータのリストを与えられた MXNet モデルをトレーニングする関数。wait をfalseに設定するため fit() 関数の呼び出し、複数のジョブを一度にトレーニングできることに注意してください。
    def fit_random(job_name, hyperparameters):
        m = MXNet('cifar10.py',
                  role=role,
                  train_instance_count=1,
                  train_instance_type='ml.p3.8xlarge',
                  hyperparameters=hyperparameters)
        m.fit(inputs, wait=False, job_name=job_name)
    
  • (ContinuousParameterIntegerParameterCategoricalParameter) のいずれかに調整したいものを定義し、適切な最小値と最大値の範囲、あるいは可能な値のリストを提供するハイパーパラメータのディクショナリ。
    import random_tuner as rt
    
    hyperparameters = {'batch_size': 1024,
                       'epochs': 50,
                       'learning_rate': rt.ContinuousParameter(0.001, 0.5),
                       'momentum': rt.ContinuousParameter(0., 0.99),
                       'wd': rt.ContinuousParameter(0., 0.001)}
    

以下でランダム検索を開始することができます。トレーニングジョブの総数が 120 に設定され、最大 8 つのジョブが並行して実行されます。 理論的には、パフォーマンスを損なうことなく 120 件のジョブを一度に実行できます。 しかし、一度に多くのジョブを開始することにはリスクがあります。 一度コードを正常にテストしたとしても、異なるハイパーパラメータ値がシステムリソースを使い果たしたり、何らかの理由で致命的な失敗になる可能性があります。 それがハイパーパラメータ空間の大部分でこのようなケースになった場合、多くの失敗ジョブで損失をこうむる可能性があります。 8 つのジョブを実行することに意欲的でも、必要に応じて原因を突き止め検索の一部を停止します。

jobs = rt.random_search(fit_random,
                        hyperparameters,
                        max_jobs=120,
                        max_parallel_jobs=8)

実行中のジョブの上と下では、精度に大きなばらつきがあることがわかります。学習率を 0.5、運動量を 0.15、重量減を 0.0004 に設定した場合、20% 以上の精度を得ることができます。( イメージクラスをランダムに推測すると 10% の精度が得られます。) しかし、うまくいった多くのハイパーパラメータ値の組み合わせを見出し、73.7% のピークの妥当な精度を得ることもできました。


自動モデルチューニング

では、Amazon SageMaker の自動モデルチューニングとランダム検索の比較を見ていきましょう。 Amazon SageMaker Python SDK に既に組み込まれているチューナー機能を使用します。 新しい MXNetエスチメーターを定義します。 (定義済みの batch_sizeepochs を指定し、調整したいハイパーパラメータは除外します,)

mt = MXNet('cifar10.py',
           role=role,
           train_instance_count=1,
           train_instance_type='ml.p3.8xlarge',
           hyperparameters={'batch_size': 1024,
                            'epochs': 50})

次に、チューニングしたいハイパーパラメータの範囲を定義しましょう。

from sagemaker.tuner import IntegerParameter, CategoricalParameter, ContinuousParameter

hyperparameter_ranges = {'learning_rate': ContinuousParameter(0.001, 0.5),
                         'momentum': ContinuousParameter(0., 0.99),
                         'wd': ContinuousParameter(0., 0.001)}

最後に、客観的なメトリックを定義し、Amazon CloudWatch logs 内のトレーニングジョブのログからそれを取り除くのに必要な正規表現を提供します。

objective_metric_name = 'Validation-accuracy'
metric_definitions = [{'Name': 'Validation-accuracy',
                       'Regex': 'validation: accuracy=([0-9\\.]+)'}]

これらを HyperparameterTuner クラスに渡し、 .fit() を実行します。これにより、一度に2つのトレーニングジョブ 30 件をサブミットし、Amazon SageMaker はすべてをバックグラウンドでオーケストレーションして実行します。 ランダム検索と同様に、トレーニングジョブの合計と並列ジョブの比率を同じ15倍にしました。 これは、両方がほぼ同じ時間で完了することを意味します。自動モデルチューニングでは、前に実行したジョブのパフォーマンスを使って見込みのハイパーパラメータ値を取得して、一度に実行するジョブの数を減らしモデルフィットが向上します。

from sagemaker.tuner import HyperparameterTuner

tuner = HyperparameterTuner(mt,
                            objective_metric_name,
                            hyperparameter_ranges,
                            metric_definitions,
                            max_jobs=30,
                            max_parallel_jobs=2)

tuner.fit('s3://sagemaker-<region>-<account>/data/DEMO-gluon-cifar10')

結果として、トレーニングのジョブの 1/4 において、Amazon SageMaker 自動モデルチューニングによって、ランダム検索よりも精度の高いモデル (74%) が作成されたことがわかりました。 その後の実行では、両者の方法において全体で最も高い精度がわずかに変化する可能性があることに注意してください。しかし、この実験において、「より少ない実行で精度を向上させる」というメッセージに変更はありません。


まとめ

本ブログ記事は、ハイパーパラメータチューニングの重要性を示しました。この手法を使用して、全体的なモデルのパフォーマンスを向上させることができます。さらに、Amazon SageMaker の自動モデルチューニングのような効率的な方法を使用して調整することもできます。

私たちの結果を上回ることができる方法があります。グリッド検索のような別のチューニング方法をテストすることができました。 グリッド検索は、重要な手法のひとつです。概念化が容易で、ハイパーパラメータ空間についての直感を得るのに役立ちます。しかし、ランダム検索 (Bergstra and Bengio, 2012)。 追加のハイパーパラメータをチューニングすることもできます。 または、1回目のハイパーパラメータチューニングを使用して範囲をさらに絞り込んで、2回目に通知することもできます。 留意すべき最も重要な点は、Amazon SageMaker 自動モデルチューニングは、組み込みアルゴリズム、深層学習フレームワーク、および Amazon SageMaker の独自のコンテナアルゴリズムを使用して動作するので、トレーニング中のモデルに適用できることです。

Amazon SageMaker 自動モデルチューニングの使用に関する詳細については、このポストの 対応するノート例・ノート および ドキュメント

 

今回のブログ投稿者について

David Arpin は、AWS Professional Services のデータサイエンスプラクティスマネージャーです。Amazon のデータサイエンスチームをマネージメントし、Amazon SageMaker チームのプロダクトマネージャーとして務めてました。