python - 连接嵌入层

标签 python keras

我正在尝试创建一个以单词作为输入的模型。其中大部分单词都在手套单词向量集中(~50000)。然而,一些常用词却不是(~1000)。问题是,如何连接以下两个嵌入层来创建一个巨大的嵌入查找表?

trained_em = Embedding(50000, 50, 
                       weights=np.array([word2glove[w] for w in words_in_glove]), 
                       trainable=False)
untrained_em = Embedding(1000, 50)

据我了解,这些只是两个具有相同维数的查找表。所以我希望有一种方法可以堆叠这两个查找表。

编辑 1: 我刚刚意识到这可能不仅仅是堆叠嵌入层,因为输入序列将是 0-50999 之间的数字。然而,上面的 untrained_em 只期望 0-999 之间的数字。因此也许需要不同的解决方案。

编辑 2: 这就是我期望在表示嵌入的 numpy 数组中执行的操作:

np.random.seed(42) # Set seed for reproducibility
pretrained = np.random.randn(15,3)
untrained = np.random.randn(5,3)
final_embedding = np.vstack([pretrained, untrained])

word_idx = [2, 5, 19]
np.take(final_embedding, word_idx, axis=0)

我相信最后一点可以通过与keras.backend.gather有关的事情来完成,但不确定如何将它们放在一起。

最佳答案

事实证明我需要实现一个自定义层。这是通过调整原始的 Embedding 类来实现的。

下面的类中显示的两个最重要的部分是 self.embeddings = K.concatenate([fixed_weight, variable_weight], axis=0)out = K.gather(self .嵌入,输入)。第一个希望是不言自明的,而第二个则从 embeddings 表中挑选出相关的 input 行。

但是,在我正在开发的特定应用程序中,事实证明使用嵌入层而不是修改层效果更好。可能是因为学习率太高了。在我进行更多实验后,我会报告这一点。

from keras.engine.topology import Layer
import keras.backend as K
from keras import initializers
import numpy as np

class Embedding2(Layer):

    def __init__(self, input_dim, output_dim, fixed_weights, embeddings_initializer='uniform', 
                 input_length=None, **kwargs):
        kwargs['dtype'] = 'int32'
        if 'input_shape' not in kwargs:
            if input_length:
                kwargs['input_shape'] = (input_length,)
            else:
                kwargs['input_shape'] = (None,)
        super(Embedding2, self).__init__(**kwargs)

        self.input_dim = input_dim
        self.output_dim = output_dim
        self.embeddings_initializer = embeddings_initializer
        self.fixed_weights = fixed_weights
        self.num_trainable = input_dim - len(fixed_weights)
        self.input_length = input_length

    def build(self, input_shape, name='embeddings'):
        initializer = initializers.get(self.embeddings_initializer)
        shape1 = (self.num_trainable, self.output_dim)
        variable_weight = K.variable(initializer(shape1), dtype=K.floatx(), name=name+'_var')

        fixed_weight = K.variable(self.fixed_weights, name=name+'_fixed')


        self._trainable_weights.append(variable_weight)
        self._non_trainable_weights.append(fixed_weight)

        self.embeddings = K.concatenate([fixed_weight, variable_weight], axis=0)

        self.built = True

    def call(self, inputs):
        if K.dtype(inputs) != 'int32':
            inputs = K.cast(inputs, 'int32')
        out = K.gather(self.embeddings, inputs)
        return out

    def compute_output_shape(self, input_shape):
        if not self.input_length:
            input_length = input_shape[1]
        else:
            input_length = self.input_length
        return (input_shape[0], input_length, self.output_dim)

关于python - 连接嵌入层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46032700/

相关文章:

python - %load_ext rpy2.ipython 错误

python - SQLAlchemy插入,更新前提条件(一致性检查)

machine-learning - BERT HuggingFace 给出 NaN 损失

python - Keras:从 flow_from_directory 获取图像和标签数组

python - keras.layers.Embedding 的输出形状

python - 我可以在没有 node.js 的情况下使用 Electron

python - 使用请求安全地处理潜在的恶意 URL

python - 无法导入我的 util 模块

neural-network - 如何在 keras 中拥有并行卷积层?

python - 使用 Keras np_utils.to_categorical 的问题