In [ ]:
import numpy as np
np.random.seed(123)

import os
from keras.models import Model
from keras.layers import Input, Convolution2D, MaxPooling2D, BatchNormalization
from keras.layers import Flatten, Dense, Reshape, UpSampling2D
from keras.utils.layer_utils import print_summary

import cv2
import h5py

import matplotlib.pyplot as plt
%matplotlib inline

In [ ]:
def autoencoder(weights_path=None):
    # encoder
    inputs = Input(shape=(3,224,224), name='input')
    
    enc1 = Convolution2D(32, 3, 3, activation='relu')(inputs)
    enc1 = BatchNormalization(mode = 0 , axis = 1)(enc1)
    enc1 = Convolution2D(32, 3, 3, activation='relu')(enc1)
    enc1 = BatchNormalization(mode = 0 , axis = 1)(enc1)
    enc1 = MaxPooling2D((2,2), strides=(2,2))(enc1)
    
    enc2 = Convolution2D(64, 3, 3, activation='relu')(enc1)
    enc2 = BatchNormalization(mode = 0 , axis = 1)(enc2)
    enc2 = Convolution2D(64, 3, 3, activation='relu')(enc2)
    enc2 = BatchNormalization(mode = 0 , axis = 1)(enc2)
    enc2 = MaxPooling2D((2,2), strides=(2,2))(enc2)
    
    enc3 = Convolution2D(128, 3, 3, activation='relu')(enc2)
    enc3 = BatchNormalization(mode = 0 , axis = 1)(enc3)
    enc3 = Convolution2D(128, 3, 3, activation='relu')(enc3)
    enc3 = BatchNormalization(mode = 0 , axis = 1)(enc3)
    enc3 = MaxPooling2D((2,2), strides=(2,2))(enc3)
    
    enc4 = Convolution2D(256, 3, 3, activation='relu')(enc3)
    enc4 = BatchNormalization(mode = 0 , axis = 1)(enc4)
    enc4 = Convolution2D(256, 3, 3, activation='relu')(enc4)
    enc4 = BatchNormalization(mode = 0 , axis = 1)(enc4)
    enc4 = MaxPooling2D((2,2), strides=(2,2))(enc4)
    
    enc5 = Convolution2D(512, 3, 3, activation='relu')(enc4)
    enc5 = BatchNormalization(mode = 0 , axis = 1)(enc5)
    enc5 = Convolution2D(512, 3, 3, activation='relu')(enc5)
    enc5 = BatchNormalization(mode = 0 , axis = 1)(enc5)
    enc5 = MaxPooling2D((2,2), strides=(2,2))(enc5)
    
    enc6 = Flatten()(enc5)
    enc6 = Dense(2048, activation='relu')(enc6)
    enc6 = Dense(5*5*128, activation='linear', name='encoded_img')(enc6)
    
    # decoder (generator)
    g2 = Reshape((128,5,5))(enc6)
    
    g3 = UpSampling2D(size=(2, 2))(g2) # 10x10
    g3 = Convolution2D(512,2,2,activation='relu',border_mode='valid')(g3) # 9x9
    g3 = BatchNormalization(mode = 0 , axis = 1)(g3)
    g3 = Convolution2D(512,2,2,activation='relu',border_mode='same')(g3) # 9x9
    g3 = BatchNormalization(mode = 0 , axis = 1)(g3)
    
    g4 = UpSampling2D(size=(2, 2))(g3) # 18x18
    g4 = Convolution2D(256,3,3,activation='relu',border_mode='valid')(g4) # 16x16
    g4 = BatchNormalization(mode = 0 , axis = 1)(g4)
    g4 = Convolution2D(256,3,3,activation='relu',border_mode='same')(g4) # 16x16
    g4 = BatchNormalization(mode = 0 , axis = 1)(g4)
    
    g5 = UpSampling2D(size=(2, 2))(g4) # 32x32
    g5 = Convolution2D(256,3,3,activation='relu',border_mode='valid')(g5)# 30x30
    g5 = BatchNormalization(mode = 0 , axis = 1)(g5)
    g5 = Convolution2D(256,3,3,activation='relu',border_mode='same')(g5) # 30x30
    g5 = BatchNormalization(mode = 0 , axis = 1)(g5)
    
    g6 = UpSampling2D(size=(2, 2))(g5) # 60x60
    g6 = Convolution2D(128,3,3,activation='relu',border_mode='valid')(g6) # 58x58
    g6 = BatchNormalization(mode = 0 , axis = 1)(g6)
    g6 = Convolution2D(128,3,3,activation='relu',border_mode='same')(g6) # 58x58
    g6 = BatchNormalization(mode = 0 , axis = 1)(g6)
    
    g7 = UpSampling2D(size=(2, 2))(g6) # 116x116
    g7 = Convolution2D(128,4,4,activation='relu',border_mode='valid')(g7) # 113x113
    g7 = BatchNormalization(mode = 0 , axis = 1)(g7)
    g7 = Convolution2D(128,4,4,activation='relu',border_mode='same')(g7) # 113x113
    g7 = BatchNormalization(mode = 0 , axis = 1)(g7)
    
    g8 = UpSampling2D(size=(2, 2))(g7) # 226x226
    g8 = Convolution2D(64,3,3,activation='relu',border_mode='valid')(g8) # 224x224
    g8 = BatchNormalization(mode = 0 , axis = 1)(g8)
    g8 = Convolution2D(64,3,3,activation='relu',border_mode='same')(g8) # 224x224
    g8 = BatchNormalization(mode = 0 , axis = 1)(g8)
    g8 = Convolution2D(3,3,3,activation='relu',border_mode='same')(g8) # 224x224
    g8 = BatchNormalization(mode = 0, axis = 1, name='image')(g8)
    
    return Model(input=inputs, output=[g8,enc6])


