【问题标题】:How to deal with length variations for text classification using CNN (Keras)如何使用 CNN (Keras) 处理文本分类的长度变化
【发布时间】:2016-10-01 13:41:12
【问题描述】:

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

【问题讨论】:

    标签: nlp deep-learning text-classification keras


    【解决方案1】:

    这里有三个选项:

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

    【讨论】:

    • 选项1和2在裁剪或填充后会影响文章的原意吗?
    • 可能会削减(没有那么多填充),但你真的需要阅读整篇新闻文章来了解它的要点吗?切割的不利程度取决于您的任务。
    • 关于 3,我认为如果您有序列到序列的问题,例如 pos 标记,这是正确的。在序列标签中,如情感分析或情感检测,我相信你必须在 Keras 中进行截断/填充才能使用 RNN 进行序列标签。
    • @pedrobisp 使用 RNN 绝对可以标记可变长度序列。
    • 您是否有任何示例代码,其中将可变长度序列作为 Keras 中的 RNN 的输入?到目前为止,我所看到的,您总是必须应用填充/截断才能获得相同大小的序列。
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      一种可能的解决方案是分批发送 1 个序列。

      n_batch = 1
      model.fit(X, y, epochs=1, batch_size=n_batch, verbose=1, shuffle=False)
      

      keras 官方 repo 上的这个问题提供了很好的见解和可能的解决方案:https://github.com/keras-team/keras/issues/85

      引用patyork的评论:

      有两种简单且最常用的处理方法:

      1. 分桶和填充

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

      1. 分桶

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

      【讨论】:

        【解决方案4】:

        我刚刚在 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_kept 长度。所以我同时使用填充和截断。 (填充 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 数组。

        【讨论】:

          猜你喜欢
          • 2019-12-06
          • 2018-08-20
          • 2018-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-06
          • 2016-12-01
          • 1970-01-01
          相关资源
          最近更新 更多