首先,请和我一起高呼——“treevalue——通用树形结构建模工具 + 极简树形结构编程模型”。

咳咳,好久没更新了,这一次是真的好久不见,甚是想念。在之前的三期中,关于 treevalue 的核心特性等内容已经基本完成了讲述。因此本篇作为该系列的终章,将尝试用更高一层的视角来分析 treevalue ,以求进一步了解其核心思想与应用模式,并通过干货数据与实例展示来展现其真实能力。

闲话少叙,让我们开始吧!如果还没了解过 treevalue 的小伙伴们可以先去读一下之前的几篇文章:

整体设计

概念与架构

想要完整地了解 treevalue ,首先还是需要从整体架构上来看看,如下图所示。

(treevalue的整体架构)

显而易见的一点, treevalue 是基于Python构建的,并且处于运算性能上的考虑,因此也大量采用了Cython来实现,该工具可以用一种介于Python和C/C++之间的语法进行编码,并以C/C++的形式编译为静态库,通过绕开一系列不必要的动态机制等方式来实现明显的加速。

treevalue 中,最底层的为 TreeStorage ,为数据层,主要对树状数据结构进行管理,并对上层提供最基本的接口。建立在之上的 TreeValue 为最关键的一个类,基于数据层进行了基本的封装,能实现 treevalue 的基本特性且具备进一步扩展的能力。树化(treelize)在之前的几篇文章中有过介绍,其作用在于将现有库的函数和类进行树化的扩展,使 treevalue 的特性可以被快速应用至现有工具上。工具部分(utilities)即为基于 TreeValue 构建的一些简单工具,支持了基本的树操作、函数式运算等功能。另一个极为重要的部分即为 FastTreeValue 类,其为 TreeValue 的子类,包含了大部分的运算符,并可以实现“装载即用”,只需要将现有的对象装入FastTreeValue即可批量访问其属性、批量调用其方法,因此 FastTreeValue 被最为广泛的使用。这里需要注意的是, treevalue 并未针对任何一个特定的现有库进行特殊化设计,而是通过泛用型设计,让诸如PyTorch、Numpy、Tensorflow在内的几乎全部接口均可以被快速扩展到树运算上

总的来说,基于 treevalue ,可以将现有轮子中的函数与类扩展为支持树状运算的新形态,并可以让编程者基于这一扩展进行更加方便快捷的代码构建。

设计定位

在前面几篇该系列的文章里,我们都加上了“强化学习(Reinforcement Learning)”的标签,也是因此,此文才会被推送到关注了这一话题的用户手里。可是你们大概已经发现,无论是之前的三篇文章,还是我们的源码仓库,都并没有深度强化学习相关的内容,甚至在源代码中看不到 numpytorch 等常见AI相关库的存在。想必各位读者也从之前的文章发出后便早已疑惑多时了。因此在这里我们来回答一个重要的问题—— treevalue的设计定位是什么

其实仔细琢磨的话,答案也已经很明显了—— treevalue从设计之初就是一款具备充分泛用型,且易用性为主运行性能为辅的树数据结构计算框架。之前各个文章乃至代码中未大量涉及具体的深度强化学习内容也正是这个原因。在Treevalue(0x02)——函数树化详细解析(上篇)中介绍的 func_treelize 特性也是可以针对任意函数进行使用的,因此即便不是 torch 这样的经典的库,换上其他的库与其他的类、方法,也同样可以使用treevalue,且使用体验与原本的库基本一致,极为友好。甚至于深度强化学习以外的任意领域,只要有基于树结构的运算的地方, treevalue 就有它的用武之地——这也正是它设计上的核心理念,与真正的优势所在。

与同类产品的对比

基于上述的介绍,读者们可能会担心一个易用性、泛用性为主的库,会不会在其他上,尤其是在深度强化学习程序的特性支持与运行性能上存在劣势。这样的顾虑其实很正常,因为在大部分情况下,软件的泛用性和性能都是不容易做到兼顾的。但是 treevalue 是否存在这样的问题呢?因此本节将会通过与同类或相近产品的对比分析,来对这一问题进行回答

同类或相近产品介绍

