Cloud TPU(TF 2.x)での NCF のトレーニング

概要

これは、Neural Matrix Factorization(NeuMF)モデルを使用したニューラル コラボレーション フィルタリング(NCF)フレームワークの実装です。詳細は、ニューラル コラボレーション フィルタリングのレポートで説明されています。現在の実装は、作成者の NCF コードと、MLPerf Repo の Stanford 実装のコードに基づきます。

NCF は、ニューラル ネットワーク アーキテクチャを使用してユーザー インタラクションのインタラクションをモデル化するための推奨事項のコラボレーション フィルタリングの一般的なフレームワークです。従来のモデルとは異なり、NCF はユーザーやアイテムの潜在機能に関する内積がある行列分解(MF)に依存しません。内積は、データから任意の関数を学習できる Multi-Layer Perceptron に置き換えられます。

NCF の 2 つの実装は、Generalized Matrix Factorization(GMF)と Multi-Layer Perceptron(MLP)です。GMF では、潜在機能のインタラクションをモデル化するために線形カーネルを適用し、MLP では非線形カーネルを使用してデータからインタラクション関数を学習します。NFMF は複雑なユーザー - アイテム インタラクションのモデルを改善するための GMF と MLP の融合モデルです。また、ユーザー - アイテムの潜在構造をモデル化するために、MF の線形性と MLF の非線形性の長所を統一します。NFMF を使用すると、GMF と MLP で別々の埋め込みを学習し、最後の隠しレイヤを連結して 2 つのモデルを組み合わせます。neuf_model.py はアーキテクチャの詳細を定義します。

以下の手順では、Cloud TPU でモデルをトレーニングする方法をすでに理解していることを前提としています。Cloud TPU を初めて使用する場合は、クイックスタートで基本的な概要をご確認ください。

データセット

MovieLens データセットは、モデルのトレーニングと評価に使用されます。具体的には、ml-1m(MovieLens 100 万の略)、ml-20m(MovieLens 2000 万の略)の 2 つのデータセットを使用します。

ml-1m

ml-1m データセットには、2000 年に MovieLens に参加した 6,040 人のユーザーが作成した、およそ 3,706 本の映画の 1,000,209 件の匿名評価が含まれます。すべての評価は、次の形式のヘッダー行のない「ratings.dat」ファイルに含まれています。

UserID::MovieID::Rating::Timestamp

  • UserID の範囲は 1~6040 です。
  • MovieID の範囲は 1~3952 です。
  • 評価は 5 段階の星評価です(整数の星評価のみ)。

ml-20m

ml-20m データセットには、138,493 人のユーザーによる 26,744 本の映画の 20,000,263 件の評価が含まれます。すべての評価が「ratings.csv」ファイルに含まれます。このファイルのヘッダー行の後の各行に、次の形式で 1 本の映画に対する 1 つの評価がユーザーごとに表示されます。

userId,movieId,rating,timestamp

このファイル内の行は、まず userId の順に並べられ、次にユーザー内で movieId の順に並べられます。評価は 5 段階の星評価で、0.5 星ごとに増分します(0.5~5.0 星)。どちらのデータセットも、協定世界時(UTC)の1970 年 1 月 1 日午前 0 時を起点としたタイムスタンプが秒単位で表されます。各ユーザーには 20 以上の評価があります。

目標

  • データセットとモデルの出力を格納する Cloud Storage バケットを作成する
  • MovieLens データセットを準備する
  • トレーニングと評価のための Compute Engine VM と Cloud TPU ノードを設定する
  • トレーニングと評価を行う

料金

このチュートリアルでは、Google Cloud の課金対象となる以下のコンポーネントを使用します。

  • Compute Engine
  • Cloud TPU
  • クラウド ストレージ

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

このチュートリアルを開始する前に、Google Cloud プロジェクトが正しく設定されていることを確認します。

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    [プロジェクトの選択] ページに移動

  3. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. このチュートリアルでは、Google Cloud の課金対象となるコンポーネントを使用します。費用を見積もるには、Cloud TPU の料金ページを確認してください。不要な課金を回避するために、このチュートリアルを完了したら、作成したリソースを必ずクリーンアップしてください。

