Keras- Combined model how to extract only portion on autoencoder

Viewed 64

I have compiled 2 models , (Classification and Autoencoder) using KERAS ,I am able to evaluate the model and there is no issue running as per below.

   model.compile(loss={'classification': 'categorical_crossentropy', 
                        'autoencoder': 'mean_squared_error'},
                  optimizer='adam',
                  metrics={'classification': 'accuracy'})

history = model.fit(x_train, 
          {'classification': y_train, 'autoencoder': x_train},
          batch_size=300,
          epochs=1,
          validation_data= (x_test, {'classification': y_test}),
          verbose=1)

The second part requires me to exploit only the portion of the model on autoencoder , and visualize 8 samples of the images. Please refer to the code below , it can't run as the code is meant for the whole model , how do i extract only the portion of the model on autoencoder to plot the image?

# Generate reconstructions
num_reconstructions = 8
samples = x_test[:num_reconstructions]
targets = y_test[:num_reconstructions]
reconstructions = model.autoencoder.predict(samples)

import numpy as np

# Plot reconstructions
for i in np.arange(0, num_reconstructions):
  # Get the sample and the recoax = pp.subplot(111)nstruction
  sample = samples[i][:, :, 0]
  reconstruction = reconstructions[i][:, :, 0]
  input_class = targets[i]
  # Matplotlib preparations
  fig, axes = plt.subplots(1, 2)
  # Plot sample and reconstruciton
  axes[0].imshow(sample)
  axes[0].set_title('Original image')
  axes[1].imshow(reconstruction)
  axes[1].set_title('Reconstruction with Conv2DTranspose')
  fig.suptitle(f'MNIST target = {input_class}')
  plt.show()

See below for my network architect fyi:Keras combined model

  • I know that one way to do it is to retrain a model with only autoencoder after the network architecture , but that would be a different model which is not the same evaluated earlier , the loss/accuracy corresponds to the autoencoder/classification evaluated together at the start of the question.
1 Answers

This can be done without problems

I repropose a version of your model:

inp = Input((28,28,1))
enc = Conv2D(63, 3, padding='same')(inp)
enc = MaxPool2D()(enc)

clas = Flatten()(enc)
clas = Dense(1000)(clas)
clas = Dropout(0.3)(clas)
clas = Dense(10, activation='softmax', name='classification')(clas)

dec = Dense(1000)(enc)
dec = Conv2DTranspose(63, 3, padding='same')(dec)
dec = Conv2D(1, 3, padding='same')(dec)
dec = UpSampling2D(name='autoencoder')(dec)

model = Model(inp, [clas,dec])
model.compile(loss={'classification': 'sparse_categorical_crossentropy', 'autoencoder': 'mean_squared_error'},
                  optimizer='adam',
                  metrics={'classification': 'accuracy'})

I create dummy data and fit the whole structure (classification + autoencoder)

X = np.random.uniform(0,1, (8,28,28,1))
y = np.random.randint(0,10, 8)

model.fit(X, [y,X], epochs=3)
prob, rec1 = model.predict(X)

after fitting I extract only the autoencoder part

autoenc = Model(inp, dec)
rec2 = autoenc.predict(X)

check the results (rec1 must be equal to rec2)

(rec1 == rec2).all() # True ===> correct

here the full running example: https://colab.research.google.com/drive/12CJzXHz8fdjAv2Jvmp5IV_D-UDiHWtTY?usp=sharing

Related