text_plain_output_1.png
from keras.datasets import mnist, cifar10

from keras.layers import  Conv2DTranspose, BatchNormalization, add, LeakyReLU

from keras.layers import  Input,Conv2D,MaxPool2D, UpSampling2D,Dense, Dropout

from keras.models import Model

from keras.models import load_model

from keras.models import load_model

from keras.optimizers import Adam

from tensorflow.keras import layers, losses

from tensorflow.keras import losses

import matplotlib.pyplot as plt

import numpy as np

import tensorflow as tf

def preprocess(array1, array2, channel):
    """
    Normalizes/scales [0,1], divinding by the supplied array and reshapes 
    it into the appropriate format.
    """
    if channel == 1:
        ar1 = array1.astype('float32').reshape([-1, 28, 28, 1]) / 255.0
        ar2 = array2.astype('float32').reshape([-1, 28, 28, 1]) / 255.0
    else:
        ar1 = array1.astype('float32').reshape([-1, 32, 32, 3]) / 255
        ar2 = array2.astype('float32').reshape([-1, 32, 32, 3]) / 255
    return (ar1, ar2)

def noise(a1, a2, channel):
    """
    Adds random noise to each image in the supplied array.
    """
    if channel == 1:
        noise_factor = 0.2
        noisy_arr1 = a1 + noise_factor * np.random.normal(0.0, 1.0, size=a1.shape)
        noisy_arr2 = a2 + noise_factor * np.random.normal(0.0, 1.0, size=a2.shape)
    else:
        noi = 0.1
        noisy_arr1 = a1 + noi * np.random.normal(0.0, 1.0, size=a1.shape)
        noisy_arr2 = a2 + noi * np.random.normal(0.0, 1.0, size=a2.shape)
    ab1 = np.clip(noisy_arr1, 0, 1)
    ab2 = np.clip(noisy_arr2, 0, 1)
    return (ab1, ab2)

# Visualization for mnist, cifar10, noisy, denoised/predictions data
def display(rows, cols, a, b, check=False ):
    '''rows: defining no. of rows in figure
      cols: defining no. of colums in figure
      a: train images without noise or noisy_image while test
      prediction
      b: train images with noise or denoised_image based while test 
      prediction
      check: default False for 32*32 cifar10, true for 28*28
      mnist dataset and any predictions
    '''
    # defining a figure 
    f = plt.figure(figsize=(2*cols,2*rows*2)) 
    for i in range(rows):
        for j in range(cols):
            # adding subplot to figure on each iteration
            f.add_subplot(rows*2,cols, (2*i*cols)+(j+1))
            if check:
                plt.imshow(a[i*cols + j].reshape([28,28]),cmap="Blues")
            else:
                plt.imshow(a[i*cols + j])
            plt.axis("off")
        for j in range(cols):
            # adding subplot to figure on each iteration
            f.add_subplot(rows*2,cols,((2*i+1)*cols)+(j+1)) 
            if check:
                plt.imshow(b[i*cols + j].reshape([28,28]),cmap="Blues")
            else:
                plt.imshow(b[i*cols + j])
            plt.axis("off")
            plt.axis("off")
        
    #f.suptitle("Sample Training Data",fontsize=18)
    plt.savefig("ss.png")
    plt.show()

(train_data, _), (test_data, _) = mnist.load_data()
channel = 1
train_data, test_data = preprocess(train_data, test_data, channel)
noisy_train_data, noisy_test_data = noise(train_data, test_data, channel)

(cifar_train, _), (cifar_test, _) = cifar10.load_data()
rows = 2
cols = 3
channel = 3
cifar_train, cifar_test = preprocess(cifar_train, cifar_test, channel)
cifar_train_noise, cifar_test_noise = noise(cifar_train, cifar_test, channel)

inputs = Input(shape=(28, 28, 1))
x = Conv2D(32, 3, activation='relu', padding='same')(inputs)
x = MaxPool2D()(x)
x = Dropout(0.2)(x)
x = Conv2D(32, 3, activation='relu', padding='same')(x)
encoded = MaxPool2D()(x)
x = Conv2D(32, 3, activation='relu', padding='same')(encoded)
x = UpSampling2D()(x)
x = Dropout(0.2)(x)
x = Conv2D(32, 3, activation='relu', padding='same')(x)
x = UpSampling2D()(x)
decoded = Conv2D(1, 3, activation='sigmoid', padding='same')(x)

