Why Do Predictions Differ For Autoencoder Vs. Encoder + Decoder?
I build a CNN 1d Autoencoder in Keras, following the advice in this SO question, where Encoder and Decoder are separated. My goal is to re-use the decoder, once the Autoencoder has
Solution 1:
Main problem with your code: lack of use of a random seed. I refer to full explanation to this answer, and focus on your particular instance here.
Explanation:
- Order of model instantiation matters, as it changes the initialized weights
- In usage, if you train multiple models, you should reset seed both at model instantiation and before training
- Your AE, Encoder, and Decoder definitions make a redundant use of
Input
, and complicate introspection (e.g..summary()
);Encoder()
andDecoder()
already take care of it - To check whether loaded decoder weights match saved trained AE decoder weights, see example below
SOLUTION:
reset_seeds()
X = np.random.randn(10, 501, 1) # '10' arbitrary
encoder_input = Input(batch_shape=(None, 501, 1))
reset_seeds()
encoder = Encoder()
decoder = Decoder()
autoencoder = Model(x, decoder(encoder(x)))
autoencoder.compile(optimizer='adam', loss='mse')
reset_seeds()
encoder = Encoder()
decoder = Decoder()
predictions = autoencoder.predict(X)
features = encoder.predict(X)
score = decoder.predict(features)
print(np.sum(score - predictions))
# 0.0 <-- 100% agreement
Save/load example + preferred AE definition; reference
Your AE definition limits introspection via e.g. .summary()
; instead, define as below.
X = np.random.randn(10, 501, 1)
reset_seeds()
encoder = Encoder()
AE = DecoderAE(encoder.input, encoder.output)
AE.compile(optimizer='adam', loss='mse')
reset_seeds()
encoder = Encoder()
decoder = Decoder()
# Test equality
features = encoder.predict(X)
score = decoder.predict(features)
predictions = AE.predict(X)
print(np.sum(score - predictions))
# 0.0 <-- exact or close to
AE.save_weights('autoencoder_weights.h5')
AE_saved_weights = AE.get_weights()
decoder = Decoder()
load_weights(decoder, 'autoencoder_weights.h5') # see "reference"
decoder_loaded_weights = decoder.get_weights()
AE_decoder_weights = AE_saved_weights[-len(decoder_loaded_weights):]
for w1, w2 in zip(AE_decoder_weights, decoder_loaded_weights):
print(np.sum(w1 - w2))
# 0.0
# 0.0
# ...
Functions used:
def reset_seeds():
np.random.seed(1)
random.seed(2)
if tf.__version__[0] == '2':
tf.random.set_seed(3)
else:
tf.set_random_seed(3)
print("RANDOM SEEDS RESET")
def DecoderAE(encoder_input, encoded_input):
encoded_reshaped = Reshape((32,1))(encoded_input)
d1 = Conv1D(32, 3, activation='tanh', padding='valid',
name='decod_conv1d_1')(encoded_reshaped)
d2 = UpSampling1D(2, name='decod_upsampling1d_1')(d1)
d3 = Conv1D(256, 3, activation='tanh', padding='valid', name='decod_conv1d_2')(d2)
d4 = UpSampling1D(2, name='decod_upsampling1d_2')(d3)
d5 = Flatten(name='decod_flatten')(d4)
d6 = Dense(501, name='decod_dense1')(d5)
decoded = Reshape((501,1), name='decod_reshape')(d6)
return Model(encoder_input, decoded)
Post a Comment for "Why Do Predictions Differ For Autoencoder Vs. Encoder + Decoder?"