首页 > 解决方案 > 具有同时 POS 标记和情感分类的 RNN?

问题描述

我正在解决一个需要同时执行词性 (POS) 标记和情绪分析的问题。我正在使用 Tensorflow 并正在考虑使用 Keras。

我有大量的英语句子数据集,这些句子都用词性标签和情绪(消极、中性、积极)进行了标记。

是否可以训练一个循环神经网络(vanilla RNN、GRU 或 LSTM)来学习POS 标记和情感分类当然,在测试期间,我想输入一个句子,让 RNN 同时为 POS 标签和情绪生成预测。

我正在考虑以下 RNN 架构。我不确定是否可以使用 Tensorflow(我一直在使用)或 Keras(我现在正在学习)。我之前实现过执行一项任务而不是两项任务的 RNN。

在此处输入图像描述

谢谢你的帮助。

标签: tensorflowmachine-learningkerasdeep-learningrecurrent-neural-network

解决方案


一个可能适用于 POS 标记的非常简单的 Keras 模型可能如下所示:

from keras.layers import Dense, LSTM
from keras.models import Model, Sequential


model = Sequential()
model.add(
    LSTM(
        hidden_layer_size,
        return_sequences=True,
        input_shape=(seq_length, nb_words),
        unroll=True
    )
)
model.add(Dense(nb_pos_types, activation="softmax"))
model.compile(loss="categorical_crossentropy", optimizer="rmsprop")

我假设各种参数:

  • hidden_layer_size:内部循环层的任何维度。
  • seq_length: 输入序列长度。
  • nb_words:词汇量大小,用于单热编码输入,详细说明哪个单词对应哪个序列位置。
  • nb_pos_types: 不同可能的 POS 标签的数量(对于 one-hot 编码标签)。

目标是修改这样一个简单的网络,以便它也可以对情绪进行预测(不清楚你的情绪是分数还是类别标签,但我会假设一个类别标签),因此损失函数包括该情绪预测的惩罚项。

有很多方法可以做到这一点,但一种常见的方法是从某个早期层“分叉”模型的新辐条,并让该辐条产生额外的预测(通常称为“多任务”或“联合-任务”学习)。

为此,我们将从 开始Sequential,但将其重命名为base_model清楚地表明它在为多个任务分支之前用作基础层集。然后我们将使用 Keras 的函数式语法对每个分支执行我们需要的操作,然后将它们组合在一起作为 a 的多个输出final_model,其中我们可以表达每个输出的整体损失函数的一部分。

下面是我们如何修改上面的例子来做到这一点:

base_model = Sequential()
base_model.add(
    LSTM(
        hidden_layer_size,
        return_sequences=True,
        input_shape=(seq_length, nb_words),
        unroll=True
    )
)

# Get a handle to the output of the recurrent layer.
rec_output = base_model.outputs[0]

# Create a layer representing the POS prediction.
pos_spoke = Dense(nb_pos_types, activation="softmax", 
                  name="pos")(rec_output)

# Create a layer representing the sentiment prediction.
# I assume `nb_sentiments` is the number of sentiment categories.
sentiment_spoke = Dense(nb_sentiments, activation="softmax", 
                        name="sentiment")(rec_output)

# Reunify into a single model which takes the same inputs as
# determined for `base_model`, and provides a list of 2 outputs,
# one for each spoke (POS and sentiment).
final_model = Model(inputs=base_model.inputs, 
                    outputs=[pos_spoke, sentiment_spoke])

# Finally, use a dictionary for the loss function to specify the
# loss for each output, and optionally separate weights for when
# the losses are added as a weighted sum for the total loss.    
final_model.compile(
    optimizer='rmsprop',
    loss={'pos': 'categorical_crossentropy', 
          'sentiment': 'categorical_crossentropy'},
    loss_weights={'pos': 1.0, 'sentiment': 1.0}
)

最后,在调用 时final_model.fit,您将为标签提供一个列表,其中包含与每个输出相关联的两个张量或标签数组。

您可以在 Keras 文档中的多输入和多输出模型中阅读更多关于多输出损失和架构的信息。

最后,请注意这是一个非常简单的模型(并且可能表现不佳——它仅用于说明)。如果您有特定的 POS 特定或情绪特定的架构,您可以使用我们创建的辐条,pos_spoke并拥有具有更复杂网络拓扑的附加层。sentiment_spoke

与其直接将它们定义为Dense,不如将它们定义为额外的循环层,甚至可能是卷积层等,然后是一些最终Dense层,其变量名称和层名称将用于输出和损失中的适当位置。

还要注意return_sequences=True这里的使用。这允许在序列中的每个步骤进行 POS情绪预测,即使您可能只关心最后的情绪预测。一个可能的选项是修改为仅对来自 的最终序列元素进行操作,或者另一个(不太可能)选项是为输入序列中的每个单词重复句子的整体情感标签。sentiment_spokerec_output


推荐阅读