リソースを設定する

このセクションでは、このチュートリアルで使用する Cloud Storage、VM、Cloud TPU の各リソースを設定する方法を説明します。

  1. Cloud Shell ウィンドウを開きます。

    Cloud Shell を開く

  2. プロジェクト ID の環境変数を作成します。

    export PROJECT_ID=project-id
  3. Cloud TPU を作成するプロジェクトを使用するように gcloud コマンドライン ツールを構成します。

    gcloud config set project ${PROJECT_ID}
    

    このコマンドを新しい Cloud Shell VM で初めて実行すると、Authorize Cloud Shell ページが表示されます。ページの下部にある [Authorize] をクリックして、gcloud に認証情報を使用した GCP API の呼び出しを許可します。

  4. Cloud TPU プロジェクトのサービス アカウントを作成します。

    gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
    

    このコマンドでは、Cloud TPU サービス アカウントを次の形式で返します。

    service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
    
  5. 次のコマンドを使用して Cloud Storage バケットを作成します。

    gsutil mb -p ${PROJECT_ID} -c standard -l europe-west4 -b on gs://bucket-name
    

    この Cloud Storage バケットには、モデルのトレーニングに使用するデータとトレーニング結果が格納されます。このチュートリアルで使用する ctpu up ツールは、前の手順で設定した Cloud TPU サービス アカウントのデフォルトの権限を設定します。権限の詳細な設定が必要な場合は、アクセスレベル権限をご覧ください。

    バケットのロケーションは、仮想マシン(VM)および TPU ノードと同じリージョンにする必要があります。VM と TPU ノードは、リージョン内のサブディビジョンである特定のゾーンに配置されます。

  6. ctpu up コマンドを使用して、Compute Engine VM を起動します。

    $ ctpu up --project=${PROJECT_ID} \
     --zone=europe-west4-a \
     --vm-only \
     --disk-size-gb=300 \
     --machine-type=n1-standard-8 \
     --name=ncf-tutorial \
     --tf-version=2.3.1
    

    コマンドフラグの説明

    project
    GCP プロジェクト ID
    zone
    Cloud TPU を作成するゾーン
    vm-only
    VM のみを作成します。デフォルトでは、ctpu up コマンドは VM と Cloud TPU を作成します。
    disk-size-gb
    VM のディスクのサイズ(GB)。
    machine_type
    ctpu up コマンドで作成される VM のマシンタイプ
    name
    作成する Compute Engine VM の名前。
    tf-version
    Tensorflow ctpu のバージョンが VM にインストールされます。
  7. 指定した構成が表示されます。承認する場合は y、キャンセルする場合は n を入力してください。

  8. ctpu up コマンドの実行が終了したら、shell プロンプトが username@projectname から username@vm-name に変更されたことを確認します。変更されていれば、Compute Engine VM にログインしていることになります。

    gcloud compute ssh ncf-tutorial --zone=europe-west4-a
    

    これらの手順を続行する場合は、VM セッション ウィンドウで、(vm)$ で始まる各コマンドを実行します。

データを準備する

  1. ストレージ バケットの環境変数を追加します。bucket-name は、使用するバケット名に置き換えてください。

    (vm)$ export STORAGE_BUCKET=gs://bucket-name
    
  2. データ ディレクトリの環境変数を追加します。

    (vm)$ export DATA_DIR=${STORAGE_BUCKET}/ncf_data
    
  3. Python パスの環境変数を追加します。

    (vm)$ export PYTHONPATH="${PYTHONPATH}:/usr/share/models"
    
  4. DATA_DIR で ml-20m データセットのトレーニング データと評価データを生成します。

    (vm)$ python3 /usr/share/models/official/recommendation/create_ncf_data.py \
        --dataset ml-20m \
        --num_train_epochs 4 \
        --meta_data_file_path ${DATA_DIR}/metadata \
        --eval_prebatch_size 160000 \
        --data_dir ${DATA_DIR}
    

このスクリプトは、VM 上でデータセットを生成して前処理します。前処理を行うと、データがモデルに必要な TFRecord 形式に変換されます。ダウンロードと前処理には約 25 分かかり、次のような出力が生成されます。

