如何使用CNN(Keras)处理文本分类中的长度变化问题

11

已经证明了卷积神经网络(CNN)在文本/文档分类方面非常有用。我想知道如何处理文章长度差异,因为大多数情况下文章的长度是不同的。Keras 中是否有任何示例? 谢谢!

4个回答

3

以下是三个选项:

  1. 裁剪较长的文章。
  2. 填充较短的文章。
  3. 使用循环神经网络,自然支持可变长度的输入。

可能会有一些删减(不太多的填充),但你真的需要阅读整篇新闻文章才能理解要点吗?删减的劣势取决于你的任务。 - 1''
关于第三点,如果你有一个序列到序列的问题,比如词性标注,我认为这是正确的。在序列标注中,比如情感分析或情绪检测,我相信你必须在Keras中进行截断/填充,以便使用RNN进行序列标注。 - pedrobisp
@pedrobisp 使用递归神经网络(RNN),对变长序列进行标记化处理绝对是可行的。 - 1''
@pedrobisp 我对keras和深度学习真的很新,你能给我解释一下为什么“情感分析或情绪检测”需要截断/填充吗? - Mithril
这与情感分析任务无关。我们正在谈论Keras中的RNN实现。 - pedrobisp
显示剩余3条评论

3

2
一种可能的解决方案是将您的序列分批发送,每批只包含一个序列。
n_batch = 1
model.fit(X, y, epochs=1, batch_size=n_batch, verbose=1, shuffle=False)

此问题在官方的 Keras 存储库上提供了很好的见解和可能的解决方案:https://github.com/keras-team/keras/issues/85 引用 patyork 的评论:
有两种简单且常用的处理方式:
1. 桶派和填充
将输入样本分成具有相似长度的桶,最好使每个桶都有一定数量的样本,这些样本是 mini-batch 大小的倍数。对于每个桶,在其中最长的样本的长度处使用中性数字填充样本。0 是频繁出现的数字,但对于像语音数据这样的东西,使用表示沉默的表示形式通常不是零(例如,使用静音音频部分的 FFT 作为中性填充)。
2. 桶派
将输入样本分成完全相同长度的桶可以消除确定中性填充的需要,但是在这种情况下,桶的大小通常不会是 mini-batch 大小的倍数,因此在每个 epoch 中,多次更新将不基于完整的 mini-batch。

0

我刚刚使用Keras的LSTM RNN模型创建了一个模型。它强制我填充我的输入(即句子)。然而,我只是添加了一个空字符串到句子中,直到它达到所需的长度。可能等于具有最大长度(以单词计)的特征的长度。然后,我能够使用glove将我的特征转换为向量空间,然后通过我的模型运行。

def getWordVector(X):
    global num_words_kept
    global word2vec
    global word_vec_dim

    input_vector = []
    for row in X:
        words = row.split()
        if len(words) > num_words_kept:
            words = words[:num_words_kept]
        elif len(words) < num_words_kept:
            for i in range(num_words_kept - len(words)):
                words.append("")
        input_to_vector = []
        for word in words:
            if word in word2vec:
                input_to_vector.append(np.array(word2vec[word]).astype(np.float).tolist())#multidimensional wordvecor
            else:
                input_to_vector.append([5.0] * word_vec_dim)#place a number that is far different than the rest so as not to be to similar
        input_vector.append(np.array(input_to_vector).tolist())
    input_vector = np.array(input_vector)
    return input_vector

其中X是句子列表,该函数将返回每个数组中的特征的长度为num_words_kept的单词向量(使用glove的word_to_vec)。因此,我同时使用填充和截断。(填充用于Keras实现,截断是因为当输入大小差异如此之大时,Keras也会出现问题。我不完全确定原因。当我开始对某些句子进行填充时,有些句子会添加超过100个空字符串,导致出现了问题。)

X = getWordVectors(features)
y = to_categorical(y)# for categorical_crossentropy
model.fit(X, y, batch_size=16, epochs=5, shuffle=False)

Keras 要求在输入数据之前使用 numpy 数组,因此我的特征和标签都是 numpy 数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接