Skip to content

Latest commit

 

History

History
161 lines (117 loc) · 5.54 KB

model_develop.md

File metadata and controls

161 lines (117 loc) · 5.54 KB

如何添加自定义模型

当您希望开发自定义模型时,需要继承模型的模板基类,并实现三个必要的方法init_hyper_parameter,intput_data,net

并按照以下规范添加代码。

基类的继承

继承paddlerec.core.model的ModelBase,命名为Class Model

from paddlerec.core.model import ModelBase


class Model(ModelBase):

    # 构造函数无需显式指定
    # 若继承,务必调用基类的__init__方法
    def __init__(self, config):
        ModelBase.__init__(self, config)
        # ModelBase的__init__方法会调用_init_hyper_parameter()
    

超参的初始化

继承并实现_init_hyper_parameter方法(必要),可以在该方法中,从yaml文件获取超参或进行自定义操作。如下面的示例:

所有的envs调用接口在_init_hyper_parameters()方法中实现,同时类成员也推荐在此做声明及初始化。

 def _init_hyper_parameters(self):
    self.feature_size = envs.get_global_env(
        "hyper_parameters.feature_size")
    self.expert_num = envs.get_global_env("hyper_parameters.expert_num")
    self.gate_num = envs.get_global_env("hyper_parameters.gate_num")
    self.expert_size = envs.get_global_env("hyper_parameters.expert_size")
    self.tower_size = envs.get_global_env("hyper_parameters.tower_size")

数据输入的定义

继承并实现input_data方法(非必要)

直接使用基类的数据读取方法

ModelBase中的input_data默认实现为slot_reader,在config.yaml中分别配置reader.sparse_slotreader.dense_slot选项实现slog:feasign模式的数据读取。

Slot : Feasign 是什么?

Slot直译是槽位,在Rec工程中,是指某一个宽泛的特征类别,比如用户ID、性别、年龄就是Slot,Feasign则是具体值,比如:12345,男,20岁。

在实践过程中,很多特征槽位不是单一属性,或无法量化并且离散稀疏的,比如某用户兴趣爱好有三个:游戏/足球/数码,且每个具体兴趣又有多个特征维度,则在兴趣爱好这个Slot兴趣槽位中,就会有多个Feasign值。

PaddleRec在读取数据时,每个Slot ID对应的特征,支持稀疏,且支持变长,可以非常灵活的支持各种场景的推荐模型训练。

使用示例请参考rank.dnn模型。

自定义数据输入

如果您不想使用slot:feasign模式,则需继承并实现input_data接口,接口定义:def input_data(self, is_infer=False, **kwargs)

使用示例如下:

def input_data(self, is_infer=False, **kwargs):
    ser_slot_names = fluid.data(
        name='user_slot_names',
        shape=[None, 1],
        dtype='int64',
        lod_level=1)
    item_slot_names = fluid.data(
        name='item_slot_names',
        shape=[None, self.item_len],
        dtype='int64',
        lod_level=1)
    lens = fluid.data(name='lens', shape=[None], dtype='int64')
    labels = fluid.data(
        name='labels',
        shape=[None, self.item_len],
        dtype='int64',
        lod_level=1)
 
    train_inputs = [user_slot_names] + [item_slot_names] + [lens] + [labels]
    infer_inputs = [user_slot_names] + [item_slot_names] + [lens]
 
    if is_infer:
        return infer_inputs
    else:
        return train_inputs

更多数据读取教程,请参考自定义数据集及Reader

组网的定义

继承并实现net方法(必要)

  • 接口定义def net(self, inputs, is_infer=False)

  • 自定义网络需在该函数中使用paddle组网,实现前向逻辑,定义网络的Loss及Metrics,通过is_infer判断是否为infer网络。

  • 我们强烈建议traininfer尽量复用相同代码,

  • net中调用的其他函数以下划线为头进行命名,封装网络中的结构模块,如_sparse_embedding_layer(self)

  • inputsdef input_data()的输出,若使用slot_reader方式,inputs为占位符,无实际意义,通过以下方法拿到dense及sparse的输入

    self.sparse_inputs = self._sparse_data_var[1:]
    self.dense_input = self._dense_data_var[0]
    self.label_input = self._sparse_data_var[0]

可以参考官方模型的示例学习net的构造方法。

如何运行自定义模型

记录model.py,config.yaml及数据读取reader.py的文件路径,建议置于同一文件夹下,如/home/custom_model下,更改config.yaml中的配置选项

  1. 更改 workerspace为模型文件所在文件夹
workspace: "/home/custom_model"
  1. 更改数据地址及读取reader地址
dataset:
- name: custom_model_train
- data_path: "{workspace}/data/train" # or  "/home/custom_model/data/train"
- data_converter: "{workspace}/reader.py" # or "/home/custom_model/reader.py"
  1. 更改执行器的路径配置
mode: train_runner

runner:
- name: train_runner
  class: train
  device: cpu
  epochs: 10
  save_checkpoint_interval: 2
  save_inference_interval: 5
  save_checkpoint_path: "{workspace}/increment" # or  "/home/custom_model/increment"
  save_inference_path: "{workspace}/inference" # or  "/home/custom_model/inference"
  print_interval: 10

phase:
- name: train
  model: "{workspace}/model.py" # or "/home/custom_model/model"
  dataset_name: custom_model_train
  thread_num: 1
  1. 使用paddlerec.run方法运行自定义模型
python -m paddlerec.run -m /home/custom_model/config.yaml 

以上~请开始享受你的推荐算法高效开发流程。如有任何问题,欢迎在issue提出,我们会第一时间跟进解决。