【问题标题】:Keras dataset has different vector length for train and test setsKeras 数据集对于训练集和测试集具有不同的向量长度
【发布时间】:2018-12-22 09:18:32
【问题描述】:

我正在尝试使用来自keras.datasets 的路透社和 imdb 数据集。标准调用是:

(x_train, y_train), (x_test, y_test) = imdb.load_data(path="imdb.npz",
                                                  num_words=None,
                                                  skip_top=0,
                                                  maxlen=None,
                                                  seed=113,
                                                  start_char=1,
                                                  oov_char=2,
                                                  index_from=3)

当我检查维度时,训练数据集给出 (25000, 10922),这很有意义。但是测试给出了(25000,)。如果您转储像x_test[0] 这样的单个测试数据集元素,它会给出一个列表而不是numpy.array。问题是每一行的列表维度都会发生变化,并且总是与训练向量维度不同。您应该如何将其用作测试数据?

【问题讨论】:

  • 我猜可能测试列表只是没有频率的单词索引?
  • 训练和测试数据集的形状均为(25000,)
  • @bhomass 我的回答有什么模棱两可的地方吗?
  • 是的,你是对的。有一条线我忽略了。 x_train = np.array([np.bincount(doc, minlength=V) for doc in x_train])

标签: python list keras dataset numpy-ndarray


【解决方案1】:

好吧,正如您提到的,x_trainx_test 中的每个元素都是一个列表。该列表包含句子(或段落或在本例中为评论)的单词索引,并且由于句子可能具有不同数量的单词,因此该相应表示也具有可变长度。让我们解码其中一个句子,看看它是什么样子,并更加熟悉数据集:

from keras.datasets import imdb

(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=10000)

# a mapping from words to their indices, for example `human`: 403
word_index = imdb.get_word_index()

# create the reverse mapping i.e. from indices to words
rev_word_index = {idx:w for w,idx in word_index.items()}

def decode_sentence(s):
    # index 0 to 2 are reserved for things like padding, unknown word, etc.
    decoded_sent = [rev_word_index.get(idx-3, '[RES]') for idx in s]
    return ' '.join(decoded_sent)

print(decode_sentence(x_train[100]))

以人类可读的形式输出选定的评论:

[RES] 我是大卫·林奇的忠实粉丝,拥有他所拥有的一切 用 DVD 制作,除了酒店房间 2 小时双峰电影,所以什么时候 我发现了这一点,我立即抓住了它,这是什么 这是一堆 [RES] 绘制的黑白卡通,声音响亮, 嘴巴脏而且不好玩也许我不知道什么是好的但也许这个 只是一堆以 [RES] 名义向公众公开的废话 大卫林奇也为了赚几块钱让我明确表示我没有 关心粗话部分但必须保持[RES]声音 因为我的邻居可能有这一切 令人失望的发布,很可能刚刚被留在 [RES] 盒子作为一种好奇心,我强烈建议你不要花钱 在这 10 人中有 2 人

这些数据的使用完全取决于您和您要解决的问题。您可以将句子原样提供给可以处理可变长度句子的网络。这通常由一维卷积层或 LSTM 层或两者的混合组成。另一种方法是通过将所有句子编码为固定长度编码来使它们具有相同的长度。下面是一个例子,one-hot 将每个句子编码为一个 0 和 1 的向量,所有句子的长度都是固定的:

from keras.datasets import imdb
import numpy as np

# you can limit the vocabulary size by passing `num_words` argument 
# to ignore rare words and make data more manageable
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=10000)

def encode_sentences(sentences, dim):
    encodings = np.zeros((len(sentences), dim))
    for idx, sentence in enumerate(sentences):
        encodings[idx, sentence] = 1.0
    return encodings

x_train = encode_sentences(x_train, 10000)
x_test = encode_sentences(x_test, 10000)

print(x_train.shape)
print(x_test.shape)

哪个输出:

(25000, 10000)
(25000, 10000)

所有句子都被编码为一个长度为 10000 的向量,其中该向量的第 i 个元素表示索引为 i 的单词是否存在于相应的句子中。

另一种方法是截断或填充句子以使它们的长度相同。这是一个例子:

from keras.datasets import imdb
from keras import preprocessing

n_feats = 10000   # maximum number of words we want to consider in our vocabulary
max_len = 500     # maximum length of each sentence (i.e. truncate those longer
                  # than 500 words and pad those shorter than 500 words)

# you can limit the vocabulary size by passing `num_words` argument
# to ignore rare words and make it more manageable
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=n_feats)

# preprocess the sequences (i.e. truncate or pad)
x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=max_len)
x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=max_len)

print(x_train.shape)
print(x_test.shape)

哪个输出:

(25000, 500)
(25000, 500)

现在所有 25000 个句子的长度都相同,可以使用了。

我强烈推荐阅读the Keras documentation on this dataset

【讨论】:

  • 谢谢,示例中参数值的选择让我们更难理解数据集的行为。
猜你喜欢
  • 1970-01-01
  • 2017-04-05
  • 2020-06-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 2015-01-17
  • 2016-03-26
相关资源
最近更新 更多