使用RNN进行imdb影评情感识别--use RNN to sentiment analysis

原创帖子,转载请说明出处html

1、RNN神经网络结构python

 

 

 

RNN隐藏层神经元的链接方式和普通神经网路的链接方式有一个很是明显的区别,就是同一层的神经元的输出也成为了这一层神经元的输入。固然同一时刻的输出是不可能做为这个时刻的输入的。因此是前一个时刻(t-1)的输出做为这个时刻(t)的输入。算法

 

 

 

序列结构展开示意图,s为隐藏层,o为输出层,x为输入层,U为输入层到隐层的权重矩阵,V则是隐层到输出层的权重矩阵,这个网络在t时刻接收到输入 [公式] 以后,隐藏层的值是 [公式] ,输出值是 [公式] 。关键一点是, [公式] 的值不只仅取决于 [公式] ,还取决于 [公式] 。数据库

 

 

2、RNN应用范围网络

RNNs主要用于处理NLP类的问题,如词向量表达、语句合法性检查、词性标注等。在RNNs中,目前使用最普遍最成功的模型即是LSTMs(Long Short-Term Memory,长短时记忆模型)模型,该模型一般比vanilla RNNs可以更好地对长短时依赖进行表达,该模型相对于通常的RNNs,只是在隐藏层作了手脚。下篇文章会对LSTM进行介绍。数据结构

 

3、使用RNN进行影评情感分析函数

0x00 实验环境性能

  tensorflow2.0,此版本的keras已经被包含到tf中,导入keras时注意加入tensorflow前缀,若是想关闭vision2.0版本的特性的话,可使用:学习

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

 

0x01 数据预处理测试

  导入数据集和相应的库,这里使用imdb数据集

#导入imdb影评库
from tensorflow.keras.datasets import imdb
from tensorflow.keras.preprocessing import sequence

  以后咱们对数据集与训练集进行划分,下面的vocab_num表明着我要从imdb数据库中导入10000条数据,第二行的左括号与右括号表明训练集与测试集的划分

#划分训练集与测试集
#label中的0表明消极,1表明积极
vocab_num=10000
(X_train,y_train),(X_test,y_test)=imdb.load_data(num_words=vocab_num)

print("----review----")
print(X_train[5])
print("----label-----")
print(y_train[5])

  打印结果

----review----
[1, 6740, 365, 1234, 5, 1156, 354, 11, 14, 5327, 6638, 7, 1016, 2, 5940, 356, 44, 4, 1349, 500, 746, 5, 200, 4, 4132, 11, 2, 9363, 1117, 1831, 7485, 5, 4831, 26, 6, 2, 4183, 17, 369, 37, 215, 1345, 143, 2, 5, 1838, 8, 1974, 15, 36, 119, 257, 85, 52, 486, 9, 6, 2, 8564, 63, 271, 6, 196, 96, 949, 4121, 4, 2, 7, 4, 2212, 2436, 819, 63, 47, 77, 7175, 180, 6, 227, 11, 94, 2494, 2, 13, 423, 4, 168, 7, 4, 22, 5, 89, 665, 71, 270, 56, 5, 13, 197, 12, 161, 5390, 99, 76, 23, 2, 7, 419, 665, 40, 91, 85, 108, 7, 4, 2084, 5, 4773, 81, 55, 52, 1901]
----label-----
1

  上面打印结果显示的数字表明着字典中对应单词的索引,咱们使用下面的代码来找出每一个索引对应的词

word2id = imdb.get_word_index()
id2word = {i: word for word,i in word2id.items()}
print('---review with word---')
print([id2word.get(i, '') for i in X_train[6]])

  为了让数据可以输入 RNN 模型,全部的输入文档必须有相同的长度。咱们须要设置max_words变量来限制评论的最大长度,超过该长度的评论将被截断,不足该长度的评论将被填充空值(0)。在 Keras 中,咱们可使用pad_sequences()函数来达到此目标。如今设置max_words变量的值为 500。

from tensorflow.keras.preprocessing.sequence import pad_sequences
max_words=500
X_train = pad_sequences(X_train, maxlen=max_words)
X_test = pad_sequences(X_test, maxlen=max_words)

 

0x02 模型创建

from tensorflow.keras import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout

embedding_size = 32
model=Sequential()
model.add(Embedding(vocab_num,embedding_size, input_length= max_words))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
print(model.summary())

  这里逐个解释一下每一个参数的状况。这几步为创建神经网络的基本流程。

  (1)首先,embedding_size,是第六行嵌入层的一个参数,嵌入层,要了解它,首先要知道词嵌入,这里以https://juejin.im/entry/5acc23f26fb9a028d1416bb3 这篇文章来简单介绍一下词嵌入以及embedding层的做用。词嵌入是对传统的词袋模型编码方案的改进,词袋模型能够看这篇http://www.javashuo.com/article/p-hvjqhyxj-dg.html ,

