RNN、LSTM、GRU都存在一个严重的问题: 前后两个时刻 $t-1$ 和 $t$ 的计算存在完全的依赖性。这种自回归结构无法并行,不能充分利用GPU计算资源。
the sequential dependencies that are central to recurrent architectures limit parallelization potential
GRU对LSTM进行了简化,详见GRU。
注意观察$c _ {t-1} $ 和 $ h _ {t-1}$的流向。很容易发现,这两个信息几乎影响每一个节点,因此LSTM和GRU是严重的autoregressive,严重的时序依赖。
如何加速?一个自然的思路: 能否尽量减少$t-1$时刻的影响,剥离出时序无关的计算,类似以下的架构:
具体怎么做呢?比如我们大开脑洞,把LSTM中的$h_{t-1}$直接去掉,豁然开朗,下面的都能并行了。(当然脑洞太大往往不靠谱,也许把孩子和洗脚水一起丢了)
如何既能并行,又尽量少的损失时序信息?SRU是这样做的。
SRU
SRU(Simple Recurrent Unit)则提出更激进的架构,去掉了前后时刻计算的依赖。
- 核心一: 门$f$不再依赖$t-1$了
- 核心二: 门
- input gate和forget gate的合并 (借鉴自GRU)
- c和h的合并,(并未采用)
- 宏观上,类似window_size=1的QRNN
效果
实现细节(trick)
SRU实现:增加highway连接和变分dropout
首先,他们在循环层之间增加了highway连接,因为此前的研究已经证明,像highway连接这样的skip connections,在训练深度网络时非常有效;
其次,在将RNN正则化时,SRU在标准的dropout外,增加了变分dropout,变分dropout在时间步长t与dropout使用相同的mask。
什么是
CUDA级的优化
。。。待看
吐槽环节
关于架构
- SRU就是QRNN的window_size=1的特例 - Richard Socher (是哎,我也跟着起哄)
- autoregressive CNNs with gated incremental pooling perform comparably to RNNs
关于gate
- gate的开关只取决于当前输入,不靠谱吧?
疑问环节
问题一
图三中,既然要剥离出时序无关的计算,为什么不把时序无关的计算剥离出RNN作为独立的layer?
可以
SRU等价于: x -> fork layer
-> RNN
fork layer
: 同时映射(W)和分流(分到不同的gate,不同的作用)。
(类似transformer中的multi-head)。
具体实现: $x’ = Wx$,然后split,然后分工,不同的gate,可以group gate。
LSTM自身也可以视为 x -> fork layer
-> 时序依赖。详见cudnnLSTM。
问题二
。。
源码
- https://github.com/taolei87/sru/blob/master/sru/sru_functional.py#L128
好复杂,看着头疼
扩展阅读
- Training RNNs as Fast as CNNs. pdf
- 神仙打架: SRU引发的争议. openreview | facebook | reddit