Tensorflow——循环神经网络(二)序列式问题

作者: cnpim CNPIM 2023年06月01日

在上一篇文章中,我们介绍了数据padding,Embedding与变长输入的处理的问题,并且使用Embedding解决文本分类的问题

今天我们来解释为什么需要循环神经网络和循环神经网络的结构,并且使用循环神经网络来进行文本分类。


  • 2.1 序列问题
    • 2.1.1 为什么需要循环神经网络——合并+padding的缺点?
      • 信息丢失
        • 多个embedding合并
        • Pad噪音、无主次
      • 无效计算太多、抵消
        • 太多的padding
    • 2.1.2 为什么需要循环神经网络——序列式问题
      • 普通神经网络 Tensorflow——循环神经网络(二)序列式问题
      • 1对多:图片生成描述 Tensorflow——循环神经网络(二)序列式问题
      • 多对1:文本分类(文本情感分析) Tensorflow——循环神经网络(二)序列式问题
      • 多对多:encoding-decoding机器翻译 Tensorflow——循环神经网络(二)序列式问题
      • 实时多对多:视频解说 Tensorflow——循环神经网络(二)序列式问题
    • 2.1.3 循环神经网络
      • Tensorflow——循环神经网络(二)序列式问题
    • 维护一个状态作为下一步的额外输出
    • 每一步使用同样的激活函数和参数 Tensorflow——循环神经网络(二)序列式问题
    • 最简单的循环神经网络 Tensorflow——循环神经网络(二)序列式问题
    • 循环神经网络的列子
      • Tensorflow——循环神经网络(二)序列式问题
      • Tensorflow——循环神经网络(二)序列式问题
    • Tensorflow——循环神经网络(二)序列式问题
  • 2.2 循环神经网络文本分类

    • 2.2.1 定义一个1层单层单向的rnn,2层全连接层的模型
