大家好,我技术人Howzit,这是深度学习入门系列第二十一篇,欢迎大家一起交流!

深度学习入门系列1:多层感知器概述
深度学习入门系列2:用TensorFlow构建你的第一个神经网络
深度学习入门系列3:深度学习模型的性能评价方法
深度学习入门系列4:用scikit-learn找到最好的模型
深度学习入门系列5项目实战:用深度学习识别鸢尾花种类
深度学习入门系列6项目实战:声纳回声识别
深度学习入门系列7项目实战:波士顿房屋价格回归
深度学习入门系列8:用序列化保存模型便于继续训练
深度学习入门系列9:用检查点保存训练期间最好的模型
深度学习入门系列10:从绘制记录中理解训练期间的模型行为
深度学习入门系列11:用Dropout正则减少过拟合
深度学习入门系列12:使用学习规划来提升性能
深度学习入门系列13:卷积神经网络概述
深度学习入门系列14:项目实战:基于CNN的手写数字识别
深度学习入门系列15:用图像增强改善模型性能
深度学习入门系列16:项目实战:图像中目标识别
深度学习入门系列17:项目实战:从电影评论预测情感
深度学习入门系列18:循环神经网络概述
深度学习入门系列19:基于窗口(window)的多层感知器解决时序问题
深度学习入门系列20:LSTM循环神经网络解决国际航空乘客预测问题
深度学习入门系列21:项目:用LSTM+CNN对电影评论分类
深度学习入门系列22:从猜字母游戏中理解有状态的LSTM递归神经网络
深度学习入门系列23:项目:用爱丽丝梦游仙境生成文本

文章目录

  • 1 用极简LSTM模型解决序列分类
  • 2 使用Dropout的LSTM模型解决序列分类问题
  • 3 用LSTM和CNN实现序列分类
  • 4总结
    • 4.1 接下来

序列分类是个预测建模问题,它输入序列有空间或者时间属性,其任务是预测序列的类别。这个问题变得如此难的因为序列长度不断变化的,由大量的词汇组成的字符,可能还需要模型学习序列中的字符之间的长期上下文或者依赖关系。在这个项目中,你将学习如何用 Keras 深度学习库构建LSTM循环神经网络模型用于序列分类问题。完成这个项目后,你将了解:

  • 如何构建LSTM模型用于序列分类问题。
  • 如何通过使用Dropout技术减少LSTM过拟合。
  • 如何将LSTM和擅长空间结构的卷积神经网(CNN)络结合起来。

让我们开始吧!

1 用极简LSTM模型解决序列分类

在本节课中描述的序列学习的问题是 IMDB 电影评论情感分析问题,在第十七章 项目:从电影评论中预测情感用的数据集。我们能够快速的为IMDB问题构建一个简单的LSTM网络,而且还获得不错的准确率。让我先从导入模型必要的类和函数开始,并初始化随机生成器为常数,确保结果的可复制性。

import numpy
from keras.datasets import imdb
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence # fix random seed for reproducibility
numpy.random.seed(7)

我们需要加载IMDB数据集,我们限制了数据集中的单词在前5000个。我们也将数据集分为训练集(50%)和测试集(50%)。

# load the dataset but only keep the top n words, zero the rest
top_words = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)

接下来,我们需要裁减和平铺输入序列,目的是用同样的输入长度进行建模。学了0值模型是不携带任何信息的,因此就内容而言其序列的内容并不是一样的长,但是在Keras中计算的话还是需要同样长度的向量。

# truncate and pad input sequences
max_review_length = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)

现在,我们定义,编译和拟合我们LSTM模型,第一层是用长度为32的向量代表单词的embedding层。接下来层是有100个记忆单元(小神经元)的LSTM层,最后,因为这是个分类问题,在这个问题上,我们使用一个神经元的Dense层和并使用sigmoid激活函数做0或者1预测(好或者坏)。因为它是个二分类问题,对数损失我使用损失函数(Keras中的binary_crossentropy),使用有效的ADAM优化算法。因为在这个问题上很快过拟合,模型仅仅拟合3个迭代周期。一个更大批处理尺寸64用于分隔权重更新。

