概览
这是神经协同过滤论文中所述的采用神经矩阵分解 (NeuMF) 模型的神经协同过滤 (NCF) 框架的实现。目前的实现基于作者的 NCF 代码中的代码以及 MLPerf 代码库中的 Stanford 实现。
NCF 是一个用于推荐的协同过滤的通用框架,在该框架中,神经网络架构用于为用户-推荐项交互建模。NCF 用一个多层感知机替换内部积,该感知器可以学习 任意函数。
NCF 有两种实现方式:泛化矩阵分解 (GMF) 和多层感知机 (MLP)。GMF 应用线性核对潜在 特征交互,而 MLP 则使用非线性内核来学习交互 函数。NeuMF 是 GMF 和 MLP 的融合模型,可以更好地为复杂的用户-推荐项交互建模,并统一了 MLP 的线性和 MLP 的非线性在为用户-推荐项潜在结构建模方面的优势。NeuMF 允许 GMF 和 MLP 学习不同的嵌入,并通过连接最后一个隐藏层将两个模型组合在一起。neumf_model.py 定义了架构细节。
以下说明假定您熟悉 Cloud TPU。如果您刚接触 Cloud TPU,请参阅 使用入门:了解基本介绍。
数据集
MovieLens 数据集用于模型训练和评估。我们使用两个数据集:ml-1m(MovieLens 一百万的简称)和 ml-20m(MovieLens 两千万的简称)。
ml-1m
ml-1m 数据集包含 1000209 个匿名评分,对应大约 3706 部电影 调查对象为 2000 年加入 MovieLens 的 6,040 名用户。所有评分均包含在 文件“ratings.dat”没有标题行,并采用以下格式:
UserID::MovieID::Rating::Timestamp
- UserID 的范围介于 1 到 6040 之间。
- MovieID 的范围介于 1 到 3952 之间。
- 评分采用 5 星制(仅限全星评分)。
ml-20m
ml-20m 数据集包含 138493 名用户对 26744 部电影的 20000263 个评分。所有评分都包含在文件“ratings.csv”中。在此文件中,标题行之后的每一行代表一个用户对一部电影的一个评分,并采用以下格式:
userId,movieId,rating,timestamp
此文件中的行首先按 userId 排序,然后在 user 中按 movieId。评分按 5 星制评分,每增加半星 (0.5 星 - 5.0 星)。两个数据集中的时间戳均以从世界协调时间 (UTC) 1970 年 1 月 1 日零点起计算的秒数表示。每个 用户至少获得 20 个评分。
目标
- 创建 Cloud Storage 存储分区以保存数据集和模型输出
- 准备 MovieLens 数据集
- 设置 Compute Engine 虚拟机和 Cloud TPU 节点以进行训练和评估
- 运行训练和评估
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
- Compute Engine
- Cloud TPU
- Cloud Storage
您可使用价格计算器根据您的预计使用情况来估算费用。
准备工作
在开始学习本教程之前,请检查您的 Google Cloud 项目是否已正确设置。
- 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
本演示使用 Google Cloud 的收费组件。请查看 Cloud TPU 价格页面估算您的费用。请务必在使用完您创建的资源以后清理这些资源,以免产生不必要的费用。
设置资源
本部分介绍如何为此教程设置 Cloud Storage、虚拟机和 Cloud TPU 资源。
打开一个 Cloud Shell 窗口。
为项目 ID 创建一个环境变量。
export PROJECT_ID=project-id
配置 Google Cloud CLI 以使用要在其中创建 Cloud TPU 的项目。
gcloud config set project ${PROJECT_ID}
在新的 Cloud Shell 虚拟机中首次运行此命令时,系统会显示为 Cloud Shell 提供授权页面。在出现的 以允许
gcloud
使用您的凭据进行 API 调用。为 Cloud TPU 项目创建服务账号。
gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
该命令将返回以下格式的 Cloud TPU 服务账号:
service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
使用以下命令创建 Cloud Storage 存储分区:
gcloud storage buckets create gs://bucket-name --project=${PROJECT_ID} --location=europe-west4
此 Cloud Storage 存储分区存储您用于训练模型的数据和训练结果。本教程中使用的
gcloud
命令会为您设置 TPU,还会为在上一步中设置的 Cloud TPU 服务账号设置默认权限。如果您需要更精细的权限,请查看访问级层权限。存储桶位置必须与 TPU 虚拟机位于同一区域。TPU 虚拟机位于特定可用区,即区域内的细分。
创建 Cloud TPU 虚拟机。
$ gcloud compute tpus tpu-vm create ncf-tutorial \ --zone=europe-west4-a \ --accelerator-type=v3-8 \ --version=tpu-vm-tf-2.17.0-pjrt
命令标志说明
如需详细了解
gcloud
命令,请参阅 gcloud 参考文档。使用 SSH 连接到 Compute Engine 实例。连接到网络后 您的 Shell 提示符会从
username@projectname
更改为username@vm-name
:gcloud compute tpus tpu-vm ssh ncf-tutorial --zone=europe-west4-a
准备数据
为存储分区添加环境变量。将 bucket-name 替换为您的存储分区名称。
(vm)$ export STORAGE_BUCKET=gs://bucket-name
为数据目录添加环境变量。
(vm)$ export DATA_DIR=${STORAGE_BUCKET}/ncf_data
设置模型位置并设置
PYTHONPATH
环境变量。(vm)$ git clone https://github.com/tensorflow/models.git (vm)$ pip3 install -r models/official/requirements.txt
(vm)$ export PYTHONPATH="${PWD}/models:${PYTHONPATH}"
切换到存储模型处理文件的目录:
(vm)$ cd ~/models/official/recommendation
在 DATA_DIR 中为 ml-20m 数据集生成训练和评估数据:
(vm)$ python3 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}
此脚本会在虚拟机上生成并预处理数据集。预处理 将数据转换为模型所需的 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
设置 Cloud TPU 名称变量。
(vm)$ export TPU_NAME=local
运行训练和评估
以下脚本运行一个示例训练,运行三个周期:
为 Model 目录添加环境变量以保存检查点和 TensorBoard 总结:
(vm)$ export MODEL_DIR=${STORAGE_BUCKET}/ncf
创建 TPU 时,如果您将
--version
参数设置为以-pjrt
结尾的版本,请设置以下环境变量以启用 PJRT 运行时:(vm)$ export NEXT_PLUGGABLE_DEVICE_USE_C_API=true (vm)$ export TF_PLUGGABLE_DEVICE_LIBRARY_PATH=/lib/libtpu.so
运行以下命令训练 NCF 模型:
(vm)$ python3 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 分钟时间,并生成如下所示的最终输出:
Result is {'loss': <tf.Tensor: shape=(), dtype=float32, numpy=0.10950611>, 'train_finish_time': 1618016422.1377568, 'avg_exp_per_second': 3062557.5070816963}
清除数据
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
断开与 Compute Engine 实例的连接(如果您尚未这样做):
(vm)$ exit
您的提示符现在应为
username@projectname
,表明您位于 Cloud Shell 中。删除您的 Cloud TPU 资源。
$ gcloud compute tpus tpu-vm delete ncf-tutorial \ --zone=europe-west4-a
通过运行
gcloud compute tpus tpu-vm list
验证资源是否已删除。删除操作可能需要几分钟时间才能完成。如下所示的响应表明 您的实例已成功删除。$ gcloud compute tpus tpu-vm list \ --zone=europe-west4-a
Listed 0 items.
如下所示,运行 gcloud CLI,将 bucket-name 替换为 您为本教程创建的 Cloud Storage 存储桶的名称:
$ gcloud storage rm gs://bucket-name --recursive
后续步骤
TensorFlow Cloud TPU 教程通常使用示例数据集来训练模型。此训练的结果不能用于推理。接收者 使用模型进行推理,可以在公开可用的 或您自己的数据集。在 Cloud TPU 上训练的 TensorFlow 模型通常要求数据集采用 TFRecord 格式。
您可以使用数据集转换工具 示例,用于转换图片 转换为 TFRecord 格式。如果您使用的不是图片 分类模型,您需要将数据集转换为 TFRecord 格式 。如需了解详情,请参阅 TFRecord 和 tf.Example。
超参数调节
要使用数据集提升模型的性能,您可以调整模型的 超参数。您可以在 GitHub 上寻找所有 TPU 支持模型通用的超参数的相关信息。您可以在每个模型的源代码中寻找模型专用超参数的相关信息。如需详细了解超参数调优,请参阅概览 超参数调优 和 Tune 超参数。
推断
训练模型后,即可将其用于推理(也称为 预测)。您可以使用 Cloud TPU 推断转换器 工具来准备和优化 在 Cloud TPU v5e 上用于推理的 TensorFlow 模型。有关 如需了解如何在 Cloud TPU v5e 上进行推理,请参阅 Cloud TPU v5e 推理 简介。
- 详细了解
ctpu
,包括如何在本地机器上安装。 - 探索 TensorBoard 中的 TPU 工具。