瞎聊深度学习——IMDB影评文本分类

本文中我希望用IMDB数据集和神经网络对数据集中的影评内容进行“正面影评”和“负面影评”的二分类。

IMDB

IMDB数据集是Tensorflow中带有的数据集,其中包含来自互联网电影库的50000条影评文本,首先来下载该数据集并且查看一下:

加载数据(如果缓存中没有回自动下载该数据):

import tensorflow as tf
from tensorflow import keras
import numpy as np

imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

查看数据:

print("Trraining entries:{},labels:{}".format(len(train_data),len(train_labels)))

输出中可以看到我们训练集的样本量为25000

查看数据中的其中一个样本是什么:

print(train_data[0])

可以看书虽然是影评,在我们的数据集中译英转换为了数值类型而不是字符型,其中每一个数字都代表一个词语,后续会用其他的方法将数值型转换为字符型。

我们知道在神经网络的输入中必须要有相同的长度,所以我们先查看几条数据的长度是不是相同的:

print(len(train_data[0]),len(train_data[10]),len(train_data[100]))

由这个输出结果可以看出,每条影评的长度是不相同的所以我们要想办法处理这个问题,在这里我的办法设置一个最长值得限制,并将短的数据用零来填充:

train_data = keras.preprocessing.sequence.pad_sequences(train_data,
                                                        value=0,
                                                        padding='post',
                                                        maxlen=256)

test_data = keras.preprocessing.sequence.pad_sequences(test_data,
                                                       value=0,
                                                       padding='post',
                                                       maxlen=256)
print(len(train_data[0]),len(train_data[10]),len(train_data[100]))

输出结果如下,此时我们可以看出每一条数据的长度都是相同的:

keras.preprocessing.sequence.pad_sequences(sequences, maxlen=None, dtype=’int32’, padding=’pre’, truncating=’pre’, value=0.) 

函数说明: 
将长为nb_samples的序列(标量序列)转化为形如(nb_samples,nb_timesteps)2D numpy array。如果提供了参数maxlen,nb_timesteps=maxlen,否则其值为最长序列的长度。其他短于该长度的序列都会在后部填充0以达到该长度。长于nb_timesteps的序列将会被截断,以使其匹配目标长度。padding和截断发生的位置分别取决于padding和truncating. 
参数:

sequences:浮点数或整数构成的两层嵌套列表

maxlen:None或整数,为序列的最大长度。大于此长度的序列将被截短,小于此长度的序列将在后部填0.

dtype:返回的numpy array的数据类型

padding:‘pre’或‘post’,确定当需要补0时,在序列的起始还是结尾补

truncating:‘pre’或‘post’,确定当需要截断序列时,从起始还是结尾截断

value:浮点数,此值将在填充时代替默认的填充值0


构建模型

神经网络通过层数的堆叠创建成,下面先说一下每一层的作用。

示例中,输入数据由字词-索引数组构成,要预测的标签是0或1(正面影评和负面影评)

第一层:Embedding层,该层会在整数编码的词汇表中查找每个字词-索引的嵌入向量,模型在接受训练时会学习这些向量,这些向量会向输出数组中添加一个维度,添加后的维度是(batch,sequence,embedding);

第二层:一个 GlobalAveragePooling1D 层通过对序列维度求平均值,针对每个样本返回一个长度固定的输出向量。这样,模型便能够以尽可能简单的方式处理各种长度的输入。

第三层:该长度固定的输出向量会传入一个全连接 (Dense) 层(包含 16 个隐藏单元)。

第四层:最后一层与单个输出节点密集连接。应用 sigmoid 激活函数后,结果是介于 0 到 1 之间的浮点值,表示概率或置信水平。

vocab_size = 10000

model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation=tf.nn.relu))
model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid))

model.summary()

输出如下:

损失函数和优化器

构建完了神经网络下面我们来定义一个损失函数和优化器

model.compile(optimizer=tf.train.AdamOptimizer(),
              loss='binary_crossentropy',
              metrics=['accuracy'])

创建验证集

创建数据集的目的是为了检测模型处理未见过的数据时的准确率,我们取总数据的20%也就是10000条数据来创建验证集。

x_val = train_data[:10000]
partial_x_train = train_data[10000:]

y_val = train_labels[:10000]
partial_y_train = train_labels[10000:]

训练模型并且评估模型

用有 512 个样本的小批次训练模型 40 个周期。这将对 x_train 和 y_train 张量中的所有样本进行 40 次迭代。在训练期间,监控模型在验证集的 10000 个样本上的损失和准确率,最后我们使用evaluate来查看模型的误差和准确率:

history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=40,
                    batch_size=512,
                    validation_data=(x_val, y_val),
                    verbose=1)
results = model.evaluate(test_data, test_labels)

print(results)

最后的输出结果如下:

由此可见我们的模型准确率为0.87,并不是很完美,如果采用更好的方法可能会对准确率有更大的提高。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二哥不像程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值