# create the model
embedding_vecor_length = 32
model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(LSTM(100)) model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary() m
odel.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3, batch_size=64)

一旦拟合,我们在位置评审上估计模型的性能。

# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))

为了完整性,下面列出了在IMDB数据集上LSTM网络。

# LSTM for sequence classification in the IMDB dataset
import numpy
from keras.datasets import imdb
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers.embeddings import Embedding
from keras.models import Sequential
from keras.preprocessing import sequence  # fix random seed for reproducibility
numpy.random.seed(7)
# load the dataset but only keep the top n words, zero the rest
top_words = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)
# truncate and pad input sequences
max_review_length = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)
# create the model
embedding_vecor_length = 32
model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
model.fit(X_train, y_train, epochs=3, batch_size=64)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1] * 100))

运行上面的例子得到下面结果。注意,如果你使用TensorFlow作为后端,那么你可能看到一些和PoolAllocator相关的警告信息,你直接忽略即可。

Epoch 1/3
16750/16750 [==============================] - 107s - loss: 0.5570 - acc: 0.7149
Epoch 2/3
16750/16750 [==============================] - 107s - loss: 0.3530 - acc: 0.8577
Epoch 3/3
16750/16750 [==============================] - 107s - loss: 0.2559 - acc: 0.9019
Accuracy: 86.79%

你能够看到,这个简单的LSTM模型,做了稍微调参就在IMDB问题上获得不错的结果。重要的是,你使用的模板也能将LSTM应用自己的序列分类问题上。现在,让我们一起看看在这个模型上的扩展,也可以应用于自己的问题上。

2 使用Dropout的LSTM模型解决序列分类问题

循环神经网络(RNN)像** LSTM ** 一般都会有过拟合的问题。在层之间用Keras Dropout层实现丢弃。我们很方便在EmbeddingLSTM 层以及LSTM and Dense 输出层之间添加Dropout层。例如:

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(Dropout(0.2))
model.add(LSTM(100))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))

下面是加了Dropout层的完整代码:

# LSTM with Dropout for sequence classification in the IMDB dataset
import numpy
from keras.datasets import imdb
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import LSTM
from keras.layers.embeddings import Embedding
from keras.models import Sequential
from keras.preprocessing import sequence  # fix random seed for reproducibility
numpy.random.seed(7)
# load the dataset but only keep the top n words, zero the rest
top_words = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)
# truncate and pad input sequences
max_review_length = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)
# create the model
embedding_vecor_length = 32
model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(Dropout(0.2))
model.add(LSTM(100))
model.add(Dropout(0.2))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
model.fit(X_train, y_train, epochs=3, batch_size=64)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1] * 100))

运行上面这个例子得到下面的结果:

Epoch 1/3
16750/16750 [==============================] - 108s - loss: 0.5802 - acc: 0.6898
Epoch 2/3
16750/16750 [==============================] - 108s - loss: 0.4112 - acc: 0.8232
Epoch 3/3
16750/16750 [==============================] - 108s - loss: 0.3825 - acc: 0.8365
Accuracy: 85.56%

我们能够看到,dropout会导致训练的收敛速度稍慢,在这个例子最后的准确率更低了。模型可能需要使用更多的训练周期,可能获得更高的准确率(试试看)。或者,可以将dropout 准确而单独地应用于输入端和循环连接的记忆单元的LSTM上。KerasLSTM 层上提供参数,dropout用于配置输出端的丢弃,recurrent_dropout用于配置循环丢弃。举个例子,我们修改了第一个例子,增加dropout到输入端和循环连接上,如下:

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length, dropout=0.2))
model.add(LSTM(100, dropout_W=0.2, dropout_U=0.2))
model.add(Dense(1, activation='sigmoid'))

为了完整性,下面列出了更加精准的 LSTM dropout 的完整代码。

# LSTM with dropout for sequence classification in the IMDB dataset
import numpy
from keras.datasets import imdb
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence  # fix random seed for reproducibility
numpy.random.seed(7)
# load the dataset but only keep the top n words, zero the rest
top_words = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)
# truncate and pad input sequences
max_review_length = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)
# create the model
embedding_vecor_length = 32
model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
model.fit(X_train, y_train, epochs=3, batch_size=64)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1] * 100))

