日付を保存! Google I / Oが5月18日から20日に戻ってきます今すぐ登録
このページは Cloud Translation API によって翻訳されました。
Switch to English

ディープ&クロスネットワーク(DCN)

TensorFlow.orgで表示 GoogleColabで実行 GitHubでソースを表示ノートブックをダウンロードする

このチュートリアルでは、Deep&Cross Network(DCN)を使用して特徴のクロスを効果的に学習する方法を示します。

バックグラウンド

機能クロスとは何ですか?なぜそれらが重要なのですか?ブレンダーを顧客に販売するためのレコメンダーシステムを構築していると想像してみてください。その場合、 purchased_bananaspurchased_cooking_booksなどの顧客の過去の購入履歴、または地理的特徴は単一の特徴です。バナナ料理本の両方を購入した場合、この顧客は推奨されるブレンダーをクリックする可能性が高くなります。 purchased_bananaspurchased_cooking_booksの組み合わせは、機能クロスと呼ばれ、個々の機能以外の追加のインタラクション情報を提供します。

特徴の交差を学習する際の課題は何ですか? Webスケールのアプリケーションでは、データはほとんどがカテゴリーであり、大きくてまばらな特徴空間につながります。この設定で効果的な機能クロスを特定するには、多くの場合、手動の機能エンジニアリングまたは徹底的な検索が必要です。従来のフィードフォワード多層パーセプトロン(MLP)モデルは、普遍関数近似器です。しかしながら、それらは効率的であっても2または3次特徴交雑[近づけることができない12 ]。

ディープ&クロスネットワーク(DCN)とは何ですか? DCNは、明示的で有界のクロスフィーチャをより効果的に学習するように設計されています。入力レイヤー(通常は埋め込みレイヤー)で始まり、明示的な機能の相互作用をモデル化する複数のクロスレイヤーを含むクロスネットワークが続き、暗黙的な機能の相互作用をモデル化するディープネットワークと結合します。

  • クロスネットワーク。これがDCNのコアです。これは、各レイヤーでフィーチャクロスを明示的に適用し、最高の多項式次数はレイヤーの深さとともに増加します。次の図は、$(i + 1)$番目のクロスレイヤーを示しています。
  • ディープネットワーク。これは、従来のフィードフォワード多層パーセプトロン(MLP)です。

次に、ディープネットワークとクロスネットワークを組み合わせてDCNを形成します[ 1 ]。一般に、クロスネットワーク(スタック構造)の上に深いネットワークをスタックすることができます。それらを並列に配置することもできます(並列構造)。

以下では、最初におもちゃの例でDCNの利点を示し、次にMovieLen-1Mデータセットを使用してDCNを利用するいくつかの一般的な方法を説明します。

まず、このコラボに必要なパッケージをインストールしてインポートしましょう。

pip install -q tensorflow-recommenders
pip install -q --upgrade tensorflow-datasets
import pprint

%matplotlib inline
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds

import tensorflow_recommenders as tfrs

おもちゃの例

DCNの利点を説明するために、簡単な例を見てみましょう。顧客がブレンダー広告をクリックする可能性をモデル化しようとしているデータセットがあり、その機能とラベルは次のように説明されているとします。

機能/ラベル説明値のタイプ/範囲
$ x_1 $ =国この顧客が住んでいる国[0、199]の整数
$ x_2 $ =バナナ#お客様が購入したバナナ[0、23]の整数
$ x_3 $ =クックブック#お客様が購入した料理本[0、5]の整数
$ y $ブレンダー広告をクリックする可能性-

次に、データを次の基本的な分布に従うようにします。

$$y = f(x_1, x_2, x_3) = 0.1x_1 + 0.4x_2+0.7x_3 + 0.1x_1x_2+3.1x_2x_3+0.1x_3^2$$

ここで、尤度$ y $は、機能$ x_i $の両方に線形に依存しますが、$ x_i $間の乗法的相互作用にも依存します。私たちの場合、ブレンダー($ y $)を購入する可能性は、バナナ($ x_2 $)または料理本($ x_3 $)を購入するだけでなく、バ​​ナナと料理本を一緒に購入する($ x_2x_3 $)にも依存すると言えます。 )。

