论文复现:Feature Generation by Convolutional Neural Network for Click-Through Rate Prediction

一、简介

  • 论文《Feature Generation by Convolutional Neural Network for Click-Through Rate Prediction》FGCNN是华为诺亚方舟于2019年发布的CTR预测的论文,它利用CNN网络生成特征,从而应用于CTR任务。
  • CTR预测任务的关键挑战是如何有效地对特征的相互作用进行建模。广义线性模型,如FTRL,在实践中表现良好,但这些模型缺乏学习特征交互的能力。Wide & Deep Learning利用宽组件中的特征工程来帮助深度组件的学习,在人工特征的帮助下,深度组件的性能得到了明显的改善(离线AUC提高0.6%,在线CTR提高1%)。但特征工程成本高,并且需要领域知识。本文考虑是否可以通过自动生成复杂特征交互的方法,来增加特征交互的能力,并减小特征工程的成本。

二、算法细节

GCNN的模型组网包含三部分:FeatureEmbedding,FeatureGeneration与DeepClassifier,下面对三部分进行介绍

  1. FeatureEmbedding 在大多数CTR预测任务中,数据是以多字段分类形式收集的,因此,每个数据实例通常通过one-hot编码转化为高维稀疏向量。嵌入层将高维的稀疏特征映射到低维的稠密特征中去。在FGCNN中,嵌入矩阵E可以在特征生成和深度分类器中得到利用。为了避免更新参数时梯度方向的不一致,文中将为深度分类器引入另一个嵌入矩阵E′∈Rnf ×k,而E用于特征生成。

  2. FeatureGeneration 特征生成包含卷积层,池化层,重组层和合并操作。特征生成部分也是FGCNN的核心部分,简而言之,特征生成部分首先通过卷积层与池化层提取有用的邻域特征,之后通过重组层提取全局的特征交互,最终生成了新特征,最后将原始特征与新特征进行合并,从而得到最终特征。

  3. DeepClassifier 深度分类器的使用目的是学习原始特征与新生成特征更加深度的交互,得到更深层的特征,文中采用IPNN模型作为深度分类器的网络结构,作者认为它在模型复杂性和准确性之间有很好的权衡。同时,作者认为,任何先进的网络结构都可以被采用,这也表明FGCNN与现有工作有很好的兼容性。最终FGCNN的目标是最小化预测值与目标值的交叉熵。

  • 整个算法如图
    在这里插入图片描述

三、复现精度

模型 auc batch_size epoch_num Time of each epoch
fgcnn 0.8022 2000 2 约 2 小时

四、数据集

训练及测试数据集选用Display Advertising Challenge所用的Criteo数据集。该数据集包括两部分:训练集和测试集。训练集包含一段时间内Criteo的部分流量,测试集则对应训练数据后一天的广告点击流量。
每一行数据格式如下所示:

<label> <integer feature 1> ... <integer feature 13> <categorical feature 1> ... <categorical feature 26>

其中<label>表示广告是否被点击,点击用1表示,未点击用0表示。<integer feature>代表数值特征(连续特征),共有13个连续特征。<categorical feature>代表分类特征(离散特征),共有26个离散特征。相邻两个特征用\t分隔,缺失特征用空格表示。测试集中<label>特征已被移除。

在模型目录的data目录下为您准备了快速运行的示例数据,若需要使用全量数据可以参考下方效果复现部分。

全量数据目录结构

|- criteo_fgcnn
|  |- train
|  |  |- train.h5
|  |- test
|  |  |- valid.h5

数据集链接(预处理过的):https://paddlerec.bj.bcebos.com/datasets/fgcnn/datapro.zip

五、环境依赖

  • 硬件:
    • x86 cpu
    • NVIDIA GPU
  • 软件平台与框架:
    • PaddlePaddle >= 2.1
    • python >= 3.5

六、快速开始

1、准备全量数据集

# 进入模型目录
%cd /home/aistudio/PaddleRec/datasets/criteo_fgcnn
/home/aistudio/PaddleRec/datasets/criteo_fgcnn
# 执行脚本下载数据集并解压缩
!bash run.sh
--2022-06-27 22:11:33--  https://paddlerec.bj.bcebos.com/datasets/fgcnn/datapro.zip
正在解析主机 paddlerec.bj.bcebos.com (paddlerec.bj.bcebos.com)... 100.67.200.6
正在连接 paddlerec.bj.bcebos.com (paddlerec.bj.bcebos.com)|100.67.200.6|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 2472185427 (2.3G) [application/x-zip-compressed]
正在保存至: “datapro.zip”

