它在NLP和视觉语言问题中用于各种神经网络架构,将初始字嵌入层的权重与输出softmax的权重联系起来。通常这会提高句子生成质量。 (参见示例here)
在Keras中,使用Embedding类嵌入字嵌入层是典型的,但似乎没有简单的方法将此层的权重与输出softmax联系起来。有人会碰巧知道如何实施吗?
答案 0 :(得分:4)
请注意,Press and Wolf并不建议将权重冻结到某些预先训练的权重,但要绑定它们。这意味着,要确保在训练期间输入和输出权重始终相同(在同步意义上)。
在典型的NLP模型(例如语言建模/翻译)中,您有一个大小为V
的输入维度(词汇表)和一个隐藏的表示大小H
。然后,您从Embedding
图层开始,该图层是矩阵VxH
。输出层(可能)类似于Dense(V, activation='softmax')
,它是一个矩阵H2xV
。在绑定权重时,我们希望那些矩阵是相同的(因此,H==H2
)。
为了在Keras做到这一点,我认为要走的路是通过共享层:
在模型中,您需要实例化共享嵌入层(维度VxH
),并将其应用于输入和输出。但是您需要转置它,以获得所需的输出尺寸(HxV
)。因此,我们声明了一个TiedEmbeddingsTransposed
图层,该图层转换来自给定图层的嵌入矩阵(并应用激活函数):
class TiedEmbeddingsTransposed(Layer):
"""Layer for tying embeddings in an output layer.
A regular embedding layer has the shape: V x H (V: size of the vocabulary. H: size of the projected space).
In this layer, we'll go: H x V.
With the same weights than the regular embedding.
In addition, it may have an activation.
# References
- [ Using the Output Embedding to Improve Language Models](https://arxiv.org/abs/1608.05859)
"""
def __init__(self, tied_to=None,
activation=None,
**kwargs):
super(TiedEmbeddingsTransposed, self).__init__(**kwargs)
self.tied_to = tied_to
self.activation = activations.get(activation)
def build(self, input_shape):
self.transposed_weights = K.transpose(self.tied_to.weights[0])
self.built = True
def compute_mask(self, inputs, mask=None):
return mask
def compute_output_shape(self, input_shape):
return input_shape[0], K.int_shape(self.tied_to.weights[0])[0]
def call(self, inputs, mask=None):
output = K.dot(inputs, self.transposed_weights)
if self.activation is not None:
output = self.activation(output)
return output
def get_config(self):
config = {'activation': activations.serialize(self.activation)
}
base_config = super(TiedEmbeddingsTransposed, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
该图层的用法是:
# Declare the shared embedding layer
shared_embedding_layer = Embedding(V, H)
# Obtain word embeddings
word_embedding = shared_embedding_layer(input)
# Do stuff with your model
# Compute output (e.g. a vocabulary-size probability vector) with the shared layer:
output = TimeDistributed(TiedEmbeddingsTransposed(tied_to=shared_embedding_layer, activation='softmax')(intermediate_rep)
我在NMT-Keras进行了测试,并进行了正常训练。但是,当我尝试加载经过训练的模型时,会出现与Keras加载模型的方式相关的错误:它不会加载tied_to
的权重。我已经找到了几个有关此问题的问题(1,2,3),但我还没有设法解决这个问题。如果有人对接下来的步骤有任何想法,我很高兴听到他们:)
答案 1 :(得分:1)
您可以阅读here,只需将<SearchBar Grid.Row="0" Grid.Column="0" Margin="15" x:Name="search"></SearchBar>
标记设为trainable
即可。 E.g。
False