このためのデータは次のように生成できます。

合成データの生成

最初に、上記のように$ f(x_1、x_2、x_3)$を定義します。

def get_mixer_data(data_size=100_000, random_seed=42):
  # We need to fix the random seed
  # to make colab runs repeatable.
  rng = np.random.RandomState(random_seed)
  country = rng.randint(200, size=[data_size, 1]) / 200.
  bananas = rng.randint(24, size=[data_size, 1]) / 24.
  coockbooks = rng.randint(6, size=[data_size, 1]) / 6.

  x = np.concatenate([country, bananas, coockbooks], axis=1)

  # # Create 1st-order terms.
  y = 0.1 * country + 0.4 * bananas + 0.7 * coockbooks

  # Create 2nd-order cross terms.
  y += 0.1 * country * bananas + 3.1 * bananas * coockbooks + (
        0.1 * coockbooks * coockbooks)

  return x, y

分布に従うデータを生成し、データをトレーニング用に90%、テスト用に10%に分割してみましょう。

x, y = get_mixer_data()
num_train = 90000
train_x = x[:num_train]
train_y = y[:num_train]
eval_x = x[num_train:]
eval_y = y[num_train:]

モデル構築

クロスネットワークとディープネットワークの両方を試して、クロスネットワークが推奨者にもたらす利点を説明します。作成したデータには2次の特徴の相互作用しか含まれていないため、単層のクロスネットワークで説明するだけで十分です。高次の機能の相互作用をモデル化する場合は、複数のクロスレイヤーをスタックし、マルチレイヤーのクロスネットワークを使用できます。構築する2つのモデルは次のとおりです。

  1. クロスレイヤーが1つしかないクロスネットワーク。
  2. より広く、より深いReLUレイヤーを備えたディープネットワーク。

最初に、損失が平均二乗誤差である統合モデルクラスを構築します。

class Model(tfrs.Model):

  def __init__(self, model):
    super().__init__()
    self._model = model
    self._logit_layer = tf.keras.layers.Dense(1)

    self.task = tfrs.tasks.Ranking(
      loss=tf.keras.losses.MeanSquaredError(),
      metrics=[
        tf.keras.metrics.RootMeanSquaredError("RMSE")
      ]
    )

  def call(self, x):
    x = self._model(x)
    return self._logit_layer(x)

  def compute_loss(self, features, training=False):
    x, labels = features
    scores = self(x)

    return self.task(
        labels=labels,
        predictions=scores,
    )

次に、クロスネットワーク(サイズ3のクロスレイヤーが1つ)とReLUベースのDNN(レイヤーサイズ[512、256、128])を指定します。

crossnet = Model(tfrs.layers.dcn.Cross())
deepnet = Model(
    tf.keras.Sequential([
      tf.keras.layers.Dense(512, activation="relu"),
      tf.keras.layers.Dense(256, activation="relu"),
      tf.keras.layers.Dense(128, activation="relu")
    ])
)

モデルトレーニング

データとモデルの準備ができたので、モデルをトレーニングします。まず、データをシャッフルしてバッチ処理し、モデルトレーニングの準備をします。

train_data = tf.data.Dataset.from_tensor_slices((train_x, train_y)).batch(1000)
eval_data = tf.data.Dataset.from_tensor_slices((eval_x, eval_y)).batch(1000)

次に、エポック数と学習率を定義します。

epochs = 100
learning_rate = 0.4

さて、これですべての準備が整いました。モデルをコンパイルしてトレーニングしましょう。モデルの進行状況を確認したい場合は、 verbose=True設定できます。

crossnet.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate))
crossnet.fit(train_data, epochs=epochs, verbose=False)
WARNING:tensorflow:Layer model is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

WARNING:tensorflow:Layer ranking is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.
<tensorflow.python.keras.callbacks.History at 0x7fb9dc772da0>
deepnet.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate))
deepnet.fit(train_data, epochs=epochs, verbose=False)
WARNING:tensorflow:Layer model_1 is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

