<jupyter_start><jupyter_text>Import Useful Libraries<jupyter_code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm_notebook
%matplotlib inline
import tensorflow
print (tensorflow.__version__)<jupyter_output><empty_output><jupyter_text>Download and Unzip Data<jupyter_code>!wget https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets/horse2zebra.zip
!unzip horse2zebra.zip
!ls horse2zebra
import glob
path = ""
horses_train = glob.glob(path + 'horse2zebra/trainA/*.jpg')
zebras_train = glob.glob(path + 'horse2zebra/trainB/*.jpg')
horses_test = glob.glob(path + 'horse2zebra/testA/*.jpg')
zebras_test = glob.glob(path + 'horse2zebra/testB/*.jpg')
len(horses_train), len(zebras_train), len(horses_test), len(zebras_test)
import cv2
for file in horses_train[:10]:
    img = cv2.imread(file)
    print (img.shape)<jupyter_output><empty_output><jupyter_text>Display few Samples<jupyter_code>print ("Horses")
for k in range(2):
    plt.figure(figsize=(15, 15))
    for j in range(6):
        file = np.random.choice(horses_train)
        img = cv2.imread(file)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        plt.subplot(660 + 1 + j)
        plt.imshow(img)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()

print ("-"*80)
print ("Zebras")
for k in range(2):
    plt.figure(figsize=(15, 15))
    for j in range(6):
        file = np.random.choice(zebras_train)
        img = cv2.imread(file)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        plt.subplot(660 + 1 + j)
        plt.imshow(img)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()<jupyter_output><empty_output><jupyter_text>Define Generator Model (Res-Net Like)<jupyter_code>#Following function is taken from: https://keras.io/examples/generative/cyclegan/

class ReflectionPadding2D(tensorflow.keras.layers.Layer):
    """Implements Reflection Padding as a layer.

    Args:
        padding(tuple): Amount of padding for the
        spatial dimensions.

    Returns:
        A padded tensor with the same type as the input tensor.
    """

    def __init__(self, padding=(1, 1), **kwargs):
        self.padding = tuple(padding)
        super(ReflectionPadding2D, self).__init__(**kwargs)

    def call(self, input_tensor, mask=None):
        padding_width, padding_height = self.padding
        padding_tensor = [
            [0, 0],
            [padding_height, padding_height],
            [padding_width, padding_width],
            [0, 0],
        ]
        return tensorflow.pad(input_tensor, padding_tensor, mode="REFLECT")
import tensorflow_addons as tfa
# Weights initializer for the layers.
kernel_init = tensorflow.keras.initializers.RandomNormal(mean=0.0, stddev=0.02)
# Gamma initializer for instance normalization.
gamma_init = tensorflow.keras.initializers.RandomNormal(mean=0.0, stddev=0.02)
def custom_resnet_block(input_data, filters):
    x = ReflectionPadding2D()(input_data)
    x = tensorflow.keras.layers.Conv2D(filters, kernel_size=(3,3), padding='valid', kernel_initializer=kernel_init)(x)
    x = tfa.layers.InstanceNormalization()(x)
    x = tensorflow.keras.layers.Activation('relu')(x)

    x = ReflectionPadding2D()(x)
    x = tensorflow.keras.layers.Conv2D(filters, kernel_size=(3,3), padding='valid', kernel_initializer=kernel_init)(x)
    x = tfa.layers.InstanceNormalization()(x)

    x = tensorflow.keras.layers.Add()([x, input_data])
    return x
