使用RNN和CNN混合的’鸡尾酒疗法’,提升网络对文本的识别正确率

前几节我们详细研究了GRU和LSTM网络层,这两者特点是能够抓取输入数据在时间上的逻辑联系,因此这两种网络特别容易从文本中抓取规律,因为文本是有一个个单词依据前后次序连接起来的整体,单词与单词之间的连接可以看做是时间上前后相连的组合,因此使用GRU和LSTM构成的网络来进行文本的情绪分析时,正确率能高达90%。

然而GRU和LSTM网络存在一个非常严重的问题,因为他们要计算输入数据的前后关联,因此运行这两种网络时需要消耗大量内存,同时也损耗大量的运算时间,特别是当他们运行在CPU上时,时间损耗更是令人难以接受,这一节我们看看,能否在不严重降低准确率的情况下,有效的提升网络的处理速度。

在前几节我们提到过卷积网络,它专门用于识别图片。它的做法是将二维图片切成若干个3*3的小块,分别识别这些小块,最后把这些识别结果综合起来得到对正个图片的识别。其实我们也可以使用卷积网络来识别文本序列,文本相对于图片是一维的,但识别方法可以沿用,那就是把一维的文本序列切割成多个小片,让网络分别识别每个小片,然后再把多个小片段的识别结果综合起来得到对整篇文本的识别。Keras框架提供了识别2维数据的卷积网络层Con2D和MaxPooling2D,它同时也提供了识别1维数据的卷积网络层Conv1D和MaxPooling1D,我们使用1维的卷积网络来识别文本序列,看看能得到什么效果。首先我们先把文本数据加载进来,代码如下:

from keras.datasets import imdb
from keras.preprocessing import sequence

max_features = 10000
max_len = 500
print('Loading data...')
(x_train, y_train),(x_test, y_test)=imdb.load_data(num_words=max_features)
print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')

print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=max_len)
x_test = sequence.pad_sequences(x_test, maxlen=max_len)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)

上面代码把keras框架自带的影评文本数据加载到内存中,接下来我们可以构造一个含有1维卷积层的网络来识别影评文本中的情绪,代码如下:

from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

model = Sequential()
model.add(layers.Embedding(max_features, 128, input_length=maxlen))
model.add(layers.Conv1D(32, 7, activation='relu'))
model.add(layers.MaxPooling1D(5))
model.add(layers.Conv1D(32, 7, activation='relu'))
model.add(layers.GlobalMaxPooling1D())
model.add(layers.Dense(1))

model.summary()

上面代码需要注意的是语句:layers.Conv1D(32, 7, activation=’relu’),其中的7表示把文本序列中,每7个单词当做一个切片进行识别,这与前面我们把二维图片中美3*3个像素作为识别单位是同一个道理,同时识别的结果用含有32个元素的一维向量表示,代码构建的网络含有两个卷积层,最后一层值含有一个节点,用来输出文本属于哪种情绪,运行上面代码后,我们把识别结果绘制出来,代码如下:

import matplotlib.pyplot as plt

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo', label = 'Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.legend()
plt.figure()
plt.show()

上面代码运行后,结果如下:

从上图看出,使用1维卷积网络识别文本所得准确率为85%,上一节我们使用LSTM得到的准确率是89%,这次的准确率有所下降,但是程序的运行速度相比于LSTM可是有几十倍的提升!由此看来使用一维卷积网络来识别文本使得准确率有所下降,但随着程序运行速度的极大提升,从而带来了非常有吸引力的性价比。

既然CNN能提升速度,RNN能提升准确率,如果把两者混合起来是不是能获得两者的效用呢。前面使用的CNN之所以准确率不如LSTM,原因在于它对数据没有“记忆性”,它把单词序列切成多个小块分别处理,但是它无法抽取出这些小块之间存在的逻辑联系,显然这些有文本构成的小块之间是存在很强的逻辑联系的,后抽取这些逻辑联系是LSTM这里”记忆性“网络的特长。