datapro.zip         100%[===================>]   2.30G  94.6MB/s    in 26s     

2022-06-27 22:11:59 (91.7 MB/s) - 已保存 “datapro.zip” [2472185427/2472185427])

Archive:  datapro.zip
   creating: criteo_x4_5c863b0f_c15c45a1/
  inflating: criteo_x4_5c863b0f_c15c45a1/feature_encoder.pkl  
  inflating: criteo_x4_5c863b0f_c15c45a1/feature_map.json  
  inflating: criteo_x4_5c863b0f_c15c45a1/train.h5  
  inflating: criteo_x4_5c863b0f_c15c45a1/valid.h5  
Complete data download.
# 进入项目目录
%cd /home/aistudio/PaddleRec/models/rank/fgcnn
/home/aistudio/PaddleRec/models/rank/fgcnn

2、执行以下命令训练

!python -u ../../../tools/trainer.py -m config_bigdata.yaml # 全量数据运行config_bigdata.yaml 
2022-06-27 22:14:01,408 - INFO - **************common.configs**********
2022-06-27 22:14:01,408 - INFO - use_gpu: True, use_xpu: False, use_npu: False, use_visual: False, train_batch_size: 2000, train_data_dir: ../../../datasets/criteo_fgcnn/train, epochs: 2, print_interval: 2000, model_save_path: output_model_all_fgcnn
2022-06-27 22:14:01,408 - INFO - **************common.configs**********
W0627 22:14:01.409466  6825 gpu_context.cc:278] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0627 22:14:01.412858  6825 gpu_context.cc:306] device: 0, cuDNN Version: 7.6.
2022-06-27 22:14:05,454 - INFO - read data
2022-06-27 22:14:05,455 - INFO - reader path:reader
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/train/train.h5
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/train/train.h5
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/nn/layer/norm.py:654: UserWarning: When training, we now always track global mean and variance.
  "When training, we now always track global mean and variance.")
2022-06-27 22:14:08,116 - INFO - epoch: 0, batch_id: 0, auc:0.495077, loss:0.7010272, avg_reader_cost: 0.00063 sec, avg_batch_cost: 0.00128 sec, avg_samples: 1.00000, ips: 779.89968 ins/s
2022-06-27 22:27:26,709 - INFO - epoch: 0, batch_id: 2000, auc:0.777585, loss:0.4792568, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39889 sec, avg_samples: 2000.00000, ips: 5013.86763 ins/s
2022-06-27 22:40:44,897 - INFO - epoch: 0, batch_id: 4000, auc:0.785751, loss:0.45518488, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39868 sec, avg_samples: 2000.00000, ips: 5016.49655 ins/s
2022-06-27 22:54:01,923 - INFO - epoch: 0, batch_id: 6000, auc:0.789658, loss:0.4496535, avg_reader_cost: 0.00011 sec, avg_batch_cost: 0.39811 sec, avg_samples: 2000.00000, ips: 5023.71165 ins/s
2022-06-27 23:07:22,186 - INFO - epoch: 0, batch_id: 8000, auc:0.792430, loss:0.45026135, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39973 sec, avg_samples: 2000.00000, ips: 5003.41810 ins/s
2022-06-27 23:20:40,630 - INFO - epoch: 0, batch_id: 10000, auc:0.794615, loss:0.4497902, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39882 sec, avg_samples: 2000.00000, ips: 5014.84225 ins/s
2022-06-27 23:34:01,417 - INFO - epoch: 0, batch_id: 12000, auc:0.796342, loss:0.44737732, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39999 sec, avg_samples: 2000.00000, ips: 5000.09533 ins/s
2022-06-27 23:47:20,289 - INFO - epoch: 0, batch_id: 14000, auc:0.797672, loss:0.45437783, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39905 sec, avg_samples: 2000.00000, ips: 5011.84700 ins/s
2022-06-28 00:00:44,612 - INFO - epoch: 0, batch_id: 16000, auc:0.798829, loss:0.43731716, avg_reader_cost: 0.00014 sec, avg_batch_cost: 0.40174 sec, avg_samples: 2000.00000, ips: 4978.32650 ins/s
2022-06-28 00:14:01,523 - INFO - epoch: 0, batch_id: 18000, auc:0.799844, loss:0.4586409, avg_reader_cost: 0.00013 sec, avg_batch_cost: 0.39806 sec, avg_samples: 2000.00000, ips: 5024.33767 ins/s
2022-06-28 00:16:13,887 - INFO - epoch: 0 done, auc: 0.799969,loss:0.44447154, epoch time: 7328.34 s
2022-06-28 00:18:02,737 - INFO - Already save model in output_model_all_fgcnn/0
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/train/train.h5
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/train/train.h5
2022-06-28 00:18:05,336 - INFO - epoch: 1, batch_id: 0, auc:0.809100, loss:0.42051184, avg_reader_cost: 0.00069 sec, avg_batch_cost: 0.00129 sec, avg_samples: 1.00000, ips: 772.24118 ins/s
^C
Traceback (most recent call last):
  File "../../../tools/trainer.py", line 225, in <module>
    main(args)
  File "../../../tools/trainer.py", line 146, in main
    dy_model, metric_list, batch, config)
  File "/home/aistudio/PaddleRec/models/rank/fgcnn/dygraph_model.py", line 79, in train_forward
    label, inputs = self.create_feeds(batch_data, config)
  File "/home/aistudio/PaddleRec/models/rank/fgcnn/dygraph_model.py", line 50, in create_feeds
    inputs = paddle.to_tensor(np.array(batch_data[0]).astype('int64'))