embedding_dim = 16batch_size = 512single_rnn_model = keras.models.Sequential([    # 1. define matrix: [vocab_size, embedding_dim]    # 2. [1,2,3,4..], max_length * embedding_dim    # 3. batch_size * max_length * embedding_dim    keras.layers.Embedding(vocab_size, embedding_dim,                           input_length = max_length),    # return_sequences: 决定你返回的输出(False)是最后一步的输出,还是所有的输出    keras.layers.SimpleRNN(units = 64, return_sequences = False),    keras.layers.Dense(64, activation = 'relu'),    keras.layers.Dense(1, activation='sigmoid'),])single_rnn_model.summary()single_rnn_model.compile(optimizer = 'adam',                         loss = 'binary_crossentropy',                         metrics = ['accuracy'])
Model: "sequential"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================embedding (Embedding)        (None, 500, 16)           160000    _________________________________________________________________simple_rnn (SimpleRNN)       (None, 64)                5184      _________________________________________________________________dense (Dense)                (None, 64)                4160      _________________________________________________________________dense_1 (Dense)              (None, 1)                 65        =================================================================Total params: 169,409Trainable params: 169,409Non-trainable params: 0

训练模型:

history_single_rnn = single_rnn_model.fit(    train_data, train_labels,    epochs = 30,    batch_size = batch_size,    validation_split = 0.2)

在训练30次之后,发现accuracy是0.4990,这对于一个二分类问题来说是没有进展的,因为做随机猜测的话,accuracy也有50%。

这说明普通的单层rnn并没有效果。

打印学习曲线

def plot_learning_curves(history, label, epochs, min_value, max_value):    data = {}    data[label] = history.history[label]    data['val_'+label] = history.history['val_'+label]    pd.DataFrame(data).plot(figsize=(8, 5))    plt.grid(True)    plt.axis([0, epochs, min_value, max_value])    plt.show()    plot_learning_curves(history_single_rnn, 'accuracy', 30, 0, 1)plot_learning_curves(history_single_rnn, 'loss', 30, 0, 1)

运行结果:

Tensorflow——循环神经网络(二)序列式问题

Tensorflow——循环神经网络(二)序列式问题 在测试集上的效果:

single_rnn_model.evaluate(    test_data, test_labels,    batch_size = batch_size,    verbose = 0)

运行结果:

[0.7533659934997559, 0.5001599788665771]
  • 2.2.2 实现一个双层双向的rnn,2层全连接层的模型
    • 只需要使用Bidirectional对RNN进行一个封装,封装完之后就是一个双向的RNN
embedding_dim = 16batch_size = 512model = keras.models.Sequential([    # 1. define matrix: [vocab_size, embedding_dim]    # 2. [1,2,3,4..], max_length * embedding_dim    # 3. batch_size * max_length * embedding_dim    keras.layers.Embedding(vocab_size, embedding_dim,                           input_length = max_length),    keras.layers.Bidirectional(        keras.layers.SimpleRNN(            units = 64, return_sequences = True)),    # return_sequences改为True的原因:下一个RNN的输入是序列,而不是单个的输入    keras.layers.Bidirectional(        keras.layers.SimpleRNN(            units = 64, return_sequences = False)),    keras.layers.Dense(64, activation = 'relu'),    keras.layers.Dense(1, activation='sigmoid'),])model.summary()model.compile(optimizer = 'adam',              loss = 'binary_crossentropy',              metrics = ['accuracy'])

运行结果:

Model: "sequential"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================embedding (Embedding)        (None, 500, 16)           160000    _________________________________________________________________bidirectional (Bidirectional (None, 500, 128)          10368     _________________________________________________________________bidirectional_1 (Bidirection (None, 128)               24704     _________________________________________________________________dense (Dense)                (None, 64)                8256      _________________________________________________________________dense_1 (Dense)              (None, 1)                 65        =================================================================Total params: 203,393Trainable params: 203,393Non-trainable params: 0_________________________________________________________________

训练模型:

history = model.fit(    train_data, train_labels,    epochs = 30,    batch_size = batch_size,    validation_split = 0.2)

可以发现,在训练集上的accuracy是1.0,但是在验证集上的accuracy只有0.5572,也只比单层RNN好了一点点

打印学习曲线:

plot_learning_curves(history, 'accuracy', 30, 0, 1)plot_learning_curves(history, 'loss', 30, 0, 3.8)

运行结果:

Tensorflow——循环神经网络(二)序列式问题 Tensorflow——循环神经网络(二)序列式问题发现在训练集上accuracy非常好,但是在验证集上的accuracy不太好,这说明模型在训练集上过拟合了

这次的模型定义的是一个双层双向的RNN,模型太复杂了

  • 2.2.3 实现一个单层双向的rnn,2层全连接层的模型
embedding_dim = 16batch_size = 512bi_rnn_model = keras.models.Sequential([    # 1. define matrix: [vocab_size, embedding_dim]    # 2. [1,2,3,4..], max_length * embedding_dim    # 3. batch_size * max_length * embedding_dim    keras.layers.Embedding(vocab_size, embedding_dim,                           input_length = max_length),    keras.layers.Bidirectional(        keras.layers.SimpleRNN(            units = 32, return_sequences = False)),    keras.layers.Dense(32, activation = 'relu'),    keras.layers.Dense(1, activation='sigmoid'),])bi_rnn_model.summary()bi_rnn_model.compile(optimizer = 'adam',                     loss = 'binary_crossentropy',                     metrics = ['accuracy'])

运行结果:

Model: "sequential"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================embedding (Embedding)        (None, 500, 16)           160000    _________________________________________________________________bidirectional (Bidirectional (None, 64)                3136      _________________________________________________________________dense (Dense)                (None, 32)                2080      _________________________________________________________________dense_1 (Dense)              (None, 1)                 33        =================================================================Total params: 165,249Trainable params: 165,249Non-trainable params: 0_________________________________________________________________

训练模型:

history = bi_rnn_model.fit(    train_data, train_labels,    epochs = 30,    batch_size = batch_size,    validation_split = 0.2)

可以发现:在训练集上的accuracy达到了1.0,在测试集上的accur达到了0.7888,比双层双向的模型要好很多

打印学习曲线:

plot_learning_curves(history, 'accuracy', 30, 0, 1.1)plot_learning_curves(history, 'loss', 30, 0, 2.5)

运行结果:

Tensorflow——循环神经网络(二)序列式问题

Tensorflow——循环神经网络(二)序列式问题

虽然在验证集上的效果要好很多,但是依然由过拟合的现象存在。

在测试集上进行评估:

bi_rnn_model.evaluate(test_data, test_labels, batch_size = batch_size, verbose = 0)

运行结果:

[1.404372215270996, 0.7716000080108643]
  • 可以发现:训练集上的accuracy是0.7716,相较于之前的简单模型的accur是0.85,那么这是说明循环神经网络比普通的神经网络还要弱吗?
    • 可以仔细看一下loss的曲线图,发现循环神经网络在训练第5次的时候,val_loss急剧上升,而在普通神经网络中在训练第10次的时候,val_loss急剧上升,这说明循环神经网络的过拟合更加明显,它的过拟合更加明显反而说明了这个模型更加强大。
    • 在搭建模型的过程中,使用了一种方法来缓解过拟合,就是降低模型尺寸,把两层循环神经网络变成单层的;在搭建模型的时候,还有其他手段来缓解过拟合,比如dropout,正则化项等。


本文阅读量:

声明:本信息来源于网络,仅用于学习和技术交流,如有侵权或其他问题,请联系本站处理。

技术支持:CNPIM.COM