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



已经证明,CNN(卷积神经网络)对文本/文档分类非常有用。我想知道如何处理长度差异,因为在大多数情况下,文章的长度是不同的。喀拉拉邦有什么例子吗?谢谢

这里有三个选项:

  1. 裁剪较长的文章
  2. 把较短的文章垫起来
  3. 使用递归神经网络,它自然支持可变长度的输入

您可以在这里看到一个具体的示例:https://github.com/fchollet/keras/blob/master/examples/imdb_cnn.py

一个可能的解决方案是以1为一批的方式发送序列。

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. 屈曲和衬垫

将输入样本分离到具有长度相似,理想情况下每个桶都有多个样本这是小批量大小的倍数对于每个桶,填充样本长度为该桶中最长样本的长度中性数字。0是频繁的,但对于类似语音数据的东西,使用通常不是零的静默表示(例如音频的无声部分的FFT被用作中性填充)。

  1. 屈曲

将输入样本分离到完全相同的桶中长度消除了确定什么是中性填充的需要然而,在这种情况下,bucket的大小通常不会是小批量大小的倍数,因此在每个epoch中更新将不会基于完整的小批量。

我刚刚在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是句子列表,此函数将返回一个单词向量(使用glove的word_to_vec),其中每个特征的长度为num_words_keep。所以我同时使用填充和截断。(填充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数组。

最新更新