treevalue 开发与测试的阶段,我们发现其实在现有的其他库中,也有类似的树状运算支持。其中比较具有典型意义的有以下四个:

  • dm-tree,DeepMind团队开发的轻量级树状运算库。
  • Tianshou-Batch,清华大学机器学习组开发,基于PyTorch的深度强化学习库,其中Batch为重点设计的一个关键组件。
  • jax-libtree,谷歌团队开发的机器学习库,其中libtree为内部的一个轻量级树运算封装库。
  • torchbeast-nest,Meta研究院(原facebook研究院)开发,基于PyTorch的深度强化学习框架,其中nest为内部的一个轻量级树运算封装库。

特性对比

基于上面提到的四款同类产品及 treevalue ,所开源的代码及提供的文档,可以得出以下的分析。

同类产品 重量级 泛用性 函数式 结构运算 自建结构 函数扩展 自扩展
dm-tree 轻量级 × × × ×
Tianshou-Batch 中轻量级 × × × × ×
jax-libtree 轻量级 × × ×
torchbeast-nest 轻量级 × × ×
treevalue 中量级

具体来说:

  • dm-tree为基于C++实现的独立轻量级库,不针对特定的框架,且支持简单的函数式运算。
  • tianshou-Batch为中轻量级库,自建了一套针对PyTorch的树数据结构,实现了基本的增删查改功能,并且实现了包括stack、split在内的少量运算操作。
  • jax-libtree为Google Jax库中的子模块,不针对特定框架,支持简单的函数式运算,还支持了诸如transpose这样的树结构运算。
  • torchbeast-nest为Meta torchbeast中的树结构子模块,不针对特定框架,支持简单的函数式运算,此外还支持简单的二元函数扩展运算能力。

    而相比之下, treevalue 为一款泛用型中量级库,且支持主要的函数式运算。其实现原理为自建树状数据结构,并基于这一结构展开运算。不仅如此,还支持了比jax-libtree更加丰富的结构运算(subside与支持自动检测结构的rise),也支持了比torchbeast-nest更灵活的函数扩展能力(func_treelize)。而 treevalue 最为强大的地方体现在treetensor中,只需要对部分 torch.Tensor 的方法进行特别支持后,剩下的全部方法均可在现有框架上实现,并保持和原有API一样的使用方式。

这一点,意味着对于基于 treevalue 的开发者而言,不再需要大规模逐个进行封装迁移,只需要针对个别较特殊的API进行特别实现,其他的可以直接批量快速映射,直接做到无一遗漏。实际上,对于兼容库的开发而言,往往实现了90%,甚至与99%的接口,都可能对实际使用带来较多的限制,而基于treevalue开发的应用而言,则在原理上便不存在这一问题,接口的扩展可以一步到位。而对于使用者而言,兼容库的使用体验将和原有库高度一致,原有的运算性质不会改变,且进一步支持了树状运算,而一步到位的兼容更是让使用者不会被不全的API所限制,使用体验极佳,甚至于可以将现有代码以极小规模的修改便实现从原有库向兼容库的迁移,很容易确保正常运行,并可以进一步简化代码实现

性能对比

上文中提到, treevalue 是其中唯一的一款中量级库,这意味着从实现的角度来看,其需要为了支持高度的泛用性和易用性,而考虑更多的情况,设立更多的处理机制。因此,理论上 treevalue 会在性能上存在一定的劣势。然而事实真的如理论所言吗?让我们来看看接下来的性能分析数据。

在本次性能对比中,我们将根据同类产品的特点,将实验分为两组:

  • 数据结构组——tianshou Batch和treevalue,比较对象为split(将单个Tensor进行拆分)、stack(将多个Tensor进行拼接)运算的性能
  • 泛用运算组——dm-tree、jax-libtree、torchbeast-nest和treevalue,比较对象为flatten(将树结构展开为可逆的列表结构)、mapping(简单的函数式映射运算)运算的性能

    数据结构组的性能测试结果如下所示,不难发现 treevalue 在张量运算的性能上具有明显优势。



(treevalue和tianshou Batch在torch.split操作上的性能对比,treevalue具有明显的优势)



(treevalue和tianshou Batch在torch.stack操作上的性能对比,treevalue具有明显的优势)

泛用运算组的性能测试结果如下图所示,其中dm-tree为其中最轻量级的库,却意外地拥有最低的性能;而jax-libtree和torchbeast-nest相比之下拥有不错的性能。但是,作为中量级库且包含大量易用性设计的treevalue,仍然在各种规模的数据上拥有性能优势——在小规模数据上优势极为明显,即便在大规模数据上依然可以较之jax-libtree保持微弱优势,且较之torchbeast-nest保持大比例的优势。



