《深度学习推荐系统实战》 学习笔记 3月Day 23

425 阅读4分钟

17 | Embedding+MLP:如何用TensorFlow实现经典的深度学习模型?

Embedding+MLP 模型的结构

微软提出的深度学习模型 Deep Crossing,它是一个经典的 Embedding+MLP 模型结构。Deep Crossing 从下到上可以分为 5 层,分别是 Feature 层、Embedding 层、Stacking 层、MLP 层和 Scoring 层。Feature 层是整个模型的输入特征层,其中 One-hot 特征需要通过连接到 Embedding 层的方式,把稀疏的 One-hot 向量转换成比较稠密的 Embedding 向量。Embedding 层的内部结构是从输入层到隐层之间的全连接网络,它的作用是把稀疏的 One-hot 向量转换成稠密的 Embedding 向量。Stacking 层的作用是把不同的 Embedding 特征和数值型特征拼接在一起,形成新的包含全部特征的特征向量。MLP 层的特点是全连接,它的作用是让特征向量不同维度之间做充分的交叉,让模型能够抓取到更多的非线性特征和组合特征的信息。最后是 Scoring 层,它的作用是预测分类的概率。整个模型的结构重点用一句话总结就是,对于类别特征,先利用 Embedding 层进行特征稠密化,再利用 Stacking 层连接其他特征,输入 MLP 的多层结构,最后用 Scoring 层预估结果。

Embedding+MLP 模型的实战

特征选择和模型设计

image.png

Embedding+MLP 模型的 TensorFlow 实现

我们先来看第一步,导入 TensorFlow 包。

import tensorflow as tf


TRAIN_DATA_URL = "file:///Users/zhewang/Workspace/SparrowRecSys/src/main/resources/webroot/sampledata/modelSamples.csv"
samples_file_path = tf.keras.utils.get_file("modelSamples.csv", TRAIN_DATA_URL)**

第二步是载入训练数据

def get_dataset(file_path):
    dataset = tf.data.experimental.make_csv_dataset(
        file_path,
        batch_size=12,
        label_name='label',
        na_value="?",
        num_epochs=1,
        ignore_errors=True)
    return dataset



# sample dataset size 110830/12(batch_size) = 9235
raw_samples_data = get_dataset(samples_file_path)


test_dataset = raw_samples_data.take(1000)
train_dataset = raw_samples_data.skip(1000)
**

第三步是载入类别型特征。
我们用到的类别型特征主要有这三类,分别是 genre、userId 和 movieId。在载入 genre 类特征时,我们采用了 tf.feature_column.categorical_column_with_vocabulary_list 方法把字符串型的特征转换成了 One-hot 特征。在这个转换过程中我们需要用到一个词表,你可以看到我在开头就定义好了包含所有 genre 类别的词表 genre_vocab。在转换 userId 和 movieId 特征时,我们又使用了 tf.feature_column.categorical_column_with_identity 方法把 ID 转换成 One-hot 特征,这个方法不用词表,它会直接把 ID 值对应的那个维度置为 1。比如,我们输入这个方法的 movieId 是 340,总的 movie 数量是 1001,使用这个方法,就会把这个 1001 维的 One-hot movieId 向量的第 340 维置为 1,剩余的维度都为 0。为了把稀疏的 One-hot 特征转换成稠密的 Embedding 向量,我们还需要在 One-hot 特征外包裹一层 Embedding 层,你可以看到 tf.feature_column.embedding_column(movie_col, 10) 方法完成了这样的操作,它在把 movie one-hot 向量映射到了一个 10 维的 Embedding 层上。

genre_vocab = ['Film-Noir', 'Action', 'Adventure', 'Horror', 'Romance', 'War', 'Comedy', 'Western', 'Documentary',
               'Sci-Fi', 'Drama', 'Thriller',
               'Crime', 'Fantasy', 'Animation', 'IMAX', 'Mystery', 'Children', 'Musical']


GENRE_FEATURES = {
    'userGenre1': genre_vocab,
    'userGenre2': genre_vocab,
    'userGenre3': genre_vocab,
    'userGenre4': genre_vocab,
    'userGenre5': genre_vocab,
    'movieGenre1': genre_vocab,
    'movieGenre2': genre_vocab,
    'movieGenre3': genre_vocab
}


categorical_columns = []
for feature, vocab in GENRE_FEATURES.items():
    cat_col = tf.feature_column.categorical_column_with_vocabulary_list(
        key=feature, vocabulary_list=vocab)
    emb_col = tf.feature_column.embedding_column(cat_col, 10)
    categorical_columns.append(emb_col)


movie_col = tf.feature_column.categorical_column_with_identity(key='movieId', num_buckets=1001)
movie_emb_col = tf.feature_column.embedding_column(movie_col, 10)
categorical_columns.append(movie_emb_col)


user_col = tf.feature_column.categorical_column_with_identity(key='userId', num_buckets=30001)
user_emb_col = tf.feature_column.embedding_column(user_col, 10)
categorical_columns.append(user_emb_c

第四步是数值型特征的处理。

numerical_columns = [tf.feature_column.numeric_column('releaseYear'),
                   tf.feature_column.numeric_column('movieRatingCount'),
                     tf.feature_column.numeric_column('movieAvgRating'),
                     tf.feature_column.numeric_column('movieRatingStddev'),
                     tf.feature_column.numeric_column('userRatingCount'),
                     tf.feature_column.numeric_column('userAvgRating'),
                     tf.feature_column.numeric_column('userRatingStddev')]

第五步是定义模型结构。

preprocessing_layer = tf.keras.layers.DenseFeatures(numerical_columns + categorical_columns)


model = tf.keras.Sequential([
    preprocessing_layer,
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid'),
])

第六步是定义模型训练相关的参数。

model.compile(
    loss='binary_crossentropy',
    optimizer='adam',
    metrics=['accuracy'])

第七步是模型的训练和评估

model.fit(train_dataset, epochs=10)


test_loss, test_accuracy = model.evaluate(test_dataset)


print('\n\nTest Loss {}, Test Accuracy {}'.format(test_loss, test_accuracy)
**

小结

这节课是我们深度学习模型实践的第一课,我们要掌握两个重点内容,一是 Embedding+MLP 的模型结构,二是 Embedding+MLP 模型的 TensorFlow 实现。Embedding+MLP 主要是由 Embedding 部分和 MLP 部分这两部分组成,使用 Embedding 层是为了将类别型特征转换成 Embedding 向量,MLP 部分是通过多层神经网络拟合优化目标。具体来说,以微软的 Deep Crossing 为例,模型一共分为 5 层,从下到上分别是 Feature 层、Embedding 层、Stacking 层、MLP 层和 Scoring 层。在 TensorFlow 实践部分,我们利用上节课处理好的特征和训练数据,实现了 Sparrow Recsys 项目中的第一个深度学习模型。在实践过程中,我们要重点掌握类别型特征的处理方法,模型的定义方式和训练方式,以及最后的模型评估方法。我也把这些重点知识总结在了一张表格里,你可以利用它来认真回顾。

image.png此文章为3月Day25学习笔记,内容来源于极客时间《深度学习推荐系统实战》,强烈推荐该课程!

f90b5d6255252bda60a8c7852aee69a.jpg