作业函数的定义与调用
在 OneFlow 中,将训练、预测任务封装在一个函数中,统称为作业函数(job function),作业函数联系用户的业务逻辑与 OneFlow 管理的计算资源。
在 OneFlow 中,被 @oneflow.global_function 装饰器所修饰的 python 函数,就是 OneFlow 作业函数。
主要在作业函数中定义网络模型的结构、选择优化指标;此外,还可以将训练有关的超参及环境配置当做参数,传递给作业函数(如:下面例子中的:get_train_config()),OneFlow 会根据设置为管理内存、GPU 等硬件资源。
本文中将具体学习:
• 如何定义和调用作业函数
• 如何获取作业函数的返回值
作业函数与 OneFlow 运行流程的关系
作业函数分为定义和调用两个阶段。
这与 OneFlow 本身的运行机制有关,简化地说,OneFlow Python 层接口,只是在描述网络模型和训练环境的配置信息,这些信息将传递给底层的 C++ 代码,经过编译、优化等工作得到计算图,最终交给 OneFlow 运行时(runtime),由 OneFlow 运行时执行。
因为定义作业函数只是做描述工作,在这个阶段,并没有实际的数据,而只能通过规定网络节点的形状、数据类型等信息,起到 数据占位符 的作用,方便 OneFlow 的编译构图过程进行模型推理。
作业函数的调用,发生在 OneFlow runtime 已经启动后,可以通过调用作业函数,向其传递真实的数据,并获取返回结果。
以下将具体介绍作业函数的定义与调用方法。
作业函数的定义
将模型封装在 Python 中,再使用oneflow.global_function修饰符进行修饰。就完成了作业函数的定义。
作业函数主要描述两方面的事情:
• 模型结构
• 训练过程中的优化目标
以下代码示例中,构建了一个 mlp 模型。并且将由 flow.nn.sparse_softmax_cross_entropy_with_logits 计算得到交叉熵损失结果作为优化目标。
@flow.global_function(type=“train”)
def train_job(
images: tp.Numpy.Placeholder((BATCH_SIZE, 1, 28, 28), dtype=flow.float),
labels: tp.Numpy.Placeholder((BATCH_SIZE,), dtype=flow.int32),
) -> tp.Callback[tp.Numpy]:
# mlp
initializer = flow.truncated_normal(0.1)
reshape = flow.reshape(images, [images.shape[0], -1])
hidden = flow.layers.dense(
reshape,
512,
activation=flow.nn.relu,
kernel_initializer=initializer,
name=“hidden”,
)
logits = flow.layers.dense(
hidden, 10, kernel_initializer=initializer, name=“output”
)

loss = flow.nn.sparse_softmax_cross_entropy_with_logits(labels, logits, name="softmax_loss"
)
lr_scheduler = flow.optimizer.PiecewiseConstantScheduler([], [0.1])
flow.optimizer.SGD(lr_scheduler, momentum=0).minimize(loss)
return loss

oneflow.global_function 的参数
oneflow.global_function 修饰符接受两个参数,分别是 type 与 function_config。
• type 参数接受字符串,只能设定为 train 或者 predict,当定义一个训练模型时,设定为 train,当定义测试模型时,设定为 predict
• function_config 参数接受一个 oneflow.function_config() 所构造的对象,在 function_config 对象中,可以通过成员方法或属性,进行相关配置。如以下代码:
def get_train_config():
config = flow.function_config()
config.default_data_type(flow.float)
return config
设置了默认数据类型,然后,可以在向 global_function 装饰器传递这个function_config 对象:
@flow.global_function(type=“train”, function_config=get_train_config())
def train_job(
images: tp.Numpy.Placeholder((BATCH_SIZE, 1, 28, 28), dtype=flow.float),
labels: tp.Numpy.Placeholder((BATCH_SIZE,), dtype=flow.int32),
) -> tp.Numpy:
包含以上代码的完整示例可见文章Consistent 与 Mirrored 视角中的 mixed_parallel_mlp.py
数据占位符
注意,以上的 images、logits、labels、loss等对象,在定义作业函数时,并没有实际的数据。作用只是 描述数据的形状和属性 ,起到 占位符 的作用。
在作业函数的参数中的数据占位符,使用 oneflow.typing 下的Numpy.Placeholder、ListNumpy.Placeholder、ListListNumpy.Placeholder,注解作业函数的参数,对应作业函数调用时,传递 numpy 数据对象。
除了oneflow.typing下的几种类型外,不出现在参数中,而由 OneFlow 的算子或层产生的变量,如以上代码中的reshape、hidden、logits、loss等,也都起到了数据占位符的作用。
不管是以上提及的哪种变量,都直接或间接继承自 OneFlow 的 BlobDef 基类,OneFlow 中把这种对象类型统称为 Blob。
Blob 在作业函数定义时,均无真实数据,均只起到数据占位方便框架推理的作用。
作业函数的返回值
之所以在上文中强调数据占位符 Blob 的概念,因为作业函数的返回值是不能任意指定的,必须是 Blob 类型的对象,或者存有 Blob 对象的容器。
如以上代码的中所返回的 loss,它就是 Blob 类型。
作业函数的返回值,需要通过注解声明,比如以上代码中的 -> tp.Numpy,表示返回1个 Blob。
再比如,可以通过注解声明返回值类型为 -> Tuple[tp.Numpy, tp.Numpy],表示返回1个 tuple,该 tuple 中有2个 Blob 对象。
具体的使用例子,可以参考获取作业函数的结果
作业函数的调用
OneFlow 利用函数修饰符将普通 Python 函数转变为 OneFlow 特有的作业函数的过程,对于用户而言是无感、透明的。
可以像调用普通的 Python 函数一样调用作业函数。每一次调用,OneFlow 都会在框架内部完成正向传播、反向传播、参数更新等一系列事情。
以下代码,获取数据之后,向 train_job 作业函数传递参数并调用,打印 loss。
(train_images, train_labels), (test_images, test_labels) = flow.data.load_mnist(
BATCH_SIZE
)

