是真正需要的只是10000字的字典什么嵌入层output_dim?(What embedding-l

2019-09-27 02:30发布

我练了一个RNN与一组字功能非常减少,大约10,000。 我打算与添加RNNs之前嵌入层开始,但它是非常不清楚我是真正需要什么样的维度。 我知道,我可以尝试不同的值(32,64,等等),但我宁愿有一些直觉进入它第一次。 例如,如果我使用32维嵌入矢量,则需要每尺寸仅3个不同的值,以充分地描述空间( 32**3>>10000 )。

另外,对于这个小数目字的空间,也有人甚至真的需要使用嵌入层或它更有意义,只是从到RNN的输入层右走?

Answer 1:

这是没有一个好的答案一个很好的问题。 你肯定应该使用嵌入层,而不仅仅是直接进入一个LSTM/GRU 。 然而,嵌入层的潜在尺寸应该是“尽可能地大,同时保持峰值性能验证”。 为了围绕你的尺寸的字典,128或256应该是一个合理的决定。 我怀疑你会看到完全不同的表现。

然而,有些东西真的影响到一个小数据集的结果没有使用预先训练字的嵌入。 这将导致你的嵌入惨遭过拟合到你的训练数据。 我建议使用手套字的嵌入。 下载手套数据后,您可以使用它们的权重初始化为您的埋层,然后emebdding层将微调的权重,你的用例。 下面是一些代码我用来与Keras手套的嵌入。 它让你加载它们的大小不同,也缓存矩阵,使其快速跑来跑去第二次。

class GloVeSize(Enum):

    tiny = 50
    small = 100
    medium = 200
    large = 300


__DEFAULT_SIZE = GloVeSize.small


def get_pretrained_embedding_matrix(word_to_index,
                                    vocab_size=10000,
                                    glove_dir="./bin/GloVe",
                                    use_cache_if_present=True,
                                    cache_if_computed=True,
                                    cache_dir='./bin/cache',
                                    size=__DEFAULT_SIZE,
                                    verbose=1):

    """
    get pre-trained word embeddings from GloVe: https://github.com/stanfordnlp/GloVe
    :param word_to_index: a word to index map of the corpus
    :param vocab_size: the vocab size
    :param glove_dir: the dir of glove
    :param use_cache_if_present: whether to use a cached weight file if present
    :param cache_if_computed: whether to cache the result if re-computed
    :param cache_dir: the directory of the project's cache
    :param size: an enumerated choice of GloVeSize
    :param verbose: the verbosity level of logging
    :return: a matrix of the embeddings
    """
    def vprint(*args, with_arrow=True):
        if verbose > 0:
            if with_arrow:
                print(">>", *args)
            else:
                print(*args)

    if not os.path.exists(cache_dir):
        os.makedirs(cache_dir)

    cache_path = os.path.join(cache_dir, 'glove_%d_embedding_matrix.npy' % size.value)
    if use_cache_if_present and os.path.isfile(cache_path):
        return np.load(cache_path)
    else:
        vprint('computing embeddings', with_arrow=True)
        embeddings_index = {}
        size_value = size.value
        f = open(os.path.join(glove_dir, 'glove.6B.' + str(size_value) + 'd.txt'),
                 encoding="ascii", errors='ignore')

        for line in f:
            values = line.split()
            word = values[0]
            coefs = np.asarray(values[1:], dtype='float32')
            embeddings_index[word] = coefs

        f.close()
        vprint('Found', len(embeddings_index), 'word vectors.')

        embedding_matrix = np.random.normal(size=(vocab_size, size.value))

        non = 0
        for word, index in word_to_index.items():
            embedding_vector = embeddings_index.get(word)
            if embedding_vector is not None:
                embedding_matrix[index] = embedding_vector
            else:
                non += 1

        vprint(non, "words did not have mappings")
        vprint(with_arrow=False)

        if cache_if_computed:
            np.save(cache_path, embedding_matrix)

return embedding_matrix

然后实例与权重矩阵的埋层:

 embedding_size = GloVeSize.small
    embedding_matrix = get_pretrained_embedding_matrix(data.word_to_index,
size=embedding_size)

embedding = Embedding(
     output_dim=self.embedding_size,
     input_dim=self.vocabulary_size + 1,
     input_length=self.input_length,
     mask_zero=True,
     weights=[np.vstack((np.zeros((1, self.embedding_size)),
                         self.embedding_matrix))],
     name='embedding'
)(input_layer)


文章来源: What embedding-layer output_dim is really needed for a dictionary of just 10000 words?