RNN同时进行POS标记和情感分类?

时间:2018-05-21 19:37:16

标签: tensorflow machine-learning keras deep-learning recurrent-neural-network

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

我有大量英文句子数据,这些句子都标有POS标签和情绪(负面,中立,正面)。

是否有可能训练一个递归神经网络(vanilla RNN,GRU或LSTM)来学习两者 POS标记和情绪分类?当然,在测试期间,我想输入一个句子并让RNN一起生成POS标签和情绪的预测。

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

enter image description here

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

可能适用于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标签数量(针对单热编码标签)。

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

有很多方法可以做到这一点,但一种常见的方法是" fork"从一些早期阶段开始对模型进行新的讨论,并使这种说法产生额外的预测(通常称为"多任务"或"联合任务"学习)。 / p>

要做到这一点,我们将从Sequential开始,但重命名为base_model,以明确它在分支多个任务之前充当基本图层集。然后我们将使用Keras的函数语法来完成我们需要的每个分支,然后将它们组合在一起作为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时,您将为标签提供一个列表,其中包含两个与每个输出相关联的张量或标签数组。

您可以阅读有关多输出损耗和架构at the Keras docs on multi-input and multi-output models的更多信息。

最后,请注意,这是一个非常简单的模型(可能效果不佳 - 它仅用于说明)。如果您具有特定的POS特定或特定于情感的体系结构,则可以使用我们创建的辐条pos_spokesentiment_spoke来使其他层具有更复杂的网络拓扑。

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

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