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

Python 如何获得二进制序列作为自动编码器瓶颈的输出?,python,keras,deep-learning,autoencoder,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, activat

我正在尝试实现一个自动编码器,我想要一个二进制序列作为瓶颈层的输出,因为我想要分别使用编码器和解码器

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

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')
我尝试在sigmoid层之后使用函数
tf.math.round(x)
,这会导致错误,因为它是一个不可微函数

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


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

这看起来像是量化问题(如果您需要查找有关此主题的更多信息)

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


需要考虑的是乙状结肠会给你一个介于0和1之间的值,所以圆会破坏信号的大部分。通过保留更多位,您可能可以从模型中获得更多信息。比方说,每个值保留3位,将sigmoid的结果乘以
2**3-1
,然后四舍五入,得到一个介于0和7之间的值。在解码器上,您必须先除以
2**3-1
,然后才能将其送入网络。显然,这需要在解码器和编码器之间传输更多的比特。但是,您可以牺牲嵌入的维度来保持大小不变(只有1/(2**3)个维度,以补偿每个值的3位)。这样可能会使模型更容易获得良好的性能。一如既往,要找到正确的值,您需要进行一些超参数调整。

感谢您的回答,我将检查量化问题文献。我已经尝试过训练网络跳过
round
函数,并将其用于推理,但精确度降低了很多。这就是为什么考虑到四舍五入,我要训练它。关于您建议的可能实现,我不能使用它,因为我确实需要将编码器输出保持为二进制序列,以便在将其插入解码器之前使其通过噪声层。@kevinsneideribaralancheros输出保持二进制。只需要27位代表27个节点,而不是27位代表9个节点。如果噪声是主要问题(不是大小),为什么不将原始输出转换为抗噪声编码?如果你想训练一种抗噪声的编码,那么你真的应该在噪声部分建模。