循环神经网络,时间步t的隐藏变量的计算由当前时间步的输入和上一个时间步的隐藏状态共同决定。
门控循环单元,引入了重置门和更新门的概念。
重置门输出R与上一时间步的隐藏状态按元素乘法,产生候选隐藏状态,决定是否drop上一时间步的隐藏状态。
更新们对上一步的隐藏状态以及候选隐藏状态做加权平均,产生当前时间步的隐藏状态。
长短期记忆,引入输入门,遗忘门,输出门。
记住有6个公式。
三个门的输出I,F,O均由当前时间步的输入以及上一时间步的隐藏状态通过加权偏置并sigmoid后得到。
候选记忆细胞由当前时间步的输入以及上一时间步的隐藏状态通过加权偏置并tanh后得到。
记忆细胞由F与上一时间步的记忆细胞按元素相乘加上I与候选记忆细胞按元素相乘,F趋近于1而I趋近于0代表时间序列上有较长的依赖关系。
当前时间步的隐藏状态由O与tanh(记忆细胞)按元素相乘得到,可以控制当前是直接使用记忆细胞里的信息还是留在之后再使用。
import d2lzh as d2l
import math
from mxnet import autograd, gluon, init, nd
from mxnet.gluon import loss as gloss, nn, rnn
(corpus_indices, char_to_idx, idx_to_char,
vocab_size) = d2l.load_data_jay_lyrics()
num_inputs, num_hiddens, num_outputs = vocab_size, 256, vocab_size
ctx = d2l.try_gpu()
num_epochs, num_steps, batch_size, lr, clipping_theta = 500, 35, 32, 1e2, 1e-2
pred_period, pred_len, prefixes = 50, 50, ['分开', '不分开']
rnn_layer = rnn.RNN(num_hiddens)
gru_layer = rnn.GRU(num_hiddens)
lstm_layer = rnn.LSTM(num_hiddens)
layer = [rnn_layer, gru_layer, lstm_layer]
for layer in layer:
model = d2l.RNNModel(layer, vocab_size)
d2l.train_and_predict_rnn_gluon(model, num_hiddens, vocab_size, ctx,
corpus_indices, idx_to_char, char_to_idx,
num_epochs, num_steps, lr, clipping_theta,
batch_size, pred_period, pred_len, prefixes)
结果就放一个gru呗
epoch 50, perplexity 112.992608, time 0.07 sec