Tensorflow2.1入门(基于API)实战2

问题描述&数据集准备:

在做了之前的衣物分类教程以后,我们来看看第二个入门实战吧,同样是基于官方API的教程API传送门,希望能帮助到大家。
这次试用的数据集是一个电影评论数据集,数据集中一共有50000条文本,训练集测试集各占25000条,我们的目标是对评论进行二分类,分为消极评论与积极评论两类。跟上次一样,数据集不许要额外准备。

准备工作:

首先导入必要的包

from __future__ import absolute_import, division, print_function, unicode_literals
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)

word_index=imdb.get_word_index()

word_index={k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"]=0
word_index["<START>"]=1
word_index["<UNK>"]=2
word_index["<UNUSED>"]=3

在数据集的准备中,保留了评论中最常出现的10000个高频单词。
这里我们的数据集中,每条记录实际上并不是单词,而是单词对应的数字索引。官网上有将数字转化为文字的步骤,在这里我觉得并没有必要,所以就省略了。可以在上方的链接中自行查看。每一条记录大致长成这个样子:

print(train_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.....]

数据处理:

显然,在评论中每一条记录的长度并不相同,而在神经网络中的输入必须保证每条长度都一致,所以我们需要对记录进行预先处理。

train_data=keras.preprocessing.sequence.pad_sequences(train_data
,value=word_index["<PAD>"],padding='post',maxlen=256)
test_data=keras.preprocessing.sequence.pad_sequences(test_data
,value=word_index["<PAD>"],padding='post',maxlen=256)

查了一下官网API,关于keras.preprocessing.sequence.pad_sequences()

tf.keras.preprocessing.sequence.pad_sequences(
    sequences,
    maxlen=None,
    dtype='int32',
    padding='pre',
    truncating='pre',
    value=0.0
)

参数解释
sequences:这里对应的就是我们的train_data,这个数据集由数条记录组成,每条记录长度不同。
maxlen:设定的最大长度,为后面两个参数做准备
dtype:经过函数以后的输出sequences中的数据类型。
padding:若一条记录的长度小于maxlen,就进行补全。可以选择为’pre’在记录前补全,或‘post’在记录后补全。
truncating:若一条记录的长度大于maxlen,就进行删减。可以选择为‘pre’在记录前删改,或‘post’在记录后删改。
value:补全时使用得值。

搭建模型:

vocab_size=10000

model = keras.Sequential([
    keras.layers.Embedding(vocab_size, 16),
    keras.layers.GlobalAveragePooling1D(),
    keras.layers.Dense(16,activation='relu'),
    keras.layers.Dense(1,activation='sigmoid'),
    ])

model.summary()

搭建模型的代码中,Embedding()使用如下:

keras.layers.Embedding(input_dim, output_dim, embeddings_initializer='uniform', embeddings_regularizer=None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None)

Embedding是专门为了处理文字(单词)而设计的,这里给出几个参数的解释:
input_dim:词汇表的大小。我们这里所有的记录经筛选只涉及1000个词汇,转化为索引只有0~999,因此这里的参数是1000.
output_dim:我们将每个词汇已经转化为了索引的形式,例如brilliant对应索引12,经过这一层的处理以后brilliant将会对应一个长度为output_dim的序列。

GlobalAveragePooling1D()可以使模型以尽可能最简单的方式处理可变长度的输出。
对文本数据进行平均池化操作:
输入数据格式为:(batch_size, steps, features)
batch_size:表示本批次有多少条文本
steps:表示一个文本里面有是多少个单词
features:表示一个单词使用多少维度进行表示
输出数据格式为:(batch_size, features)

后续有两个全连接层,最后一层输出介于 0 与 1 之间的浮点数,表示概率或置信度。

模型配置:

这是一个二分类问题,所以在损失函数中使用二分类交叉熵。

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

获取验证集:

x_val = train_data[:10000]
partial_x_train = train_data[10000:]
y_val = train_labels[:10000]
partial_y_train = train_labels[10000:]

训练模型:

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

history中会记录训练模型中的所有细节,方便以后的查看。训练中以 512 的 mini-batch迭代 40 个epoch来训练模型。
batch_size:批次中含有的记录数量。若在梯度下降算法中用所有的记录计算损失,然后再梯度下降,会有很大的计算量。将数据分为若干批次,分批次进行梯度下降,可以减少计算量,加快训练速度。
epochs:训练的轮数。
verbose:可以是0,1,2。0无显示,1进度条, 2每一轮一行显示。

模型评估:

results = model.evaluate(test_data,  test_labels, verbose=2)
print(results)

图表显示:

之前我们已经获得了一个History对象,对象包含一个字典,现在可以利用history来生成图表。

history_dict = history.history
history_dict.keys()
import matplotlib.pyplot as plt

acc=history_dict['accuracy']
val_acc=history_dict['val_accuracy']
loss=history_dict['loss']
val_loss=history_dict['val_loss']

epochs=range(1,len(acc)+1)

plt.plot(epochs,loss,'bo',label='Training loss')
plt.plot(epochs,val_loss,'b',label='Vlidation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

plt.show()

显示训练损失与验证损失图表

plt.clf() 
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()

plt.show()

显示训练准确度与验证准确度图表

结语:

总的来说基于API写这个实战还是比较简单的,出现的几个比较难理解的地方有pad_sequences,Embedding,GlobalAveragePooling以及epochs,本篇并没有对这些函数进行很深入的探索,主要以应用为主,当掌握一定的实战技巧以后再回过头来理解这些可能会更容易些。如果大家在操作过程中发现代码有问题,欢迎留言丫!
Thanks♪(・ω・)ノ

发布了2 篇原创文章 · 获赞 3 · 访问量 578

猜你喜欢

转载自blog.csdn.net/weixin_44322824/article/details/104091813