在嵌入中,单词由密集向量表示,其中向量表示将单词投影到连续向量空间中。向量空间中的单词的位置是从文本中学习的,而且基于在使用单词时围绕单词的单词。学习到的向量空间中的单词的位置被称为它的嵌入:Embedding。通俗的说,就是以一种比较准确的方式表达词的位置。

  Keras提供了一个嵌入层,适用于文本数据的神经网络。它要求输入数据是整数编码的,因此每一个字都用一个惟一的整数表示。例如咱们这篇文章说到的imdb的词库中每一个数字表明的词。嵌入层用随机权重进行初始化,并将学习训练数据集中全部单词的嵌入。

  嵌入层被定义为网络的第一个隐藏层。它必须指定3个参数:

  • input_dim:这是文本数据中词汇的取值可能数。例如,若是您的数据是整数编码为0-9之间的值,那么词汇的大小就是10个单词;
  • output_dim:这是嵌入单词的向量空间的大小。它为每一个单词定义了这个层的输出向量的大小。例如,它多是32或100甚至更大,能够视为具体问题的超参数;
  • input_length:这是输入序列的长度,就像您为Keras模型的任何输入层所定义的同样,也就是一次输入带有的词汇个数。例如,若是您的全部输入文档都由1000个字组成,那么input_length就是1000。

  所以,这里的embedding_size就是嵌入单词的向量空间大小,同时,嵌入层的输出是一个二维向量,每一个单词在输入文本(输入文档)序列中嵌入一个。

 (2)sequential()

  Keras有两种类型的模型,序贯模型(Sequential)和函数式模型(Model),函数式模型应用更为普遍,序贯模型是函数式模型的一种特殊状况。sequential model就是那种最简单的结构的模型。按顺序一层一层训练,一层一层往前的那种。没有什么环的结构。好比像前馈网络那样。Keras 的核心数据结构是“模型”,模型是一种组织网络层的方式。Keras 中主要的模型是 Sequential 模型,Sequential 是一系列网络层按顺序构成的栈。

   (3)  以后加入LSTM

   Keras中的LSTM函数参数能够参考这篇文章:https://blog.csdn.net/jiangpeng59/article/details/77646186 ,这里的100是指输出维度为100

 (4)Dense层

  这里的DENSE层添加了激活函数为sigmoid,Dense层的详细知识能够见:https://blog.csdn.net/m0_37592397/article/details/79982601

 (5)model.summary是指展现model的层数现状,这里的显示结果为:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, 500, 32)           320000    
_________________________________________________________________
lstm (LSTM)                  (None, 100)               53200     
_________________________________________________________________
dense (Dense)                (None, 1)                 101       
=================================================================
Total params: 373,301
Trainable params: 373,301
Non-trainable params: 0
_________________________________________________________________
None

 

0x03 模型训练

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
from tensorflow.keras.callbacks import EarlyStopping
#from tensorboardcolab import TensorBoardColab
#tbc = TensorBoardColab()
es = EarlyStopping(monitor = "val_loss", patience = 10)
batch_size = 64
num_epochs = 10

X_valid, y_valid = X_train[:batch_size], y_train[:batch_size]
X_train2, y_train2 = X_train[batch_size:], y_train[batch_size:]

model.fit(X_train2, y_train2, validation_data=(X_valid, y_valid), batch_size=batch_size, epochs=num_epochs, callbacks = [es])

(1)model.compile

  这个函数主要为设置损失函数和优化器及评估标准。参数设置以下:

  • 优化器 optimizer。它能够是现有优化器的字符串标识符,如 rmsprop 或 adagrad,也能够是 Optimizer 类的实例。详见:optimizers
  • 损失函数 loss,模型试图最小化的目标函数。它能够是现有损失函数的字符串标识符,如 categorical_crossentropy 或 mse,也能够是一个目标函数。详见:losses
  • 评估标准 metrics。对于任何分类问题,你都但愿将其设置为 metrics = ['accuracy']。评估标准能够是现有的标准的字符串标识符,也能够是自定义的评估标准函数

 (2)earlystipping

  这个为keras封装的回调函数,具体信息能够查看https://keras.io/zh/callbacks/,具体的做用为当被监测的数量再也不提高,则中止训练

 (3)batch_size,num_epochs

  简单说,epochs 指的就是训练过程当中数据将被“轮询”多少次。

  深度学习的优化算法,说白了就是梯度降低。每次的参数更新有两种方式。

  第一种,遍历所有数据集算一次损失函数,而后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数都要把数据集里的全部样本都看一遍,计算量开销大,计算速度慢,不支持在线学习,这称为批梯度降低(Batch gradient descent)。

  另外一种,每看一个数据就算一下损失函数,而后求梯度更新参数,这个称为随机梯度降低(stochastic gradient descent)。这个方法速度比较快,可是收敛性能不太好,可能在最优势附近晃来晃去,达不到最优势。两次参数的更新也有可能互相抵消掉,形成目标函数震荡的比较剧烈。

  为了克服两种方法的缺点,如今通常采用的是一种折中手段,小批的梯度降低(mini-batch gradient decent),这种方法把数据分为若干个批,按批来更新参数,这样,一个批中的一组数据共同决定了本次梯度的方向,降低起来就不容易跑偏,减小了随机性。另外一方面由于批的样本数与整个数据集相比小了不少,因此计算量也不是很大。基本上如今的梯度降低都是基于 mini-batch 的,因此 Keras 的模块中常常会出现 batch_size,就是指这个。

 (4)model.fit函数启动训练

 

0x04 模型评估

scores = model.evaluate(X_test, y_test, verbose=0)
print('Test accuracy:', scores[1])

 (1)verbose

  verbose:日志显示,verbose = 0 为不在标准输出流输出日志信息,verbose = 1 为输出进度条记录,verbose = 2 为每一个epoch输出一行记录

 

0x05 所有代码

  由于懒因此麻烦各位本身复制整合了

 

4、总结

  RNN的基本实践流程如上,这是网咯上大部分文章共同流传的一个python代码的例子,我这里将每一行代码进行讲解,适用于具有一丁点ML或者DL基础的旁友观看。

相关文章
相关标签/搜索