天天看点

Treevalue(0x01)——功能概述

Treevalue v1.0.0版本已经于2021年10月24日正式发布,欢迎下载体验:opendilab / treevalue。

这算是treevalue的第一个正式实用化版本,本文将会对其主要功能和特性进行一个概述。

设想这样一个实际的应用场景,我们需要使用numpy对机器学习中的一批样本进行预处理,并组装成一个训练用的mini-batch。一个数据样本的格式如下面的代码所示,即函数 <code>get_data</code> 的返回值:

如果使用最常见的写法,大概会是这样的

而当我们有了treevalue库之后,完全一致的功能可以被这样简短的代码实现

可以看到,实现一段同样的基于树结构的业务逻辑,有了treevalue库的辅助后代码变得极为简短和清晰,也更加易于维护。

这正是treevalue的最大亮点所在,接下来的章节中将会对其主要功能和特性进行概述,以便读者对这个库有一个整体的了解和认识。

在treevalue库中,我们提供一种核心数据结构—— <code>TreeValue</code> 类。该类为整个treevalue的核心特性,后续的一系列操作都是围绕 <code>TreeValue</code> 类所展开的。

首先是 <code>TreeValue</code> 对象的构造(使用的是增强版子类 <code>FastTreeValue</code> ,关于 <code>TreeValue</code> 类与 <code>FastTreeValue</code> 类的区别可以参考文档,本文不作展开),只需要将dict格式的数据作为唯一的构造函数参数传入即可完成<code>TreeValue</code>的构造

不仅如此, <code>TreeValue</code> 类还提供了树状结构的几种基本操作接口供使用

以上是 <code>TreeValue</code> 类的几种常见基本操作,支持了最基本的增删查改等。

当一个 <code>TreeValue</code> 对象被构造出来后,我们如何比较直观地去观察其整体结构呢?有两种方式可以对 <code>TreeValue</code> 进行可视化:

通过 <code>print</code> 进行快速文字打印

通过 <code>treevalue graph</code> 命令行工具进行图像导出

实际上对于第一种情况,在上一节中已经有了展示,在此展示一个更加复杂的案例

输出结果如下,可以看到诸如 <code>torch.Tensor</code> 这样多行的对象也一样可以被有序地排版输出,且对于存在嵌套引用的情况,输出时也可以被准确地识别出来,避免无限循环打印

除了基于文本的可视化外,我们还提供了命令行工具以进行图像导出。例如上面的代码,我们可以用如下的命令行导出图像

Treevalue(0x01)——功能概述

此外,对于更复杂的情况,例如这样的一份源代码

可以通过以下的命令行导出为图像,不难发现对于共用节点和共用对象的情况也都进行了准确地体现(如需进一步了解,可以执行 <code>treevalue graph -h</code> 查看帮助信息)

Treevalue(0x01)——功能概述

以上是对于 <code>TreeValue</code> 对象的两种可视化方法。

在treevalue中,我们可以快速地将函数进行装饰,使之可以支持 <code>TreeValue</code> 对象作为参数进行运算。例如下面的例子

将整数之间的最大公因数进行了装饰后,可以形成兼容 <code>TreeValue</code> 对象的函数,且不会影响普通对象的运算结果,因此上述代码的输出结果如下所示

除了 <code>TreeValue</code> 自带的一系列基本操作之外,treevalue库还提供了一些常用的树结构运算函数。例如如下的四种:

map——值映射运算

reduce——值归纳运算

subside——顶层结构下沉运算

rise——值结构提取上浮运算

<code>TreeValue</code> 对象的值映射运算和列表类型的map运算类似,会产生一个同结构且值为映射值的新 <code>TreeValue</code> 对象,例如下面的案例

<code>t1</code> 和 <code>t2</code> 的图像如下

Treevalue(0x01)——功能概述

<code>TreeValue</code> 对象的值归纳运算和 <code>functools.reduce</code> 函数的功能类似,可以将树结构以子树为单位进行归纳,最终计算出一个结果来,例如下面的案例

可以快捷的实现整棵树的求和运算。

<code>TreeValue</code> 还可以支持将其上层结构进行解析后,下沉到节点值上,形成一棵新的树,例如下面的案例

下沉后产生的树 <code>t</code> 的图像为

Treevalue(0x01)——功能概述

上浮运算(rise)为下沉运算的逆运算,可以从值节点中提取共同结构至 <code>TreeValue</code> 对象外,例如如下的案例

对象 <code>dt</code> 是一个字典类型的对象,包含 <code>i1</code> 和 <code>i2</code> 两个键,其中 <code>i1</code> 为一个 <code>TreeValue</code> 对象, <code>i2</code> 为一个长度为2,由 <code>TreeValue</code> 对象构成的元组。因此 <code>dt_i1</code> 、 <code>dt_i2_0</code> 和 <code>dt_i2_1</code> 的图像为

Treevalue(0x01)——功能概述

本文作为一个对于treevalue现有主要功能的一个概述,受限于篇幅暂时做不到深入全面的讲解内部原理和机制。因此后续会考虑继续出包括但不限于以下的内容:

treevalue的整体体系结构

<code>func_treelize</code> 树化函数的原理与机制

treevalue的一些神奇的用法与黑科技

treevalue的优化历程与经验

treevalue的具体实战案例

敬请期待,同时欢迎了解其他OpenDILab的开源项目:https://github.com/opendilab。