运行上面这个例子得到如下的结果:

Epoch 1/3
16750/16750 [==============================] - 112s - loss: 0.6623 - acc: 0.5935
Epoch 2/3
16750/16750 [==============================] - 113s - loss: 0.5159 - acc: 0.7484
Epoch 3/3
16750/16750 [==============================] - 113s - loss: 0.4502 - acc: 0.7981
Accuracy: 82.82%

我们能够看到,指定的dropoutLSTM要比面向层的dropout在网络收敛上影响更明显。正如上面,迭代周期不变和增加迭代周期两种情况能够看到模型的性能是否进一步提升。在你的LSTM模型中,Dropout一种抵抗过拟合的有效技术。最好的是两种方法你都试下,但是最好的结果是Keras中提供的制定门(gate)的。

3 用LSTM和CNN实现序列分类

卷积神经网络在学习输入数据的空间结构方便表现比较出色。IMDB评论数据中的单词序列具有一维空间结构,CNN能够提取好和坏情感的单变量特征。这种已学习的空间特征也有可能被LSTM层作为序列进行学习。我们能很方便在 Embedding层之后添加一个一维的 CNNmax pooling 层,而Embedding层将综合特征输入 LSTM。我们使用过滤器长为3的32个小特征集合,pooling层使用标准大小为2用于获取特征图的大小。例如,我们创建模型如下:

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))

为了完整性,下面列出了 CNNLSTM 层的所有代码。

# LSTM and CNN for sequence classification in the IMDB dataset
import numpy
from keras.datasets import imdb
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from keras.layers.embeddings import Embedding
from keras.models import Sequential
from keras.preprocessing import sequence  # fix random seed for reproducibility
numpy.random.seed(7)
# load the dataset but only keep the top n words, zero the rest
top_words = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)  # truncate and pad input sequences
max_review_length = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_review_length)
X_test = sequence.pad_sequences(X_test, maxlen=max_review_length)
# create the model
embedding_vecor_length = 32
model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
model.fit(X_train, y_train, epochs=3, batch_size=64)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))

运行提供的代码,得到如下结果:

Epoch 1/3
16750/16750 [==============================] - 58s - loss: 0.5186 - acc: 0.7263
Epoch 2/3
16750/16750 [==============================] - 58s - loss: 0.2946 - acc: 0.8825
Epoch 3/3
16750/16750 [==============================] - 58s - loss: 0.2291 - acc: 0.9126 Accuracy: 86.36%

我们能够看到,虽然我们使用更少的权重和更多的训练时间,但是我们获得和第一例子相似的结果。我期望,如果这个例子进一步扩展下,使用dropout,那么会获得更好的结果。

4总结

在这个项目中,你已经学习了如何构建LSTM网络模型用于序列分类预测建模问题,特别是,你已经学到:

  • 如何构建简单的单层 LSTM 模型用于 IMDB 电影评论的情感分类问题。
  • 如何用面向层和指定LSTM dropout扩展的LSTM模型来减少过拟合。
  • 如何将具有空间结构学习的卷积神经网络和具有序列学习的LSTM进行结合。

4.1 接下来

在即将完成的这个项目中,你已经学习了使用LSTM循环神经网络解决序列分类问题,在下节课,你将建立在LSTM网络立即之前,针对简单的序列预测问题,更好的理解Keras api如何维持状态。

深度学习入门系列21:项目:用LSTM+CNN对电影评论分类相关推荐

  1. 深度学习入门系列6项目实战:声纳回声识别

    大家好,我技术人Howzit,这是深度学习入门系列第六篇,欢迎大家一起交流! 深度学习入门系列1:多层感知器概述 深度学习入门系列2:用TensorFlow构建你的第一个神经网络 深度学习入门系列3: ...

  2. 深度学习入门系列23:项目:用爱丽丝梦游仙境生成文本

    大家好,我技术人Howzit,这是深度学习入门系列第二十三篇,欢迎大家一起交流! 深度学习入门系列1:多层感知器概述 深度学习入门系列2:用TensorFlow构建你的第一个神经网络 深度学习入门系列 ...

  3. 深度学习入门系列1:多层感知器概述

    本人正在学习<deep learning with python>–Jason Brownlee,有兴趣的可以一起学习. 仅供学习参考,不做商用! 大家好,我技术人Howzit,这是深度学 ...

  4. BP算法双向传,链式求导最缠绵(深度学习入门系列之八)

    摘要: 说到BP(Back Propagation)算法,人们通常强调的是反向传播,其实它是一个双向算法:正向传播输入信号,反向传播误差信息.接下来,你将看到的,可能是史上最为通俗易懂的BP图文讲解, ...

  5. LSTM长短记,长序依赖可追忆(深度学习入门系列之十四)

    摘要:如果你是一名单身狗,不要伤心,或许是因为你的记忆太好了.有时,遗忘是件好事,它让你对琐碎之事不再斤斤计较.然而每当自己记不住单词而"问候亲人"时,也确实气死个人.于是你懂得了 ...

  6. BP算法双向传_链式求导最缠绵(深度学习入门系列之八)

    摘要: 说到BP(Back Propagation)算法,人们通常强调的是反向传播,其实它是一个双向算法:正向传播输入信号,反向传播误差信息.接下来,你将看到的,可能是史上最为通俗易懂的BP图文讲解, ...

  7. 卷地风来忽吹散,积得飘零美如画(深度学习入门系列之十)

    点击查看全文 此情可待成追忆".可"记忆"到底是什么?如果我告诉你,"记忆"就是一种"卷积",你可别不信.卷积并不神秘,它就在你我 ...

  8. 局部连接来减参,权值共享肩并肩(深度学习入门系列之十一)

    系列文章: 一入侯门"深"似海,深度学习深几许(深度学习入门系列之一) 人工"碳"索意犹尽,智能"硅"来未可知(深度学习入门系列之二) 神经 ...

  9. 损失函数减肥用_神经网络调权重(深度学习入门系列之六)

    原文链接 更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud 系列文章: 一入侯门"深"似海,深度学习深几许(深度学习入门系列之一) 人工&qu ...

最新文章

  1. language mysql_MySql 语言的分类;
  2. .NET 关于Geometry转GeoJson
  3. 郑风田:老美哪些地儿值得咱们?
  4. Crawler:基于urllib库+实现爬虫有道翻译
  5. Django 多数据库联用(看着不错还有源码可以下载)
  6. 安装 MongoDB PHP 驱动 在CentOS 6.x和遇到的问题
  7. JDK 14的新特性:instanceof模式匹配
  8. 无法在源表中获得一组稳定的行_行输出变压器的结构、符号及电路分析
  9. Java 面向对象 之 对象引用 this的引用
  10. Openvswitch手册(2): OpenFlow Controller
  11. arduino连接12864LCD方法
  12. 在线html解压,javascript实现网页端解压并查看zip文件
  13. 金蝶K3 WISE 12.3版本系统部署指南
  14. 口袋超萌服务器维护中,口袋超萌手游加速攻略 口袋超萌加速方法说明
  15. 如何用burpsuite和手机模拟器给apk抓包
  16. TrafficMonitor:最好用的网速/内存/CPU监控软件
  17. BSN智能合约开发培训-CITA(三)
  18. 小程序源码:喝酒娱乐小游戏助力神器-多玩法安装简单
  19. 大学英语综合教程一 Unit 2 课文内容英译中 中英翻译
  20. STM8控制LCD12864液晶屏实验

热门文章

  1. CTFshow击剑杯osint——人家想玩嘛,人有点多超详细解法
  2. linux_linux自动化换源等优化美化自动化操作脚本/oh my zsh安装/卸载与删除/vim/vi卸载与更新异常/linux发行版本/内核版本查看
  3. 技术人员的赚钱之道-9:极思极恐,技术人员需了解的“穷人”思维与“富人”思维的差别
  4. java解压/读取rar文件
  5. server2012安全_2012年重要安全提示
  6. MATLAB regress命令
  7. python基础学习的书籍
  8. python的io模块
  9. PLC工程师必备知识— IO模块选型和使用(上篇)
  10. SecureCRT Backspace/delete 键失效的解决方法