# compile model
model = autoencoder()
print_summary(model.layers)
model.compile(optimizer='adadelta', loss='mean_squared_error')

In [ ]:
def transform_image(im):
    im = cv2.cvtColor(im.astype(np.uint8), cv2.COLOR_RGB2BGR)
    im = im.astype(np.float32)
    im[:,:,0] -= 103.939
    im[:,:,1] -= 116.779
    im[:,:,2] -= 123.68
    im = im.transpose((2,0,1))
    im = np.expand_dims(im, axis=0)
    return im

def reconstruct_image(im):
    im2 = np.squeeze(im)*1
    im2 = im2.transpose((1,2,0))
    im2[:,:,0] += 103.939
    im2[:,:,1] += 116.779
    im2[:,:,2] += 123.68
    im2 = im2.astype(np.uint8)
    return cv2.cvtColor(im2,cv2.COLOR_BGR2RGB)

In [ ]:
# get all images and corresponding filter responses
path_all = 'n02084071/'
f_imgs = os.listdir(path_all)
train_pics = []
for i, pic in enumerate(f_imgs):
    img = cv2.resize(cv2.imread(path_all+pic), (224, 224)).astype(np.float32)
    img = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_BGR2RGB)
    img = transform_image(img)
    train_pics.append(img)
    
train_pics = np.squeeze(np.array(train_pics))
dummy_labels = np.zeros(shape=(len(f_imgs),5*5*128))

In [ ]:
# train auto-encoder
model.fit(train_pics, [train_pics,dummy_labels], nb_epoch=400, batch_size=24, class_weight=[1.,0.])

In [ ]:
# test
idx = np.random.choice(train_pics.shape[0])
pic = train_pics[idx:idx+1]
out = model.predict(pic)

code = np.squeeze(out[1])
print('code: ',code)
plt.figure()
plt.plot(code)
plt.show()

plt.figure(figsize=(10,10))
plt.subplot(1,2,1)
plt.imshow(reconstruct_image(pic))
plt.subplot(1,2,2)
plt.imshow(reconstruct_image(out[0]))
plt.show()

In [ ]:
# save the decoder weights for later use
model.save_weights('decoder_weights.h5')

In [ ]: