3.7 循环神经网络【stanford-cs329p】


Dense layer -> Recurrent networks

  • 语言模型:预测下一个词
    • hello -> world,hello world -> !
  • 使用MLP并不能很好的处理时序信息,每次输入一个词用同一个MLP模型的话就根本看不到之前的序列,当然也可以想用bag of word用one-hot编码把词加起来表示序列,但是这样还是丢失了时序信息,因为 hello world 和 world hello 其实是一个表示了

RNN and Gated RNN

  • 简单的RNN:$h_t=\phi (W_{hh}h_{t-1}+W_{hx}x_t+b_h)$ ,第一项是和MLP不同的主要所在,主要是增加了让模型看到上一个时间步的信息
  • Gated RNN (LSTM,GRU):通过一些可以学习的参数来控制信息流动
    • 忘记输入:当计算 $h_t$ 的时候抑制 $x_t$,这个输入对预测没有多大关系了就可以忘记等等
    • 忘记过去:当计算 $h_t$ 的时候抑制 $h_{t-1}$,比如新的一段开始了,很久之前的信息跟现在没多大关系了就可以忘记

Code

  • 实现一个简单的RNN
1
2
3
4
5
6
7
8
9
10
W_xh = nn.Parameter(torch.randn(num_inputs, num_hiddens) * 0.01)
W_hh = nn.Parameter(torch.randn(num_hiddens, num_hiddens) * 0.01)
b_h = nn.Parameter(torch.zeros(num_hiddens))

H = torch.zeros(num_hiddens)
outputs = []

for X in inputs: # `inputs` shape: (num_steps, batch_size, num_inputs)
H = torch.tanh(X @ W_xh + H @ W_hh + b_h)
outputs.append(H)

Bi-RNN and Deep RNN

能拿到整个序列的时候可以看到双向的表示,一个是防止神经网络遗忘,另一个是可以获取更好的上下文语义信息

同样的,RNN也是可以一直堆叠起来变得很深

Model Selections

  • 表格:决策树、线性/MLP
  • 文本/语音:RNN、transformer
  • 图片/频谱/视频:transformer、CNN

Summary

  • MLP:通过堆叠多个稠密层和非线性激活函数
  • CNN:堆卷积层、池化层来获取有效的空间信息
  • RNN:堆叠循环层获取隐藏状态来获取时序信息