循环神经网络RNN与Pytorch实现
1、循环神经网络(RNN)是什么
(1)简介
循环神经网络的英文名为 Recurrent Neural Networks ,简称为 R N N RNN RNN,这里最关键的就是**“循环”**,通过 R N N RNN RNN可以处理不定长输入的模型,并且 R N N RNN RNN适用于处理输入数据具有前后关系的数据,因此常用于 N L P NLP NLP和时间序列任务中
(2)RNN网络结构
- 上图左边就是 R N N RNN RNN的网络结构,一共有六个数据 x x x、 U U U、 s s s、 V V V、 W W W、 o o o,三个操作(即三个箭头,每个箭头代表一个网络层[ linear 层 ])。6个参数的形状及含义如下:
- x t x_t xt:时刻 t t t的输入,shape = (1, 57)
- s t s_t st:时刻 t t t的状态值,shape=(1, 128)
- o t o_t ot:时刻t的输出值,shape=(1, 18)
- U U U:linear 层的权重参数, shape = (128, 57)
- W W W:linear 层的权重参数, shape = (128, 128)
- V V V:linear 层的权重参数, shape = (18, 128)
- 因此可以推导出, R N N RNN RNN的计算公式为:
- s t = f ( U x t + W s t − 1 ) s_{t}=f\left(U x_{t}+W s_{t-1}\right) st=f(Uxt+Wst−1)
- o t = softmax ( V s t ) o_{t}=\operatorname{softmax}\left(V s_{t}\right) ot=softmax(Vst)
- 从公式中可以看出, R N N RNN RNN中含有 s t s_t st,说明 R N N RNN RNN不仅包含现在的信息,也会对过去的信息进行关注,如上图右边,把整个网络展开就能清洗看到以往的数据是如何对最终的结果起作用的
2、 RNN如处理成不定长输入?
R N N RNN RNN能够实现不定长的输入,并不是因为这个模型有多么的牛逼,而是训练运行的机制非常独特,通常输入的是一个字符串, R N N RNN RNN并不会将这个字符串作为整体输入,而是逐字符进行输入,这样就能确保不定长输入,具体过程如下:
- 单个字符 → \rightarrow →数字(转化为 one-hot 向量)
- 数字 → \rightarrow → model(将向量输入模型)
- 利用
for
循环实现:下一个字符 → \rightarrow →数字 → \rightarrow → model - 最后一个字符
→
\rightarrow
→数字
→
\rightarrow
→ model
→
\rightarrow
→ 分类向量
伪代码如下:
for string in [C, h, o, u]:
one-hot: string -> [0, 0, ..., 1, ..., 0]
y,h = model([0,0,...,1, ...,0],h)
3、训练RNN实现人名分类
- 问题定义:输入任意长度姓名(字符串),输出姓名来自哪一个国家(18分类任务)
- 数据:见链接
- 核心代码:
class RNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(RNN, self).__init__()
self.hidden_size = hidden_size
self.u = nn.Linear(input_size, hidden_size)
self.w = nn.Linear(hidden_size, hidden_size)
self.v = nn.Linear(hidden_size, output_size)
self.tanh = nn.Tanh()
self.softmax = nn.LogSoftmax(dim=1)
def forward(self, inputs, hidden):
u_x = self.u(inputs)
hidden = self.w(hidden)
hidden = self.tanh(hidden + u_x)
output = self.softmax(self.v(hidden))
return output, hidden
def initHidden(self):
return torch.zeros(1, self.hidden_size)
- 训练损失函数曲线: