【论文阅读25】HollowNet——NN对微分算子的模拟

这篇文章标题并没有提到HollowNet,标题为Neural Networks with Cheap Differential Operators

是去年(19)NIPS,由著名的陈天琦写的文章

文献链接: https://papers.nips.cc/paper/9187-neural-networks-with-cheap-differential-operators.pdf ,更详细的地址在 http://papers.nips.cc/paper/9187-neural-networks-with-cheap-differential-operators

这篇文章我其实没有读透,文中的 $(6)$ 式我还没懂,而且我喜欢挑刺,我总觉得文章里很多记号写得不好不统一…不过问题也不大,记个笔记就好啦~

Why HollowNet?——背景

本文的标题没有提及HollowNet,但是其实说明了文章做了什么,即用NN来模拟微分算子,只不过模拟的微分算子可能比较简单,所以说是cheap的。

那么文章是怎么考虑到要用NN模拟微分算子的呢?(我塔喵其实就是在想这个问题!)

其实没什么可考虑的,就是想模拟微分算子嘛,但是微分算子比较复杂,本身就是抽象的数学记号,而且还有各种微妙的复杂性,如对时间、或者是对空间等变量的变化的描述。

这篇文章就是基于此想法,提出了HollowNet,它完成的任务是对输入为向量 $\mathbf{x}$ 的向量函数 $\mathbf{f}(\mathbf{x})$ 求对 $\mathbf{x}$ 的单变量 $x_j$ (以第 $j$ 元为例)的高阶偏导数,即 $\displaystyle \dfrac{\partial^k \mathbf{f}(\mathbf{x})}{\partial x_j^k}$ 。文中称之为dimension-wise k-th order derivatives

How HollowNet?——挖空NN

这里要先声明文章完成的任务是模拟了dimension-wise k-th order derivatives $\displaystyle \dfrac{\partial^k \mathbf{f}(\mathbf{x})}{\partial \mathbf{x}_j^k}$ ,其中 $\mathbf{f}:\mathbb{R}^d\rightarrow \mathbb{R}^d$ ,dimension-wise k-th order derivatives为:

文章这里就有一些小问题,这些真的是dimension-wise的,如果需要混合偏导,比如 $\dfrac{\partial^k f_i(\mathbf{x})}{\partial x_j^k},\ where\ i\neq j$ ,那这个式子就无能为力了,这大概也是为什么文章标题说是“cheap”的微分算子


至于具体怎么用网络实现,话不多说,日常上图:

左图是完整的前向计算过程,这里为了求 $f_k$ 对 $x_k$ 的偏导数,先由除了 $x_k$ 之外的所有分量 $\mathbf{x}_{-k} \triangleq \{x_1, x_2, \cdots, x_d\}/ \{x_k\}$ ,计算一个 $h_k = c_k(\mathbf{x}_{-k})$ ,其中 $h_k$ 不一定是标量,因为标量的信息一般不够描述高阶导数,一般是向量,这里先假定为 $d_h(\forall k)$ 维,然后这个 $h_k$ 和 $x_k$ 再作为输入得到函数值分量 $f_k=\tau_k(h_k,x_k)$ 。这样设计的目的是为了方便后面挖空网络之后,函数值分量 $f_k$ 只保留对输入分量 $x_k$ 的偏导数。

那么右图就是挖空计算图的操作了。由左图的设计,只要在编程中通过detach一类的操作断掉 $f_k$ 和 $h_k$ 之间的联系,那么在计算图中就只保留了 $\dfrac{\partial f_k}{\partial x_k}$ ,对其它分量的偏导数一律为0。

在左图中,从输入变量的分量 $\mathbf{x}_{-k}$ 到中间变量 $h_k$ 的过程叫做conditioner,表示这种特殊设计的条件关系;从中间变量 $h_k$ 到最终函数分量 $f_k$ 的过程则叫做transformer,这个不太好解释,反正是这么个说法。

有了这个挖空计算图的操作还不够,因为显然我们会注意到 $f_k$ 本身还是由所有分量计算得到的,单独切掉 $\mathbf{x}_{-i}$ 对应的计算图,那么如果有对 $f_k$ 的后续计算,比如计算损失函数 $c$ ,那么就有 $\displaystyle \dfrac{\partial c}{x_k} = \sum_j \dfrac{\partial c}{\partial f_j}\dfrac{\partial f_j}{\partial x_k}$ ,而这样的话相当于在计算图中,右边只能保留一项梯度 $\dfrac{\partial c}{\partial f_k}\dfrac{\partial f_k}{\partial x_k}$ ,这和我们的认知不符,我认为文章基于这个考虑对挖空的计算图做了一个补全,即文章的 $(6)$ 式,我自己学了点计算图想推一下,但是应该是推错了,过程记录如下:

最后两行我是懵了,看了点计算图还是不懂,先放在这里了

Pros & Cons

讲方法优劣之前,其实看了一点点实验,为文章的 $(5.2)$ 节,大概就是说对于一个随机微分方程,这个HollowNet模拟得不错

Pros Cons
cheap微分算子的成功模拟❕ 只构建了cheap微分算子,维度-wise的,那么混合偏导等算子呢
HollowNet构建方式和我想的不一样,这也是我可以借鉴的地方之一 原文$(2.1)$ 节提到 $d_h$ 要小一些,这样可以大量减少计算量,但是这样维度较小,信息流足够么❓
HollowNet没有太多对模型的限制,之前很多流模型,包括NICE等都有很多限制(原文 $(2.1)$ 节) 原文 $(6)$ 式的计算图补偿方式讲得不洗,没看懂哇,是不是和图 $(1)$ 提到的对角分解有关❓
原文的例子都看起来很复杂,有实例的一个还是SDE,为何不举像NODE中那样一般的简单例子呢❓

补充知识——学习计算图

学这个是因为开始看文章的时候 $(6)$ 式不明白,所以先快速补一下

参考的资源是B大李宏毅深度学习(2017)课程第三讲: https://www.bilibili.com/video/BV1Ux411S7rk?p=3

一般计算图

计算图的目的是计算梯度,一般的有效方法是BP,不过程序计算大多都是通过计算图。

计算图可以看成描述函数的语言,包括节点(变量)和边(运算),和PRML第8章讲得差不多。

举了好几个例子,都看懂了,注意一点就是每个中间变量都可以单独作为一个节点;另一点是链式法则可以根据计算图考虑,把箭头连接看成偏微分再写出链式法则的式子。

使用计算图的几个原因:

  1. 一般我们会得到一个loss,对这个单输出求参数的偏导数,在计算图上从单输出reverse比较有效率
  2. NN中往往存在参数共享的时候,同一参数可能反复使用,这时考虑从该变量到输出的所有路径,偏导加起来就好了,非常直接

前馈网络的计算图

算好每条边上对应的偏导数,然后reverse计算总的偏导数就好了。不过真正的计算过程挺麻烦的,我直接截一张图了:

RNN的计算图

RNN都忘光了,放一张图在这里吧:

行了,大概明白具体是怎么算的了

参考链接

[1] Ricky T. Q. Chen and David K Duvenaud. Neural networks with cheap differential operators. In H. Wallach, H. Larochelle, A. Beygelzimer, F. d’Alché-Buc, E. Fox, and R. Garnett, editors, Advances in Neural Information Processing Systems 32, pages 9961–9971. Curran Associates, Inc., 2019.