WARNING:tensorflow:Layer ranking_1 is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.
<tensorflow.python.keras.callbacks.History at 0x7fb9dc4a1860>

モデル評価

評価データセットでモデルのパフォーマンスを検証し、二乗平均平方根誤差を報告します(RMSE、低いほど良い)。

crossnet_result = crossnet.evaluate(eval_data, return_dict=True, verbose=False)
print(f"CrossNet(1 layer) RMSE is {crossnet_result['RMSE']:.4f} "
      f"using {crossnet.count_params()} parameters.")

deepnet_result = deepnet.evaluate(eval_data, return_dict=True, verbose=False)
print(f"DeepNet(large) RMSE is {deepnet_result['RMSE']:.4f} "
      f"using {deepnet.count_params()} parameters.")
CrossNet(1 layer) RMSE is 0.0003 using 18 parameters.
DeepNet(large) RMSE is 0.0350 using 166403 parameters.

クロスネットワークは、ReLUベースのDNNよりもRMSE低くパラメータが少ないことがわかります。これは、特徴のクロスを学習する際のクロスネットワークの効率を示唆しています。

モデルの理解

データでどのフィーチャクロスが重要であるかはすでにわかっているので、モデルが実際に重要なフィーチャクロスを学習したかどうかを確認するのは楽しいでしょう。これは、DCNで学習した重み行列を視覚化することで実行できます。重み$ W_ {ij} $は、機能$ x_i $と$ x_j $の間の相互作用の学習された重要性を表します。

mat = crossnet._model._dense.kernel
features = ["country", "purchased_bananas", "purchased_cookbooks"]

plt.figure(figsize=(9,9))
im = plt.matshow(np.abs(mat.numpy()), cmap=plt.cm.Blues)
ax = plt.gca()
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
cax.tick_params(labelsize=10) 
_ = ax.set_xticklabels([''] + features, rotation=45, fontsize=10)
_ = ax.set_yticklabels([''] + features, fontsize=10)
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/ipykernel_launcher.py:11: UserWarning: FixedFormatter should only be used together with FixedLocator
  # This is added back by InteractiveShellApp.init_path()
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/ipykernel_launcher.py:12: UserWarning: FixedFormatter should only be used together with FixedLocator
  if sys.path[0] == '':
<Figure size 648x648 with 0 Axes>

png

色が濃いほど、学習した相互作用が強くなります。この場合、モデルがババナと料理本を一緒に購入することが重要であることを学習したことは明らかです。

より複雑な合成データを試すことに興味がある場合は、このペーパーをチェックしてください。

Movielens1Mの例

ここで、実際のデータセットであるMovielens 1M [ 3 ]に対するDCNの有効性を調べます。 Movielens 1Mは、推奨調査で人気のあるデータセットです。ユーザー関連の機能と映画関連の機能を指定して、ユーザーの映画のレイティングを予測します。このデータセットを使用して、DCNを利用するいくつかの一般的な方法を説明します。

情報処理

データ処理手順は、基本的なランキングチュートリアルと同様の手順に従います。

ratings = tfds.load("movie_lens/100k-ratings", split="train")
ratings = ratings.map(lambda x: {
    "movie_id": x["movie_id"],
    "user_id": x["user_id"],
    "user_rating": x["user_rating"],
    "user_gender": int(x["user_gender"]),
    "user_zip_code": x["user_zip_code"],
    "user_occupation_text": x["user_occupation_text"],
    "bucketized_user_age": int(x["bucketized_user_age"]),
})
WARNING:absl:The handle "movie_lens" for the MovieLens dataset is deprecated. Prefer using "movielens" instead.
Downloading and preparing dataset movie_lens/100k-ratings/0.1.0 (download: 4.70 MiB, generated: 32.41 MiB, total: 37.10 MiB) to /home/kbuilder/tensorflow_datasets/movie_lens/100k-ratings/0.1.0...
Shuffling and writing examples to /home/kbuilder/tensorflow_datasets/movie_lens/100k-ratings/0.1.0.incompleteBFZ1VZ/movie_lens-train.tfrecord
Dataset movie_lens downloaded and prepared to /home/kbuilder/tensorflow_datasets/movie_lens/100k-ratings/0.1.0. Subsequent calls will reuse this data.

