使用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()

上面代码运行后,结果如下:
acc.png
从上图看出,使用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)

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

loss.png

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

更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
这里写图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用卷积神经网络CNN)和循环神经网络RNN)对原始脑电图(EEG)信号进行端到端的模式识别可以实现病人识别。EEG信号是一种记录脑电活动的生理信号,它可以反映出人脑的电活动变化。 首先,我们可以将原始EEG信号进行预处理,这包括去除噪声、滤波和剪裁等步骤,以提取出需要的特征信息。然后,将处理后的EEG信号输入到CNN网络中,通过卷积层、池化层和全连接层等结构,对信号进行特征学习和提取。卷积层可以捕捉EEG信号中的空间特征,池化层可以对特征进行降维和提取,全连接层可以将提取的特征与病人类别进行关联。 接着,我们可以将CNN的输出结果输入到RNN网络中进行进一步处理。RNN可以建立起当前EEG信号与之前信号之间的时间关系,并对序列数据进行建模。通过使用LSTM或GRU等RNN单元,我们可以对EEG信号的时间序列进行编码和建模,捕捉到连续时间上的动态模式。 最后,将RNN的输出结果经过全连接层进行分类,可以得到病人的分类结果。我们可以使用softmax函数将输出结果映射到不同病人类别上,并通过训练样本的类别标签进行损失函数的计算和模型的优化。 通过端到端的模式识别方法,使用CNNRNN对原始EEG信号进行处理和学习,我们可以实现对病人进行识别和分类。这种方法具有较好的自动特征学习能力和泛化性能,可以提高病人识别的准确性和效,同时也方便了模型的应用和迁移。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值