RNN模型与NLP应用(3):Simple RNN

前文

这篇文章首先介绍基础版的RNN,虽然在自然语言处理上已经有了Transformer和Bert模型,但是RNN在小规模数据集上还有很有用的

正文

怎样对持续数据来建模?
我们知道人类的大脑在阅读处理信息的时候,是从左到右,逐渐积累信息,当你阅读完一段话之后,脑子就已经积累的整段文字的大意。
请添加图片描述
RNN模型,输入输出的长度都不需要固定,适合文本,语音持续序列等数据
如下图,RNN每次看一个词,就会用状态h来积累阅读过的信息
整个RNN只有一个参数A,不论这条链有多长,参数A只有一个,最开始A随机初始化,然后利用训练数据来学习A
请添加图片描述双曲正切函数
请添加图片描述
为什么需要这个激活函数呢
假设输入向量都是0,
状态会爆炸或者都等于0,用激活函数做nomalization,回到正1和负1之间,把激活函数的输出作为新的状态向量
整个参数的数量:h的维度*(h的维度+x的维度)
请添加图片描述
如下图所示,新的状态 h t 是由旧状态 h t − 1 和新的输入 x t 的函数生成的 h_t是由旧状态h_{t-1}和新的输入x_t的函数生成的 ht是由旧状态ht1和新的输入xt的函数生成的
请添加图片描述

搭建神经网络

上一篇文章,我们使用线形规划二分类判断电影评论是正面还是负面的,这里改用RNN来解决这个问题,搭建神经网络
最底层是Word Embedding,它可以把词映射到向量X,利用交叉验证函数来选择最优的维度
再往上搭建一层Simple RNN Layer,输入的是词向量X,输出的状态是h,h的维度也是超参数,根据自己需要设置,应该用交叉验证来选出最好维度

请添加图片描述

将状态矩阵变成一个向量,经过Flatten
请添加图片描述
simple RNN 的缺点
is bad at long-term dependence
请添加图片描述
如下图,输出应该是Chinese,但是Simple RNN看不远,也不需要更多的上下文,最可能输出一种语言,但不一定是Chinese
请添加图片描述

总结

请添加图片描述
在这里插入图片描述
代码实现

'数据集读取与预处理'
# 此处使用Keras库自带函数进行简洁实现(从零开始实现请看上一节)
# 使用keras的embedding层处理文字数据(同样使用imdb数据集)

from keras.datasets import imdb
from keras import preprocessing

max_feature = 10000  # 词汇量(作为特征的单词个数)
maxlen = 500  # 在500个单词以后截断文本

(input_train, y_train), (input_test, y_test) = imdb.load_data(num_words=max_feature)
# y_train、y_test分别表示训练集和测试集的标签
# max_words=10000:只考虑数据集中前10000个最常见的单词
print(len(input_train), 'train sequences')
print(len(input_test), 'test sequences')

print('sequence 格式:(samples*time)')
input_train = preprocessing.sequence.pad_sequences(input_train, maxlen=maxlen)
input_test = preprocessing.sequence.pad_sequences(input_test, maxlen=maxlen)
# 此处相当于对齐序列(补0或者阶段评论)
print('input_train shape:', input_train.shape)
print('input_test shape:', input_test.shape)

'定于模型:Simple RNN'
from keras.models import Sequential     # 调入Sequential模型,按顺序搭建神经网络层
from keras.layers import SimpleRNN, Dense, Embedding   # 各种层

'词嵌入操作:降低输入向量维度'
embedding_dim = 32
model = Sequential()
model.add(Embedding(max_feature, embedding_dim, input_length=maxlen))
# 第一层是Embedding层,设定字典里10000个单词,Embedding层的输出是个500×32的矩阵,
# 只考虑每条电影评论中最后的500个单词,每个单词用32维的向量来表示
# 参数矩阵在此的维度是320000,矩阵的参数根据设定的每个单词表示的向量(32)*字典词个数10000得到
'Simple RNN Layer'
state_dim = 32
model.add(SimpleRNN(state_dim, return_state=False))
# return_state=False,不需要存储ht之前的状态

model.add(Dense(1, activation='sigmoid'))
# units :代表该层的输出维度或神经元个数,此处设定输出的维度为1
# activation=None:激活函数.但是默认 liner

'设定优化算法以及模型评价标准'
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
# optimizer: 优化器,loss:损失函数,metrics: 评价函数.
# 评价函数的结果不会用于训练过程中,可以传递已有的评价函数名称

'设置训练模型'
history = model.fit(
    input_train, y_train,
    epochs=10,
    batch_size=128,
    validation_split=0.2
)
# input_train:输入数据,y_train:标签,
# batch_size:整数,指定进行梯度下降时每个batch包含的样本数
# epochs:整数,训练终止时的epoch值
# validation_split:0~1之间的浮点数,用来指定训练集的一定比例数据作为验证集
model.summary()
'查看模型最终性能'
loss_and_acc = model.evaluate(input_test, y_test)
print('loss=' + str(loss_and_acc[0]))
print('acc=' + str(loss_and_acc[1]))

# loss=0.6762722058105469
# acc=0.80744


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值