POSTS
Thoughts About RNN and Causal CNN
RNN和Causal CNN都可以作为序列生成网络的模块选择。
我最近用TensorFlow实现自回归Causal CNN时,想到可以用RNN的思路来写这个模块——即用一种“状态”的思路。
首先抽象一下RNN的计算过程:
\[ O_t,h_t = f(x_t,h_{t-1};\theta) \]
其中,
- \(f\)为一个非线性映射,\(\theta\)为参数;
- \(O_t,h_t\)分别为\(t\)时间步的输出和该RNN单元的状态;
- \(x_t,h_{t-1}\)分别为此时间步的输入和上一时刻的状态。
Causal CNN的计算则可以这样表示:
\[ O_t = Conv(z_t;\theta) \]
\[ z_t = [x_{t-N+1},…,x_t] = h_{t-1} + [x_t] \]
\[ h_t = [x_{t-N+2},…,x_t] = h_{t-1}[1:] + [x_t] \]
其中,
- \(Conv\)是一个感受野为\(N\)的一维卷积运算,\(\theta\)为参数;
- \(O_t\)是Causal CNN单元\(t\)时刻的输出,不考虑batch阶其形状为\((out\_channels,)\);
- \(z_t\)是卷积运算的输入,不考虑batch阶其形状为\((N, in\_channels)\);
- \(h_t\)是Causal CNN单元的\(t\)时刻状态,不考虑batch阶其形状为\((N-1, in\_channels)\)。
将Causal CNN的\(z_t\)及\(h_t\)的计算用线性代数的方式可以进一步表示为:
\[ z_t = h_{t-1}W_{hz} + x_tV_{xz} \]
\[ h_t = h_{t-1}W_{hh} + x_tV_{xh} \]
\[ W_{hz} = \begin{bmatrix}1 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0\\
0 & 0 & 1 & 0 & 0\\
0 & 0 & 0 & 1 & 0\end{bmatrix},
V_{xz} = \begin{bmatrix}0 & 0 & 0 & 0 & 1\end{bmatrix} \]
\[ W_{hh} = \begin{bmatrix}0 & 0 & 0 & 0\\
1 & 0 & 0 & 0\\
0 & 1 & 0 & 0\\
0 & 0 & 1 & 0\end{bmatrix},
V_{xh} = \begin{bmatrix}0 & 0 & 0 & 1\end{bmatrix} \]
可以看出,Causal CNN的单步运算也可以看做RNN运算。 实际上,RNN的全称为Recurrent Neural Network,中文意为循环神经网络, RNN并没有限制其内部运算不能用卷积的形式实现。
不过一般意义上的RNN和Causal CNN有一点很重要的区别在于, RNN传递的隐状态是一个将过去所有信息压缩到一个固定维度的高维空间的向量; 而Causal CNN传递的则是一列固定长度的过去时间步的输入。
当然,需要说明的一点是:上面所说的这种思考方法仅对Causal CNN在自回归合成阶段时有帮助作用。 在训练阶段,可以利用shifted CNN或masked CNN来实现Causal CNN。CNN的并行特性可以帮助自回归模型极大地提高训练速度。