def make_generator():
    source_image = tensorflow.keras.layers.Input(shape=(256, 256, 3))

    x = ReflectionPadding2D(padding=(3, 3))(source_image)
    x = tensorflow.keras.layers.Conv2D(64, kernel_size=(7,7), kernel_initializer=kernel_init, use_bias=False)(x)
    x = tfa.layers.InstanceNormalization()(x)
    x = tensorflow.keras.layers.Activation('relu')(x)

    x = tensorflow.keras.layers.Conv2D(128, kernel_size=(3,3), strides=(2,2), padding='same', kernel_initializer=kernel_init)(x)
    x = tfa.layers.InstanceNormalization()(x)
    x = tensorflow.keras.layers.Activation('relu')(x)

    x = tensorflow.keras.layers.Conv2D(256, kernel_size=(3,3), strides=(2,2), padding='same', kernel_initializer=kernel_init)(x)
    x = tfa.layers.InstanceNormalization()(x)
    x = tensorflow.keras.layers.Activation('relu')(x)

    x = custom_resnet_block(x, 256)
    x = custom_resnet_block(x, 256)
    x = custom_resnet_block(x, 256)

    x = custom_resnet_block(x, 256)
    x = custom_resnet_block(x, 256)
    x = custom_resnet_block(x, 256)

    x = custom_resnet_block(x, 256)
    x = custom_resnet_block(x, 256)
    x = custom_resnet_block(x, 256)

    x = tensorflow.keras.layers.Conv2DTranspose(128, kernel_size=(3,3), strides=(2,2), padding='same', kernel_initializer=kernel_init)(x)
    x = tfa.layers.InstanceNormalization()(x)
    x = tensorflow.keras.layers.Activation('relu')(x)

    x = tensorflow.keras.layers.Conv2DTranspose(64, kernel_size=(3,3), strides=(2,2), padding='same', kernel_initializer=kernel_init)(x)
    x = tfa.layers.InstanceNormalization()(x)
    x = tensorflow.keras.layers.Activation('relu')(x)

    x = ReflectionPadding2D(padding=(3, 3))(x)
    x = tensorflow.keras.layers.Conv2D(3, kernel_size=(7,7), padding='valid')(x)
    x = tfa.layers.InstanceNormalization()(x)

    translated_image = tensorflow.keras.layers.Activation('tanh')(x)

    return source_image, translated_image

source_image, translated_image = make_generator()
generator_network_AB = tensorflow.keras.models.Model(inputs=source_image, outputs=translated_image)

source_image, translated_image = make_generator()
generator_network_BA = tensorflow.keras.models.Model(inputs=source_image, outputs=translated_image)

print (generator_network_AB.summary())<jupyter_output><empty_output><jupyter_text>Define Discriminator Network<jupyter_code>def my_conv_layer(input_layer, filters, strides, bn=True):
    x = tensorflow.keras.layers.Conv2D(filters, kernel_size=(4,4), strides=strides, padding='same', kernel_initializer=kernel_init)(input_layer)
    x = tensorflow.keras.layers.LeakyReLU(alpha=0.2)(x)
    if bn:
        x = tfa.layers.InstanceNormalization()(x)
    return x
 def make_discriminator():
    target_image_input = tensorflow.keras.layers.Input(shape=(256, 256, 3))

    x = my_conv_layer(target_image_input, 64, (2,2), bn=False)
    x = my_conv_layer(x, 128, (2,2))
    x = my_conv_layer(x, 256, (2,2))
    x = my_conv_layer(x, 512, (1,1))

    patch_features = tensorflow.keras.layers.Conv2D(1, kernel_size=(4,4), padding='same')(x)
    return target_image_input, patch_features


target_image_input, patch_features = make_discriminator()
discriminator_network_A = tensorflow.keras.models.Model(inputs=target_image_input, outputs=patch_features)

target_image_input, patch_features = make_discriminator()
discriminator_network_B = tensorflow.keras.models.Model(inputs=target_image_input, outputs=patch_features)

