Deep_Rank是一套从数据生成到模型生成的完整框架。对输入特征,特征工程,核心模型,模型输出分别进行了封装。 模型更新迭代的时候可以针对性的修改指定模块,也方便后续模型的切换,特征的迭代,以及输入数据在输入,特征工程,保存模型,线上服务各个模块的统一配置。本库对一些经典的ctr预估模型进行了复现,方便自己在工作中迭代优化模型。
利用 tfrecords/
下的代码可以很方便的利用spark集群将数仓经过ETL的hive表训练数据转化成frecords
格式,并存储HDFS上。
配置训练数据中的字段,可以只选择模型需要的字段;
格式:
"user_id":
{
"feature_type": "fixed_len",
"value_type": "int",
"default_value": 0
}
字段名为key;
feature_type:tensorflow特征类型,当前所有模型使用的是fixed_len;
value_type:特征值的类型,当前支持{'string', 'int', 'double'},
可以在train_model.py#19 函数get_input_schema_spec中添加/修改;
default_value: 该特征值的默认填充值,类型需要和value_type一致;
配置模型中特征的形式,使用tensorflow FeatureColumns API实现;
具体支持的FeatureColumns包括:
"categorical_column_with_hash_bucket"
"numeric_column"
"embedding_column"
"categorical_column_with_vocabulary_list"
"categorical_column_with_identity"
"indicator_column"
"bucketized_column"
"shared_embedding_columns"
"crossed_column"
"NumericColumnV2" (这个是修改的原始numeric_column,用来自适应学习缺失值,具体思路可以看源码)
配置格式:
{
"name": "IndicatorColumn",
"parameters":
{
"input_tensor": "u_sc_gender_hashbucket",
"output_tensor": "u_sc_gender_indicator",
"wide_or_deep": "deep"
}
}
input_tensor:定义输入名
output_tensor:定义输出名
wide_or_deep:用于wd,deepfm的wide侧和deep侧区分;
如果只是中间特征,不作为最后的输出则不填;
其他模型默认只取"deep"值特征;
din,dien等模型,用于attention的sequence特征和目标id不需要在model_feature.json进行配置;
本文件存放模型核心代码,所有代码继承BaseModel
类,底层使用tensorflow的FeatureColumns实现统一的embedding层。上层利用tensorlfow的Layers实现核心模型结构,最后把模型封装成Esitmator,输出统一的estimator_spec接口。
已经实现好的模型有以下几个:
DNN
实现的是一个简单的embedding+MLP,方便调试整体代码,在model_feature.json
中配置wide_or_deep
参数值 "deep"
;
Deep Cross Network(DCN)
在model_feature.json
中只需配置deep特征
,croos层和deep层同用统一的embeddig层。
对应算法论文[click here]
Wide and Deep Network(WD)
需要在model_feature.json
配置wide侧和deep侧对应的特征。
对应算法论文[click here]
Deep Interest Network(DIN)
的上下文特征和基础画像特征需要配置model_feature.json
中,统一使用"deep"
特征,其中需要做attention
的sequence
和sequence对应的目标id
不需要配置在model_feature.json
中,直接配置在模型参数中。
在对应算法论文[click here]
Entire Space Multi-Task Model(ESMM)
也一样,默认只使用"deep"
特征。
对应算法论文[click here]
Deep Interest Evolution Network(DIEN)
和DIN一样,序列特征
和序列对应目标id
需要在模型中写。
这里为了实现方便,序列的负采样
部分没有按照原始论文的方式单独使用一份负采样的item数据集,而是直接使用同一个batch
中的其他sequence
作为当前的负采样序列
。
对应算法论文[click here]
DeepFM
的wide侧放线性特征,deep侧放的是统一的MLP和FM的特征
,所有这里必须保证deep特征全部是embedding特征,并且embedding维度全部一致
。这里后续会优化一下,对一些数值特征做优化,方便扩展。
对应算法论文[click here]
xDeepFM
的参数配置和deepFM类似,wide侧放线性特征,deep侧放的是统一的MLP和CIN特征
,所有这里必须保证deep特征全部是embedding特征,并且embedding维度全部一致
。
对应算法论文[click here]
DSSM
需要在wide和deep侧分别放置user info和item info。
对应算法论文[click here]
youtube_net
本文是youtube提出的排序模型 "Recommending What Video to Watch Next: A Multitask Ranking System",不知道叫啥,所以直接叫youtube_net了。
对应算法论文[click here]
后续利用空闲时间和节假日会持续添加新算法
直接运行主函数
`python train_model.py`
部分实现参考了:
x-deeplearning的xdl-algorithm-solution: [click here]
脚本配置方式:[click here]
esmm实现:[click here]
tensorflow自带的分类器: [click here]
xDeepFM实现:click_here
MMoE实现:click_here
代码实现的问题:
代码实现为了方便调试,DIN,DIEN中的所有的序列特征都只用了id,可自行添加类目序列,产品词序列等边界信息
存放tfrecords文件的生成和使用代码
利用spark读取数据保存成tfrecods这里提供两个思路。
1.如果集群上已经安装了tensorflow,可以用本文件下的代码进行处理。
2.对于没有安装tensorflow的集群,可以参考:spark-tensorflow-connector 来将数据转换成tfrecords。这个更快。
-------------------------以下已经删除或弃用--------------------------------
所以这里我自己实现了一个wide&deep模型。支持连续特征,类别特征,embedding特征,特征交叉等常见操作,也支持list特征以及各种数据类型。能很方便的将生成的模型export,以及支持分布式训练。
修改模型的核心代码可以很方便的扩展到其他DNN模型,现在暂时只支持Wide,DNN,WD三类。
实现esmm模型
便于迭代模型,以及之前脚本代码写的有点乱,部分同学反馈代码不是很优雅。所以针对性的进行了优化。
- 配置config/inputs.json,配置好输入的字段,以及需要做的操作,以及相对应的操作
- 配置好对应的路径
- 运行train_wd_model.py即可。
存放模型配置文件