zoukankan      html  css  js  c++  java
  • 使用RNN对文本进行分类实践电影评论

    本教程在IMDB大型影评数据集 上训练一个循环神经网络进行情感分类。

    使用RNN对文本进行分类实践电影评论 (tensorflow2官方教程翻译)

     

    from __future__ import absolute_import, division, print_function, unicode_literals
    # !pip install tensorflow-gpu==2.0.0-alpha0
    import tensorflow_datasets as tfds
    import tensorflow as tf

    导入matplotlib并创建一个辅助函数来绘制图形

    import matplotlib.pyplot as plt
    def plot_graphs(history, string):
    plt.plot(history.history[string])
    plt.plot(history.history['val_'+string])
    plt.xlabel("Epochs")
    plt.ylabel(string)
    plt.legend([string, 'val_'+string])
    plt.show()

    1. 设置输入管道

    IMDB大型电影影评数据集是一个二元分类数据集,所有评论都有正面或负面的情绪标签。

    使用TFDS下载数据集,数据集附带一个内置的子字标记器

    dataset, info = tfds.load('imdb_reviews/subwords8k', with_info=True,
    as_supervised=True)
    train_dataset, test_dataset = dataset['train'], dataset['test']

    由于这是一个子字标记器,它可以传递任何字符串,并且标记器将对其进行标记。

    tokenizer = info.features['text'].encoder
    print ('Vocabulary size: {}'.format(tokenizer.vocab_size))
    Vocabulary size: 8185
    sample_string = 'TensorFlow is cool.'
    tokenized_string = tokenizer.encode(sample_string)
    print ('Tokenized string is {}'.format(tokenized_string))
    original_string = tokenizer.decode(tokenized_string)
    print ('The original string: {}'.format(original_string))
    assert original_string == sample_string
    Tokenized string is [6307, 2327, 4043, 4265, 9, 2724, 7975]
    The original string: TensorFlow is cool.

    如果字符串不在字典中,则标记生成器通过将字符串分解为子字符串来对字符串进行编码。

    for ts in tokenized_string:
    print ('{} ----> {}'.format(ts, tokenizer.decode([ts])))
    6307 ----> Ten
    2327 ----> sor
    4043 ----> Fl
    4265 ----> ow
    9 ----> is
    2724 ----> cool
    7975 ----> .
    BUFFER_SIZE = 10000
    BATCH_SIZE = 64
    train_dataset = train_dataset.shuffle(BUFFER_SIZE)
    train_dataset = train_dataset.padded_batch(BATCH_SIZE, train_dataset.output_shapes)
    test_dataset = test_dataset.padded_batch(BATCH_SIZE, test_dataset.output_shapes)

    2. 创建模型

    构建一个tf.keras.Sequential模型并从嵌入层开始,嵌入层每个字存储一个向量,当被调用时,它将单词索引的序列转换为向量序列,这些向量是可训练的,在训练之后(在足够的数据上),具有相似含义的词通常具有相似的向量。

    这种索引查找比通过tf.keras.layers.Dense层传递独热编码向量的等效操作更有效。

    递归神经网络(RNN)通过迭代元素来处理序列输入,RNN将输出从一个时间步传递到其输入端,然后传递到下一个时间步。

    tf.keras.layers.Bidirectional包装器也可以与RNN层一起使用。这通过RNN层向前和向后传播输入,然后连接输出。这有助于RNN学习远程依赖性。

    model = tf.keras.Sequential([
    tf.keras.layers.Embedding(tokenizer.vocab_size, 64),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
    ])
    # 编译Keras模型以配置训练过程:
    model.compile(loss='binary_crossentropy',
    optimizer='adam',
    metrics=['accuracy'])

    3. 训练模型

    history = model.fit(train_dataset, epochs=10,
    validation_data=test_dataset)
    ...
    Epoch 10/10
    391/391 [==============================] - 70s 180ms/step - loss: 0.3074 - accuracy: 0.8692 - val_loss: 0.5533 - val_accuracy: 0.7873
    test_loss, test_acc = model.evaluate(test_dataset)
    print('Test Loss: {}'.format(test_loss))
    print('Test Accuracy: {}'.format(test_acc))
    391/Unknown - 19s 47ms/step - loss: 0.5533 - accuracy: 0.7873Test Loss: 0.553319326714
    Test Accuracy: 0.787320017815

    上面的模型没有屏蔽应用于序列的填充。如果我们对填充序列进行训练,并对未填充序列进行测试,就会导致偏斜。理想情况下,模型应该学会忽略填充,但是正如您在下面看到的,它对输出的影响确实很小。

    如果预测 >=0.5,则为正,否则为负。

    def pad_to_size(vec, size):
    zeros = [0] * (size - len(vec))
    vec.extend(zeros)
    return vec
    def sample_predict(sentence, pad):
    tokenized_sample_pred_text = tokenizer.encode(sample_pred_text)
    if pad:
    tokenized_sample_pred_text = pad_to_size(tokenized_sample_pred_text, 64)
    predictions = model.predict(tf.expand_dims(tokenized_sample_pred_text, 0))
    return (predictions)
    # 对不带填充的示例文本进行预测
    sample_pred_text = ('The movie was cool. The animation and the graphics '
    'were out of this world. I would recommend this movie.')
    predictions = sample_predict(sample_pred_text, pad=False)
    print (predictions)
    [[ 0.68914342]]
    # 对带填充的示例文本进行预测
    sample_pred_text = ('The movie was cool. The animation and the graphics '
    'were out of this world. I would recommend this movie.')
    predictions = sample_predict(sample_pred_text, pad=True)
    print (predictions)
    [[ 0.68634349]]
    plot_graphs(history, 'accuracy')
    使用RNN对文本进行分类实践电影评论 (tensorflow2官方教程翻译)

     

    plot_graphs(history, 'loss')
    使用RNN对文本进行分类实践电影评论 (tensorflow2官方教程翻译)

     

    4. 堆叠两个或更多LSTM层

    Keras递归层有两种可以用的模式,由return_sequences构造函数参数控制:

    • 返回每个时间步的连续输出的完整序列(3D张量形状 (batch_size, timesteps, output_features))。
    • 仅返回每个输入序列的最后一个输出(2D张量形状 (batch_size, output_features))。
    model = tf.keras.Sequential([
    tf.keras.layers.Embedding(tokenizer.vocab_size, 64),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(
    64, return_sequences=True)),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
    ])
    model.compile(loss='binary_crossentropy',
    optimizer='adam',
    metrics=['accuracy'])
    history = model.fit(train_dataset, epochs=10,
    validation_data=test_dataset)
    ...
    Epoch 10/10
    391/391 [==============================] - 154s 394ms/step - loss: 0.1120 - accuracy: 0.9643 - val_loss: 0.5646 - val_accuracy: 0.8070
    test_loss, test_acc = model.evaluate(test_dataset)
    print('Test Loss: {}'.format(test_loss))
    print('Test Accuracy: {}'.format(test_acc))
    391/Unknown - 45s 115ms/step - loss: 0.5646 - accuracy: 0.8070Test Loss: 0.564571284348
    Test Accuracy: 0.80703997612
    # 在没有填充的情况下预测示例文本
    sample_pred_text = ('The movie was not good. The animation and the graphics '
    'were terrible. I would not recommend this movie.')
    predictions = sample_predict(sample_pred_text, pad=False)
    print (predictions)
    [[ 0.00393916]]
    # 在有填充的情况下预测示例文本
    sample_pred_text = ('The movie was not good. The animation and the graphics '
    'were terrible. I would not recommend this movie.')
    predictions = sample_predict(sample_pred_text, pad=True)
    print (predictions)
    [[ 0.01098633]]
    plot_graphs(history, 'accuracy')
    使用RNN对文本进行分类实践电影评论 (tensorflow2官方教程翻译)

     

    plot_graphs(history, 'loss')
    使用RNN对文本进行分类实践电影评论 (tensorflow2官方教程翻译)

     

    你可以查看其它现有的递归层,例如GRU层。

  • 相关阅读:
    【程序员面试宝典】第五章 程序设计基本概念
    win7打开或关闭windows功能 提示“出现错误,并非所有的功能被更改”,管理员权限惹的祸
    堆排序
    目态与管态的概念
    循环不变式的概念
    getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析
    java算法 -- 冒泡排序
    Java算法 -- 二分查找
    Sql知识点总结
    java实现 链表反转
  • 原文地址:https://www.cnblogs.com/cuiyubo/p/10981835.html
Copyright © 2011-2022 走看看