次に、データをトレーニング用に80%、テスト用に20%にランダムに分割します。

tf.random.set_seed(42)
shuffled = ratings.shuffle(100_000, seed=42, reshuffle_each_iteration=False)

train = shuffled.take(80_000)
test = shuffled.skip(80_000).take(20_000)

次に、各機能の語彙を作成します。

feature_names = ["movie_id", "user_id", "user_gender", "user_zip_code",
                 "user_occupation_text", "bucketized_user_age"]

vocabularies = {}

for feature_name in feature_names:
  vocab = ratings.batch(1_000_000).map(lambda x: x[feature_name])
  vocabularies[feature_name] = np.unique(np.concatenate(list(vocab)))

モデル構築

構築するモデルアーキテクチャは、埋め込みレイヤーから始まります。埋め込みレイヤーは、クロスネットワークに供給され、その後にディープネットワークが続きます。埋め込みサイズは、すべての機能で32に設定されています。機能ごとに異なる埋め込みサイズを使用することもできます。

class DCN(tfrs.Model):

  def __init__(self, use_cross_layer, deep_layer_sizes, projection_dim=None):
    super().__init__()

    self.embedding_dimension = 32

    str_features = ["movie_id", "user_id", "user_zip_code",
                    "user_occupation_text"]
    int_features = ["user_gender", "bucketized_user_age"]

    self._all_features = str_features + int_features
    self._embeddings = {}

    # Compute embeddings for string features.
    for feature_name in str_features:
      vocabulary = vocabularies[feature_name]
      self._embeddings[feature_name] = tf.keras.Sequential(
          [tf.keras.layers.experimental.preprocessing.StringLookup(
              vocabulary=vocabulary, mask_token=None),
           tf.keras.layers.Embedding(len(vocabulary) + 1,
                                     self.embedding_dimension)
    ])

    # Compute embeddings for int features.
    for feature_name in int_features:
      vocabulary = vocabularies[feature_name]
      self._embeddings[feature_name] = tf.keras.Sequential(
          [tf.keras.layers.experimental.preprocessing.IntegerLookup(
              vocabulary=vocabulary, mask_value=None),
           tf.keras.layers.Embedding(len(vocabulary) + 1,
                                     self.embedding_dimension)
    ])

    if use_cross_layer:
      self._cross_layer = tfrs.layers.dcn.Cross(
          projection_dim=projection_dim,
          kernel_initializer="glorot_uniform")
    else:
      self._cross_layer = None

    self._deep_layers = [tf.keras.layers.Dense(layer_size, activation="relu")
      for layer_size in deep_layer_sizes]

    self._logit_layer = tf.keras.layers.Dense(1)

    self.task = tfrs.tasks.Ranking(
      loss=tf.keras.losses.MeanSquaredError(),
      metrics=[tf.keras.metrics.RootMeanSquaredError("RMSE")]
    )

  def call(self, features):
    # Concatenate embeddings
    embeddings = []
    for feature_name in self._all_features:
      embedding_fn = self._embeddings[feature_name]
      embeddings.append(embedding_fn(features[feature_name]))

    x = tf.concat(embeddings, axis=1)

    # Build Cross Network
    if self._cross_layer is not None:
      x = self._cross_layer(x)

    # Build Deep Network
    for deep_layer in self._deep_layers:
      x = deep_layer(x)

    return self._logit_layer(x)

  def compute_loss(self, features, training=False):
    labels = features.pop("user_rating")
    scores = self(features)
    return self.task(
        labels=labels,
        predictions=scores,
    )

モデルトレーニング

トレーニングデータとテストデータをシャッフル、バッチ処理、キャッシュします。

cached_train = train.shuffle(100_000).batch(8192).cache()
cached_test = test.batch(4096).cache()

モデルを複数回実行し、複数の実行からモデルのRMSE平均と標準偏差を返す関数を定義しましょう。