(treevalue、dm-tree、jax-libtree、torchbeast-nest在flatten运算上的性能对比,treevalue整体处于优势)



(treevalue、dm-tree、jax-libtree、torchbeast-nest在mapping运算上的性能对比,treevalue整体处于优势)

不仅如此,我们还针对其他的各类基础操作于运算进行了性能测试,更多的测试结果信息参见项目README.md

经过一系列的测试,结果表明性能问题并未出现,甚至于相较于同类产品仍有性能优势。这一点对于中量级设计的库而言是极为难得的,这意味着无论从性能还是从使用体验来说,treevalue均具备全方位的优势

案例对比

在上文中,我们在与同类产品的的对比中,展现了 treevalue 强大的泛用性与易用性,以及堪称优秀的运算性能。而实际上要想更具说服力地展现这一点,还是需要一些更加具体的例子。

首先是官方文档中的两组例子,分别用于Numpy和Scikit-Learn:

  • Apply Into Numpy,这组例子展现了在实现同样涉及树数据结构的情况下,使用FastTreeValue的代码极为明显地短于原有实现,且简洁清晰程度远超以往
  • Apply Into Scikit-Learn,该组例子展现了基于原有的接口,通过极简的装饰扩展即可将PCA运算应用到整棵树上,得出整棵树的解,全程高度精简易懂。

    此外,我们还准备了一个 treevalue 用于具体DRL项目的例子,这次我们选择了在深度强化学习领域最复杂的项目——AlphaStar中的相关数据处理函数 collate_fn ,这个函数的作用是在每个训练iteration之前对数据进行堆叠、填充和预处理。原始的代码充斥着大量的for循环和if-else分支控制,而通过使用 treevalue ,我们可以将上述所有操作完全用并行操作API重写,具体来说,两个版本的代码度量分析如下表所示:

这表明, treevalue 在复杂项目上的优势将更加显著,具体表现为代码行数缩减到1/3逻辑复杂度大幅降低可维护性明显提高——以及由此带来的编码用时大幅缩减。此外,在性能测试中,treevalue版代码相较于原始代码也并无劣势。至此, treevalue 的各项能力已经得到了充分的验证。

展望

treevalue 的各项能力,在上文中已经进行了充分的论述。因此,本节将采用开放式问题的方式,抛出一系列问题,也作为展望。欢迎读者一同参与讨论,以及如有更进一步的脑洞,也欢迎留言~~

问题1:你认为, treevalue 仅仅只是一个库?一组操作工具?还是一整套运算模型?

问题2treevalue运算模型的核心是什么?此处核心指的是,基于该核心可以直接或间接衍生出几乎全部现有特性。

问题3:在之前的文章中,已经详细描述了函数的树化扩展(treelize)机制,效果为将普通函数扩展为支持树运算的函数。除此之外,是否还有其他类似的可扩展对象?是否有可以基于函数树化的上位可扩展对象?

问题4:如果需要对现有的数据模型类(例如torch.Tensor、np.ndarray等)进行树化扩展,需要注意哪些问题?工厂类(工厂模式构建的类)呢?工具类(集成静态工具的类,多见于Java)呢?对模块(module)的扩展呢?上述的各种扩展机制是否可以归纳为另一种统一的运算模型

问题5:treevalue相较于同类产品的性能优势虽然普遍存在,但依然没有做到全方位拉开差距。有哪些可能的优化点?其中哪些是可以针对具体应用情况作针对性优化的?

问题6:如何通过扩展让treevalue支持任意类型的数据容器(包括list、tuple,甚至自建数据模型)?眼下的主要障碍在哪里?是在技术上还是运算模型上

问题7:你还能想到其他的 treevalue + 机器学习的应用吗?图神经网络数据结构的表示是否可以实现?

