理解循环神经网络
之前有一篇文章已经初步介绍过RNN
的原理(https://forchenxi.github.io/2021/04/23/nlp-rnn/),里面其实已经介绍的比较清晰易懂了,这篇文章再来回顾和拓展一下.
首先要知道RNN
是一个带有内部环的神经网络,上面的这篇文章中的图描述的更形象,这里再来简单回顾下,使用tensorflow
来实现(实际也是用keras
来实现的)。
SimpleRNN
RNN
基本计算过程
这张图中为了让大家看到RNN
网络的计算过程,没有展现出RNN
网络的内部循环,但是各个参数的含义表示的非常清楚。
import tensorflow as tf
# 这里随机生成一个3*2的矩阵,前面的1表示样本数量(表示本批次只有一个样本)
# 输出数据的第一维与这里样本数量一致
# 3*2可以理解为一个文本句子的向量表示,有三个单词,每个单词的的向量长度为2
x = tf.random.normal((1, 3, 2))
# 这里的4可以理解为权重向量的长度(上面的图上有标注出来),最后输出张量的尺寸也与此参数有关
layer = tf.keras.layers.SimpleRNN(4, input_shape=(3, 2))
output = layer(x)
print(output.shape)
print(output)
(1, 4)
tf.Tensor([[0.8968392 0.53277504 0.07782626 0.42022803]], shape=(1, 4), dtype=float32)
这里最后输出只有一个长度为4的向量,而RNN
在实际计算时是每个单词都计算了一遍,所以实际计算过程得到了3个长度为4的向量,上篇文章中也有提到是通过return_sequences
这个参数来控制的。
RNN
的输出
RNN
的输出分为多对一(N vs 1)、多对多(N vs N)和一对多(1 vs N)三种
上面的代码是单输出形式,多输出的代码如下:
x = tf.random.normal((1, 3, 2))
layer = tf.keras.layers.SimpleRNN(4, input_shape=(3, 2), return_sequences=True)
output = layer(x)
print(output.shape)
(1, 3, 4)
代码理解图
上面仅是得到了每个时间步的张量,还可以通过添加输层出来获取输出
model = tf.keras.Sequential()
model.add(tf.keras.layers.SimpleRNN(4, input_shape=(3, 2),
return_sequences=True))
model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(4, activation='softmax')))
另外也可以将多个RNN
层叠加在一起
model = tf.keras.Sequential()
model.add(tf.keras.layers.SimpleRNN(4, input_shape=(3, 2), return_sequences=True))
model.add(tf.keras.layers.SimpleRNN(4))
添加embedding层
这里的词向量是随机矩阵,直接输入到RNN
中,其实还可以再此之前插入一个embedding层
model = tf.keras.Sequential()
# embedding层的shape与RNN的输入shape保持一致
model.add(tf.keras.layers.Embedding(3, 2))
model.add(tf.keras.layers.SimpleRNN(4, input_shape=(3, 2)))
关于embedding层的原理和使用方法,在这篇博客中也有介绍
https://forchenxi.github.io/2021/03/15/nlp-vectorize/
双向RNN
双向的RNN
实际上就是将一个前向的RNN
和一个后向的RNN
在每个时间步得到的状态值拼接在一起作为总的状态。
model = tf.keras.Sequential()
model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(10, return_sequences=True), input_shape=(5, 10)))
model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(10)))
model.add(tf.keras.layers.Dense(5))
model.add(tf.keras.layers.Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
这里实际是用的LSTM
网络