Skip to content

  • 体验新版
    • 正在加载...
  • 登录
  • PaddlePaddle
  • Paddle
  • Issue
  • #2077

P
Paddle
  • 项目概览

PaddlePaddle / Paddle
大约 2 年 前同步成功

通知 2325
Star 20933
Fork 5424
  • 代码
    • 文件
    • 提交
    • 分支
    • Tags
    • 贡献者
    • 分支图
    • Diff
  • Issue 1423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
  • Wiki 0
    • Wiki
  • 分析
    • 仓库
    • DevOps
  • 项目成员
  • Pages
P
Paddle
  • 项目概览
    • 项目概览
    • 详情
    • 发布
  • 仓库
    • 仓库
    • 文件
    • 提交
    • 分支
    • 标签
    • 贡献者
    • 分支图
    • 比较
  • Issue 1,423
    • Issue 1,423
    • 列表
    • 看板
    • 标记
    • 里程碑
  • 合并请求 543
    • 合并请求 543
  • Pages
  • 分析
    • 分析
    • 仓库分析
    • DevOps
  • Wiki 0
    • Wiki
  • 成员
    • 成员
  • 收起侧边栏
  • 动态
  • 分支图
  • 创建新Issue
  • 提交
  • Issue看板
已关闭
开放中
Opened 5月 10, 2017 by saxon_zh@saxon_zhGuest

PaddlePaddle v2 api design

Created by: jacquesqiao

背景

  1. PaddlePaddle最初的使用方式是调用二进制trainer,通过解析配置文件的方式来驱动整个训练过程,例如demo/quick_start/train.sh的内容如下:
cfg=trainer_config.lr.py
paddle train \
  --config=$cfg \
  --save_dir=./output \
  --trainer_count=4 \
  --log_period=100 \
  --num_passes=15 \
  --use_gpu=false \
  --show_parameter_stats_period=100 \
  --test_all_data_in_one_period=1 \
  2>&1 | tee 'train.log'

最初通过swig暴露出来了一些python接口,然后当时可以通过裸掉这些接口的方式来实现一个python驱动的训练流程,一个典型的例子见:paddle/demo/quick_start/api_train.py,这个版本的python api中直接操作paddle中的核心组件,比如gradinet_machine, trainer来实现训练流程,封装比较简陋,不便于用户使用和理解。

后来为了使用户能够在notebook这种环境中方便的使用paddle进行训练任务,启动了python api v2的设计工作。详情见:https://github.com/PaddlePaddle/Paddle/projects/10 上面这个wiki中的很多设计都是一些中间状态,最终也被抛弃掉了,最终形成设计文档design_doc(https://github.com/PaddlePaddle/Paddle/pull/1088/files)。

目标

v2 api的主要目标是: 1,用户可以方便的用python驱动整个训练流程。 2,核心概念清晰易于理解,接口易用。

重构的主要内容。

1,网络配置相关: 灵活的layer配置方式。包含 layer topology等概念。 2,数据相关:dataset api。 3,训练相关:trainer,optimizer,parameters。

网络配置的主要变化。

1,最初的网络配置是一个文件,例如paddle/demo/quick_start/trainer_config.lr.py,trainer启动之后会通过内嵌的python解释器parse这个文件,生成的结果是一个proto。

data = data_layer(name="word", size=len(word_dict))
embedding = embedding_layer(input=data, size=128)
conv = sequence_conv_pool(input=embedding, context_len=3, hidden_size=512)
output = fc_layer(input=conv, size=2, act=SoftmaxActivation())

上面是一个典型的配置,data_layer,embedding_layer等都是一些function,上面代码的每一行都会执行函数,并且生成相应的结果,返回结果一般叫做LayerOutput,然后LayerOutput作为intput输入给下一个function。

所以每次解析一个网络,需要将上述所有代码依次执行一遍。

重构的主要变化是,每个layer变成了一个class(paddle/python/paddle/v2/config_base.py#Layer),配置过程中不做解析,layer会组成一个tree的结构,在需要解析的时候,传给topology这个结构进行parse,结果依然是原来那个proto。

network解析过程:

为了避免重写太多代码,实际上v2的网络解析是封装了上面v1的那些function,每个layer对应原来的一个function,核心思想是先把用户配置网络时输入的那些参数保存在v2 layer的class中,在适当的时候,调用v1的function。

    def to_proto_impl(self, **kwargs):
        args = dict()
        args['size'] = self.type.dim
        for each in kwargs:
            args[each] = kwargs[each]
        for each in self.__kwargs__:
            args[each] = self.__kwargs__[each]
        # 调用v2 function的地方
        return getattr(conf_helps, self.__method_name__)(name=self.name, **args)

调用的时机呢,因为v2是一个tree的结构,而parse需要从最初的layer开始,所以整个解析过程是一个递归的过程,其核心逻辑在Layer#to_proto这个函数里面。这个地方会先找到依赖的parent layer,先去调用他们的解析,解析的时候会把LayerOutput放到context中,这样后面的layer如果依赖这个layer的结果,就可以从context中找到并且使用了。

目前的问题:

1,核心问题在于目前v2 layer是一个递归结构,每个被配置的layer一定要在这个tree中的某个位置才能被解析到,然而有一些配置的layer只是依赖了某个layer,却没有被layer依赖,递归路径上找不到,就没有被解析。

指派人
分配到
无
里程碑
无
分配里程碑
工时统计
无
截止日期
无
标识: paddlepaddle/Paddle#2077
渝ICP备2023009037号

京公网安备11010502055752号

网络110报警服务 Powered by GitLab CE v13.7
开源知识
Git 入门 Pro Git 电子书 在线学 Git
Markdown 基础入门 IT 技术知识开源图谱
帮助
使用手册 反馈建议 博客
《GitCode 隐私声明》 《GitCode 服务条款》 关于GitCode
Powered by GitLab CE v13.7