{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "GAN_V2", "provenance": [], "collapsed_sections": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "accelerator": "GPU" }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "zK59a-YN_peF", "colab_type": "text" }, "source": [ "import necessary library" ] }, { "cell_type": "code", "metadata": { "id": "fEU4VVN1_RLc", "colab_type": "code", "colab": {} }, "source": [ "import tensorflow as tf\n", "import tensorflow_addons as tfa\n", "\n", "from tensorflow.keras import layers\n", "import tensorflow.keras as keras\n", "import matplotlib.pyplot as plt\n", "import os\n", "import datetime\n", "import numpy as np\n", "\n", "import PIL \n" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "aiG3tQvnEMBd", "colab_type": "code", "colab": {} }, "source": [ "def denorm_int(x):\n", " return tf.cast((x+1.0)*127.5,tf.int8)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "_MRTgJRDEfWU", "colab_type": "code", "colab": {} }, "source": [ "def denorm_float(x):\n", " return (x+1.0)/2.0" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "xoR6YFXp3OMz", "colab_type": "text" }, "source": [ "Conv block" ] }, { "cell_type": "code", "metadata": { "id": "S0KLJh3G3Niw", "colab_type": "code", "colab": {} }, "source": [ "def convBlock(filters, size, stride, norm = \"batch_norm\", activation=\"lrelu\",padd=\"valid\"):\n", " initializer = tf.random_normal_initializer(0., 0.02)\n", " #initializer = tf.keras.initializers.GlorotNormal()\n", " result = tf.keras.Sequential()\n", " if padd == \"none\": \n", " result.add(tf.keras.layers.Conv2D(filters, size, stride, kernel_initializer=initializer))\n", " elif padd ==\"valid\": \n", " result.add(tf.keras.layers.Conv2D(filters, size, stride, padding='valid', kernel_initializer=initializer))\n", "\n", "\n", " if norm == \"batch_norm\":\n", " result.add(tf.keras.layers.BatchNormalization())\n", " elif norm == \"instance_norm\":\n", " result.add(tfa.layers.InstanceNormalization())\n", " elif norm == \"none\":\n", " pass\n", " else:\n", " print(\"parameter error\") \n", " \n", " if activation == \"lrelu\":\n", " result.add(tf.keras.layers.LeakyReLU(0.2))\n", " elif activation == \"tanh\":\n", " result.add(tf.keras.layers.Activation('tanh'))\n", " elif activation == \"none\":\n", " pass\n", " else:\n", " print(\"parameter error\")\n", "\n", " return result" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "4I9Aua2YJGMk", "colab_type": "text" }, "source": [ "Generator model" ] }, { "cell_type": "code", "metadata": { "id": "V51NRNw_VsPn", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 656 }, "outputId": "332f8291-3c04-4c5c-cbc0-5de46e7515b2" }, "source": [ "def create_generator(cur_scale):\n", " filter_num = 32\n", " pad = tf.keras.layers.ZeroPadding2D(5)\n", "\n", " prev_img = tf.keras.layers.Input(shape=[None,None,3],name=\"prev_img\")\n", " noise = tf.keras.layers.Input(shape=[None,None,3],name=\"noise\")\n", " pad_prev_img = pad(prev_img)\n", " pad_noise = pad(noise)\n", "\n", " x = tf.keras.layers.Add()([pad_prev_img, pad_noise])\n", " for i in range(4):\n", " x = convBlock(filter_num, 3, 1)(x)\n", " \n", " x = convBlock(3, 3, 1, norm=\"none\",activation=\"tanh\")(x)\n", " x = tf.keras.layers.Add()([prev_img,x])\n", "\n", " return tf.keras.Model(inputs=[prev_img, noise], outputs=x)\n", "\n", "#unit testing\n", "g = create_generator(6)\n", "tf.keras.utils.plot_model(g, show_shapes=True, dpi=64)\n", "#g.save(\"generator.h5\")" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 27 } ] }, { "cell_type": "markdown", "metadata": { "id": "6hcv1BdYBWdv", "colab_type": "text" }, "source": [ "Discriminator model" ] }, { "cell_type": "code", "metadata": { "id": "QZPVCyHzBV--", "colab_type": "code", "colab": { "base_uri": "https://localhost:8080/", "height": 435 }, "outputId": "c6345078-1c96-4b0d-c986-03bd124f0b51" }, "source": [ "def create_discriminator(cur_scale):\n", " filter_num = 32\n", " img = tf.keras.layers.Input(shape=[None,None,3])\n", " x = img\n", "\n", " for i in range(4):\n", " x = convBlock(filter_num, 3, 1)(x)\n", "\n", " x = convBlock(1, 3, 1,norm = \"none\",activation=\"none\")(x)\n", "\n", " return tf.keras.Model(inputs=img, outputs=x)\n", "\n", "#unit testing\n", "d = create_discriminator(6)\n", "tf.keras.utils.plot_model(d, show_shapes=True, dpi=64)\n", "#d.save(\"discriminator.h5\")" ], "execution_count": null, "outputs": [ { "output_type": "execute_result", "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": { "tags": [] }, "execution_count": 28 } ] }, { "cell_type": "markdown", "metadata": { "id": "kIMuO8PIFx3O", "colab_type": "text" }, "source": [ "Load image" ] }, { "cell_type": "code", "metadata": { "id": "CJzomXp5FxJk", "colab_type": "code", "colab": {} }, "source": [ "#return rescaled and [-1,1] float value image\n", "def load_and_preprocess(image_path):\n", " max_size = 400\n", " init_scale_factor = 0.75\n", " image = PIL.Image.open(image_path).convert(\"RGB\")\n", " image = tf.keras.preprocessing.image.img_to_array(image)\n", " image = tf.dtypes.cast(image, tf.float32)\n", " max_length = max(image.shape[0],image.shape[1])\n", " if max_length > max_size:\n", " resize_factor = max_size/max_length\n", " resize_h = tf.cast(image.shape[0]*resize_factor, tf.int16)\n", " resize_w = tf.cast(image.shape[1]*resize_factor, tf.int16)\n", " image = tf.image.resize(image, [resize_h, resize_w],antialias=True)\n", " #normalize the image value to [-1,1]\n", " image = (image / 127.5) - 1.0\n", " \n", " return image\n", "#x = load_and_preprocess(\"cows.png\")" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "AN7pJUUpGDcI", "colab_type": "code", "colab": {} }, "source": [ "#return 255 float value image\n", "def load_image(image_path):\n", " image = PIL.Image.open(image_path).convert(\"RGB\")\n", " image = tf.keras.preprocessing.image.img_to_array(image)\n", " return image" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "U3ZJurWfNmHU", "colab_type": "code", "colab": {} }, "source": [ "def calc_scale_and_factor(image):\n", " #init parameters\n", " init_factor = 0.75\n", " min_size = 25\n", "\n", " #decide the shorter length of image\n", " short_length = min(image.shape[0],image.shape[1])\n", "\n", " #step 1: calc approximate scale number\n", " scale = tf.math.floor(tf.math.log(min_size/short_length)/tf.math.log(init_factor))\n", "\n", " #step2: according to the scale number, calculate the scale factor\n", " factor = tf.math.pow((min_size/short_length),1/scale)\n", "\n", " #return int(scale+1), factor\n", " return 6, 0.75\n", "\n", "#image = load_and_preprocess(\"night.jpg\")\n", "#sca ,fa = calc_scale_and_factor(image)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "bzVeTUjx9dEO", "colab_type": "text" }, "source": [ "Create downsamples" ] }, { "cell_type": "code", "metadata": { "id": "SALH_Q5DzViQ", "colab_type": "code", "colab": {} }, "source": [ "def create_downsamples(image, scale,scale_factor):\n", " MIN_IMAGE_SIZE = 25\n", " downsample_images = []\n", " image_h, image_w = image.shape[0], image.shape[1]\n", " for cur_scale in range(scale):\n", " resize_image_h = max(int(image_h * pow(scale_factor,cur_scale)),MIN_IMAGE_SIZE) \n", " resize_image_w = max(int(image_w * pow(scale_factor,cur_scale)),MIN_IMAGE_SIZE)\n", " \n", " resize_image = tf.image.resize(image, [resize_image_h, resize_image_w],antialias=True)\n", " resize_image = tf.expand_dims(resize_image,0)\n", " downsample_images.append(resize_image)\n", " \n", " downsample_images.reverse()\n", " for cur_scale in range(scale):\n", " print(\"scale: \", cur_scale, \"shape:\",downsample_images[cur_scale].shape)\n", "\n", " return downsample_images\n", "\n", "#x = load_and_preprocess(\"cows.png\")\n", "#y = create_downsamples(x,7)" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "8pj7qatL9x1i", "colab_type": "text" }, "source": [ "gradient penalty" ] }, { "cell_type": "code", "metadata": { "id": "4Kq5ohwo9uy1", "colab_type": "code", "colab": {} }, "source": [ "def gradient_penalty(dnet, real, gen_img):\n", " epsilon = tf.random.uniform(shape=[1],maxval=1.0)\n", " interpolation = epsilon * real + (1 - epsilon) * gen_img\n", " with tf.GradientTape() as t:\n", " t.watch(interpolation)\n", " interpolation_score = dnet(interpolation)\n", " gradients = t.gradient(interpolation_score, interpolation)\n", " gradient_per_pixel = tf.sqrt(tf.reduce_sum(gradients ** 2, axis=[3]))\n", " gp = tf.reduce_mean((gradient_per_pixel - 1.0) ** 2)\n", " return gp" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "QhK-9VCUgfjn", "colab_type": "text" }, "source": [ "Inference part" ] }, { "cell_type": "code", "metadata": { "id": "8MErMVIFEQnG", "colab_type": "code", "colab": {} }, "source": [ "#generate random samples at generate_scale, return generated image with shape(height,width,3)\n", "def random_sample(trainer, generate_scale=0 ):\n", " prev_ = tf.zeros_like(trainer.real_images[0])\n", " for i in range(trainer.num_scale):\n", " if i < generate_scale:\n", " noise = trainer.noise_rec[i]*trainer.noise_amp[i]\n", " if i >= generate_scale:\n", " noise = tf.random.normal(trainer.real_images[i].shape,0,0.2)\n", " noise = noise * trainer.noise_amp[i]\n", " prev_ = trainer.gnets[i]([prev_, noise])\n", " if i != trainer.num_scale - 1:\n", " prev_ = tf.image.resize(prev_,[trainer.real_images[i+1].shape[1],trainer.real_images[i+1].shape[2]])\n", " img = denorm_float(prev_)\n", " #plt.imshow(img[0])\n", " return img[0]" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "KVnEXiLkGEKf", "colab_type": "code", "colab": {} }, "source": [ "#inject an image at generate_scale, return generated image with shape(height,width,3)\n", "def inject_image(trainer, inject_image_path, generate_scale=1):\n", " inject_image = load_image(inject_image_path)\n", " inject_image = (inject_image/127.5)-1.0\n", " if generate_scale ==0:\n", " print(\"ERROR, generate scale is not allowed to be 0 in image manipulation task \")\n", " return 0\n", " else:\n", " shape = trainer.real_images[generate_scale].shape\n", " inject_image = tf.image.resize(inject_image,[shape[1],shape[2]])\n", " prev_ = tf.expand_dims(inject_image,0)\n", " for i in range(trainer.num_scale):\n", " if i >= generate_scale:\n", " noise = tf.random.normal(trainer.real_images[i].shape,0,0.2)\n", " noise = noise * trainer.noise_amp[i]\n", " #noise = trainer.noise_rec[i]*trainer.noise_amp[i]\n", "\n", " prev_ = trainer.gnets[i]([prev_, noise])\n", " if i != trainer.num_scale - 1:\n", " prev_ = tf.image.resize(prev_,[trainer.real_images[i+1].shape[1],trainer.real_images[i+1].shape[2]])\n", " img = denorm_float(prev_)\n", " #plt.imshow(img[0])\n", " return img[0]" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "HsU_NMFaX8HU", "colab_type": "text" }, "source": [ "Main train" ] }, { "cell_type": "code", "metadata": { "id": "P3GniIbiJNwn", "colab_type": "code", "colab": {} }, "source": [ "class main_train:\n", " def __init__(self):\n", " self.EPOCHS = 2001\n", " self.D_STEP = 3\n", " self.G_STEP = 3\n", " self.ALPHA = 0.1\n", " self.BETA = 10.0\n", " self.dnets = []\n", " self.gnets = []\n", " \n", " def preprocess(self,image_path):\n", " self.file_name = image_path\n", " image = load_and_preprocess(image_path)\n", " self.num_scale, self.scale_factor = calc_scale_and_factor(image)\n", " self.real_images = create_downsamples(image,self.num_scale,self.scale_factor)\n", "\n", "\n", " def init_model(self):\n", " for scale in range(self.num_scale):\n", " dnet = create_discriminator(scale)\n", " gnet = create_generator(scale)\n", " self.dnets.append(dnet)\n", " self.gnets.append(gnet)\n", " self.noise_amp = [0. for i in range(self.num_scale)]\n", " self.noise_rec = [0. for i in range(self.num_scale)]\n", " \n", " def save_model(self,scale):\n", " d_dir = f'weight/{self.file_name}/d/{scale}'\n", " g_dir = f'weight/{self.file_name}/g/{scale}'\n", "\n", " self.dnets[scale].save_weights(d_dir, save_format='tf')\n", " self.gnets[scale].save_weights(g_dir, save_format='tf')\n", "\n", " def train_timer(self,last_time):\n", " cur_time = datetime.datetime.now()\n", " interval = (cur_time - last_time).seconds\n", " interval_in_minute = interval/60.0\n", " return interval_in_minute\n", "\n", " def load_model(self,scale):\n", " if scale%4 != 100:\n", " self.dnets[scale].load_weights(f'weight/{self.file_name}/d/{scale-1}')\n", " self.gnets[scale].load_weights(f'weight/{self.file_name}/g/{scale-1}')\n", "\n", " def train(self,image_path):\n", " #timer\n", " start_time = datetime.datetime.now()\n", "\n", " #load image and calculate scale, factor, and downsamole\n", " self.preprocess(image_path)\n", " self.init_model()\n", "\n", " for cur_scale in range(self.num_scale):\n", " scale_start_time = datetime.datetime.now()\n", " #------training--------\n", " self.train_single_scale(cur_scale)\n", " self.save_model(cur_scale)\n", " #------end-------------\n", " interval = self.train_timer(scale_start_time)\n", " print(f\"finish training scale {cur_scale}, used time: {interval}\")\n", " amp_dir = f'weight/{self.file_name}/amp'\n", " rec_dir = f'weight/{self.file_name}/rec'\n", " np.save(amp_dir, self.noise_amp)\n", " np.save(rec_dir, self.noise_rec[0])\n", " interval = self.train_timer(start_time)\n", " print(\"used time: \", interval)\n", " self.train_status = True\n", "\n", " def inference(self, inject_image_path, mode, generate_scale):\n", " if mode == \"pure\":\n", " random_sample(self,generate_scale)\n", " elif mode == \"inject\":\n", " inject_image(self,inject_image_path,generate_scale)\n", "\n", " def train_single_scale(self,cur_scale): \n", " #network parameter\n", " lr = tf.keras.optimizers.schedules.ExponentialDecay(5e-4, decay_steps=4800, decay_rate=0.1, staircase=True)\n", " #lr_d = tf.keras.optimizers.schedules.ExponentialDecay(5e-4, decay_steps=1600, decay_rate=0.1, staircase=True)\n", "\n", "\n", " g_optimizer = tf.keras.optimizers.Adam(lr, beta_1=0.5, beta_2 = 0.999)\n", " d_optimizer = tf.keras.optimizers.Adam(lr, beta_1=0.5, beta_2 = 0.999)\n", " if cur_scale != 0:\n", " self.load_model(cur_scale)\n", " \n", " real_image = self.real_images[cur_scale]\n", "\n", " for epoch in range(self.EPOCHS):\n", " #noise_rec, prev_rec, noise_amp\n", " if cur_scale == 0:\n", " self.noise_rec[cur_scale] = tf.random.normal(real_image.shape,0,0.2)\n", " prev_rec = tf.zeros_like(real_image)\n", " prev_img = tf.zeros_like(real_image)\n", " self.noise_amp[cur_scale]= 1.0\n", " else:\n", " self.noise_rec[cur_scale] = tf.zeros_like(real_image)\n", " prev_rec = self.generate_prev_img(cur_scale,\"rec\")\n", " prev_img = self.generate_prev_img(cur_scale,\"img\")\n", " if epoch ==0:\n", " RMSE = tf.math.sqrt(tf.reduce_mean(tf.square(real_image - prev_rec)))\n", " self.noise_amp[cur_scale] = 0.1 * RMSE\n", " \n", " #prev_img, noise\n", " noise = tf.random.normal(real_image.shape,0,0.2)\n", " noise = noise * self.noise_amp[cur_scale]\n", "\n", " \n", " #----------------------------\n", " #training discriminator\n", " for step in range(self.D_STEP):\n", " with tf.GradientTape() as disc_tape:\n", " fake_image = self.gnets[cur_scale]([prev_img,noise])\n", " d_real_score = tf.reduce_mean(self.dnets[cur_scale](real_image))\n", " d_fake_score = tf.reduce_mean(self.dnets[cur_scale](fake_image))\n", " d_adv_loss = d_fake_score - d_real_score\n", " gp = gradient_penalty(self.dnets[cur_scale],real_image,fake_image)\n", " d_loss = d_adv_loss + self.ALPHA * gp\n", "\n", " d_grad = disc_tape.gradient(d_loss,self.dnets[cur_scale].trainable_variables)\n", " d_optimizer.apply_gradients(zip(d_grad,self.dnets[cur_scale].trainable_variables))\n", " \n", " \n", " #----------------------------\n", " #training generator\n", " for step in range(self.G_STEP):\n", " with tf.GradientTape() as gen_tape:\n", " fake_image = self.gnets[cur_scale]([prev_img,noise])\n", " fake_rec = self.gnets[cur_scale]([prev_rec,self.noise_rec[cur_scale]])\n", " g_real_score = tf.reduce_mean(self.dnets[cur_scale](real_image))\n", " g_fake_score = tf.reduce_mean(self.dnets[cur_scale](fake_image))\n", " g_adv_loss = -g_fake_score\n", " rec_loss = tf.reduce_mean(tf.square(fake_rec - real_image))\n", " g_loss = g_adv_loss + self.BETA * rec_loss\n", " \n", " g_grad = gen_tape.gradient(g_loss,self.gnets[cur_scale].trainable_variables)\n", " g_optimizer.apply_gradients(zip(g_grad,self.gnets[cur_scale].trainable_variables))\n", "\n", " shown_loss = tf.reduce_mean(tf.square(fake_image - real_image))\n", "\n", " if epoch % 100 ==0:\n", " print(\"epoch: \",epoch)\n", " print(\"d_real_score: \",d_real_score)\n", " print(\"d_fake_score: \",d_fake_score)\n", " #print(\"grad_penalty: \",self.ALPHA * gp)\n", " #print(\"d_loss: \",d_loss)\n", "\n", " print(\"g_real_score: \",g_real_score)\n", " print(\"g_fake_score: \",g_fake_score)\n", " print(\"rec_loss: \",rec_loss)\n", " print(\"exact loss: \",shown_loss)\n", " #print(\"g_loss: \",g_loss)\n", " \n", " return 1\n", "\n", "\n", "\n", " def generate_prev_img(self, cur_scale,mode):\n", " #when cur_scale == 0\n", " prev_ = tf.zeros_like(self.real_images[0])\n", " if mode == \"rec\":\n", " for i in range(cur_scale):\n", " noise = self.noise_rec[i] * self.noise_amp[i]\n", " prev_ = self.gnets[i]([prev_, noise])\n", " prev_ = tf.image.resize(prev_,[self.real_images[i+1].shape[1],self.real_images[i+1].shape[2]])\n", " \n", " elif mode == \"img\":\n", " for i in range(cur_scale):\n", " noise = tf.random.normal(self.real_images[i].shape,0,0.2)\n", " noise = noise * self.noise_amp[i]\n", " prev_ = self.gnets[i]([prev_, noise])\n", " prev_ = tf.image.resize(prev_,[self.real_images[i+1].shape[1],self.real_images[i+1].shape[2]])\n", " \n", " return prev_" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "wAuEjKurq6Li", "colab_type": "text" }, "source": [ "Training single image" ] }, { "cell_type": "code", "metadata": { "id": "d4ith09qfcZG", "colab_type": "code", "colab": {} }, "source": [ "trainer = main_train()\n", "trainer.train(\"6_wheat_field_vangogh.jpg\")" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "w4vMu0wOrBkI", "colab_type": "text" }, "source": [ "Batch training" ] }, { "cell_type": "code", "metadata": { "id": "cdRXT625l7Fx", "colab_type": "code", "colab": {} }, "source": [ "\"\"\"\n", "def batch_train(file_list):\n", " for name in file_list:\n", " trainer = main_train()\n", " trainer.train(name)\n", " source = f'weight/{trainer.file_name}'\n", " des = f'drive/My\\ Drive/new_weight400/{trainer.file_name}'\n", " print(source, des)\n", " !cp -r $source $des\n", "\n", "file_list = ['example.jpg','balloons.png','sea.jpg']\n", "batch_train(file_list)\n", "\"\"\"" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "tgV4xa2i_z9G", "colab_type": "text" }, "source": [ "Inferencer" ] }, { "cell_type": "code", "metadata": { "id": "nG5QqKWmoYax", "colab_type": "code", "colab": {} }, "source": [ "def save_img(image,path):\n", " image *= 255.0\n", " image = tf.clip_by_value(image, clip_value_min=0.0, clip_value_max=255.0)\n", " image = PIL.Image.fromarray(np.array(image).astype(np.uint8).squeeze())\n", " image.save(path)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "HzR-hAyUrg6j", "colab_type": "code", "colab": {} }, "source": [ "#this code is copied from SinGAN and modified.\n", "from skimage import color, morphology, filters\n", "def dilate_mask(mask,mode):\n", " if mode == \"harmonization\":\n", " element = morphology.disk(radius=1)\n", " if mode == \"editing\":\n", " element = morphology.disk(radius=20)\n", " mask = mask[:,:,0]\n", " mask = morphology.binary_dilation(mask,selem=element)\n", " mask = filters.gaussian(mask, sigma=5)\n", " mask = tf.expand_dims(mask,2)\n", " return mask" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "9NK6hzp_rgUB", "colab_type": "code", "colab": {} }, "source": [ "#loader use to load weight and parametes from trained model\n", "def create_loader(img_path):\n", " loader = main_train()\n", " #load num_scale, scale_factor, real_images\n", " loader.preprocess(img_path)\n", " #load gnet, noise_amp\n", " loader.init_model()\n", " for scale in range(loader.num_scale):\n", " loader.gnets[scale].load_weights(f'weight/{loader.file_name}/g/{scale}')\n", " amp_dir = f'weight/{loader.file_name}/amp.npy'\n", " loader.noise_amp = np.load(amp_dir)\n", " #load noise_rec\n", " rec_dir = f'weight/{loader.file_name}/rec.npy'\n", " loader.noise_rec[0] = tf.convert_to_tensor(np.load(rec_dir))\n", " for scale in range(1,loader.num_scale):\n", " loader.noise_rec[scale] = tf.zeros_like(loader.real_images[scale])\n", " \n", " return loader" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "ELonKnBvJeNo", "colab_type": "code", "colab": {} }, "source": [ "def main_inference(mode,img_path,inject_path,mask_path,num_sample):\n", " loader = create_loader(img_path)\n", " dir_path = f'generated_image/{loader.file_name}/{mode}'\n", " if not os.path.exists(dir_path):\n", " os.makedirs(dir_path)\n", " if mode == \"random\":\n", " for i in range(num_sample):\n", " result = random_sample(loader,0)\n", " save_path = dir_path+f'/sample:{i}.jpg'\n", " save_img(result,save_path)\n", " plt.imshow(result)\n", " elif mode == \"low_random\":\n", " for start_scale in range(1,loader.num_scale):\n", " result = random_sample(loader,start_scale)\n", " save_path = dir_path+ f'/scale:{start_scale}.jpg'\n", " save_img(result,save_path)\n", " plt.imshow(result)\n", " elif mode == \"paint\":\n", " for start_scale in range(1,loader.num_scale):\n", " result = inject_image(loader,inject_path,start_scale)\n", " save_path = dir_path+f'/scale:{start_scale}.jpg'\n", " save_img(result,save_path)\n", " plt.imshow(result)\n", " elif mode == \"harmonization\" or mode ==\"editing\":\n", " for start_scale in range(1,loader.num_scale):\n", " real = loader.real_images[-1]\n", " real = denorm_float(real[0])\n", " mask = load_image(mask_path)\n", " mask = dilate_mask(mask,mode)\n", " mask = tf.image.resize(mask,[real.shape[0],real.shape[1]],antialias = True)\n", " fake = inject_image(loader,inject_path,start_scale)\n", " result = mask * fake + (1-mask) * real\n", " save_path = dir_path+f'/scale:{start_scale}.jpg'\n", " save_img(result,save_path)\n", " plt.imshow(result)\n", " else:\n", " print(\"mode parameter wrong\")" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "hSHDhh3MRxrS", "colab_type": "code", "colab": {} }, "source": [ "main_inference(\"random\",\"wheat_field_vangogh.jpg\",None,None,20)" ], "execution_count": null, "outputs": [] }, { "cell_type": "code", "metadata": { "id": "OHNIGJGB_iuL", "colab_type": "code", "colab": {} }, "source": [ "#cp -r generated_image drive/My\\ Drive/sxsxsx" ], "execution_count": null, "outputs": [] }, { "cell_type": "markdown", "metadata": { "id": "SK-DpGWiPl7G", "colab_type": "text" }, "source": [ "remaining things(useless)" ] }, { "cell_type": "code", "metadata": { "id": "mKMmjRQ2C1oh", "colab_type": "code", "colab": {} }, "source": [ "#check ge erated image at each scale\n", "def generate_scale(trainer,scale): \n", " prev_ = trainer.generate_prev_img(scale,\"img\")\n", " noise = tf.random.normal(trainer.real_images[scale].shape,0,0.2)\n", " noise = noise * trainer.noise_amp[scale]\n", " prev_ = trainer.gnets[scale]([prev_, noise])\n", " prev_ = (prev_ + 1.0)/2.0\n", " plt.imshow(prev_[0])\n", "\n", "generate_scale(trainer,1)" ], "execution_count": null, "outputs": [] } ] }