KeyboardInterrupt

3、执行以下命令评估

!python -u ../../../tools/infer.py -m config_bigdata.yaml # 全量数据运行config_bigdata.yaml 
2022-06-28 00:21:37,483 - INFO - **************common.configs**********
2022-06-28 00:21:37,483 - INFO - use_gpu: True, use_xpu: False, use_npu: False, use_visual: False, infer_batch_size: 5000, test_data_dir: ../../../datasets/criteo_fgcnn/test, start_epoch: 0, end_epoch: 1, print_interval: 2000, model_load_path: output_model_all_fgcnn
2022-06-28 00:21:37,483 - INFO - **************common.configs**********
W0628 00:21:37.484494 39425 gpu_context.cc:278] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0628 00:21:37.487735 39425 gpu_context.cc:306] device: 0, cuDNN Version: 7.6.
2022-06-28 00:21:41,130 - INFO - read data
2022-06-28 00:21:41,130 - INFO - reader path:reader
2022-06-28 00:21:41,200 - INFO - load model epoch 0
2022-06-28 00:21:41,200 - INFO - start load model from output_model_all_fgcnn/0
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/test/valid.h5
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/test/valid.h5
2022-06-28 00:22:36,474 - INFO - epoch: 0, batch_id: 0, auc: 0.831889,loss:0.39073417, avg_reader_cost: 0.00075 sec, avg_batch_cost: 0.00096 sec, avg_samples: 5000.00000, ips: 180916.58 ins/s
2022-06-28 00:32:19,464 - INFO - epoch: 0 done, auc: 0.807540,loss:0.4395584, epoch time: 638.26 s

七、代码结构与详细说明

7.1 代码结构

以下为本项目代码结构

├── data #样例数据
    ├── trainlite
        |—— train_sample.h5 #样例训练数据
    |—— testlite
        |—— train_sample.h5 #样例测试数据
├── README.md #文档
├── config.yaml # sample数据配置
├── config_bigdata.yaml # 全量数据配置
├── net.py # 模型核心组网(动静统一)
├── reader.py #数据读取程序
├── dygraph_model.py # 构建动态图

7.2 参数说明

可以在config_bigdata.yaml中设置相关参数。

训练参数说明如下

参数 默认值 说明 其他
train_data_dir “…/…/…/datasets/criteo_fgcnn/train” 训练数据地址
train_reader_path “reader” 训练数据加载脚本地址 本项目的reader.py就是数据加载脚本
use_gpu True 是否使用gpu
use_auc True 是否使用auc
train_batch_size 2000 训练批大小
epochs 2 训练轮次
print_interval 1000 日志打印间隔
model_save_path “output_model_all_fgcnn” 模型保存地址
test_data_dir “…/…/…/datasets/criteo_fgcnn/test” 测试数据地址
infer_reader_path “reader” 推理(测试)数据加载脚本地址 本项目训练测试数据加载共用脚本
infer_batch_size 5000 推理批大小
infer_load_path “output_model_all_fgcnn” 推理模型加载目录 这里推理模型加载的目录就是训练时保存模型的目录
infer_start_epoch 0 推理起始轮次 即选择从第几个训练模型开始推理
infer_end_epoch 2 推理结束轮次 即选择推理到第几个训练模型截至

模型参数说明如下

参数 默认值 说明 其他
optimizer.class Adam 优化器
optimizer.learning_rate 0.001 学习率
sparse_inputs_slots 26 稀疏特征数量 criteo数据集的稀疏特征为26个
sparse_feature_size 1000000 稀疏特征大小
feature_name [‘I1’,‘I2’,‘I3’,‘I4’,‘I5’,‘I6’,‘I7’,‘I8’,‘I9’,‘I10’,‘I11’,‘I12’,‘I13’,‘C1’,‘C2’,‘C3’,‘C4’,‘C5’,‘C6’,‘C7’,‘C8’,‘C9’,‘C10’,‘C11’,‘C12’,‘C13’,‘C14’,‘C15’,‘C16’,‘C17’, ‘C18’,‘C19’, ‘C20’, ‘C21’, ‘C22’,‘C23’, ‘C24’, ‘C25’, ‘C26’] 特征名 总共39个特征,I1-I13为稠密特征,C1-C26为稀疏特征
dense_inputs_slots 13 稠密特征数量 criteo数据集的稠密特征为13个
feature_dim 20 特征维度
conv_kernel_width [9,9,9,9] 卷积核大小
conv_filters [38,40,42,44] 卷积核数目
new_maps [3, 3, 3, 3] 新特征映射
pooling_width [2,2,2,2] 池化大小
stride [1,1] 步长
dnn_hidden_units [1000,1000,1000] DNN的隐层SIZE
dnn_dropout 0.0 DNN的Dropout

7.3 训练流程

下面展示一个epoch的训练日志

2022-06-27 22:14:01,408 - INFO - **************common.configs**********
2022-06-27 22:14:01,408 - INFO - use_gpu: True, use_xpu: False, use_npu: False, use_visual: False, train_batch_size: 2000, train_data_dir: ../../../datasets/criteo_fgcnn/train, epochs: 2, print_interval: 2000, model_save_path: output_model_all_fgcnn
2022-06-27 22:14:01,408 - INFO - **************common.configs**********
W0627 22:14:01.409466  6825 gpu_context.cc:278] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0627 22:14:01.412858  6825 gpu_context.cc:306] device: 0, cuDNN Version: 7.6.
2022-06-27 22:14:05,454 - INFO - read data
2022-06-27 22:14:05,455 - INFO - reader path:reader
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/train/train.h5
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/train/train.h5
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/paddle/nn/layer/norm.py:654: UserWarning: When training, we now always track global mean and variance.
  "When training, we now always track global mean and variance.")