from tensorflow.keras import losses
autoencoder1 = Model(inputs, decoded)
autoencoder1.compile(optimizer='adam', loss=losses.binary_crossentropy)
autoencoder1.summary()

history1 = autoencoder1.fit(noisy_train_data, train_data, epochs=50, batch_size=256, shuffle=True, validation_data=(noisy_test_data, test_data))

autoencoder1.save('autoencoder_model1.h5')
from keras.models import load_model
model1 = load_model('autoencoder_model1.h5')

num_imgs = 45
rand = np.random.randint(1, 100)
test_images = noisy_test_data[rand:rand + num_imgs]
test_denoised = model1.predict(test_images)

from tensorflow.keras import layers, losses
class Denoise(Model):
    """__init__ constructor in OOP
    This method called when an object is created from the class and 
    it allow the class to initialize the attributes of a class.
    super()function used to give access to 
    methods and properties of a parent or sibling class
    """
    def __init__(self):
        super(Denoise, self).__init__()
        self.encoder = tf.keras.Sequential([layers.Input(shape=(28, 28, 1)), layers.Conv2D(16, (3, 3), activation='relu', padding='same', strides=2), layers.Conv2D(8, (3, 3), activation='relu', padding='same', strides=2)])
        self.decoder = tf.keras.Sequential([layers.Conv2DTranspose(8, kernel_size=3, strides=2, activation='relu', padding='same'), layers.Conv2DTranspose(16, kernel_size=3, strides=2, activation='relu', padding='same'), layers.Conv2D(1, kernel_size=(3, 3), activation='sigmoid', padding='same')])
    def call(self, x):
        encoded = self.encoder(x)
        decoded = self.decoder(encoded)
        return decoded
autoencoder = Denoise()

autoencoder.compile(optimizer='rmsprop', loss=losses.MeanSquaredError())

history = autoencoder.fit(noisy_train_data, train_data, epochs=10, batch_size=256, shuffle=True, validation_data=(noisy_test_data, test_data))

num_imgs = 45
rand = np.random.randint(1, 100)
test_images = noisy_test_data[rand:rand + num_imgs]
test_denoised = autoencoder.predict(test_images)

size = 32
channel = 3

inputs = Input(shape=(size, size, channel))
x = Conv2D(32, 3, activation='relu', padding='same')(inputs)
x = BatchNormalization()(x)
x = MaxPool2D()(x)
x = Dropout(0.5)(x)
skip = Conv2D(32, 3, padding='same')(x)
x = LeakyReLU()(skip)
x = BatchNormalization()(x)
x = MaxPool2D()(x)
x = Dropout(0.5)(x)
x = Conv2D(64, 3, activation='relu', padding='same')(x)
x = BatchNormalization()(x)
encoded = MaxPool2D()(x)
x = Conv2DTranspose(64, 3, activation='relu', strides=(2, 2), padding='same')(encoded)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Conv2DTranspose(32, 3, activation='relu', strides=(2, 2), padding='same')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Conv2DTranspose(32, 3, padding='same')(x)
x = add([x, skip])
x = LeakyReLU()(x)
x = BatchNormalization()(x)
decoded = Conv2DTranspose(3, 3, activation='sigmoid', strides=(2, 2), padding='same')(x)
autoencoder2 = Model(inputs, decoded)
autoencoder2.compile(optimizer=Adam(lr=0.0001), loss='binary_crossentropy')
autoencoder2.summary()

epochs = 25
batch_size = 256
history2 = autoencoder2.fit(cifar_train_noise, cifar_train, epochs=epochs, batch_size=batch_size, shuffle=True, validation_data=(cifar_test_noise, cifar_test))

autoencoder2.save('autoencoder_model.h5')
from keras.models import load_model
model2 = load_model('autoencoder_model.h5')

num_imgs = 48
rand = np.random.randint(1, cifar_test_noise.shape[0] - 48)
cifar_test_images = cifar_test_noise[rand:rand + num_imgs]
cifar_test_denoised = autoencoder2.predict(cifar_test_images)

display(3, 4, cifar_test_images, cifar_test_denoised)