我正在使用Keras进行(字符)序列到序列的RNN应用。由于我有一组相对较少的A - >; B,以及B的更大的一组例子,我决定尝试自动编码器方法:首先训练网络以学习B上的身份功能,为B的成员产生嵌入,然后训练网络以学习A - >嵌入(B)。通过将第二个网络与第一个网络的一半解码器相结合,希望它能够推广出合理的B。
以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())
第一个脚本在B上训练autoencoder
- > B;然后另一个脚本实例化encoder
两次并在A - >上训练encoderA
encoderB.predict(B)
;最后,查询脚本使用encoderA
和decoderB
进行预测。
这一切都很好,但性能不如我想的那么好,所以我真正想做的是同时训练两个模型。我想要的是两个自动编码器模型,单独的编码器一半,但解码器一半的共享权重。然后我在一批A - >训练模型A之间交替。 B,并且在一批B上训练模型B - > B,应该在备用批次上更新两个编码器,但在每个批次上更新共享解码器。
我的问题是,简单地说,我如何构建这两个模型,以便按照我想要的方式共享权重? Here是一个类似的问题,但它只解释了如何做我已经做过的事情。如果后端很重要(可能没有),我可以使用TF或Theano。
答案 0 :(得分:1)
使用功能API创建零件模型,并将它们连接起来,就像它们是图层一样。
不同之处在于您正在创建两个解码器(通过调用两次应用解码器)
编码器A:
aInput = Input(...)
encodedA = LotsOfLayers(...)(aInput)
self.encoderA = Model(aInput,encodedA)
编码器B:
bInput = Input(...)
encodedB = LotsOfLayers(...)(bInput)
self.encoderB = Model(bInput,encodedB)
<强>解码器:强>
我们在这里只创建一个解码器:
encodedInput = Input(...)
decodedOutput = LotsOfLayers(...)(encodedInput)
self.decoder = Model(encodedInput, decodedOutput)
<强> AutoencoderB:强>
这是猫的跳跃&#34;:
autoInput = Input(sameShapeAsEncoderBInput)
encoded = self.encoderB(autoInput)
decoded = self.decoder(encoded)
self.autoencoderB = Model(autoInput,decoded)
预测员来自A:
遵循相同的逻辑:
anotherAInput = Input(sameShapeAsEncoderAInput)
encoded = self.encoderA(anotherAInput)
decoded = self.decoder(encoded)
self.predictorFromA = Model(anotherAInput,decoded)
这将使解码器与A中的AutoencoderB和Predictor相同(共享权重)。