print (discriminator_network_A.summary())
adam_optimizer = tensorflow.keras.optimizers.Adam(learning_rate=0.0002, beta_1=0.5)
discriminator_network_A.compile(loss='mse', optimizer=adam_optimizer, metrics=['accuracy'])
discriminator_network_B.compile(loss='mse', optimizer=adam_optimizer, metrics=['accuracy'])<jupyter_output><empty_output><jupyter_text>Define Cycle-GAN<jupyter_code>source_image_A = tensorflow.keras.layers.Input(shape=(256, 256, 3))
source_image_B = tensorflow.keras.layers.Input(shape=(256, 256, 3))

# Domain Transfer
fake_B = generator_network_AB(source_image_A)
fake_A = generator_network_BA(source_image_B)

# Restoring original Domain
get_back_A = generator_network_BA(fake_B)
get_back_B = generator_network_AB(fake_A)

# Get back Identical/Same Image
get_same_A = generator_network_BA(source_image_A)
get_same_B = generator_network_AB(source_image_B)
  
discriminator_network_A.trainable=False
discriminator_network_B.trainable=False

# Tell Real vs Fake, for a given domain
verify_A = discriminator_network_A(fake_A)
verify_B = discriminator_network_B(fake_B)

cycle_gan = tensorflow.keras.models.Model(inputs = [source_image_A, source_image_B], \
                              outputs = [verify_A, verify_B, get_back_A, get_back_B, get_same_A, get_same_B])
cycle_gan.summary()<jupyter_output><empty_output><jupyter_text>Compiling Model<jupyter_code>cycle_gan.compile(loss=['mse', 'mse', 'mae', 'mae', 'mae', 'mae'], loss_weights=[1, 1, 10, 10, 5, 5],\
                                          optimizer=adam_optimizer)<jupyter_output><empty_output><jupyter_text>Define Data Generators<jupyter_code>def horses_to_zebras(horses, generator_network):
    generated_samples = generator_network.predict_on_batch(horses)
    return generated_samples

def zebras_to_horses(zebras, generator_network):
    generated_samples = generator_network.predict_on_batch(zebras)
    return generated_samples

def get_horse_samples(batch_size):
    random_files = np.random.choice(horses_train, size=batch_size)
    images = []
    for file in random_files:
        img = cv2.imread(file)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        images.append((img-127.5)/127.5)
    horse_images = np.array(images)
    return horse_images

def get_zebra_samples(batch_size):
    random_files = np.random.choice(zebras_train, size=batch_size)
    images = []
    for file in random_files:
        img = cv2.imread(file)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        images.append((img-127.5)/127.5)
    zebra_images = np.array(images)
    return zebra_images

def show_generator_results_horses_to_zebras(generator_network_AB, generator_network_BA):
    images = []
    for j in range(5):
        file = np.random.choice(horses_test)
        img = cv2.imread(file)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        images.append(img)

    print ('Input Horse Images')
    plt.figure(figsize=(13, 13))
    for j, img in enumerate(images):
        plt.subplot(550 + 1 + j)
        plt.imshow(img)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()

    print ('Translated (Horse -> Zebra) Images')
    translated = []
    plt.figure(figsize=(13, 13))
    for j, img in enumerate(images):
        img = (img-127.5)/127.5
        output = horses_to_zebras(np.array([img]), generator_network_AB)[0]
        translated.append(output)
        output = (output+1.0)/2.0
        plt.subplot(550 + 1 + j)
        plt.imshow(output)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()

    print ('Translated reverse ( Fake Zebras -> Fake Horses)')
    plt.figure(figsize=(13, 13))
    for j, img in enumerate(translated):
        output = zebras_to_horses(np.array([img]), generator_network_BA)[0]
        output = (output+1.0)/2.0
        plt.subplot(550 + 1 + j)
        plt.imshow(output)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()