def run_models(use_cross_layer, deep_layer_sizes, projection_dim=None, num_runs=5):
  models = []
  rmses = []

  for i in range(num_runs):
    model = DCN(use_cross_layer=use_cross_layer,
                deep_layer_sizes=deep_layer_sizes,
                projection_dim=projection_dim)
    model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate))
    models.append(model)

    model.fit(cached_train, epochs=epochs, verbose=False)
    metrics = model.evaluate(cached_test, return_dict=True)
    rmses.append(metrics["RMSE"])

  mean, stdv = np.average(rmses), np.std(rmses)

  return {"model": models, "mean": mean, "stdv": stdv}

モデルにいくつかのハイパーパラメータを設定します。これらのハイパーパラメータは、デモンストレーションの目的ですべてのモデルに対してグローバルに設定されていることに注意してください。各モデルで最高のパフォーマンスを得る場合、またはモデル間で公正な比較を行う場合は、ハイパーパラメーターを微調整することをお勧めします。モデルアーキテクチャと最適化スキームが絡み合っていることを忘れないでください。

epochs = 8
learning_rate = 0.01

DCN(スタック)。最初に、スタック構造のDCNモデルをトレーニングします。つまり、入力はクロスネットワークに送られ、続いてディープネットワークに送られます。

dcn_result = run_models(use_cross_layer=True,
                        deep_layer_sizes=[192, 192])
5/5 [==============================] - 0s 15ms/step - RMSE: 0.9306 - loss: 0.8662 - regularization_loss: 0.0000e+00 - total_loss: 0.8662
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9339 - loss: 0.8725 - regularization_loss: 0.0000e+00 - total_loss: 0.8725
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9326 - loss: 0.8702 - regularization_loss: 0.0000e+00 - total_loss: 0.8702
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9350 - loss: 0.8750 - regularization_loss: 0.0000e+00 - total_loss: 0.8750
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9339 - loss: 0.8729 - regularization_loss: 0.0000e+00 - total_loss: 0.8729

低ランクのDCN。トレーニングとサービングのコストを削減するために、低ランクの手法を活用してDCN重み行列を概算します。ランクは引数projection_dimを介して渡されます。 projection_dimを小さくprojection_dimと、コストが低くなります。コストを削減するには、 projection_dim (入力サイズ)/ 2より小さくする必要があることに注意してください。実際には、ランク(入力サイズ)/ 4の低ランクDCNを使用すると、フルランクDCNの精度が一貫して維持されることがわかりました。

dcn_lr_result = run_models(use_cross_layer=True,
                           projection_dim=20,
                           deep_layer_sizes=[192, 192])
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9307 - loss: 0.8669 - regularization_loss: 0.0000e+00 - total_loss: 0.8669
5/5 [==============================] - 0s 4ms/step - RMSE: 0.9312 - loss: 0.8668 - regularization_loss: 0.0000e+00 - total_loss: 0.8668
5/5 [==============================] - 0s 4ms/step - RMSE: 0.9304 - loss: 0.8667 - regularization_loss: 0.0000e+00 - total_loss: 0.8667
5/5 [==============================] - 0s 4ms/step - RMSE: 0.9334 - loss: 0.8718 - regularization_loss: 0.0000e+00 - total_loss: 0.8718
5/5 [==============================] - 0s 4ms/step - RMSE: 0.9300 - loss: 0.8658 - regularization_loss: 0.0000e+00 - total_loss: 0.8658

DNN。参照として同じサイズのDNNモデルをトレーニングします。

dnn_result = run_models(use_cross_layer=False,
                        deep_layer_sizes=[192, 192, 192])
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9460 - loss: 0.8985 - regularization_loss: 0.0000e+00 - total_loss: 0.8985
5/5 [==============================] - 0s 4ms/step - RMSE: 0.9358 - loss: 0.8773 - regularization_loss: 0.0000e+00 - total_loss: 0.8773
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9392 - loss: 0.8842 - regularization_loss: 0.0000e+00 - total_loss: 0.8842
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9362 - loss: 0.8772 - regularization_loss: 0.0000e+00 - total_loss: 0.8772
5/5 [==============================] - 0s 3ms/step - RMSE: 0.9377 - loss: 0.8798 - regularization_loss: 0.0000e+00 - total_loss: 0.8798

