我正在keras中实现自定义丢失功能。该模型是autoencoder
。第一层是嵌入层,它将大小为(batch_size, sentence_length)
的输入嵌入(batch_size, sentence_length, embedding_dimension)
。然后,模型将嵌入压缩为特定维度的向量,最后必须重建嵌入(batch_size, sentence_lenght, embedding_dimension)
。
但是嵌入层是可训练的,并且丢失必须使用嵌入层的权重(我必须对我的词汇表的所有单词嵌入进行求和)。
例如,如果我想训练玩具例如:“猫”。 sentence_length is 2
并假设embedding_dimension is 10
和vocabulary size is 50
,因此嵌入矩阵的形状为(50,10)
。嵌入图层的输出X
的形状为(1,2,10)
。然后它传入模型,输出X_hat
也是形状(1,2,10)
。必须对模型进行训练,以最大化表示'the'的向量X_hat[0]
与嵌入层中表示'the'的向量X[0]
最相似的概率,以及'cat'相同的概率。但是我必须计算X
和X_hat
之间的余弦相似度,并通过X_hat
和每次嵌入的余弦相似度之和进行归一化(50,因为词汇量大小是50)在嵌入矩阵中,嵌入矩阵是嵌入层的权重的列。
但是如何在训练过程的每次迭代中访问嵌入层中的权重?
谢谢!
答案 0 :(得分:1)
它似乎有点疯狂,但它似乎有效:不是创建我将在model.compile中传递的自定义丢失函数,网络在一个函数中计算损失(来自arxiv.org/pdf/1708.04729.pdf的等式1)我打电话给Lambda:
loss = Lambda(lambda x: similarity(x[0], x[1], x[2]))([X_hat, X, embedding_matrix])
网络有两个输出:X_hat
和loss
,但我的权重X_hat
有0的权重和损失,以便拥有所有权重:
model = Model(input_sequence, [X_hat, loss])
model.compile(loss=mean_squared_error,
optimizer=optimizer,
loss_weights=[0., 1.])
当我训练模型时:
for i in range(epochs):
for j in range(num_data):
input_embedding = model.layers[1].get_weights()[0][[data[j:j+1]]]
y = [input_embedding, 0] #The embedding of the input
model.fit(data[j:j+1], y, batch_size=1, ...)
这样,训练模型使loss
趋于0,当我想使用训练模型的预测时,我使用第一个输出,即重建X_hat