{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport os","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-20T16:09:15.561215Z","iopub.execute_input":"2022-07-20T16:09:15.561647Z","iopub.status.idle":"2022-07-20T16:09:15.567553Z","shell.execute_reply.started":"2022-07-20T16:09:15.561615Z","shell.execute_reply":"2022-07-20T16:09:15.566064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import Input, Reshape, Dropout, Dense \nfrom tensorflow.keras.layers import Flatten, BatchNormalization\nfrom tensorflow.keras.layers import Activation, ZeroPadding2D\nfrom tensorflow.keras.layers import LeakyReLU\nfrom tensorflow.keras.layers import UpSampling2D, Conv2D\nfrom tensorflow.keras.models import Sequential, Model, load_model\nfrom tensorflow.keras.optimizers import Adam\nimport numpy as np\nfrom PIL import Image\nfrom tqdm import tqdm\nimport os \nimport time\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:15.620174Z","iopub.execute_input":"2022-07-20T16:09:15.620490Z","iopub.status.idle":"2022-07-20T16:09:15.629726Z","shell.execute_reply.started":"2022-07-20T16:09:15.620460Z","shell.execute_reply":"2022-07-20T16:09:15.628190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generation resolution - Must be square \n# Training data is also scaled to this.\n# Note GENERATE_RES 4 or higher  \n# will blow Google CoLab's memory and have not\n# been tested extensivly.\nGENERATE_RES = 3 # Generation resolution factor \n# (1=32, 2=64, 3=96, 4=128, etc.)\nGENERATE_SQUARE = 32 * GENERATE_RES # rows/cols (should be square)\nIMAGE_CHANNELS = 3\n\n# Preview image \nPREVIEW_ROWS = 4\nPREVIEW_COLS = 7\nPREVIEW_MARGIN = 16\n\n# Size vector to generate images from\nSEED_SIZE = 100\n\n# Configuration\nDATA_PATH = '/kaggle/input/gan-getting-started'\nEPOCHS = 1000\nBATCH_SIZE = 32\nBUFFER_SIZE = 60000\n\nprint(f\"Will generate {GENERATE_SQUARE}px square images.\")","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:15.703447Z","iopub.execute_input":"2022-07-20T16:09:15.703918Z","iopub.status.idle":"2022-07-20T16:09:15.715216Z","shell.execute_reply.started":"2022-07-20T16:09:15.703871Z","shell.execute_reply":"2022-07-20T16:09:15.713663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Nicely formatted time string\ndef hms_string(sec_elapsed):\n    h = int(sec_elapsed / (60 * 60))\n    m = int((sec_elapsed % (60 * 60)) / 60)\n    s = sec_elapsed % 60\n    return \"{}:{:>02}:{:>05.2f}\".format(h, m, s)","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:15.755386Z","iopub.execute_input":"2022-07-20T16:09:15.755832Z","iopub.status.idle":"2022-07-20T16:09:15.768796Z","shell.execute_reply.started":"2022-07-20T16:09:15.755771Z","shell.execute_reply":"2022-07-20T16:09:15.767401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_binary_path =f'training_data_{GENERATE_SQUARE}_{GENERATE_SQUARE}.npy'\n\nprint(f\"Looking for file: {training_binary_path}\")\n\nif not os.path.isfile(training_binary_path):\n    start = time.time()\n    print(\"Loading training images...\")\n    training_data = []\n    monet_path = os.path.join(DATA_PATH,'monet_jpg')\n    for filename in tqdm(os.listdir(monet_path)):\n        path = os.path.join(monet_path,filename)\n        if path!='/kaggle/input/gan-getting-started/monet_jpg':\n            image = Image.open(path).resize((GENERATE_SQUARE,\n            GENERATE_SQUARE),Image.ANTIALIAS)\n            training_data.append(np.asarray(image))\n    training_data = np.reshape(training_data,(-1,GENERATE_SQUARE,\n        GENERATE_SQUARE,IMAGE_CHANNELS))\n    training_data = training_data.astype(np.float32)\n    training_data = training_data / 127.5 - 1.\n    print(\"Saving training image binary...\")\n    np.save(training_binary_path,training_data)\n    elapsed = time.time()-start\n    print (f'Image preprocess time: {hms_string(elapsed)}')\nelse:\n    print(\"Loading previous training pickle...\")\n    training_data = np.load(training_binary_path)","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:15.854533Z","iopub.execute_input":"2022-07-20T16:09:15.854970Z","iopub.status.idle":"2022-07-20T16:09:15.882379Z","shell.execute_reply.started":"2022-07-20T16:09:15.854934Z","shell.execute_reply":"2022-07-20T16:09:15.880833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(training_data[10])","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:15.973750Z","iopub.execute_input":"2022-07-20T16:09:15.974920Z","iopub.status.idle":"2022-07-20T16:09:16.210111Z","shell.execute_reply.started":"2022-07-20T16:09:15.974868Z","shell.execute_reply":"2022-07-20T16:09:16.208827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = tf.data.Dataset.from_tensor_slices(training_data) \\\n    .shuffle(BUFFER_SIZE).batch(BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:16.212731Z","iopub.execute_input":"2022-07-20T16:09:16.214173Z","iopub.status.idle":"2022-07-20T16:09:16.258764Z","shell.execute_reply.started":"2022-07-20T16:09:16.214126Z","shell.execute_reply":"2022-07-20T16:09:16.257244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_generator(seed_size, channels):\n    model = Sequential()\n\n    model.add(Dense(4*4*256,activation=\"relu\",input_dim=seed_size))\n    model.add(Reshape((4,4,256)))\n\n    model.add(UpSampling2D())\n    model.add(Conv2D(256,kernel_size=3,padding=\"same\"))\n    model.add(BatchNormalization(momentum=0.8))\n    model.add(Activation(\"relu\"))\n\n    model.add(UpSampling2D())\n    model.add(Conv2D(256,kernel_size=3,padding=\"same\"))\n    model.add(BatchNormalization(momentum=0.8))\n    model.add(Activation(\"relu\"))\n   \n    # Output resolution, additional upsampling\n    model.add(UpSampling2D())\n    model.add(Conv2D(128,kernel_size=3,padding=\"same\"))\n    model.add(BatchNormalization(momentum=0.8))\n    model.add(Activation(\"relu\"))\n\n    if GENERATE_RES>1:\n        model.add(UpSampling2D(size=(GENERATE_RES,GENERATE_RES)))\n        model.add(Conv2D(128,kernel_size=3,padding=\"same\"))\n        model.add(BatchNormalization(momentum=0.8))\n        model.add(Activation(\"relu\"))\n\n    # Final CNN layer\n    model.add(Conv2D(channels,kernel_size=3,padding=\"same\"))\n    model.add(Activation(\"tanh\"))\n\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:16.261040Z","iopub.execute_input":"2022-07-20T16:09:16.261511Z","iopub.status.idle":"2022-07-20T16:09:16.276367Z","shell.execute_reply.started":"2022-07-20T16:09:16.261465Z","shell.execute_reply":"2022-07-20T16:09:16.275141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_discriminator(image_shape):\n    model = Sequential()\n\n    model.add(Conv2D(32, kernel_size=3, strides=2, input_shape=image_shape, \n                     padding=\"same\"))\n    model.add(LeakyReLU(alpha=0.2))\n\n    model.add(Dropout(0.25))\n    model.add(Conv2D(64, kernel_size=3, strides=2, padding=\"same\"))\n    model.add(ZeroPadding2D(padding=((0,1),(0,1))))\n    model.add(BatchNormalization(momentum=0.8))\n    model.add(LeakyReLU(alpha=0.2))\n\n    model.add(Dropout(0.25))\n    model.add(Conv2D(128, kernel_size=3, strides=2, padding=\"same\"))\n    model.add(BatchNormalization(momentum=0.8))\n    model.add(LeakyReLU(alpha=0.2))\n\n    model.add(Dropout(0.25))\n    model.add(Conv2D(256, kernel_size=3, strides=1, padding=\"same\"))\n    model.add(BatchNormalization(momentum=0.8))\n    model.add(LeakyReLU(alpha=0.2))\n\n    model.add(Dropout(0.25))\n    model.add(Conv2D(512, kernel_size=3, strides=1, padding=\"same\"))\n    model.add(BatchNormalization(momentum=0.8))\n    model.add(LeakyReLU(alpha=0.2))\n\n    model.add(Dropout(0.25))\n    model.add(Flatten())\n    model.add(Dense(1, activation='sigmoid'))\n\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:16.279239Z","iopub.execute_input":"2022-07-20T16:09:16.279708Z","iopub.status.idle":"2022-07-20T16:09:16.295498Z","shell.execute_reply.started":"2022-07-20T16:09:16.279662Z","shell.execute_reply":"2022-07-20T16:09:16.294275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_images(cnt,noise):\n    image_array = np.full(( \n      PREVIEW_MARGIN + (PREVIEW_ROWS * (GENERATE_SQUARE+PREVIEW_MARGIN)), \n      PREVIEW_MARGIN + (PREVIEW_COLS * (GENERATE_SQUARE+PREVIEW_MARGIN)), IMAGE_CHANNELS), \n      255, dtype=np.uint8)\n  \n    generated_images = generator.predict(noise)\n    generated_images = 0.5 * generated_images + 0.5\n\n    image_count = 0\n    for row in range(PREVIEW_ROWS):\n        for col in range(PREVIEW_COLS):\n            r = row * (GENERATE_SQUARE+16) + PREVIEW_MARGIN\n            c = col * (GENERATE_SQUARE+16) + PREVIEW_MARGIN\n            image_array[r:r+GENERATE_SQUARE,c:c+GENERATE_SQUARE] \\\n            = generated_images[image_count] * 255\n            image_count += 1\n\n          \n    output_path = './output'\n    if not os.path.exists(output_path):\n        os.makedirs(output_path)\n  \n    filename = os.path.join(output_path,f\"train-{cnt}.png\")\n    im = Image.fromarray(image_array)\n#     plt.imshow(im)\n    im.save(filename)","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:11:09.722655Z","iopub.execute_input":"2022-07-20T16:11:09.723327Z","iopub.status.idle":"2022-07-20T16:11:09.736696Z","shell.execute_reply.started":"2022-07-20T16:11:09.723290Z","shell.execute_reply":"2022-07-20T16:11:09.735162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator = build_generator(SEED_SIZE, IMAGE_CHANNELS)\n\nnoise = tf.random.normal([1, SEED_SIZE])\ngenerated_image = generator(noise, training=False)\n\nplt.imshow(generated_image[0, :, :, 0])","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:16.412972Z","iopub.execute_input":"2022-07-20T16:09:16.415067Z","iopub.status.idle":"2022-07-20T16:09:16.807524Z","shell.execute_reply.started":"2022-07-20T16:09:16.415032Z","shell.execute_reply":"2022-07-20T16:09:16.806246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_shape = (GENERATE_SQUARE,GENERATE_SQUARE,IMAGE_CHANNELS)\n\ndiscriminator = build_discriminator(image_shape)\ndecision = discriminator(generated_image)\ndecision","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:16.810487Z","iopub.execute_input":"2022-07-20T16:09:16.811266Z","iopub.status.idle":"2022-07-20T16:09:16.985199Z","shell.execute_reply.started":"2022-07-20T16:09:16.811219Z","shell.execute_reply":"2022-07-20T16:09:16.983952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cross_entropy = tf.keras.losses.BinaryCrossentropy()\n\ndef discriminator_loss(real_output, fake_output):\n    real_loss = cross_entropy(tf.ones_like(real_output), real_output)\n    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)\n    total_loss = real_loss + fake_loss\n    return total_loss\n\ndef generator_loss(fake_output):\n    return cross_entropy(tf.ones_like(fake_output), fake_output)","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:16.988965Z","iopub.execute_input":"2022-07-20T16:09:16.989310Z","iopub.status.idle":"2022-07-20T16:09:16.997243Z","shell.execute_reply.started":"2022-07-20T16:09:16.989279Z","shell.execute_reply":"2022-07-20T16:09:16.995773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"discriminator loss :\",discriminator_loss(training_data[100],generated_image))\nprint(\"generator loss :\",generator_loss(generated_image))","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:17.001509Z","iopub.execute_input":"2022-07-20T16:09:17.002781Z","iopub.status.idle":"2022-07-20T16:09:17.021862Z","shell.execute_reply.started":"2022-07-20T16:09:17.002720Z","shell.execute_reply":"2022-07-20T16:09:17.020545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = tf.keras.optimizers.Adam(1.5e-4,0.5)","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:17.025841Z","iopub.execute_input":"2022-07-20T16:09:17.026249Z","iopub.status.idle":"2022-07-20T16:09:17.032438Z","shell.execute_reply.started":"2022-07-20T16:09:17.026180Z","shell.execute_reply":"2022-07-20T16:09:17.030022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"generator_optimizer=optimizer\ndiscriminator_optimizer=optimizer","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:17.034637Z","iopub.execute_input":"2022-07-20T16:09:17.035812Z","iopub.status.idle":"2022-07-20T16:09:17.052893Z","shell.execute_reply.started":"2022-07-20T16:09:17.035762Z","shell.execute_reply":"2022-07-20T16:09:17.051389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_step(images):\n    seed = tf.random.normal([BATCH_SIZE, SEED_SIZE])\n\n    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:\n        generated_images = generator(seed, training=True)\n        real_output = discriminator(images, training=True)\n        fake_output = discriminator(generated_images, training=True)\n\n        gen_loss = generator_loss(fake_output)\n        disc_loss = discriminator_loss(real_output, fake_output)\n    \n\n        gradients_of_generator = gen_tape.gradient(\\\n            gen_loss, generator.trainable_variables)\n        gradients_of_discriminator = disc_tape.gradient(\\\n            disc_loss, discriminator.trainable_variables)\n\n        generator_optimizer.apply_gradients(zip(\n            gradients_of_generator, generator.trainable_variables))\n        discriminator_optimizer.apply_gradients(zip(\n            gradients_of_discriminator, \n            discriminator.trainable_variables))\n    return gen_loss,disc_loss","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:17.055099Z","iopub.execute_input":"2022-07-20T16:09:17.055924Z","iopub.status.idle":"2022-07-20T16:09:17.067458Z","shell.execute_reply.started":"2022-07-20T16:09:17.055868Z","shell.execute_reply":"2022-07-20T16:09:17.065870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(dataset, epochs):\n    fixed_seed = np.random.normal(0, 1, (PREVIEW_ROWS * PREVIEW_COLS, \n                                       SEED_SIZE))\n    start = time.time()\n\n    for epoch in range(epochs):\n        epoch_start = time.time()\n\n        gen_loss_list = []\n        disc_loss_list = []\n\n        for image_batch in dataset:\n            t = train_step(image_batch)\n            gen_loss_list.append(t[0])\n            disc_loss_list.append(t[1])\n\n        g_loss = sum(gen_loss_list) / len(gen_loss_list)\n        d_loss = sum(disc_loss_list) / len(disc_loss_list)\n\n        epoch_elapsed = time.time()-epoch_start\n        print (f'Epoch {epoch+1}, gen loss={g_loss},disc loss={d_loss},'\\\n               f' {hms_string(epoch_elapsed)}')\n        save_images(epoch,fixed_seed)\n        \n    elapsed = time.time()-start\n    print (f'Training time: {hms_string(elapsed)}')","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:09:17.069361Z","iopub.execute_input":"2022-07-20T16:09:17.070504Z","iopub.status.idle":"2022-07-20T16:09:17.084654Z","shell.execute_reply.started":"2022-07-20T16:09:17.070472Z","shell.execute_reply":"2022-07-20T16:09:17.082456Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train(train_dataset, EPOCHS)","metadata":{"execution":{"iopub.status.busy":"2022-07-20T16:11:23.114262Z","iopub.execute_input":"2022-07-20T16:11:23.114740Z","iopub.status.idle":"2022-07-20T16:12:02.100090Z","shell.execute_reply.started":"2022-07-20T16:11:23.114707Z","shell.execute_reply":"2022-07-20T16:12:02.098284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}