-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Paddle Python API 设计文档(初稿) #1069
Comments
有不少看不明白的地方:
|
我先回答部分概念问题: |
一个pass = 训练过所有数据。Pass的结束就是所有数据训练结束。Online Learning这个概念,可以整体是一个Pass。
Paddle的模型主体分为两个方面,一个是神经网络结构(protobuf),一个是神经网络的参数。神经网络参数的save是在某一个RunnerItem中做的。 当然,也可以手动获得这些参数。
Runner是一个比Trainer更广义的概念。只要是Run一个有Pass--Batch关系的东西,都可以叫做Runner。并且Runner可以嵌套。 常见的Runner是,外层是一个训练过程,训练所有的数据。内层嵌套一个Runner用作测试过程,在训练的Runner Pass结束的时候,调用内层嵌套的Runner,进行测试或者Evaluate。 这都是可以自定义的。
RunnerItem是一个Runner的某一层操作。类似于中间件。这些中间件可以相互组合,形成不同的Runner。例如,面对集群训练的时候,只需要将LocalParameterUpdater的Item替换成Remote的即可。又例如,在每隔100个Batch之后测试全量数据,也是一种RunnerItem。 通过这种中间件的组合,用户可以更方便的自定义训练过程。
有意思的地方就是这个Builder。因为各种任务的训练过程可能不同,所以通过组合RunnerItem可以复用非常多的逻辑。 |
这个文档并不完善,我再把整体思路整理一下,说明为什么要用Runner,RunnerItem这种抽象吧。 其实主体是复用代码。 |
好。我建议我们明天开一个VC讨论。欢迎更多同学加入。 这个设计会影响到今后很长时间Paddle用户的体验。一定得做好。 做一个好的设计不容易。不仅是有一个“做法”,而且得能说明白为什么我们的“做法”是最好的。 很多时候,“好”不容易定义,所以大家会用“简洁”来衡量,是以谓之 Occam's Razor。或者Rob Pike称为“Less is exponentially more“。 要能设计出最简洁的做法,首先对系统里重要概念得能拿得住。比如NN的核心是“模型”,不管训练还是inference都要用到。TF把模型描述成一个很通用的compute flow graph,但是我们看到太通用会带来很多麻烦——说白了就是不够简洁——这是我们得避免的。我不确定我们定义模型的时候,是不是应该考虑到 @hedaoyuan 的 Function 概念,以及这样是否会让我们的模型定义更简洁。 在此基础上,我们要做两件事:trainng 和 inference。超出这两件事儿的,我们应该倾向于砍掉。所以当我看到“runner是一个比trainer更通用的概念”这样的描述,就会就raze的冲动。:-) 我赞同得有一个trainer,trainer貌似要能执行一个training algorithm,这个algorithm在循环里要等调用 training data的 fetch 方法来获得训练数据(minibatch)。我以为我们最好提供几个algorithms的实现即可。 考虑到有些用户可能需要定义自己的algorithm,自己写trainng loop,那我们确实就得暴露更多底层facilities,比如 gradient machine 和 updater。它俩如何简洁地和model以及training data交互,会是另一层要考虑的问题。 |
Function的概念是可以对外的,单纯把Function的概念引入到Python中Code实现上也部分很复杂。这里有几点问题:
|
这太好了。之所以写这个Experimental的code其实是因为很多东西我也想不明白,只是边写边想。并且,确实要把这个东西做的『简单』、『好用』,思考起来非常困难。所以,也期待大家帮忙,把这事情搞的好一些。 Function我也调查了一下,但是现阶段本身Function的API还在持续变动中,目前暴露可能比较麻烦。 至于很多PR,写的第一版可能只是一种整理思考的过程,完全可以废弃。之所以写code,可能只是写code思考比写文档来思考更快一些。所以,如果完全废弃,也完全没必要担心 :-) |
这个文档更多的是面向paddle开发者,而不是使用者,所以应该从用户的角度重新设计一下。 |
this design is discarded |
一个典型的训练过程
用一个类似调用链的东西,把操作分离开。比如上面的例子可以被拆成两个RunnerChainItems.
一些核心概念
Runner
Runner主要利用GradientMachine层面暴露出来的API,将原来Trainer.cpp的逻辑封装起来,Runner中包含很多个RunnerItem,每个RunnerItem完成Trainer中的部分逻辑,用户可以循环调用Runner的run_pass,Runner内部通过一个一个的RunnerItem完成之前各个组件的功能,比如updater,gradientmachine的forward/backward,parameter save/load等操作,用户无需关心。
Runner的实现
构造一个runner的过程
RunnerItem
RunnerItem is an item in Runner. Runner will composite the
RunnerItems together and invoke the first RunnerChainItem's methods.
And Runner will pass the next chain item's method as
next_callback
.If current chain item is the last item. A default next_callback will be
passed.
Context is a global object shared by items.
已经实现的RunnerItem
RunnerBuilder
将build Runner的过程封装起来,用with_std_local_trainer等辅助函数方式组装一个可以运行的Runner
The text was updated successfully, but these errors were encountered: