教你使用Keras一步步构建深度神经网络:以情感分析任务为例

【导读】Keras是深度学习领域一个非常流行的库,通过它可以使用简单的代码构建强大的神经网络。本文介绍基于Keras构建神经网络的基本过程,包括加载数据、分析数据、构建模型,配置模型等。并通过imdb情感分类任务来让读者更加清晰地了解每一步的过程,最终实现一个完整的情感分类实例。

作者 | Niklas Donges

编译 | 专知

参与 | Yingying, Xiaowen

用Keras构建神经网络

Keras是目前最受欢迎的深度学习库之一,对人工智能的商品化做出了巨大贡献。它使用起来非常简单,允许你用几行代码构建强大的神经网络。在这篇文章中,你将了解如何通过Keras构建神经网络,通过将用户评论分为两类:积极或消极评估来预测用户评论的情感。这就是所谓的情感分析,我们会用著名的imdb评论数据集来做实验。我们将构建的模型也可以应用于其他机器学习问题,只需进行一些更改。

请注意,本文我们不会深入Keras或深度学习的细节。本文旨在为你提供Keras神经网络的蓝图,并使你熟悉其实现。

Keras是什么?



Keras是一个开源的python库,可以让你轻松构建神经网络。该库能够在TensorFlow,Microsoft Cognitive Toolkit,Theano和MXNet上运行。 Tensorflow和Theano是Python中用来构建深度学习算法的最常用的数字平台,但它们可能相当复杂且难以使用。相比之下,Keras提供了一种简单方便的方法来构建深度学习模型。它的创造者是FrançoisChollet,使人们能够尽可能快速和简单地构建神经网络。他专注于可扩展性,模块化,极简主义和python的支持。Keras可以使用GPU和CPU,它同时支持Python 2和3。 Google Keras为深度学习和人工智能的商品化做出了巨大贡献,因为它已经商品化了强大的现代深度学习算法,这些算法以前不仅无法访问,而且也不可用。

什么是情感分析?



借助情感分析,我们想要确定说话者或作家对于文档,交互或事件的态度(例如情绪)。因此,这是一个自然语言处理问题,需要理解文本,以及潜在的意图。情绪主要分为积极的,消极的和中立三类。因此,情感分析广泛应用于诸如评论,调查,文档等等。

imdb数据集



imdb情绪分类数据集由来自imdb用户的50,000个电影评论组成,标记为positive(1)或negative(0)。评论是预处理的,每一个都被编码为一个整数形式的单词索引序列。评论中的单词按照它们在数据集中的总体频率进行索引。例如,整数“2”编码数据中第二个最频繁的词。 50,000个评论中,25000个作为训练集,另25000个作为测试集。该数据集由斯坦福大学的研究人员创建并于2011年发布,他们的准确率达到了88.89%。

导入库并获取数据



我们首先导入所需的库来预处理数据。

%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from keras.utils import to_categorical
from keras import models
from keras import layers

我们继续下载已经内置到Keras中的imdb数据集。由于我们不希望将数据集进行50/50的训练、测试拆分,我们会在下载后立即将数据合并到数据和目标中,因此我们可以稍后再进行80/20拆分。

from keras.datasets import imdb
(training_data, training_targets), (testing_data, testing_targets) = 
imdb.load_data(num_words=10000)
data = np.concatenate((training_data, testing_data), axis=0)
targets = np.concatenate((training_targets, testing_targets), axis=0)

探索数据



现在我们可以开始探索数据集了:

print("Categories:", np.unique(targets))
print("Number of unique words:", len(np.unique(np.hstack(data))))

Categories: [0 1]
Number of unique words: 9998
length = [len(i) for i in data]
print("Average Review length:", np.mean(length))
print("Standard Deviation:", round(np.std(length)))

Average Review length: 234.75892
Standard Deviation: 173.0

你可以在上面的输出中看到数据集被标记为两个类别,分别代表0或1,表示评论的情感。整个数据集包含9998个字,评论的平均长度为234个字,标准差为173个字。

现在我们来看一个训练样例:

print("Label:", targets[0])

Label: 1
print(data[0])

[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 
 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 
 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 
 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 
 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 
 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 
 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 
 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 
 82, 2, 8, 4, 107, 117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 
 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 
 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 
 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104,
 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32,
 15, 16, 5345, 19, 178, 32]

你在上面,你可以看到数据集的第一次预览,它被标记为“正”(1)。下面的代码检索字典映射词索引回到原来的单词,以便我们可以阅读它们。它用“#”替换每个未知的单词。它通过使用get_word_index()函数来完成。

index = imdb.get_word_index()
reverse_index = dict([(value, key) for (key, value) in index.items()]) 
decoded = " ".join( [reverse_index.get(i - 3, "#") for i in data[0]] )
print(decoded) 

# this film was just brilliant casting location scenery story direction everyone's 
# really suited the part they played and you could just imagine being there robert
#  is an amazing actor and now the same being director
#  father came from the same scottish island as myself so i loved the fact 
# there was a real connection with this film the witty remarks throughout 
# the film were great it was just brilliant so much that i bought the film as soon as
it was released for
#  and would recommend it to everyone to watch and the fly fishing was amazing 
really cried at the end 
# it was so sad and you know what they say if you cry at a film it must have been good 
and this definitely was also
#  to the two little boy's that played the 
#  of norman and paul they were just brilliant children are often left out of the
#  list i think because the stars that play them all grown up are such a big profile 
for the whole film 
# but these children are amazing and should be praised for what they have done don't 
you think the whole story was so lovely 
# because it was true and was someone's life after all that was shared with us all

准备



我们将矢量化每个评论并为缺失项填充零,以便它包含正好一万个数字。这意味着我们用零填充每个比10,000字少的评论。我们这样做是因为神经网络的每个输入都需要具有相同的大小。我们也将目标转化为浮点数。

def vectorize(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))


for i, sequence in enumerate(sequences):
    results[i, sequence] = 1
return results

data = vectorize(data)
targets = np.array(targets).astype("float32")

现在我们将数据分成训练和测试集。训练集将包含40,000条评论,测试设置为10,000条。

test_x = data[:10000]
test_y = targets[:10000]
train_x = data[10000:]
train_y = targets[10000:]

建立和训练模型



我们现在可以建立我们简单的神经网络。我们首先定义我们要构建的模型的类型。Keras中有两种类型的模型可供使用:Sequential模型和与API函数一起使用的Model类。

https://keras.io/models/sequential/

https://keras.io/models/model/

然后我们只需添加输入层,隐藏层和输出层。在他们之间,我们使用dropout来防止过拟合。请注意,你应始终使用20%到50%之间的dropout率。在每一层,我们使用“Dense”,这意味着单元全连接。在隐藏层中,我们使用ReLU函数,因为这在大多数情况下会产生令人满意的结果。输出层使用sigmoid函数,它将输出值映射到0和1之间。请注意,我们在输入层将输入大小设置为10,000,因为我们的整数长度为10,000个整数。输入层最多需要10,000个输入,输出层大小为50。

最后,让Keras打印我们刚刚构建的模型的概要。

# Input - Layer
model.add(layers.Dense(50, activation = "relu", input_shape=(10000, )))
# Hidden - Layers
model.add(layers.Dropout(0.3, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation = "relu")
model.add(layers.Dropout(0.2, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation = "relu"))
# Output- Layer
model.add(layers.Dense(1, activation = "sigmoid"))model.summary()
model.summary()
______________________________________________________________
Layer (type)                 Output Shape              Param #   
==============================================================
dense_1 (Dense)              (None, 50)                500050    
______________________________________________________________
dropout_1 (Dropout)          (None, 50)                0         
______________________________________________________________
dense_2 (Dense)              (None, 50)                2550      
______________________________________________________________
dropout_2 (Dropout)          (None, 50)                0         
______________________________________________________________
dense_3 (Dense)              (None, 50)                2550      
______________________________________________________________
dense_4 (Dense)              (None, 1)                 51        
==============================================================

Total params: 505,201
Trainable params: 505,201
Non-trainable params: 0
______________________________________________________________

现在我们需要编译我们的模型,也就是为模型训练进行配置。我们使用“adam”优化器。优化器是在训练期间改变权重和偏差的算法。我们也选择二进制 - 交叉熵作为损失(因为我们处理二进制分类)和准确性作为我们的评估指标。

model.compile(
 optimizer = "adam",
 loss = "binary_crossentropy",
 metrics = ["accuracy"]
)

我们现在可以训练我们的模型。我们设置batch_size为500并且只训练两个epoch,因为我发现如果我们训练的时间更长,这个模型会变好。批处理大小(batch_size)定义了将通过网络传播的样本的数量,而一个epoch是整个训练数据的迭代。通常情况下,batch_size越大,训练速度越快,但并不总是快速收敛。训练中batch_size较小的训练较慢,但收敛速度更快。这肯定是与问题相关的,你需要尝试一些不同的值。如果你第一次遇到问题,我建议你使用批处理大小为32的标准大小。

results = model.fit(
 train_x, train_y,
 epochs= 2,
 batch_size = 500,
 validation_data = (test_x, test_y)
)

Train on 40000 samples, validate on 10000 samples
Epoch 1/2
40000/40000 [==============================] - 5s 129us/step - loss: 
0.4051 - acc: 0.8212 - val_loss: 0.2635 - val_acc: 0.8945
Epoch 2/2
40000/40000 [==============================] - 4s 90us/step - loss: 
0.2122 - acc: 0.9190 - val_loss: 0.2598 - val_acc: 0.8950

评估模型:

print(np.mean(results.history["val_acc"]))

0.894750000536

你可以在下面看到整个模型的代码:

import numpy as np
from keras.utils import to_categorical
from keras import models
from keras import layers
from keras.datasets import imdb

(training_data, training_targets), (testing_data, testing_targets) = 
imdb.load_data(num_words=10000)
data = np.concatenate((training_data, testing_data), axis=0)
targets = np.concatenate((training_targets, testing_targets), axis=0)


def vectorize(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1
    return results


test_x = data[:10000]
test_y = targets[:10000]
train_x = data[10000:]
train_y = targets[10000:]
model = models.Sequential()
# Input - Layer
model.add(layers.Dense(50, activation="relu", input_shape=(10000,)))
# Hidden - Layers
model.add(layers.Dropout(0.3, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation="relu"))
model.add(layers.Dropout(0.2, noise_shape=None, seed=None))
model.add(layers.Dense(50, activation="relu"))
# Output- Layer
model.add(layers.Dense(1, activation="sigmoid"))
model.summary()
# compiling the model
model.compile(
    optimizer="adam",
    loss="binary_crossentropy",
    metrics=["accuracy"]
)
results = model.fit(
    train_x, train_y,
    epochs=2,
    batch_size=500,
    validation_data=(test_x, test_y)
)
print("Test-Accuracy:", np.mean(results.history["val_acc"]))

总结

本文介绍了情感分析的内容,以及为什么Keras是最常用的深度学习库之一。 最重要的是,你了解到Keras对深度学习和人工智能的商品化做出了重大贡献。你学会了如何建立一个简单的六层神经网络,可以预测电影评论的情感,其准确率达到89%。现在,你可以使用此模型对其他文本来源进行二值情感分析,但需要将其全部更改为10,000的长度,或者更改输入层。你也可以将此模型应用于其他相关机器学习问题,只需进行一些更改。

https://machinelearningmastery.com/introduction-python-deep-learning-library-keras/

https://keras.io/datasets/

参考链接:

https://towardsdatascience.com/how-to-build-a-neural-network-with-keras-e8faa33d0ae4

-END-

原文发布于微信公众号 - 专知(Quan_Zhuanzhi)

原文发表时间:2018-04-18

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法与Python学习

推荐 | Python机器学习项目实战(附代码 + 可下载)【一】

Putting the machine learning pieces together

41630
来自专栏机器之心

深度 | 从数据结构到Python实现:如何使用深度学习分析医学影像

选自Medium 作者:Taposh Dutta-Roy 机器之心编译 运用深度学习技术进行图像和视频分析,并将它们用于自动驾驶汽车、无人机等多种应用场景中已成...

80790
来自专栏语言、知识与人工智能

基于深度学习的FAQ问答系统

| 导语 问答系统是信息检索的一种高级形式,能够更加准确地理解用户用自然语言提出的问题,并通过检索语料库、知识图谱或问答知识库返回简洁、准确的匹配答案。相较于...

11.2K110
来自专栏专知

【干货】Python机器学习项目实战1(附代码)

4.6K30
来自专栏量子位

用Keras+TensorFlow,实现ImageNet数据集日常对象的识别

王新民 编译自 Deep Learning Sandbox博客 量子位 出品 | 公众号 QbitAI ? 在计算机视觉领域里,有3个最受欢迎且影响非常大的学术...

68580
来自专栏算法channel

机器学习储备(4):最常用的求导公式

求导公式在机器学习的梯度下降中经常使用,因为梯度就意味着要求导,所以将使用频率最高的几个公式罗列在下面,方便查阅。 ? 其中第三个是第二个的特列 求导比较重要的...

38960
来自专栏机器之心

学界 | 详解指针生成网络:自动生成长段文本的抽象摘要

作者:Abigail See 机器之心编译 参与:Nurhachu Null 这篇博文是斯坦福大学计算机科学在读博士 Abigail See 对最近自己和其他研...

84360
来自专栏量化投资与机器学习

【Matlab量化投资】支持向量机择时策略

推出【Matlab量化投资系列】 机器学习 所谓机器学习,其实就是根据样本数据寻找规律,然后再利用这些规律来预测未来的数据(结果)。 但是,直到今天,机器学习...

29560
来自专栏ATYUN订阅号

TensorFlow团队:TensorFlow Probability的简单介绍

在2018年TensorFlow开发者峰会上,我们(TensorFlow团队)宣布发布TensorFlow Probability:一种使机器学习研究人员及相关...

14050
来自专栏机器之心

资源 | 概率编程工具:TensorFlow Probability官方简介

选自Medium 作者:Josh Dillon、Mike Shwe、Dustin Tran 机器之心编译 参与:白妤昕、李泽南 在 2018 年 TensorF...

50260

扫码关注云+社区

领取腾讯云代金券