import numpy as np, matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.models import Model
from keras.layers import Input, Dense
from sklearn.manifold import TSNE

# Load & preprocess MNIST
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train.astype('float32')/255., x_test.astype('float32')/255.
x_train, x_test = x_train.reshape(len(x_train), -1), x_test.reshape(len(x_test), -1)

# Build autoencoder
inp = Input(shape=(784,))
enc = Dense(32, activation='relu')(inp)
dec = Dense(784, activation='sigmoid')(enc)
autoencoder = Model(inp, dec)
encoder = Model(inp, enc)
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')

# Train
autoencoder.fit(x_train, x_train, epochs=30, batch_size=256, shuffle=True,
                validation_data=(x_test, x_test), verbose=1)

# Reconstruct images
decoded = autoencoder.predict(x_test)

# Show original vs reconstructed
plt.figure(figsize=(18,4))
for i in range(10):
    ax = plt.subplot(2,10,i+1); plt.imshow(x_test[i].reshape(28,28)); plt.axis('off')
    ax = plt.subplot(2,10,i+11); plt.imshow(decoded[i].reshape(28,28)); plt.axis('off')
plt.suptitle('Original (top) vs Reconstructed (bottom)')
plt.show()

# Latent space visualization (t-SNE)
encoded = encoder.predict(x_test)
emb = TSNE(n_components=2, random_state=42).fit_transform(encoded)
plt.figure(figsize=(10,8))
plt.scatter(emb[:,0], emb[:,1], c=y_test, cmap='tab10', s=8)
plt.colorbar(); plt.title('t-SNE of Encoded MNIST')
plt.show()