テストデータでモデルを評価し、5回の実行からの平均と標準偏差を報告します。

print("DCN            RMSE mean: {:.4f}, stdv: {:.4f}".format(
    dcn_result["mean"], dcn_result["stdv"]))
print("DCN (low-rank) RMSE mean: {:.4f}, stdv: {:.4f}".format(
    dcn_lr_result["mean"], dcn_lr_result["stdv"]))
print("DNN            RMSE mean: {:.4f}, stdv: {:.4f}".format(
    dnn_result["mean"], dnn_result["stdv"]))
DCN            RMSE mean: 0.9332, stdv: 0.0015
DCN (low-rank) RMSE mean: 0.9312, stdv: 0.0012
DNN            RMSE mean: 0.9390, stdv: 0.0037

DCNは、ReLUレイヤーを備えた同じサイズのDNNよりも優れたパフォーマンスを達成したことがわかります。さらに、低ランクのDCNは、精度を維持しながらパラメータを削減することができました。

DCNの詳細。上で示したものに加えて、DCNを利用するためのより創造的でありながら実用的に有用な方法があります[ 1 ]。

  • 並列構造のDCN 。入力は、クロスネットワークとディープネットワークに並列に供給されます。

  • クロスレイヤーの連結。入力は、補完的な特徴のクロスをキャプチャするために、複数のクロスレイヤーに並列に供給されます。

:並列構造のDCN。:クロスレイヤーを連結します。

モデルの理解

DCNの重み行列$ W $は、モデルが交差する特徴が重要であると学習したことを示しています。前のおもちゃの例では、$ i $番目と$ j $番目の機能間の相互作用の重要性が$ W $の($ i、j $)番目の要素によってキャプチャされていることを思い出してください。

ここで少し異なるのは、機能の埋め込みがサイズ1ではなくサイズ32であるということです。したがって、重要性は、次元の$(i、j)$番目のブロック$ W_ {i、j} $によって特徴付けられます。以下では、各ブロックのフロベニウスノルム[ 4 ] $ || W_ {i、j} || _F $を視覚化します。ノルムが大きいほど、重要性が高いことを示します(機能の埋め込みが類似していると仮定)。スケール)。

ブロックノルムに加えて、行列全体、または各ブロックの平均/中央値/最大値を視覚化することもできます。

model = dcn_result["model"][0]
mat = model._cross_layer._dense.kernel
features = model._all_features

block_norm = np.ones([len(features), len(features)])

dim = model.embedding_dimension

# Compute the norms of the blocks.
for i in range(len(features)):
  for j in range(len(features)):
    block = mat[i * dim:(i + 1) * dim,
                j * dim:(j + 1) * dim]
    block_norm[i,j] = np.linalg.norm(block, ord="fro")

plt.figure(figsize=(9,9))
im = plt.matshow(block_norm, cmap=plt.cm.Blues)
ax = plt.gca()
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes("right", size="5%", pad=0.05)
plt.colorbar(im, cax=cax)
cax.tick_params(labelsize=10) 
_ = ax.set_xticklabels([""] + features, rotation=45, ha="left", fontsize=10)
_ = ax.set_yticklabels([""] + features, fontsize=10)
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/ipykernel_launcher.py:23: UserWarning: FixedFormatter should only be used together with FixedLocator
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/ipykernel_launcher.py:24: UserWarning: FixedFormatter should only be used together with FixedLocator
<Figure size 648x648 with 0 Axes>

png

このコラボは以上です。 DCNのいくつかの基本とそれを利用する一般的な方法を楽しんでいただけたことを願っています。詳細については、 DCN-v1-paperDCN-v2-paperの2つの関連する論文をご覧ください。


参考文献

DCN V2:システムをランク付けするためのWebスケール学習のための改善されたディープ&クロスネットワークと実践的なレッスン
Ruoxi Wang、Rakesh Shivanna、Derek Zhiyuan Cheng、Sagar Jain、Dong Lin、Lichan Hong、Ed Chi (2020)

広告クリック予測のためのディープ&クロスネットワーク
Ruoxi Wang、Bin Fu、Gang Fu、Mingliang Wang (AdKDD 2017)