为了能够两者兼备,我们可以构造一种混合动力型网络,首先我们把网络分成两个层次,第一层是CNN层,它先将输入数据切分成多个小段,然后对这些小段进行识别,由于前面输入CNN的数据足够长,CNN即使把输入数据切分成多个小段后,”小段“的数量依然不少。此时为了能够把握“小段”之间存在的逻辑联系,我们把这些小段输入到LSTM网络,让后者抓取他们之间存在的关联。我们把这种网络结构应用到上一节描述的天气预测数据上看看效果如何。构造网络的相应代码如下:

from keras.models import Sequential
from keras import layers
from keras.optimizers import RMSprop

model = Sequential()
#在顶层加1个卷积网络
model.add(layers.Conv1D(32, 5, activation='relu', 
                        input_shape=(None, float_data.shape[-1])))
model.add(layers.MaxPooling1D(3))
#添加一个有记忆性的GRU层
model.add(layers.GRU(32, dropout=0.1, recurrent_dropout=0.5))
model.add(layers.Dense(1))
model.summary()

model.compile(optimizer=RMSprop(), loss='mae')
history = model.fit_generator(train_gen, steps_per_epoch=500, epochs=20,
                             validation_data=val_gen,
                             validation_steps=val_steps)

上面代码运行后,我们将结果绘制出来如下:

从上图看,网络对预测的误差率最好时差不多是0.265左右,比上一节使用LSTM网络的误差率0.26稍微差了那么一点点,但是速度快了不止几十倍,由此看来使用两种类型的网络混合所得结果的性价比非常划算。

原文发布于微信公众号 - Coding迪斯尼(gh_c9f933e7765d)

原文发表时间:2018-10-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

深度学习中训练参数的调节技巧

1、学习率 步长的选择:你走的距离长短,越短当然不会错过,但是耗时间。步长的选择比较麻烦。步长越小,越容易得到局部最优化(到了比较大的山谷,就出不去了),而大了...

9878
来自专栏人工智能头条

如何选择合适的损失函数,请看......

1921
来自专栏机器学习算法与理论

几种距离的集中比较

提到检索的方法,比如KNN算法,这些都需要用到“距离”这个尺度去度量两者的近似程度。但是,距离也有很多种,除了我们熟悉的欧氏距离之外,其实还有很多。。。 余弦距...

3577
来自专栏专知

【干货】计算机视觉实战系列08——用Python做图像处理

2502
来自专栏机器之心

资源 | DanceNet:帮你生成会跳舞的小姐姐

DanceNet 中最主要的三个模块是变分自编码器、LSTM 与 MDN。其中变分自编码器(VAE)是最常见的生成模型之一,它能以无监督的方式学习复杂的分布,因...

954
来自专栏刘笑江的专栏

Factorization Machine

1394
来自专栏AI研习社

教你从零开始检测皮卡丘-CNN目标检测入门教程(下)

本文为大家介绍实验过程中训练、测试过程及结果。算法和数据集参见《从零开始码一个皮卡丘检测器-CNN目标检测入门教程(上)》 训练 Train 损失函数 Lo...

3263
来自专栏大数据挖掘DT机器学习

R语言主成分和因子分析

主成分分析(PCA)是一种数据降维技巧,它能将大量相关变量转化为一组很少的不相关变量,这些无关变量称为主成分。 探索性因子分析(EFA)是一系列用来发现一组变...

5014
来自专栏智能算法

到底该如何选择损失函数?

机器学习中的所有算法都依赖于最小化或最大化某一个函数,我们称之为“目标函数”。最小化的这组函数被称为“损失函数”。损失函数是衡量预测模型预测期望结果表现的指标。...

2965
来自专栏AI科技评论

干货 | 史上最好记的神经网络结构速记表(上)

本文提供了神经网络结构速查表,盘点了神经网络的大量框架,并绘制了直观示意图进行说明,是人手必备的神经网络学习小抄。 新的神经网络结构不断涌现,我们很难一一掌握。...

42512

扫码关注云+社区

领取腾讯云代金券