treevalue——Master Nested Data Like Tensor的更多相关文章

  1. Vue开发警告[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.

    Avoid replacing instance root $data. Use nested data properties instead. 翻译 避免替换实例根$data.请改用嵌套数据属性 错 ...

  2. ElasticStack系列之九 & master、data 和 client 节点

    在生产环境下,如果不修改elasticsearch节点的角色信息,在高数据量,高并发的场景下集群容易出现脑裂等问题. 默认情况下,elasticsearch 集群中每个节点都有成为主节点的资格,也都存 ...

  3. [PyTorch 学习笔记] 1.2 Tensor(张量)介绍

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson1/tensor_introduce1.py https: ...

  4. ExtJS4笔记 Data

    The data package is what loads and saves all of the data in your application and consists of 41 clas ...

  5. Working with Data » 使用Visual Studio开发ASP.NET Core MVC and Entity Framework Core初学者教程

    原文地址:https://docs.asp.net/en/latest/data/ef-mvc/intro.html The Contoso University sample web applica ...

  6. ZooKeeper场景实践:(6)集群监控和Master选举

    1. 集群机器监控 这通经常使用于那种对集群中机器状态,机器在线率有较高要求的场景,可以高速对集群中机器变化作出响应.这种场景中,往往有一个监控系统,实时检測集群机器是否存活. 利用ZooKeeper ...

  7. jquery data方法取值与js attr取值的区别

    <a data-v="3"></a> jquery data方法的运行机制: 第一次查找dom,使用attributes获取到dom节点值,并将其值存到缓存 ...

  8. spi master接口的fpga实现

    前言 当你器件的引脚贼少的时候,需要主机和从机通信,spi就派上了用场,它可以一对多,但只是片选到的从机能和主机通信,其他的挂机. spi:serial peripheral interface 串行 ...

  9. TensorFlow使用基础-Tensor

    使用 TensorFlow 之前你需要了解关于 TensorFlow 的以下基础知识 :• 使用图 (graphs) 来表示计算 .• 在会话 ( Session ) 中执行图 .• 使用张量 (te ...

随机推荐

  1. hisql 新功能 支持一套sql在不同数据库执行

    目前流行的ORM框架如果需要动态的拼接查询语句,只能用原生的sql进行拼接,无法跨不同数据库执行.hisql推出新的语法一套语句可以在不同的数据库执行 传统ORM框架最大的弊端就是完全要依赖于实体用l ...

  2. Python_魔法属性和方法

    魔法属性 __doc__:表示类或方法的描述信息 __moudle__:表示当前操作对象的模块,当前模块时,显示__main__ __class__:表示当前操作对象的类型 __name__:表示类或 ...

  3. Selenium_使用switch_to.frame处理网页框架切换(13)

    与在新窗口打开一个网页后需要切换窗口才能定位元素一样,在iframe标签中的元素也不能直接定位,需要切换到对应的iframe框架中才能进行元素定位. 完成网页框架切换操作需要用selenium中的两个 ...

  4. [ vue ] Quasar封装q-dialog组件,在外层实现弹出框的开启和关闭

    场景描述: 见:https://www.cnblogs.com/remly/p/12981582.html 具体实现: <!-- 父组件 --> <template> < ...

  5. [ python应用 ] python递归搜索文件,支持搜索多个文件,支持自定义处理动作

    写了一个PyQT界面的版本:https://github.com/LongchuanYu/pyqt_project PATH = r'E:\MyDocument\新しいフォルダー\' # 要搜索的目录 ...

  6. java 访问 太平洋网ip接口,解决前端js 跨域访问失败问题

    前端 js访问太平洋网IP接口地址,返回结果是403 服务器拒绝处理异常, 于是,想到了使用 服务器端访问,然后再将查询结果返回的前端 这是Java的测试源码,[具体的contronller端源码懒得 ...

  7. mysql-5.7.20-winx64安装图解教程

    原文链接:https://www.toutiao.com/i6494052843912167949/ 将安装包解压 解压目录 鼠标右键"我的电脑",弹出"快捷菜单&quo ...

  8. 深入浅出 CSS 动画

    本文将比较全面细致的梳理一下 CSS 动画的方方面面,针对每个属性用法的讲解及进阶用法的示意,希望能成为一个比较好的从入门到进阶的教程. CSS 动画介绍及语法 首先,我们来简单介绍一下 CSS 动画 ...

  9. Solon 开发,四、Bean 扫描的三种方式

    Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...

  10. 关于Jmeter线程数Ramp-Up.循环次数的理解和实验数据

    1. 关于线程组参数 线程组:即一个线程组实例里面包括多个串行的请求或动作.一个线程组的从启动到结束的时间取决于你线程中的步骤数量. 线程数:即用户数,在Ramp-up时间内(包括循环),简单把线程数 ...