2022-06-27 22:14:08,116 - INFO - epoch: 0, batch_id: 0, auc:0.495077, loss:0.7010272, avg_reader_cost: 0.00063 sec, avg_batch_cost: 0.00128 sec, avg_samples: 1.00000, ips: 779.89968 ins/s
2022-06-27 22:27:26,709 - INFO - epoch: 0, batch_id: 2000, auc:0.777585, loss:0.4792568, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39889 sec, avg_samples: 2000.00000, ips: 5013.86763 ins/s
2022-06-27 22:40:44,897 - INFO - epoch: 0, batch_id: 4000, auc:0.785751, loss:0.45518488, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39868 sec, avg_samples: 2000.00000, ips: 5016.49655 ins/s
2022-06-27 22:54:01,923 - INFO - epoch: 0, batch_id: 6000, auc:0.789658, loss:0.4496535, avg_reader_cost: 0.00011 sec, avg_batch_cost: 0.39811 sec, avg_samples: 2000.00000, ips: 5023.71165 ins/s
2022-06-27 23:07:22,186 - INFO - epoch: 0, batch_id: 8000, auc:0.792430, loss:0.45026135, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39973 sec, avg_samples: 2000.00000, ips: 5003.41810 ins/s
2022-06-27 23:20:40,630 - INFO - epoch: 0, batch_id: 10000, auc:0.794615, loss:0.4497902, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39882 sec, avg_samples: 2000.00000, ips: 5014.84225 ins/s
2022-06-27 23:34:01,417 - INFO - epoch: 0, batch_id: 12000, auc:0.796342, loss:0.44737732, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39999 sec, avg_samples: 2000.00000, ips: 5000.09533 ins/s
2022-06-27 23:47:20,289 - INFO - epoch: 0, batch_id: 14000, auc:0.797672, loss:0.45437783, avg_reader_cost: 0.00012 sec, avg_batch_cost: 0.39905 sec, avg_samples: 2000.00000, ips: 5011.84700 ins/s
2022-06-28 00:00:44,612 - INFO - epoch: 0, batch_id: 16000, auc:0.798829, loss:0.43731716, avg_reader_cost: 0.00014 sec, avg_batch_cost: 0.40174 sec, avg_samples: 2000.00000, ips: 4978.32650 ins/s
2022-06-28 00:14:01,523 - INFO - epoch: 0, batch_id: 18000, auc:0.799844, loss:0.4586409, avg_reader_cost: 0.00013 sec, avg_batch_cost: 0.39806 sec, avg_samples: 2000.00000, ips: 5024.33767 ins/s
2022-06-28 00:16:13,887 - INFO - epoch: 0 done, auc: 0.799969,loss:0.44447154, epoch time: 7328.34 s
2022-06-28 00:18:02,737 - INFO - Already save model in output_model_all_fgcnn/0

7.4 测试流程

下面展示一个epoch的测试日志

2022-06-28 00:21:37,483 - INFO - **************common.configs**********
2022-06-28 00:21:37,483 - INFO - use_gpu: True, use_xpu: False, use_npu: False, use_visual: False, infer_batch_size: 5000, test_data_dir: ../../../datasets/criteo_fgcnn/test, start_epoch: 0, end_epoch: 1, print_interval: 2000, model_load_path: output_model_all_fgcnn
2022-06-28 00:21:37,483 - INFO - **************common.configs**********
W0628 00:21:37.484494 39425 gpu_context.cc:278] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 10.1
W0628 00:21:37.487735 39425 gpu_context.cc:306] device: 0, cuDNN Version: 7.6.
2022-06-28 00:21:41,130 - INFO - read data
2022-06-28 00:21:41,130 - INFO - reader path:reader
2022-06-28 00:21:41,200 - INFO - load model epoch 0
2022-06-28 00:21:41,200 - INFO - start load model from output_model_all_fgcnn/0
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/test/valid.h5
/home/aistudio/PaddleRec/models/rank/fgcnn/../../../datasets/criteo_fgcnn/test/valid.h5
2022-06-28 00:22:36,474 - INFO - epoch: 0, batch_id: 0, auc: 0.831889,loss:0.39073417, avg_reader_cost: 0.00075 sec, avg_batch_cost: 0.00096 sec, avg_samples: 5000.00000, ips: 180916.58 ins/s
2022-06-28 00:32:19,464 - INFO - epoch: 0 done, auc: 0.807540,loss:0.4395584, epoch time: 638.26 s

八、实验心得

  • FGCNN是通过特征生成提高特征交互质量的模型,复现难点主要在于fgcnn层的实现,由于框架的灵活性,具体参数可以在config中定义,实验时对其修改即可。DNN的参数可以修改,不断实验,这个参数有许多选择。
  • PaddleRec是一个功能完善,方便易用的开源推荐框架,内含非常多的推荐算法实现,可以非常方便地通过PaddleRec实现自己的想法,复现论文的代码。本文通过PaddleRec复现FGCNN模型,可以轻松实现其模型结构,也可以根据自己需求进行优化,方便易用。

九、模型信息

训练完成后,模型保存在/home/aistudio/PaddleRec/models/rank/fgcnn/output_model_all_fgcnn目录下。

信息 说明
发布者 yoreG123、chenjiyan2001
时间 2022.06
框架版本 Paddle 2.3.0.post101
应用场景 推荐排序
支持硬件 GPU、CPU

代码已在paddlerec中收录

开源链接

AiStudio原项目链接:https://aistudio.baidu.com/aistudio/projectdetail/4257791?contributionType=1&shared=1

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