深度循环神经网络

2022-09-26  本文已影响0人  小黄不头秃

(一)深度循环神经网络

前面我们讲的RNN, GRU, LSTM都是一个隐藏层。可是一个隐藏层的模型复杂度是不够的,所以说我们需要更深的网络。

我们先回忆一下RNN,他是一层的隐藏层,我们可以通过增加隐藏层的节点数来增加模型的复杂度,但与此同时会带来的问题就是,模型过拟合。而且一层隐藏层没有很好的非线性。

所以他的想法也很好实现,和MLP是没有太大区别的,就是多堆叠几个隐层就好了。

假设在时间步t有一个小批量的输入数据
\mathbf{X}_t \in \mathbb{R}^{n \times d}
(样本数:n,每个样本中的输入数:d)。
同时,将l^\mathrm{th}隐藏层(l=1,\ldots,L
的隐状态设为\mathbf{H}_t^{(l)} \in \mathbb{R}^{n \times h}
(隐藏单元数:h),
输出层变量设为\mathbf{O}_t \in \mathbb{R}^{n \times q}
(输出数:q)。
设置\mathbf{H}_t^{(0)} = \mathbf{X}_t
l个隐藏层的隐状态使用激活函数\phi_l,则:

\mathbf{H}_t^{(l)} = \phi_l(\mathbf{H}_t^{(l-1)} \mathbf{W}_{xh}^{(l)} + \mathbf{H}_{t-1}^{(l)} \mathbf{W}_{hh}^{(l)} + \mathbf{b}_h^{(l)}),

其中,权重\mathbf{W}_{xh}^{(l)} \in \mathbb{R}^{h \times h}
\mathbf{W}_{hh}^{(l)} \in \mathbb{R}^{h \times h}
偏置\mathbf{b}_h^{(l)} \in \mathbb{R}^{1 \times h}
都是第l个隐藏层的模型参数。

最后,输出层的计算仅基于第l个隐藏层最终的隐状态:

\mathbf{O}_t = \mathbf{H}_t^{(L)} \mathbf{W}_{hq} + \mathbf{b}_q,

其中,权重\mathbf{W}_{hq} \in \mathbb{R}^{h \times q}和偏置\mathbf{b}_q \in \mathbb{R}^{1 \times q}都是输出层的模型参数。

(二)代码实现

import torch 
import torch.nn as nn
from d2l import torch as d2l 

batch_size, num_step = 32, 35

train_iter, vocab = d2l.load_data_time_machine(batch_size, num_step)
x = next(iter(train_iter))[0][:10]
print(x.shape)
# 这个类的参考模型
# class RNNModel(nn.Module):
#     def __init__(self, rnn_layer, vocab_size, **kwargs):
#         super(RNNModel, self).__init__(**kwargs)
#         self.rnn = rnn_layer
#         self.vocab_size = vocab_size
#         self.num_hiddens = self.rnn.hidden_size
#         if not self.rnn.bidirectional:
#             self.num_directions = 1
#             self.linear = nn.Linear(self.num_hiddens, self.vocab_size)
#         else:
#             self.num_directions = 2
#             self.linear = nn.Linear(self.num_hiddens * 2, self.vocab_size)

#     def forward(self, inputs, state):
#         X = F.one_hot(inputs.T.long(), self.vocab_size)
#         X = X.to(torch.float32)
#         Y, state = self.rnn(X, state)
#         # The fully connected layer will first change the shape of `Y` to
#         # (`num_steps` * `batch_size`, `num_hiddens`). Its output shape is
#         # (`num_steps` * `batch_size`, `vocab_size`).
#         output = self.linear(Y.reshape((-1, Y.shape[-1])))
#         return output, state

#     def begin_state(self, device, batch_size=1):
#         if not isinstance(self.rnn, nn.LSTM):
#             # `nn.GRU` takes a tensor as hidden state
#             return  torch.zeros((self.num_directions * self.rnn.num_layers,
#                                  batch_size, self.num_hiddens),
#                                 device=device)
#         else:
#             # `nn.LSTM` takes a tuple of hidden states
#             return (torch.zeros((
#                 self.num_directions * self.rnn.num_layers,
#                 batch_size, self.num_hiddens), device=device),
#                     torch.zeros((
#                         self.num_directions * self.rnn.num_layers,
#                         batch_size, self.num_hiddens), device=device))
# 通过num_layers的值来设定隐藏层数
vocab_size, num_hiddens, num_layers = len(vocab), 256, 2
num_inputs =  vocab_size 
device  = d2l.try_gpu()
lstm_layer = nn.LSTM(num_inputs,num_hiddens,num_layers)
model = d2l.RNNModel(lstm_layer, vocab_size)
model = model.to(device)
num_epoch = 500
lr = 1
d2l.train_ch8(model, train_iter,vocab, lr, num_epoch, device)
上一篇下一篇

猜你喜欢

热点阅读