def show_generator_results_zebras_to_horses(generator_network_AB, generator_network_BA):
    images = []
    for j in range(5):
        file = np.random.choice(zebras_test)
        img = cv2.imread(file)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        images.append(img)

    print ('Input Zebra Images')
    plt.figure(figsize=(13, 13))
    for j, img in enumerate(images):
        plt.subplot(550 + 1 + j)
        plt.imshow(img)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()

    print ('Translated (Zebra -> Horse) Images')
    translated = []
    plt.figure(figsize=(13, 13))
    for j, img in enumerate(images):
        img = (img-127.5)/127.5
        output = zebras_to_horses(np.array([img]), generator_network_BA)[0]
        translated.append(output)
        output = (output+1.0)/2.0
        plt.subplot(550 + 1 + j)
        plt.imshow(output)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()

    print ('Translated reverse (Fake Horse -> Fake Zebra)')
    plt.figure(figsize=(13, 13))
    for j, img in enumerate(translated):
        output = horses_to_zebras(np.array([img]), generator_network_AB)[0]
        output = (output+1.0)/2.0
        plt.subplot(550 + 1 + j)
        plt.imshow(output)
        plt.axis('off')
        #plt.title(trainY[i])
    plt.show()<jupyter_output><empty_output><jupyter_text>Training Cycle-GAN<jupyter_code>len(horses_train), len(zebras_train)
epochs = 500
batch_size = 1
steps = 1067

for i in range(0, epochs):
    if i%5 == 0:
        show_generator_results_horses_to_zebras(generator_network_AB, generator_network_BA)
        print ("-"*100)
        show_generator_results_zebras_to_horses(generator_network_AB, generator_network_BA)
    for j in range(steps):  
        # A == Horses
        # B == Zebras
        domain_A_images = get_horse_samples(batch_size)
        domain_B_images = get_zebra_samples(batch_size)

        fake_patch = np.zeros((batch_size, 32, 32, 1))
        real_patch = np.ones((batch_size, 32, 32, 1))
        
        fake_B_images = generator_network_AB(domain_A_images)
        fake_A_images = generator_network_BA(domain_B_images)
        
        # Updating Discriminator A weights
        discriminator_network_A.trainable=True
        discriminator_network_B.trainable=False
        loss_d_real_A = discriminator_network_A.train_on_batch(domain_A_images, real_patch)
        loss_d_fake_A = discriminator_network_A.train_on_batch(fake_A_images, fake_patch)
        
        loss_d_A = np.add(loss_d_real_A, loss_d_fake_A)/2.0
        
        # Updating Discriminator B weights
        discriminator_network_B.trainable=True
        discriminator_network_A.trainable=False
        loss_d_real_B = discriminator_network_B.train_on_batch(domain_B_images, real_patch)
        loss_d_fake_B = discriminator_network_B.train_on_batch(fake_B_images, fake_patch)
        
        loss_d_B = np.add(loss_d_real_B, loss_d_fake_B)/2.0
        
        # Make the Discriminator belive that these are real samples and calculate loss to train the generator
        
        discriminator_network_A.trainable=False
        discriminator_network_B.trainable=False
        
        # Updating Generator weights
        loss_g = cycle_gan.train_on_batch([domain_A_images, domain_B_images],\
                    [real_patch, real_patch, domain_A_images, domain_B_images, domain_A_images, domain_B_images])
        
        if j%100 == 0:
            print ("Epoch:%.0f, Step:%.0f, DA-Loss:%.3f, DA-Acc:%.3f, DB-Loss:%.3f, DB-Acc:%.3f, G-Loss:%.3f"\
                   %(i,j,loss_d_A[0],loss_d_A[1]*100,loss_d_B[0],loss_d_B[1]*100,loss_g[0]))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.123576113220573, 'fraction_numerical': 0.02623403520883673, 'mean_word_length': 3.9356047700170356, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 41, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '9912', 'license': 'MIT', 'n_tokens_mistral': 5410, 'n_tokens_neox': 5077, 'n_words': 836, 'path': 'Skill-08/cycle-gan/Cycle-GAN-No-Outputs.ipynb', 'repo_name': 'vcip2015/The-GAN-Book', 'size': '14485'}