深度学习 21、RNN

你挡我一时,挡不了我一世

发布日期: 2019-06-16 20:07:46 浏览量: 109
评分:
star star star star star star star star star star
*转载请注明来自write-bug.com

前文链接:https://write-bug.com/article/2644.html

RNN循环神经网络

RNN(循环神经网络):一类用于处理序列(时间、空间)数据的神经网络,RNN可用于分类、回归、机器翻译、文本相似度

隐层的神经元不仅接收输入层的或者上一层的信息流,还要接受上一时刻的同层神经元的信息流,即隐层之间的连接,连接传递的权重就是记忆能力。

此处的记忆能力理解为人的认知往往基于过往的经验与记忆,所以模拟时,同样根据激活函数的不同会产生梯度消失和梯度爆炸问题,也反映了人的记忆往往有限,过往太久的事不会记忆或者对现在产生影响过大。

梯度消失:每次loss反向传播时,如果使用sigmoid这样的激活函数一直乘一个小数,在这个过程中一直变小,直到逼近于0
梯度爆炸:每次loss反向传播时,如果使用relu这样的激活函数,x>0时,y=x,一直乘一个大于0的数,数值过大

所以,他的优点就是在上下文推断时,可以根据上文推断下一个出现概率最大的单词,适合短期记忆,不适合长期记忆,很难学习长距离信息,那么同样的,比较符合大脑记忆曲线

隐层展开后为上图样式。

  • t-1, t, t+1表示时间序列

  • X表示输入的样本

  • St表示样本在时间t处的的记忆,St = f(WSt-1 +UXt)

  • W表示输入的权重

  • U表示此刻输入的样本的权重

这里的W,U,V在每个时刻都是相等的(权重共享),隐藏状态: S=f(现有的输入+过去记忆总结)。

以上,便是最基本的RNN原理,我们为了更好的模拟人们根据过往的经验来判断和写文章,引出了

LSTM( Long Short Term Memory Network长短期记忆网络)

LSTM结构更复杂,不仅适合短期记忆,也适合长期记忆。

这条黑线就是从上一时刻的输入到此刻的输出,即单元状态流,用于记忆当前状态,乘号代表着当前时刻对记忆的削减,加号代表记忆的更新,也就是新信息的汇入。

LSTM包含3个门 (– 遗忘门 – 输入门 – 输出门)
这里有这个“门”的概念,下面一个一个解释:

遗忘门

上一刻的信息与此刻的新信息汇入后,σ层就会把信息转化为ft,如果决定要忘记,ft就是0,如果这 个信息要保留,则为1,选择部分记忆则按照实际情况输出0~1的数,也就是激活函数,如sigmoid

ht-1是上个网络的output(输出)
xt当前网络的input(输入)
网络会自动学习到对应的权重矩阵

输入门

首先,上一刻的信息与此刻的新信息汇入后,,统一经过σ层,决定要更新啥信息。还要另外经过tanh层,将 信息转化为一个新的候选值,两者再相乘,就是cell state中需要更新的值了。

接着,“遗忘门”和“输入门”已经决定好了 什么要遗忘,什么要更新

输出门

前面的门已经决定了信息的状态如何保留和更新,得到了Ct,现在把它经过tanh层,并再次与σ层识别哪一部分信息要输出的信息相乘就得到了输出信息ht,输出两路分别给输出(比如此刻的预测词)和下一时刻输入。

GRU

LSTM的变体,比LSTM结构更加简单,效果也很好,GRU只有两个门:更新门、重置门

zt和rt分别表示更新门和重置门

  • 更新门用于控制前一时刻的状态信息被带入到当前状态中的程度 ,更新门的值越大说明前一时刻的状态信息带入越多

  • 重置门控制前一状态有多少信息被写入到当前的候选集 h̃ t 上 ,重置门越小,前一状态的信息被写入的越少

LSTM 实践

  1. # define model
  2. class RNNModel(nn.Module):
  3. """ 一个简单的循环神经网络"""
  4. def __init__(self, rnn_type, ntoken, ninp, nhid, nlayers, dropout=0.5):
  5. ''' 该模型包含以下几层:
  6. - 词嵌入层
  7. - 一个循环神经网络层(RNN, LSTM, GRU)
  8. - 一个线性层,从hidden state到输出单词表
  9. - 一个dropout层,用来做regularization
  10. '''
  11. super(RNNModel, self).__init__()
  12. self.drop = nn.Dropout(dropout)
  13. self.encoder = nn.Embedding(ntoken, ninp)
  14. if rnn_type in ['LSTM', 'GRU']:
  15. self.rnn = getattr(nn, rnn_type)(ninp, nhid, nlayers, dropout=dropout)
  16. else:
  17. try:
  18. nonlinearity = {'RNN_TANH': 'tanh', 'RNN_RELU': 'relu'}[rnn_type]
  19. except KeyError:
  20. raise ValueError( """An invalid option for `--model` was supplied,
  21. options are ['LSTM', 'GRU', 'RNN_TANH' or 'RNN_RELU']""")
  22. self.rnn = nn.RNN(ninp, nhid, nlayers, nonlinearity=nonlinearity, dropout=dropout)
  23. self.decoder = nn.Linear(nhid, ntoken)
  24. self.init_weights()
  25. self.rnn_type = rnn_type
  26. self.nhid = nhid
  27. self.nlayers = nlayers
  28. def init_weights(self):
  29. initrange = 0.1
  30. self.encoder.weight.data.uniform_(-initrange, initrange)
  31. self.decoder.bias.data.zero_()
  32. self.decoder.weight.data.uniform_(-initrange, initrange)
  33. def forward(self, input, hidden):
  34. ''' Forward pass:
  35. - word embedding
  36. - 输入循环神经网络
  37. - 一个线性层从hidden state转化为输出单词表
  38. '''
  39. #print("input ", input.size())
  40. emb = self.drop(self.encoder(input))
  41. #print("emb ", emb.size())
  42. output, hidden = self.rnn(emb, hidden)
  43. #print("output ", output.size())
  44. #print(len(hidden))
  45. output = self.drop(output)
  46. decoded = self.decoder(output.view(output.size(0)*output.size(1), output.size(2)))
  47. #print("output size: ", output.size())
  48. #print("decoded before size: ", output.view(output.size(0)*output.size(1), output.size(2)).size())
  49. #print("decoded after size: ", decoded.size())
  50. #sys.exit()
  51. return decoded.view(output.size(0), output.size(1), decoded.size(1)), hidden
  52. def init_hidden(self, bsz, requires_grad=True):
  53. weight = next(self.parameters())
  54. if self.rnn_type == 'LSTM':
  55. return (weight.new_zeros((self.nlayers, bsz, self.nhid), requires_grad=requires_grad),
  56. weight.new_zeros((self.nlayers, bsz, self.nhid), requires_grad=requires_grad))
  57. else:
  58. return weight.new_zeros((self.nlayers, bsz, self.nhid), requires_grad=requires_grad)
  59. model = RNNModel("LSTM", VOCAB_SIZE, EMBEDDING_SIZE, EMBEDDING_SIZE, 2, dropout=0.5)#模型初始化
  60. if USE_CUDA:
  61. model = model.cuda()
上传的附件
最近文章
eject