如何获得二进制序列作为自动编码器瓶颈的输出?

时间:2020-10-08 07:33:35

标签: python keras deep-learning autoencoder

我正在尝试实现自动编码器,并且希望将二进制序列作为瓶颈层的输出,因为我想分别使用编码器和解码器。

这是我的自动编码器架构的代码:

inputs_encoder = keras.Input(shape = 2**k)
x = Dense(units=S*2**(k), activation=activation)(inputs_encoder)
x = BatchNormalization(axis=1)(x)
outputs_encoder = Dense(units=N, activation='sigmoid')(x)
model_enc = keras.Model(inputs=inputs_encoder, outputs=outputs_encoder, name = 'encoder_model')


inputs_decoder = keras.Input(shape = N)
x = Dense(units=S * 2 ** (k), activation=activation)(inputs_decoder)
x = BatchNormalization(axis=1)(x)
outputs_decoder = Dense(units=2 ** k, activation='softmax')(x)
model_dec = keras.Model(inputs=inputs_decoder, outputs=outputs_decoder, name = 'decoder_model')


inputs_meta = keras.Input(shape = 2**k)
encoded_bits = model_enc(inputs=inputs_meta) #This is the output I'd like to be binary
decoded_sequence = model_dec(inputs=encoded_bits)
meta_model = keras.Model(inputs=inputs_meta, outputs=decoded_sequence, name = 'meta_model')

我已经尝试过在S型曲面之后使用函数tf.math.round(x),因为它是不可微分的函数,所以会导致错误。

然后,我使用了一个技巧来放置``tf.stop_gradient(tf.math.round(x)-x)+ x`'',它解决了梯度问题,但是网络的精度不好。

是否有更好的方法来执行此操作?

1 个答案:

答案 0 :(得分:0)

这似乎是一个量化问题(如果您需要查找有关该主题的更多信息)。

我通常看到的处理方式是,您在训练中跳过了round,而仅将其应用于评估和推断。这也很好,因为当您比较使用和不使用舍入步骤的模型性能时,它可以告诉您舍入(量化)会造成多少额外损失。

要考虑的一件事是,S型信号将为您提供0到1之间的值,因此回合会破坏信号的很大一部分。通过保留更多位,您也许可以从模型中获得更多收益。假设您将每个值保留3位,然后将S型结果乘以2**3 -1,然后四舍五入给您一个介于0和7之间的值。在解码器上,您必须除以{{1} },然后将其输入网络。显然,这需要在解码器和编码器之间传输更多位。但是,您可以牺牲嵌入的维数以保持大小不变​​(只有1 /(2 ** 3)维,以补偿每个值3位)。这样可以使模型更容易获得良好的性能。与往常一样,要找到正确的值,您需要进行一些超参数调整。

相关问题