本教程在IMDB大型影评数据集 上训练一个循环神经网络进行情感分类。
x1from __future__ import absolute_import, division, print_function, unicode_literals
2
3# !pip install tensorflow-gpu==2.0.0-alpha0
4import tensorflow_datasets as tfds
5import tensorflow as tf
导入matplotlib并创建一个辅助函数来绘制图形
xxxxxxxxxx
101import matplotlib.pyplot as plt
2
3
4def plot_graphs(history, string):
5 plt.plot(history.history[string])
6 plt.plot(history.history['val_'+string])
7 plt.xlabel("Epochs")
8 plt.ylabel(string)
9 plt.legend([string, 'val_'+string])
10 plt.show()
IMDB大型电影影评数据集是一个二元分类数据集,所有评论都有正面或负面的情绪标签。
使用TFDS下载数据集,数据集附带一个内置的子字标记器
xxxxxxxxxx
31dataset, info = tfds.load('imdb_reviews/subwords8k', with_info=True,
2 as_supervised=True)
3train_dataset, test_dataset = dataset['train'], dataset['test']
由于这是一个子字标记器,它可以传递任何字符串,并且标记器将对其进行标记。
xxxxxxxxxx
31tokenizer = info.features['text'].encoder
2
3print ('Vocabulary size: {}'.format(tokenizer.vocab_size))
xxxxxxxxxx
11Vocabulary size: 8185
xxxxxxxxxx
91sample_string = 'TensorFlow is cool.'
2
3tokenized_string = tokenizer.encode(sample_string)
4print ('Tokenized string is {}'.format(tokenized_string))
5
6original_string = tokenizer.decode(tokenized_string)
7print ('The original string: {}'.format(original_string))
8
9assert original_string == sample_string
xxxxxxxxxx
21Tokenized string is [6307, 2327, 4043, 4265, 9, 2724, 7975]
2The original string: TensorFlow is cool.
如果字符串不在字典中,则标记生成器通过将字符串分解为子字符串来对字符串进行编码。
xxxxxxxxxx
21for ts in tokenized_string:
2 print ('{} ----> {}'.format(ts, tokenizer.decode([ts])))
xxxxxxxxxx
716307 ----> Ten
22327 ----> sor
34043 ----> Fl
44265 ----> ow
59 ----> is
62724 ----> cool
77975 ----> .
xxxxxxxxxx
71BUFFER_SIZE = 10000
2BATCH_SIZE = 64
3
4train_dataset = train_dataset.shuffle(BUFFER_SIZE)
5train_dataset = train_dataset.padded_batch(BATCH_SIZE, train_dataset.output_shapes)
6
7test_dataset = test_dataset.padded_batch(BATCH_SIZE, test_dataset.output_shapes)
构建一个tf.keras.Sequential
模型并从嵌入层开始,嵌入层每个字存储一个向量,当被调用时,它将单词索引的序列转换为向量序列,这些向量是可训练的,在训练之后(在足够的数据上),具有相似含义的词通常具有相似的向量。
这种索引查找比通过tf.keras.layers.Dense
层传递独热编码向量的等效操作更有效。
递归神经网络(RNN)通过迭代元素来处理序列输入,RNN将输出从一个时间步传递到其输入端,然后传递到下一个时间步。
tf.keras.layers.Bidirectional
包装器也可以与RNN层一起使用。这通过RNN层向前和向后传播输入,然后连接输出。这有助于RNN学习远程依赖性。
xxxxxxxxxx
111model = tf.keras.Sequential([
2 tf.keras.layers.Embedding(tokenizer.vocab_size, 64),
3 tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
4 tf.keras.layers.Dense(64, activation='relu'),
5 tf.keras.layers.Dense(1, activation='sigmoid')
6])
7
8# 编译Keras模型以配置训练过程:
9model.compile(loss='binary_crossentropy',
10 optimizer='adam',
11 metrics=['accuracy'])
xxxxxxxxxx
21history = model.fit(train_dataset, epochs=10,
2 validation_data=test_dataset)
xxxxxxxxxx
31...
2Epoch 10/10
3391/391 [==============================] - 70s 180ms/step - loss: 0.3074 - accuracy: 0.8692 - val_loss: 0.5533 - val_accuracy: 0.7873
xxxxxxxxxx
41test_loss, test_acc = model.evaluate(test_dataset)
2
3print('Test Loss: {}'.format(test_loss))
4print('Test Accuracy: {}'.format(test_acc))
xxxxxxxxxx
21391/Unknown - 19s 47ms/step - loss: 0.5533 - accuracy: 0.7873Test Loss: 0.553319326714
2Test Accuracy: 0.787320017815
上面的模型没有屏蔽应用于序列的填充。如果我们对填充序列进行训练,并对未填充序列进行测试,就会导致偏斜。理想情况下,模型应该学会忽略填充,但是正如您在下面看到的,它对输出的影响确实很小。
如果预测 >=0.5,则为正,否则为负。
xxxxxxxxxx
141def pad_to_size(vec, size):
2 zeros = [0] * (size - len(vec))
3 vec.extend(zeros)
4 return vec
5
6def sample_predict(sentence, pad):
7 tokenized_sample_pred_text = tokenizer.encode(sample_pred_text)
8
9 if pad:
10 tokenized_sample_pred_text = pad_to_size(tokenized_sample_pred_text, 64)
11
12 predictions = model.predict(tf.expand_dims(tokenized_sample_pred_text, 0))
13
14 return (predictions)
xxxxxxxxxx
61# 对不带填充的示例文本进行预测
2
3sample_pred_text = ('The movie was cool. The animation and the graphics '
4 'were out of this world. I would recommend this movie.')
5predictions = sample_predict(sample_pred_text, pad=False)
6print (predictions)
xxxxxxxxxx
11[[ 0.68914342]]
xxxxxxxxxx
61# 对带填充的示例文本进行预测
2
3sample_pred_text = ('The movie was cool. The animation and the graphics '
4 'were out of this world. I would recommend this movie.')
5predictions = sample_predict(sample_pred_text, pad=True)
6print (predictions)
xxxxxxxxxx
11[[ 0.68634349]]
xxxxxxxxxx
11plot_graphs(history, 'accuracy')
xxxxxxxxxx
11plot_graphs(history, 'loss')
Keras递归层有两种可以用的模式,由return_sequences
构造函数参数控制:
(batch_size, timesteps, output_features)
)。(batch_size, output_features)
)。xxxxxxxxxx
151model = tf.keras.Sequential([
2 tf.keras.layers.Embedding(tokenizer.vocab_size, 64),
3 tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(
4 64, return_sequences=True)),
5 tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
6 tf.keras.layers.Dense(64, activation='relu'),
7 tf.keras.layers.Dense(1, activation='sigmoid')
8])
9
10model.compile(loss='binary_crossentropy',
11 optimizer='adam',
12 metrics=['accuracy'])
13
14history = model.fit(train_dataset, epochs=10,
15 validation_data=test_dataset)
xxxxxxxxxx
31...
2Epoch 10/10
3391/391 [==============================] - 154s 394ms/step - loss: 0.1120 - accuracy: 0.9643 - val_loss: 0.5646 - val_accuracy: 0.8070
xxxxxxxxxx
41test_loss, test_acc = model.evaluate(test_dataset)
2
3print('Test Loss: {}'.format(test_loss))
4print('Test Accuracy: {}'.format(test_acc))
xxxxxxxxxx
21391/Unknown - 45s 115ms/step - loss: 0.5646 - accuracy: 0.8070Test Loss: 0.564571284348
2Test Accuracy: 0.80703997612
xxxxxxxxxx
61# 在没有填充的情况下预测示例文本
2
3sample_pred_text = ('The movie was not good. The animation and the graphics '
4 'were terrible. I would not recommend this movie.')
5predictions = sample_predict(sample_pred_text, pad=False)
6print (predictions)
xxxxxxxxxx
11[[ 0.00393916]]
xxxxxxxxxx
61# 在有填充的情况下预测示例文本
2
3sample_pred_text = ('The movie was not good. The animation and the graphics '
4 'were terrible. I would not recommend this movie.')
5predictions = sample_predict(sample_pred_text, pad=True)
6print (predictions)
xxxxxxxxxx
11[[ 0.01098633]]
xxxxxxxxxx
11plot_graphs(history, 'accuracy')
xxxxxxxxxx
11plot_graphs(history, 'loss')
查看其它现有的递归层,例如GRU层。
最新版本:https://www.mashangxue123.com/tensorflow/tf2-tutorials-text-text_classification_rnn.html 英文版本:https://tensorflow.google.cn/beta/tutorials/text/text_classification_rnn 翻译建议PR:https://github.com/mashangxue/tensorflow2-zh/edit/master/r2/tutorials/text/text_classification_rnn.md