for epoch in range(3):for i, (images, labels) in enumerate(zip(train_images, train_labels)):loss = train_job(images, labels)if i % 20 == 0:print(loss.mean())

可以看到,通过调用作业函数 train_job 直接返回了 numpy 数据。
以上展示的调用方式是同步方式, OneFlow 还支持异步调用,具体可以参阅专题获取作业函数的结果。

作业函数的定义与调用相关推荐

  1. python的函数的定义与调用

    函数的定义与调用 1.定义函数 定义函数的格式如下: def 函数名(): 代码 注:python文件名一定不要取为test.py     标出的两个文件,虽为空文件,但一定不要去删除         ...

  2. Python基础day04【函数(定义与调用、文档说明、传参函数、全局变量、返回值、嵌套调用)】

    视频.源码.课件.软件.笔记:超全面Python基础入门教程[十天课程]博客笔记汇总表[黑马程序员] Python基础day04[字典]    目录 3.函数 函数的定义和调用 函数定义 PEP8规范 ...

  3. python中怎么调用函数_浅谈Python中函数的定义及其调用方法

    一.函数的定义及其应用 所谓函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用函数的使用包含两个步骤 1.定义函数–封装独立的功能 2.调用函数–享受封装的成果 函数的作用:在开发时 ...

  4. python函数定义及调用-浅谈Python中函数的定义及其调用方法

    一.函数的定义及其应用 所谓函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用函数的使用包含两个步骤 1.定义函数�C封装独立的功能 2.调用函数�C享受封装的成果 函数的作用:在开 ...

  5. python函数定义及调用-python函数的定义和调用 | 酷python

    python函数的定义与调用 在python中 ,函数是一个组织好的 ,可以重复使用的代码段 ,函数可以提高代码的重复利用率 ,原则上一个函数只实现一个单一的功能 ,这样能增强程序的模块性, pyth ...

  6. 《Swift 权威指南》——第6章,第6.1节函数的定义和调用

    本节书摘来自异步社区<Swift 权威指南>一书中的第6章,第6.1节函数的定义和调用,作者 李宁,更多章节内容可以访问云栖社区"异步社区"公众号查看 第6章 丰富多彩 ...

  7. MATLAB及app designer中函数:定义与调用

    本文介绍MATLAB 及其APP designer 中函数定义和调用的相关方法和注意事项: 文章结构如下: 1.脚本文件(.m)中函数调用: A.同一脚本文件下,函数定义在脚本末端 B.不同脚本文件, ...

  8. Shell之function函数的定义及调用

    文章目录 `function`函数的定义及调用 `function`函数的定义 `function`函数的调用[位置传参] 函数使用return返回值[位置传参] 函数的调用[数组传参] functi ...

  9. html 定义函数调用函数,HTML function函数怎么定义和调用?

    HTML function函数怎么定义和调用实例: function myFunction() { alert("Hello World!"); } Try it 扩展资料 1.函 ...

最新文章

  1. 20个经典要诀学好英语
  2. python netsnmp_在Ubuntu18.04中关于Python使用netsnmp进行snmp编程
  3. 移动组件到指定坐标_《我的世界》传送石碑组件 史蒂夫表示跑路的日子终于结束了...
  4. [设计模式][C++]单例模式
  5. waiting for lock on working directory of:tortoiseHg
  6. Ubuntu锐捷校园网连接不上问题,认证成功但是上不去网。
  7. 数据仓库技术解决方案
  8. I/O error on GET request for http://userservice/user/point/update: userservice; nested exception
  9. 抓取猫眼电影TOP10榜数据
  10. 理解C语言中的a++、a--和++a、--a
  11. 天津市科技领军企业和领军培育企业补助奖励及认定条件,补贴500万
  12. 基础篇 | 材质01 | 4种法线
  13. 华擎主板bios设置图解_主板BIOS界面解析_华擎 Z170 极限玩家 7+_主板-中关村在线...
  14. Python爬虫项目分享二:《爬取周杰伦的歌曲评论》
  15. 全国计算机一级及格率,计算机一级通过率高吗 怎样提高通过率
  16. CBoard框架使用总结七--添加首页图表
  17. 踩坑日常_MinGW-w64安装教程及踩坑记录
  18. 什么叫域?如何建立域?域操作命令net
  19. 数据结构:带头双向循环链表——增加、删除、查找、修改,详细解析
  20. 33个必须知道的数据分析师SQL面试问题和答案

热门文章

  1. MybatisPlus忽略实体类中的非数据库字段、JPA忽略实体类中的非数据库字段、HeHibernate忽略实体类中的非数据库字段
  2. Python+OpenCV 图像处理系列(1)— Ubuntu OpenCV安装、图片加载、显示和保存
  3. Centos7.4安装Nginx
  4. 确定修改——取消修改
  5. scipy csr_matrix csc_matrix
  6. Android Animation (安卓动画)概念简介
  7. AIFramework框架Jittor特性(下)
  8. 广泛的信号处理链如何让语音助理“正常工作”
  9. Django Response对象3.4
  10. 中国矿业大学计算机学院机房,2020年中国矿业大学计算机学院初试自命题科目考试大纲-数据结构...