I0804 23:03:02.370002 139664166737728 movielens.py:124] Successfully downloaded /tmp/tmpicajrlfc/ml-20m.zip 198702078 bytes
I0804 23:04:42.665195 139664166737728 data_preprocessing.py:223] Beginning data preprocessing.
I0804 23:04:59.084554 139664166737728 data_preprocessing.py:84] Generating user_map and item_map...
I0804 23:05:20.934210 139664166737728 data_preprocessing.py:103] Sorting by user, timestamp...
I0804 23:06:39.859857 139664166737728 data_preprocessing.py:194] Writing raw data cache.
I0804 23:06:42.375952 139664166737728 data_preprocessing.py:262] Data preprocessing complete. Time: 119.7 sec.
%lt;BisectionDataConstructor(Thread-1, initial daemon)>
General:
  Num users: 138493
  Num items: 26744

Training:
  Positive count:          19861770
  Batch size:              99000
  Batch count per epoch:   1004

Eval:
  Positive count:          138493
  Batch size:              160000
  Batch count per epoch:   866

I0804 23:07:14.137242 139664166737728 data_pipeline.py:887] Negative total vector built. Time: 31.8 seconds
I0804 23:11:25.013135 139664166737728 data_pipeline.py:588] Epoch construction complete. Time: 250.9 seconds
I0804 23:15:46.391308 139664166737728 data_pipeline.py:674] Eval construction complete. Time: 261.4 seconds
I0804 23:19:54.345858 139664166737728 data_pipeline.py:588] Epoch construction complete. Time: 248.0 seconds
I0804 23:24:09.182484 139664166737728 data_pipeline.py:588] Epoch construction complete. Time: 254.8 seconds
I0804 23:28:26.224653 139664166737728 data_pipeline.py:588] Epoch construction complete. Time: 257.0 seconds

Cloud TPU を設定して起動する

  1. 次のコマンドを実行して Cloud TPU を作成します。

    (vm)$ ctpu up --project=${PROJECT_ID} \
      --tpu-only \
      --tpu-size=v3-8 \
      --zone=europe-west4-a \
      --name=ncf-tutorial \
      --tf-version=2.3.1

    コマンドフラグの説明

    project
    GCP プロジェクト ID
    tpu-only
    VM を作成せずに Cloud TPU を作成します。デフォルトでは、ctpu up コマンドは VM と Cloud TPU を作成します。
    tpu-size
    作成する Cloud TPU のタイプ
    zone
    Cloud TPU を作成するゾーン
    name
    作成する Cloud TPU の名前。
    tf-version
    Tensorflow ctpu のバージョンが VM にインストールされます。
  2. 指定した構成が表示されます。承認する場合は y、キャンセルする場合は n を入力してください。

    Operation success; not ssh-ing to Compute Engine VM due to --tpu-only flag というメッセージが表示されます。SSH 鍵の伝播は完了しているため、このメッセージは無視できます。

  3. Cloud TPU の名前の環境変数を追加します。

    (vm)$ export TPU_NAME=ncf-tutorial
    

トレーニングと評価を行う

次のスクリプトでは、3 つのエポック用のサンプル トレーニングを実行します。

  1. チェックポイントと TensorBoard のサマリーを保存するための環境変数をモデルのディレクトリに追加します。

    (vm)$ export MODEL_DIR=${STORAGE_BUCKET}/ncf
    
  2. 次のコマンドを実行して、NCF モデルをトレーニングします。

    (vm)$ python3 /usr/share/models/official/recommendation/ncf_keras_main.py \
         --model_dir=${MODEL_DIR} \
         --data_dir=${DATA_DIR} \
         --train_dataset_path=${DATA_DIR}/training_cycle_*/* \
         --eval_dataset_path=${DATA_DIR}/eval_data/* \
         --input_meta_data_path=${DATA_DIR}/metadata \
         --learning_rate=3e-5 \
         --train_epochs=3 \
         --dataset=ml-20m \
         --eval_batch_size=160000 \
         --learning_rate=0.00382059 \
         --beta1=0.783529 \
         --beta2=0.909003 \
         --epsilon=1.45439e-07 \
         --dataset=ml-20m \
         --num_factors=64 \
         --hr_threshold=0.635 \
         --keras_use_ctl=true \
         --layers=256,256,128,64 \
         --use_synthetic_data=false \
         --distribution_strategy=tpu \
         --download_if_missing=false
     

トレーニングと評価には約 2 分かかり、次のような最終出力が生成されます。

I0805 21:23:05.134161 139825684965184 ncf_keras_main.py:493] Done training epoch 3, epoch loss=0.097
I0805 21:23:06.722786 139825684965184 ncf_keras_main.py:506] Done eval epoch 3, hit_rate=0.585
I0805 21:23:16.005549 139825684965184 ncf_keras_main.py:523] Saving model as TF checkpoint: gs://gm-bucket-eu/ncf/ctl_checkpoint
I0805 21:23:16.058367 139825684965184 ncf_keras_main.py:562] Result is {'loss': <tf.Tensor: shape=(), dtype=float32, numpy=0.09678721>, 'eval_loss': None, 'eval_hit_rate': , 'step_timestamp_log': ['BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTim
estamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp',
 'BatchTimestamp', 'BatchTimestamp', 'BatchTimestamp', 'BatchTime
stamp', 'BatchTimestamp', 'BatchTimestamp'], 'train_finish_time': 1596662568.102817, 'avg_exp_per_second': 4474047.406912873}

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

Compute Engine VM インスタンスと Cloud TPU リソースをクリーンアップします。

  1. Compute Engine インスタンスとの接続を切断していない場合は切断します。

    (vm)$ exit
    

    プロンプトが username@projectname に変わります。これは、現在、Cloud Shell 内にいることを示しています。

  2. VM または Cloud Shell で、Cloud TPU の設定時に使用した --name フラグと --zone フラグを指定して ctpu delete を実行し、Cloud TPU を削除します。

    $ ctpu delete --project=${PROJECT_ID} \
      --name=ncf-tutorial \
      --zone=europe-west4-a
    
  3. 次のコマンドを実行して、Compute Engine VM と Cloud TPU がシャットダウンされたことを確認します。

    $ ctpu status --project=${PROJECT_ID} \
      --name=ncf-tutorial \
      --zone=europe-west4-a
    

    削除には数分かかることがあります。次のようなレスポンスは、割り当てられたインスタンスがないことを示します。

    2018/04/28 16:16:23 WARNING: Setting zone to "europe-west4-a"
    No instances currently exist.
            Compute Engine VM:     --
            Cloud TPU:             --
    
  4. 次に示すように gsutil を実行します。bucket-name の部分は、このチュートリアルで作成した Cloud Storage バケット名に置き換えてください。

    $ gsutil rm -r gs://bucket-name
    

次のステップ

このチュートリアルでは、サンプル データセットを使用して NCF モデルをトレーニングしました。このトレーニングの結果は(ほとんどの場合)推論には使用できません。推論にモデルを使用するには、一般公開されているデータセットまたは独自のデータセットでデータをトレーニングします。Cloud TPU でトレーニングされたモデルでは、データセットを TFRecord 形式にする必要があります。

データセット変換ツールのサンプルを使用して、画像分類データセットを TFRecord 形式に変換できます。画像分類モデルを使用しない場合は、自分でデータセットを TFRecord 形式に変換する必要があります。詳細については、TFRecord と tf.Example をご覧ください。

ハイパーパラメータ調整

データセットでモデルのパフォーマンスを向上させるには、モデルのハイパーパラメータを調整します。すべての TPU でサポートされているモデルに共通のハイパーパラメータに関する情報については、GitHub をご覧ください。モデルに固有のハイパーパラメータに関する情報については、各モデルのソースコードで確認できます。ハイパーパラメータ調整の詳細については、ハイパーパラメータ調整の概要ハイパーパラメータ調整サービスの使用ハイパーパラメータを調整するをご覧ください。

推論

モデルをトレーニングしたら、そのモデルを推論(予測)に使用できます。AI Platform は、機械学習モデルを開発、トレーニングデプロイするためのクラウドベースのソリューションです。モデルをデプロイすれば、AI Platform Prediction サービスを使用できるようになります。