【问题标题】:Embedding Layer in Keras: Vocab Size +1在 Keras 中嵌入层:词汇大小 +1
【发布时间】:2020-06-03 01:11:12
【问题描述】:

从我看到的一些例子中,当我们使用 keras 中的text_tokenizer 时,在为输入层指定输入大小时,我们使用词汇大小 +1。这自然会产生一个带有+1“行”的嵌入空间。

例如,我拟合了一个简单模型来估计大小为 3 = I like turtles 的词汇的嵌入向量。嵌入空间在我们的词汇表中每个单词的长度为 5。

嵌入权重为:

0.01209533  0.034303080 -0.04666784 0.02803965  -0.03691160
-0.01302978 -0.030584216    -0.02506201 0.04771456  0.01906699
0.02800793  0.042204402 0.05223191  -0.01184921 0.02000498
0.02692273  -0.008792922    0.01560913  -0.02783649 0.02692282

我的问题:我假设矩阵中的第一个“行”是基于 0 的向量,这样第 2、3 和 4 行将分别与“I”、“like”和“turtles”相关联.

是这样吗?我想确保我的词汇表正确对齐,但我无法确定任何文档来证实这一假设。

【问题讨论】:

    标签: r keras tensorflow2.0 word-embedding


    【解决方案1】:

    我了解您想要提取每个单词的嵌入,但我认为真正的问题是:分词器产生的输出是什么。

    另外,那个分词器有点乱。你会在下面看到我的意思。

    因为分词器会过滤单词(假设是一个重要的词汇表​​),我不想假设单词是按照它们被发现的顺序存储的。所以在这里我使用word_index 以编程方式确定词汇表。然后,我明确检查在过滤最常用词之后对哪些词进行了标记化。 (Word_index 记住所有个单词;即预过滤的值。)

    import tensorflow as tf
    from tensorflow.keras.preprocessing.text import Tokenizer
    corpus = 'I like turtles'
    num_words = len(corpus.split())
    oov = 'OOV'
    tokenizer = Tokenizer(num_words=num_words + 2, oov_token=oov)
    tokenizer.fit_on_texts(corpus.split())
    print(f'word_index: {tokenizer.word_index}')
    print(f'vocabulary: {tokenizer.word_index.keys()}')
    text = [key for key in tokenizer.word_index.keys()]
    print(f'keys: {text}: {tokenizer.texts_to_sequences(text)}')
    
    text = 'I like turtles'.split()
    print(f'{text}: {tokenizer.texts_to_sequences(text)}')
    
    text = 'I like marshmallows'.split() 
    print(f'{text}: {tokenizer.texts_to_sequences(text)}')
    

    这会产生以下输出:

    word_index: {'OOV': 1, 'i': 2, 'like': 3, 'turtles': 4}
    vocabulary: dict_keys(['OOV', 'i', 'like', 'turtles'])
    keys: ['OOV', 'i', 'like', 'turtles']: [[1], [2], [3], [4]]
    ['I', 'like', 'turtles']: [[2], [3], [4]]
    ['I', 'like', 'marshmallows']: [[2], [3], [1]]
    

    但是,如果您指定 oov_token,则输出如下所示:

    {'OOV': 1, 'i': 2, 'like': 3, 'turtles': 4}
    

    请注意我必须指定 num_words=num_words + 2 而不是预期的“+1”。 那是因为我们明确定义了一个 OOV 标记,它被添加到词汇表中,这在我看来有点疯狂。

    如果您指定 OOV 令牌并设置 num_words=num_words + 1(如文档所述),则“我喜欢海龟”将获得与“我喜欢棉花糖”相同的编码。也疯了。

    希望您现在必须使用工具来了解标记器为编码层提供的内容。然后希望将令牌与它们的嵌入相关联起来是微不足道的。

    请告诉我们您发现了什么。 :)

    (有关疯狂的更多信息,请查看this StackOverflow 帖子。)

    【讨论】:

    • 这太棒了,谢谢。我一直在使用index_wordword_index 以及文本到序列来解析我的数据。因此,基于上述内容,听起来您会建议添加 OOV(我没有),但我的问题仍然存在。上面,当添加 OOV 时,+2,在从嵌入层检索权重后,有 5 行,当只有 3 个单词时,如果包含 OOV,则为 4。我的最终目标是提取这些嵌入并将它们与原始单词对齐,所以我不知道在给定输出的情况下该去哪里。
    • @Btibert:至于从embedding层本身探索embedding,有没有看到这里的回答:stackoverflow.com/q/51235118/4093278
    • 谢谢,我已经发送了一些这样的例子,但在我的简单例子中,如果我有 3 个单词(或包含 OOV 的 4 个单词),我的嵌入层有 5 个层,如上所述。那是返回的。所以这表明可以丢弃最后一层(基于上面的链接)?再次感谢。
    猜你喜欢
    • 2020-08-19
    • 2020-06-20
    • 2021-05-12
    • 2018-08-12
    • 1970-01-01
    • 2020-10-27
    • 2018-12-16
    • 2018-09-03
    • 1970-01-01
    相关资源
    最近更新 更多