我使用Keras作为(字符)序列到序列RNN应用程序。由于我有一个相对较少的A - > B例子,以及更多的B例子,我决定尝试一种自动编码器方法:首先训练一个网络来学习B上的身份函数,为成员产生一个嵌入的B,然后训练一个网络来学习A - >嵌入(B)。通过将第二个网络与第一个网络的解码器一半相结合,希望它能够推广生产合理的Bs。用部分共享权重串联训练两个Keras模型
的代码中,Building Autoencoders in Keras教程为蓝本,看起来是这样的(好几层,辍学,正则化等已经离开了为简单起见):
class Example:
def __init(self, ...):
# Sets dense_size, rnn, rnn_size, embed_size, input_len, output_len, etc.
def apply_encoder(self, input_word):
input_masked = Masking()(input_word)
input_dense = TimeDistributed(Dense(self.dense_size), name='input_dense')(input_masked)
rnn = self.rnn(self.rnn_size, name='input_rnn')(input_dense)
embedding = Dense(self.embed_size, name='embedding')(rnn)
return embedding
def apply_decoder(self, embedding):
repeated = RepeatVector(self.output_len, name='repeat')(embedding)
rnn = self.rnn(self.rnn_size, name='output_rnn')(repeated)
output_dense = TimeDistributed(Dense(self.dense_size), name='output_dense')(rnn)
output_word = TimeDistributed(
Dense(self.chars, activation='softmax'),
name='output_word'
)(output_dense)
return output_word
def build_net(self):
input_word = Input(shape=(self.input_len, self.chars), name='input_word')
embedding = self.apply_encoder(input_word)
output_word = self.apply_decoder(embedding)
self.autoencoder = Model(input_word, output_word)
self.encoder = Model(input_word, embedding)
embed_input = Input(shape=(self.embed_size,), name='input_embedding')
decoder_output = self.apply_decoder(embed_input)
self.decoder = Model(embed_input, decoder_output)
def save_models(self):
open('models/autoencoder.json', 'w').write(self.autoencoder.to_json())
open('models/encoder.json', 'w').write(self.encoder.to_json())
open('models/decoder.json', 'w').write(self.decoder.to_json())
第一个脚本列车autoencoder
在B→B;那么另一个脚本实例化encoder
两次,并在A上训练encoderA
- >encoderB.predict(B)
;最后,查询脚本使用encoderA
和decoderB
进行预测。
这一切都很好,但表现并不像我想的那么好,所以我真正想做的是同时训练两个模型。我想要的是两个编码器型号单独编码器的一半,但共享权重为解码器的一半。然后,我在一批A→B的训练模型A和一批B→B的训练模型B之间交替,这两个批次应更新两个编码器,但每批更新共享解码器。
我的问题是,我怎样才能构建这两个模型,使权重以我想要的方式共享? Here是一个类似的问题,但它只解释了如何做我已经完成的工作。如果后端很重要(可能没有),我可以使用TF或Theano。
谢谢,我想我明白了!我会尝试今晚应用它,然后给你复选标记:) – hobbs
它的作品非常漂亮。我想我所缺少的是'Input'就像一个占位符,当你编写两个模型时,第一个插槽的输出到第二个输入的输出中。 – hobbs