提交 d0a9258e 编写于 作者: Y yinhaofeng

readme

上级 7629ffa8
......@@ -43,6 +43,10 @@
year={2017}
}
```
在全量数据下模型的指标如下:
| 模型 | auc | batch_size | thread_num| epoch_num| Time of each epoch |
| :------| :------ | :------| :------ | :------| :------ | :------ |
| deepFM | 0.8044 | 1024 | 10 | 2 | 约3.5小时 |
## 数据准备
### 数据来源
训练及测试数据集选用[Display Advertising Challenge](https://www.kaggle.com/c/criteo-display-ad-challenge/)所用的Criteo数据集。该数据集包括两部分:训练集和测试集。训练集包含一段时间内Criteo的部分流量,测试集则对应训练数据后一天的广告点击流量。
......@@ -74,6 +78,28 @@ os : windows/linux/macos
```
python -m paddlerec.run -m models/rank/deepfm/config.yaml
```
使用样例数据快速跑通的结果实例:
```
PaddleRec: Runner train_runner Begin
Executor Mode: train
processor_register begin
Running SingleInstance.
Running SingleNetwork.
Warning:please make sure there are no hidden files in the dataset folder and check these hidden files:[]
Running SingleStartup.
Running SingleRunner.
2020-09-24 03:45:57,924-INFO: [Train] batch: 1, time_each_interval: 2.22s, BATCH_AUC: [0.43357143 0.4689441 0.43859649 0.42124542 0.44302615 0.44444444
0.48305085 0.47866667 0.48032407 0.45833333], AUC: [0.43357143 0.4562963 0.43859649 0.47866667 0.44302615 0.44444444
0.48305085 0.4562963 0.49451754 0.45833333]
epoch 0 done, use time: 2.38709902763, global metrics: BATCH_AUC=2.2195661068, AUC=[0.43357143 0.4689441 0.43859649 0.42124542 0.44302615 0.44444444
0.48305085 0.47866667 0.48032407 0.45833333]
2020-09-24 03:45:59,023-INFO: [Train] batch: 1, time_each_interval: 0.07s, BATCH_AUC: [0.4570095 0.45771188 0.45467121 0.47039474 0.46313874 0.45297619
0.46199579 0.45470861 0.47237934 0.47326632], AUC: [0.4570095 0.45771188 0.45575717 0.47039474 0.46313874 0.45297619
0.46199579 0.45470861 0.47237934 0.47326632]
epoch 1 done, use time: 0.0733981132507, global metrics: BATCH_AUC=0.0677909851074, AUC=[0.4570095 0.45771188 0.45467121 0.47039474 0.46313874 0.45297619
0.46199579 0.45470861 0.47237934 0.47326632]
PaddleRec Finish
```
## 模型组网
......@@ -88,102 +114,37 @@ $$Out=sigmoid(b + \sum^{N}_{i=1}W_iX_i + \sum^{N-1}_{i=1}\sum^{N}_{j=i+1}W_{ij}X
用公式表示如下:
$$\sum^{N}_{i=1}W_iX_i$$
```python
first_weights_re = fluid.embedding(
input=feat_idx,
is_sparse=True,
is_distributed=is_distributed,
dtype='float32',
size=[self.sparse_feature_number + 1, 1],
padding_idx=0,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormalInitializer(
loc=0.0, scale=init_value_),
regularizer=fluid.regularizer.L1DecayRegularizer(self.reg)))
first_weights = fluid.layers.reshape(first_weights_re,shape=[-1, self.num_field, 1]) # None * num_field * 1
y_first_order = fluid.layers.reduce_sum((first_weights * feat_value),1)
```
### 二阶项部分
二阶项部分主要实现了公式中的交叉项部分,也就是特征的组合部分。Wij求解的思路是通过矩阵分解的方法。所有的二次项参数Wij可以组成一个对称阵W,那么这个矩阵就可以分解为 $W=V^TV$,V 的第 i 列便是第 i 维特征的隐向量。交叉项的展开式如下:
$$\sum^{N-1}_{i=1}\sum^{N}_{j=i+1}W_{ij}X_iX_j =1/2\sum^{k}_{j=1}((\sum^{N}_{i=1}W_iX_i)^2-\sum^{N}_{i=1}W_i^2X_i^2)$$
```python
feat_embeddings_re = fluid.embedding(
input=feat_idx,
is_sparse=True,
is_distributed=is_distributed,
dtype='float32',
size=[self.sparse_feature_number + 1, self.sparse_feature_dim],
padding_idx=0,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormalInitializer(
loc=0.0,
scale=init_value_ /
math.sqrt(float(self.sparse_feature_dim)))))
feat_embeddings = fluid.layers.reshape(
feat_embeddings_re,
shape=[-1, self.num_field, self.sparse_feature_dim]) # None * num_field * embedding_size
# None * num_field * embedding_size
feat_embeddings = feat_embeddings * feat_value
# sum_square part
summed_features_emb = fluid.layers.reduce_sum(feat_embeddings, 1) # None * embedding_size
summed_features_emb_square = fluid.layers.square(summed_features_emb) # None * embedding_size
# square_sum part
squared_features_emb = fluid.layers.square(feat_embeddings) # None * num_field * embedding_size
squared_sum_features_emb = fluid.layers.reduce_sum(squared_features_emb, 1) # None * embedding_size
y_second_order = 0.5 * fluid.layers.reduce_sum(summed_features_emb_square - squared_sum_features_emb,1,keep_dim=True) # None * 1
```
### dnn部分
相比fm模型,我们去除了fm模型中的偏移量,而加入了dnn部分作为特征间的高阶组合,通过并行的方式组合fm和dnn两种方法,两者共用底层的embedding数据。dnn部分的主要组成为三个全连接层,每层FC的输出维度都为400,每层FC都后接一个relu激活函数,每层FC的初始化方式为符合正态分布的随机初始化.
最后接了一层输出维度为1的fc层,方便与fm部分综合计算预测值。
```python
y_dnn = fluid.layers.reshape(feat_embeddings, [-1, self.num_field * self.sparse_feature_dim])
for s in self.layer_sizes:
y_dnn = fluid.layers.fc(
input=y_dnn,
size=s,
act=self.act,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormalInitializer(
loc=0.0, scale=init_value_ / math.sqrt(float(10)))),
bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormalInitializer(
loc=0.0, scale=init_value_)))
y_dnn = fluid.layers.fc(
input=y_dnn,
size=1,
act=None,
param_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormalInitializer(
loc=0.0, scale=init_value_)),
bias_attr=fluid.ParamAttr(
initializer=fluid.initializer.TruncatedNormalInitializer(
loc=0.0, scale=init_value_)))
```
### Loss及Auc计算
- 预测的结果将FM的一阶项部分,二阶项部分以及dnn部分相加,再通过激活函数sigmoid给出,为了得到每条样本分属于正负样本的概率,我们将预测结果和`1-predict`合并起来得到predict_2d,以便接下来计算auc。
- 每条样本的损失为负对数损失值,label的数据类型将转化为float输入。
- 该batch的损失`avg_cost`是各条样本的损失之和
- 我们同时还会计算预测的auc,auc的结果由`fluid.layers.auc()`给出,该层的返回值有三个,分别是全局auc: `auc_var`,当前batch的auc: `batch_auc_var`,以及auc_states: `_`,auc_states包含了`batch_stat_pos, batch_stat_neg, stat_pos, stat_neg`信息。
```python
self.predict = fluid.layers.sigmoid(y_first_order + y_second_order +y_dnn)
cost = fluid.layers.log_loss(
input=self.predict, label=fluid.layers.cast(self.label, "float32"))
avg_cost = fluid.layers.reduce_sum(cost)
self._cost = avg_cost
predict_2d = fluid.layers.concat([1 - self.predict, self.predict], 1)
label_int = fluid.layers.cast(self.label, 'int64')
auc_var, batch_auc_var, _ = fluid.layers.auc(input=predict_2d,
label=label_int,
slide_steps=0)
```
完成上述组网后,我们最终可以通过训练拿到`auc`指标。
## 效果复现
为了方便使用者能够快速的跑通每一个模型,我们在每个模型下都提供了样例数据。如果需要复现readme中的效果,请按如下步骤依次操作即可。
1. 确认您当前所在目录为PaddleRec/models/rank/deepfm
2. 在data目录下运行数据一键处理脚本,命令如下:
```
cd data
sh run.sh
cd ..
```
3. 退回deepfm目录中,打开文件config.yaml,更改其中的参数
将workspace改为您当前的绝对路径。(可用pwd命令获取绝对路径)
将train_sample中的batch_size从5改为1024
将train_sample中的data_path改为{workspace}/data/slot_train_data
将infer_sample中的batch_size从5改为1024
将infer_sample中的data_path改为{workspace}/data/slot_test_data
4. 开始训练。运行命令启动训练即可得到相应auc指标
```
python -m paddlerec.run -m ./config.yaml
```
5. 全量数据的训练结果示例如下:
```
PaddleRec: Runner infer_runner Begin
Executor Mode: infer
......@@ -211,26 +172,6 @@ Infer infer_phase of epoch 1 done, use time: 1764.81796193, global metrics: AUC=
PaddleRec Finish
```
## 效果复现
为了方便使用者能够快速的跑通每一个模型,我们在每个模型下都提供了样例数据。如果需要复现readme中的效果,请按如下步骤依次操作即可。
1. 确认您当前所在目录为PaddleRec/models/rank/deepfm
2. 在data目录下运行数据一键处理脚本,命令如下:
```
cd data
sh run.sh
cd ..
```
3. 退回deepfm目录中,打开文件config.yaml,更改其中的参数
将workspace改为您当前的绝对路径。(可用pwd命令获取绝对路径)
将train_sample中的batch_size从5改为512
将train_sample中的data_path改为{workspace}/data/slot_train_data
将infer_sample中的batch_size从5改为512
将infer_sample中的data_path改为{workspace}/data/slot_test_data
4. 开始训练。运行命令启动训练即可得到相应auc指标
```
python -m paddlerec.run -m ./config.yaml
```
## 进阶使用
## FAQ
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册