本篇主要记录一下循环神经网络的原理相关知识

一、案例分析

图片描述
  对于图示的一句话i hate this boring movie,现在要分析这句话的感情色彩。
  整句话可以用[5, 100]的tensor表示,对于每个时间戳是一个[100]的tensor,把这个100维的tensor作为线性层的输入,最后再用一个线性层把5个特征输入,作为一个二分类的问题(好/不好)
  但是这种方式带来的问题也很明显

  • 过长的句子会带来大量的参数
  • 没有上下文的语境信息
      比如 i do not like you 这句话,可能仅仅通过Like这个单词就把这句话定义为一个正面的话。下面是一些改进的手段:

1. 权值共享

图片描述

2. 持续记忆

图片描述

二、公式化

图片描述
图片描述

三、使用RNN层

图片描述
  需要注意的是,初始的h初始化的时候要带上batch信息,方便相加.

# 100表示word dim,用一个100维的向量表示一个单词
# 10表示记忆模块是10维的向量
rnn = nn.RNN(input_size=100, hidden_size=10)
rnn._parameters.keys()
# Out[4]: odict_keys(['weight_ih_l0', 'weight_hh_l0', 'bias_ih_l0', 'bias_hh_l0'])
rnn.weight_hh_l0.shape
# Out[5]: torch.Size([10, 10])
rnn.weight_ih_l0.shape
# Out[6]: torch.Size([10, 100])
rnn.bias_ih_l0.shape
# Out[7]: torch.Size([10])

1.RNN

# 1. RNN
# 100表示word dim,用一个100维的向量表示一个单词
# 20表示记忆模块是20维的向量
rnn = nn.RNN(input_size=100, hidden_size=20, num_layers=1)
print(rnn)
# 单词数量,句子
x = torch.randn(10, 3, 100)
out, h = rnn(x, torch.zeros(1, 3, 20))
print(out.shape, h.shape)
# out是所有层h的总和,h是最后一层 h
# 对于多个layer out不会变,但是h的shape会变大,因为现在有“多个”最后一层
# 而out只关心每一个时间戳维度的“最后”一个
# torch.Size([10, 3, 20]) torch.Size([1, 3, 20])

rnn = nn.RNN(input_size=100, hidden_size=20, num_layers=4)
# 3句话,每句话有10个单词,每个单词用100维表示
x = torch.randn(10, 3, 100)
# 这里h0也可以不传
out, h = rnn(x, torch.zeros(4, 3, 20))
print(out.shape, h.shape)
# torch.Size([10, 3, 20]) torch.Size([4, 3, 20])

2.RNNcell

  手动喂多次

# 2. RNN cell
cell1 = nn.RNNCell(100, 20)
h1 = torch.zeros(3, 20)
# 人为地多次循环,有多少时间戳,循环多少次
for xt in x:
    h1 = cell1(xt, h1)
print(h1.shape)  

cell1 = nn.RNNCell(100, 30)
    cell2 = nn.RNNCell(30, 20)
    h1 = torch.zeros(3, 30)
    h2 = torch.zeros(3, 20)
    for xt in x:
        h1 = cell1(xt, h1)
        h2 = cell2(h1, h2)
    print(h2.shape)