{"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":"!pip install pydot graphviz","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-11T19:50:40.805204Z","iopub.execute_input":"2021-08-11T19:50:40.805559Z","iopub.status.idle":"2021-08-11T19:50:46.609924Z","shell.execute_reply.started":"2021-08-11T19:50:40.805523Z","shell.execute_reply":"2021-08-11T19:50:46.608926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for loading/processing the images  \nfrom keras.preprocessing.image import load_img \nfrom keras.preprocessing.image import img_to_array \nfrom keras.applications.vgg16 import preprocess_input \n\n# models \nfrom keras.applications.vgg16 import VGG16 \nfrom keras.models import Model\n\n# clustering and dimension reduction\nfrom sklearn.cluster import KMeans\nfrom sklearn.decomposition import PCA\n\n# for everything else\nimport os\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom random import randint\nimport pandas as pd\nimport pickle\nfrom kaggle_datasets import KaggleDatasets\n\n!pip install pydot graphviz\n","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:46.611998Z","iopub.execute_input":"2021-08-11T19:50:46.612384Z","iopub.status.idle":"2021-08-11T19:50:55.005488Z","shell.execute_reply.started":"2021-08-11T19:50:46.612344Z","shell.execute_reply":"2021-08-11T19:50:55.004357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = \"../input/gan-getting-started/monet_jpg/\"\n\n# this list holds all the image filename\nmonet_images = []\n\n# creates a ScandirIterator aliased as files\nwith os.scandir(path) as files:\n  # loops through each file in the directory\n    for file in files:\n        if file.name.endswith('.jpg'):\n          # adds only the image files to the monet_images list\n            monet_images.append(path + file.name)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:55.011189Z","iopub.execute_input":"2021-08-11T19:50:55.014377Z","iopub.status.idle":"2021-08-11T19:50:55.026556Z","shell.execute_reply.started":"2021-08-11T19:50:55.014332Z","shell.execute_reply":"2021-08-11T19:50:55.025572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_images[0]\n","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:55.031848Z","iopub.execute_input":"2021-08-11T19:50:55.034080Z","iopub.status.idle":"2021-08-11T19:50:55.048050Z","shell.execute_reply.started":"2021-08-11T19:50:55.034040Z","shell.execute_reply":"2021-08-11T19:50:55.046717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load the image as a 224x224 array\nimg = load_img(monet_images[0], target_size=(224,224))\n# convert from 'PIL.Image.Image' to numpy array\nimg = np.array(img)\n\nprint(img.shape)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:55.055057Z","iopub.execute_input":"2021-08-11T19:50:55.055695Z","iopub.status.idle":"2021-08-11T19:50:55.085344Z","shell.execute_reply.started":"2021-08-11T19:50:55.055653Z","shell.execute_reply":"2021-08-11T19:50:55.084466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reshaped_img = img.reshape(1,224, 224, 3)\nprint(reshaped_img.shape)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:55.091377Z","iopub.execute_input":"2021-08-11T19:50:55.094225Z","iopub.status.idle":"2021-08-11T19:50:55.105125Z","shell.execute_reply.started":"2021-08-11T19:50:55.094187Z","shell.execute_reply":"2021-08-11T19:50:55.104031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = preprocess_input(reshaped_img)\n","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:55.107520Z","iopub.execute_input":"2021-08-11T19:50:55.109625Z","iopub.status.idle":"2021-08-11T19:50:55.117110Z","shell.execute_reply.started":"2021-08-11T19:50:55.109587Z","shell.execute_reply":"2021-08-11T19:50:55.116093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nimport matplotlib.pyplot as plt\nimport matplotlib\nimport numpy as np\nimport time\nfrom PIL import Image\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:55.119667Z","iopub.execute_input":"2021-08-11T19:50:55.121571Z","iopub.status.idle":"2021-08-11T19:50:55.137174Z","shell.execute_reply.started":"2021-08-11T19:50:55.121528Z","shell.execute_reply":"2021-08-11T19:50:55.136281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load model\nmodel = VGG16()\n# remove the output layer\nmodel = Model(inputs=model.inputs, outputs=model.layers[-2].output)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:55.138712Z","iopub.execute_input":"2021-08-11T19:50:55.140021Z","iopub.status.idle":"2021-08-11T19:50:57.891904Z","shell.execute_reply.started":"2021-08-11T19:50:55.139517Z","shell.execute_reply":"2021-08-11T19:50:57.891134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features = model.predict(x)\nprint(features.shape)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:57.893797Z","iopub.execute_input":"2021-08-11T19:50:57.894332Z","iopub.status.idle":"2021-08-11T19:50:59.170403Z","shell.execute_reply.started":"2021-08-11T19:50:57.894292Z","shell.execute_reply":"2021-08-11T19:50:59.168142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load the model first and pass as an argument\nmodel = VGG16()\nmodel = Model(inputs = model.inputs, outputs = model.layers[-2].output)\n\ndef extract_features(file, model):\n    # load the image as a 224x224 array\n    img = load_img(file, target_size=(224,224))\n    # convert from 'PIL.Image.Image' to numpy array\n    img = np.array(img) \n    # reshape the data for the model reshape(num_of_samples, dim 1, dim 2, channels)\n    reshaped_img = img.reshape(1,224,224,3) \n    # prepare image for model\n    imgx = preprocess_input(reshaped_img)\n    # get the feature vector\n    features = model.predict(imgx, use_multiprocessing=True)\n    return features","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:50:59.171979Z","iopub.execute_input":"2021-08-11T19:50:59.172248Z","iopub.status.idle":"2021-08-11T19:51:01.023421Z","shell.execute_reply.started":"2021-08-11T19:50:59.172220Z","shell.execute_reply":"2021-08-11T19:51:01.022500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_images[0]\n","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:01.024672Z","iopub.execute_input":"2021-08-11T19:51:01.025038Z","iopub.status.idle":"2021-08-11T19:51:01.032042Z","shell.execute_reply.started":"2021-08-11T19:51:01.025002Z","shell.execute_reply":"2021-08-11T19:51:01.031150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = {}\np = \"monet_images.pkl\"\n\n# lop through each image in the dataset\nfor monet_image in monet_images:\n    # try to extract the features and update the dictionary\n    feat = extract_features(monet_image,model)\n    data[monet_image] = feat\n          \n \n# get a list of the filenames\nfilenames = np.array(list(data.keys()))\n\n# get a list of just the features\nfeat = np.array(list(data.values()))\nfeat.shape\n(210, 1, 4096)\n\n# reshape so that there are 210 samples of 4096 vectors\nfeat = feat.reshape(-1,4096)\nfeat.shape\n(210, 4096)\n\nunique_labels = list(set(list(range(30))))","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:01.033685Z","iopub.execute_input":"2021-08-11T19:51:01.034390Z","iopub.status.idle":"2021-08-11T19:51:12.439534Z","shell.execute_reply.started":"2021-08-11T19:51:01.034330Z","shell.execute_reply":"2021-08-11T19:51:12.438474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pca = PCA(n_components=100, random_state=22)\npca.fit(feat)\nx = pca.transform(feat)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:12.441034Z","iopub.execute_input":"2021-08-11T19:51:12.441424Z","iopub.status.idle":"2021-08-11T19:51:12.525615Z","shell.execute_reply.started":"2021-08-11T19:51:12.441386Z","shell.execute_reply":"2021-08-11T19:51:12.524683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kmeans = KMeans(n_clusters=len(unique_labels),n_jobs=-1, random_state=22)\nkmeans.fit(x)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:12.527202Z","iopub.execute_input":"2021-08-11T19:51:12.527623Z","iopub.status.idle":"2021-08-11T19:51:12.821393Z","shell.execute_reply.started":"2021-08-11T19:51:12.527584Z","shell.execute_reply":"2021-08-11T19:51:12.820487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# holds the cluster id and the images { id: [images] }\ngroups = {}\nfor file, cluster in zip(filenames,kmeans.labels_):\n    if cluster not in groups.keys():\n        groups[cluster] = []\n        groups[cluster].append(file)\n    else:\n        groups[cluster].append(file)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:12.822681Z","iopub.execute_input":"2021-08-11T19:51:12.823221Z","iopub.status.idle":"2021-08-11T19:51:12.832764Z","shell.execute_reply.started":"2021-08-11T19:51:12.823180Z","shell.execute_reply":"2021-08-11T19:51:12.832080Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\n\nimgs = groups[2]\n\nplt.figure()\n\n#subplot(r,c) provide the no. of rows and columns\nf, axarr = plt.subplots(2,2, figsize = (2*40,40))\n\nl = 0\nfor i in range(2):\n    for j in range(2):\n        axarr[i][j].imshow(cv2.imread(imgs[l]))\n        l+=1","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:12.837313Z","iopub.execute_input":"2021-08-11T19:51:12.837761Z","iopub.status.idle":"2021-08-11T19:51:14.455753Z","shell.execute_reply.started":"2021-08-11T19:51:12.837725Z","shell.execute_reply":"2021-08-11T19:51:14.454704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# we choose image 0 in every cluster as a representitive\nmonet_dataset_paths = []\nfor i in range(len(groups)):\n    monet_dataset_paths.append(groups[i][0].replace(\"../input/gan-getting-started/monet_jpg/\", \"\"))\nprint(monet_dataset_paths)\nlen(monet_dataset_paths)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:14.457134Z","iopub.execute_input":"2021-08-11T19:51:14.457533Z","iopub.status.idle":"2021-08-11T19:51:14.466632Z","shell.execute_reply.started":"2021-08-11T19:51:14.457490Z","shell.execute_reply":"2021-08-11T19:51:14.465662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Cleaning the cuda memory","metadata":{}},{"cell_type":"code","source":"!pip install numba \nfrom numba import cuda \ndev = cuda.get_current_device()\ndev.reset()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:14.468038Z","iopub.execute_input":"2021-08-11T19:51:14.468527Z","iopub.status.idle":"2021-08-11T19:51:20.803654Z","shell.execute_reply.started":"2021-08-11T19:51:14.468489Z","shell.execute_reply":"2021-08-11T19:51:20.802609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:20.805387Z","iopub.execute_input":"2021-08-11T19:51:20.805746Z","iopub.status.idle":"2021-08-11T19:51:20.882041Z","shell.execute_reply.started":"2021-08-11T19:51:20.805706Z","shell.execute_reply":"2021-08-11T19:51:20.881151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from glob import glob\nimport itertools\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport os\nimport pandas as pd\nimport PIL\nfrom PIL import Image\nimport random\nimport shutil\nfrom sklearn.model_selection import GroupKFold\nfrom sklearn.metrics import roc_curve\nfrom sklearn import metrics\nimport time\nfrom tqdm.notebook import tqdm\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.nn.init as init\nfrom torch.utils.data import Dataset, random_split, DataLoader\n\nimport torchvision.models as models\nimport torchvision.transforms as transforms","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2021-08-11T19:51:20.883550Z","iopub.execute_input":"2021-08-11T19:51:20.883906Z","iopub.status.idle":"2021-08-11T19:51:21.488635Z","shell.execute_reply.started":"2021-08-11T19:51:20.883867Z","shell.execute_reply":"2021-08-11T19:51:21.487649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Seed","metadata":{}},{"cell_type":"code","source":"def set_seed(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:21.489927Z","iopub.execute_input":"2021-08-11T19:51:21.490335Z","iopub.status.idle":"2021-08-11T19:51:21.556605Z","shell.execute_reply.started":"2021-08-11T19:51:21.490297Z","shell.execute_reply":"2021-08-11T19:51:21.555553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:21.558246Z","iopub.execute_input":"2021-08-11T19:51:21.558697Z","iopub.status.idle":"2021-08-11T19:51:21.625592Z","shell.execute_reply.started":"2021-08-11T19:51:21.558651Z","shell.execute_reply":"2021-08-11T19:51:21.624713Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"set_seed(719)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:21.628134Z","iopub.execute_input":"2021-08-11T19:51:21.628826Z","iopub.status.idle":"2021-08-11T19:51:21.686875Z","shell.execute_reply.started":"2021-08-11T19:51:21.628786Z","shell.execute_reply":"2021-08-11T19:51:21.686036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset and Dataloader","metadata":{}},{"cell_type":"code","source":"!mkdir monet_30","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:21.688422Z","iopub.execute_input":"2021-08-11T19:51:21.688871Z","iopub.status.idle":"2021-08-11T19:51:22.431324Z","shell.execute_reply.started":"2021-08-11T19:51:21.688833Z","shell.execute_reply":"2021-08-11T19:51:22.430354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Select 30 monet images for training","metadata":{}},{"cell_type":"code","source":"FILENAMES = monet_dataset_paths\n#FILENAMES = ['3b262c6726.jpg','3c341ff93e.jpg','05b493ff42.jpg','5e357ad790.jpg','6c6cc46498.jpg','6e0429f92e.jpg','6ee7c39dbc.jpg','8b54448a07.jpg','8f02369f42.jpg','10c555c1b1.jpg','25c9904782.jpg','73f33a12c5.jpg','92c0ba8c0d.jpg','99d94af5dd.jpg','7017e6caa1.jpg','7239ba0b55.jpg','9843bc25c5.jpg','011835cfbf.jpg','064487d630.jpg','2581464ddc.jpg','88402296cc.jpg','a7977705be.jpg','b1ea5d5a7d.jpg','bf6db09354.jpg','c1dc1a85a4.jpg','cb9c553ded.jpg','cdddf326e3.jpg','dc33f0edbe.jpg','e510a74d3c.jpg','ee7adac58f.jpg']","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:22.432936Z","iopub.execute_input":"2021-08-11T19:51:22.433270Z","iopub.status.idle":"2021-08-11T19:51:22.507132Z","shell.execute_reply.started":"2021-08-11T19:51:22.433237Z","shell.execute_reply":"2021-08-11T19:51:22.506124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Augment the data","metadata":{}},{"cell_type":"code","source":"\ndef sp_noise(image,prob):\n    image = image.convert('RGB') \n    image = np.array(image) \n    image = image[:, :, ::-1].copy() \n    '''\n    Add salt and pepper noise to image\n    prob: Probability of the noise\n    '''\n    output = np.zeros(image.shape,np.uint8)\n    thres = 1 - prob \n    for i in range(image.shape[0]):\n        for j in range(image.shape[1]):\n            rdn = random.random()\n            if rdn < prob:\n                output[i][j] = 0\n            elif rdn > thres:\n                output[i][j] = 125\n            else:\n                output[i][j] = image[i][j]\n    return Image.fromarray(output )\n","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:22.508745Z","iopub.execute_input":"2021-08-11T19:51:22.509266Z","iopub.status.idle":"2021-08-11T19:51:22.578752Z","shell.execute_reply.started":"2021-08-11T19:51:22.509223Z","shell.execute_reply":"2021-08-11T19:51:22.577799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import colorsys\n\ndef shift_hue(im, hue, sat):\n#     im = Image.open(filename)\n    ld = im.load()\n    width, height = im.size\n    for y in range(height):\n        for x in range(width):\n            r,g,b = ld[x,y]\n            h,s,v = colorsys.rgb_to_hsv(r/255., g/255., b/255.)\n            h = (h + -hue/360.0) % 1.0\n            s = s**sat\n            r,g,b = colorsys.hsv_to_rgb(h, s, v)\n            ld[x,y] = (int(r * 255.9999), int(g * 255.9999), int(b * 255.9999))\n    return im","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:22.581569Z","iopub.execute_input":"2021-08-11T19:51:22.581863Z","iopub.status.idle":"2021-08-11T19:51:22.646368Z","shell.execute_reply.started":"2021-08-11T19:51:22.581836Z","shell.execute_reply":"2021-08-11T19:51:22.645575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom shutil import copyfile\nfrom skimage.util import random_noise\nfrom skimage.transform import rotate, AffineTransform, warp\n\ndirectory = '../input/gan-getting-started/monet_jpg/'\n\nsigma=0.1\ndst = '../input/gan-getting-started/monet_30'\nfor filename in FILENAMES:\n        image = Image.open(f'{directory}{filename}')  \n        im = np.fliplr(image) ###\n        flipLR = Image.fromarray(im) ###\n        hue_im = shift_hue(image, 25, 0.95) ###\n        noisyRandom = sp_noise(image,0.002) ###\n        flipLR = flipLR.save(f'monet_30/flipped_{filename}') ###\n        noisyRandom = noisyRandom.save(f'monet_30/noisy_{filename}') ###\n        hue_im = hue_im.save(f'monet_30/hue_{filename}') ###\n#         transform = AffineTransform(translation=(25,25))\n#         wrap_im = warp(image,transform,mode='wrap')\n#         wrap_im = Image.fromarray((wrap_im * 255).astype(np.uint8)) ###\n#         wrap_im = wrap_im.save(f'monet_30/wrap_{filename}') ###\n        copyfile(f'{directory}{filename}', f'monet_30/{filename}')","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:22.647765Z","iopub.execute_input":"2021-08-11T19:51:22.648353Z","iopub.status.idle":"2021-08-11T19:51:36.319942Z","shell.execute_reply.started":"2021-08-11T19:51:22.648296Z","shell.execute_reply":"2021-08-11T19:51:36.318808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls monet_30","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:36.321539Z","iopub.execute_input":"2021-08-11T19:51:36.321913Z","iopub.status.idle":"2021-08-11T19:51:37.083898Z","shell.execute_reply.started":"2021-08-11T19:51:36.321873Z","shell.execute_reply":"2021-08-11T19:51:37.082951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import matplotlib.image as mpimg\n# img = mpimg.imread(f'monet_30/hue_73f33a12c5.jpg')\n# imgplot = plt.imshow(img)\n# plt.show()\n# img = mpimg.imread(f'monet_30/73f33a12c5.jpg')\n# imgplot = plt.imshow(img)\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:37.086004Z","iopub.execute_input":"2021-08-11T19:51:37.086458Z","iopub.status.idle":"2021-08-11T19:51:37.156716Z","shell.execute_reply.started":"2021-08-11T19:51:37.086408Z","shell.execute_reply":"2021-08-11T19:51:37.155861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ImageDataset(Dataset):\n    def __init__(self, monet_dir, photo_dir, size=(256, 256), normalize=True):\n        super().__init__()\n        self.monet_dir = monet_dir\n        self.photo_dir = photo_dir\n        self.monet_idx = dict()\n        self.photo_idx = dict()\n        if normalize:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor(),\n                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))                                \n            ])\n        else:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor()                               \n            ])\n        for i, fl in enumerate(os.listdir(self.monet_dir)):\n            self.monet_idx[i] = fl\n        for i, fl in enumerate(os.listdir(self.photo_dir)):\n            self.photo_idx[i] = fl\n\n    def __getitem__(self, idx):\n        rand_idx = int(np.random.uniform(0, len(self.monet_idx.keys())))\n        photo_path = os.path.join(self.photo_dir, self.photo_idx[rand_idx])\n        monet_path = os.path.join(self.monet_dir, self.monet_idx[idx])\n        photo_img = Image.open(photo_path)\n        photo_img = self.transform(photo_img)\n        monet_img = Image.open(monet_path)\n        monet_img = self.transform(monet_img)\n        return photo_img, monet_img\n\n    def __len__(self):\n        return min(len(self.monet_idx.keys()), len(self.photo_idx.keys()))","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:37.164985Z","iopub.execute_input":"2021-08-11T19:51:37.165236Z","iopub.status.idle":"2021-08-11T19:51:37.240164Z","shell.execute_reply.started":"2021-08-11T19:51:37.165211Z","shell.execute_reply":"2021-08-11T19:51:37.239341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_ds = ImageDataset('monet_30/', '../input/gan-getting-started/photo_jpg/')","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:37.241663Z","iopub.execute_input":"2021-08-11T19:51:37.242059Z","iopub.status.idle":"2021-08-11T19:51:37.310889Z","shell.execute_reply.started":"2021-08-11T19:51:37.242020Z","shell.execute_reply":"2021-08-11T19:51:37.309780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_dl = DataLoader(img_ds, batch_size=1, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:37.314704Z","iopub.execute_input":"2021-08-11T19:51:37.315007Z","iopub.status.idle":"2021-08-11T19:51:37.375745Z","shell.execute_reply.started":"2021-08-11T19:51:37.314977Z","shell.execute_reply":"2021-08-11T19:51:37.374788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"photo_img, monet_img = next(iter(img_dl))","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:37.377061Z","iopub.execute_input":"2021-08-11T19:51:37.377452Z","iopub.status.idle":"2021-08-11T19:51:39.405936Z","shell.execute_reply.started":"2021-08-11T19:51:37.377390Z","shell.execute_reply":"2021-08-11T19:51:39.405142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def unnorm(img, mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]):\n    for t, m, s in zip(img, mean, std):\n        t.mul_(s).add_(s)\n        \n    return img","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:39.407273Z","iopub.execute_input":"2021-08-11T19:51:39.407631Z","iopub.status.idle":"2021-08-11T19:51:39.472725Z","shell.execute_reply.started":"2021-08-11T19:51:39.407595Z","shell.execute_reply":"2021-08-11T19:51:39.471978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f = plt.figure(figsize=(8, 8))\n\nf.add_subplot(1, 2, 1)\nplt.title('Photo')\nphoto_img = unnorm(photo_img)\nplt.imshow(photo_img[0].permute(1, 2, 0))\n\nf.add_subplot(1, 2, 2)\nplt.title('Monet')\nmonet_img = unnorm(monet_img)\nplt.imshow(monet_img[0].permute(1, 2, 0))","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:39.476080Z","iopub.execute_input":"2021-08-11T19:51:39.476829Z","iopub.status.idle":"2021-08-11T19:51:39.859444Z","shell.execute_reply.started":"2021-08-11T19:51:39.476783Z","shell.execute_reply":"2021-08-11T19:51:39.858329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save and Load","metadata":{}},{"cell_type":"code","source":"def load_checkpoint(ckpt_path, map_location=None):\n    ckpt = torch.load(ckpt_path, map_location=map_location)\n    print(' [*] Loading checkpoint from %s succeed!' % ckpt_path)\n    return ckpt","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:39.860833Z","iopub.execute_input":"2021-08-11T19:51:39.861218Z","iopub.status.idle":"2021-08-11T19:51:39.931825Z","shell.execute_reply.started":"2021-08-11T19:51:39.861174Z","shell.execute_reply":"2021-08-11T19:51:39.931142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_checkpoint(state, save_path):\n    torch.save(state, save_path)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:39.933571Z","iopub.execute_input":"2021-08-11T19:51:39.933952Z","iopub.status.idle":"2021-08-11T19:51:39.996290Z","shell.execute_reply.started":"2021-08-11T19:51:39.933898Z","shell.execute_reply":"2021-08-11T19:51:39.995161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"def Upsample(in_ch, out_ch, use_dropout=True, dropout_ratio=0.5):\n    if use_dropout:\n        return nn.Sequential(\n            nn.ConvTranspose2d(in_ch, out_ch, 3, stride=2, padding=1, output_padding=1),\n            nn.InstanceNorm2d(out_ch),\n            nn.Dropout(dropout_ratio),\n            nn.GELU()\n        )\n    else:\n        return nn.Sequential(\n            nn.ConvTranspose2d(in_ch, out_ch, 3, stride=2, padding=1, output_padding=1),\n            nn.InstanceNorm2d(out_ch),\n            nn.GELU()\n        )","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:39.997856Z","iopub.execute_input":"2021-08-11T19:51:39.998364Z","iopub.status.idle":"2021-08-11T19:51:40.066443Z","shell.execute_reply.started":"2021-08-11T19:51:39.998250Z","shell.execute_reply":"2021-08-11T19:51:40.065536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def Convlayer(in_ch, out_ch, kernel_size=3, stride=2, use_leaky=True, use_inst_norm=True, use_pad=True):\n    if use_pad:\n        conv = nn.Conv2d(in_ch, out_ch, kernel_size, stride, 1, bias=True)\n    else:\n        conv = nn.Conv2d(in_ch, out_ch, kernel_size, stride, 0, bias=True)\n\n    if use_leaky:\n        actv = nn.LeakyReLU(negative_slope=0.2, inplace=True)\n    else:\n        actv = nn.GELU()\n\n    if use_inst_norm:\n        norm = nn.InstanceNorm2d(out_ch)\n    else:\n        norm = nn.BatchNorm2d(out_ch)\n\n    return nn.Sequential(\n        conv,\n        norm,\n        actv\n    )","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.069049Z","iopub.execute_input":"2021-08-11T19:51:40.069679Z","iopub.status.idle":"2021-08-11T19:51:40.137884Z","shell.execute_reply.started":"2021-08-11T19:51:40.069637Z","shell.execute_reply":"2021-08-11T19:51:40.136821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Resblock(nn.Module):\n    def __init__(self, in_features, use_dropout=True, dropout_ratio=0.5):\n        super().__init__()\n        layers = list()\n        layers.append(nn.ReflectionPad2d(1))\n        layers.append(Convlayer(in_features, in_features, 3, 1, False, use_pad=False))\n        layers.append(nn.Dropout(dropout_ratio))\n        layers.append(nn.ReflectionPad2d(1))\n        layers.append(nn.Conv2d(in_features, in_features, 3, 1, padding=0, bias=True))\n        layers.append(nn.InstanceNorm2d(in_features))\n        self.res = nn.Sequential(*layers)\n\n    def forward(self, x):\n        return x + self.res(x)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.141928Z","iopub.execute_input":"2021-08-11T19:51:40.142215Z","iopub.status.idle":"2021-08-11T19:51:40.206901Z","shell.execute_reply.started":"2021-08-11T19:51:40.142181Z","shell.execute_reply":"2021-08-11T19:51:40.205970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self, in_ch, out_ch, num_res_blocks=6):\n        super().__init__()\n        model = list()\n        model.append(nn.ReflectionPad2d(3))\n        model.append(Convlayer(in_ch, 64, 7, 1, False, True, False))\n        model.append(Convlayer(64, 128, 3, 2, False))\n        model.append(Convlayer(128, 256, 3, 2, False))\n        for _ in range(num_res_blocks):\n            model.append(Resblock(256))\n        model.append(Upsample(256, 128))\n        model.append(Upsample(128, 64))\n        model.append(nn.ReflectionPad2d(3))\n        model.append(nn.Conv2d(64, out_ch, kernel_size=7, padding=0))\n        model.append(nn.Tanh())\n\n        self.gen = nn.Sequential(*model)\n\n    def forward(self, x):\n        return self.gen(x)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.208498Z","iopub.execute_input":"2021-08-11T19:51:40.209148Z","iopub.status.idle":"2021-08-11T19:51:40.280183Z","shell.execute_reply.started":"2021-08-11T19:51:40.209101Z","shell.execute_reply":"2021-08-11T19:51:40.279349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self, in_ch, num_layers=4):\n        super().__init__()\n        model = list()\n        model.append(nn.Conv2d(in_ch, 64, 4, stride=2, padding=1))\n        model.append(nn.LeakyReLU(0.2, inplace=True))\n        for i in range(1, num_layers):\n            in_chs = 64 * 2**(i-1)\n            out_chs = in_chs * 2\n            if i == num_layers -1:\n                model.append(Convlayer(in_chs, out_chs, 4, 1))\n            else:\n                model.append(Convlayer(in_chs, out_chs, 4, 2))\n        model.append(nn.Conv2d(512, 1, kernel_size=4, stride=1, padding=1))\n        self.disc = nn.Sequential(*model)\n\n    def forward(self, x):\n        return self.disc(x)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.281655Z","iopub.execute_input":"2021-08-11T19:51:40.282244Z","iopub.status.idle":"2021-08-11T19:51:40.352563Z","shell.execute_reply.started":"2021-08-11T19:51:40.282204Z","shell.execute_reply":"2021-08-11T19:51:40.351541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def init_weights(net, init_type='normal', gain=0.02):\n    def init_func(m):\n        classname = m.__class__.__name__\n        if hasattr(m, 'weight') and (classname.find('Conv') != -1 or classname.find('Linear') != -1):\n            init.normal_(m.weight.data, 0.0, gain)\n            if hasattr(m, 'bias') and m.bias is not None:\n                init.constant_(m.bias.data, 0.0)\n        elif classname.find('BatchNorm2d') != -1:\n            init.normal_(m.weight.data, 1.0, gain)\n            init.constant_(m.bias.data, 0.0)\n    net.apply(init_func)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.354847Z","iopub.execute_input":"2021-08-11T19:51:40.355515Z","iopub.status.idle":"2021-08-11T19:51:40.423983Z","shell.execute_reply.started":"2021-08-11T19:51:40.355473Z","shell.execute_reply":"2021-08-11T19:51:40.422798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Some additional classes and functions","metadata":{}},{"cell_type":"code","source":"def update_req_grad(models, requires_grad=True):\n    for model in models:\n        for param in model.parameters():\n            param.requires_grad = requires_grad","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.425519Z","iopub.execute_input":"2021-08-11T19:51:40.426286Z","iopub.status.idle":"2021-08-11T19:51:40.492327Z","shell.execute_reply.started":"2021-08-11T19:51:40.426231Z","shell.execute_reply":"2021-08-11T19:51:40.491526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://arxiv.org/pdf/1612.07828.pdf\n# Save 50 generated fake imgs and sample through them\n# to feed discriminators to avoid large oscillations \n# from iterations to iterations.\nclass sample_fake(object):\n    def __init__(self, max_imgs=50):\n        self.max_imgs = max_imgs\n        self.cur_img = 0\n        self.imgs = list()\n\n    def __call__(self, imgs):\n        ret = list()\n        for img in imgs:\n            if self.cur_img < self.max_imgs:\n                self.imgs.append(img)\n                ret.append(img)\n                self.cur_img += 1\n            else:\n                if np.random.ranf() > 0.5:\n                    idx = np.random.randint(0, self.max_imgs)\n                    ret.append(self.imgs[idx])\n                    self.imgs[idx] = img\n                else:\n                    ret.append(img)\n        return ret","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.493672Z","iopub.execute_input":"2021-08-11T19:51:40.494258Z","iopub.status.idle":"2021-08-11T19:51:40.561485Z","shell.execute_reply.started":"2021-08-11T19:51:40.494195Z","shell.execute_reply":"2021-08-11T19:51:40.560681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class lr_sched():\n    def __init__(self, decay_epochs=100, total_epochs=200):\n        self.decay_epochs = decay_epochs\n        self.total_epochs = total_epochs\n\n    def step(self, epoch_num):\n        if epoch_num <= self.decay_epochs:\n            return 1.0\n        else:\n            fract = (epoch_num - self.decay_epochs)  / (self.total_epochs - self.decay_epochs)\n            return 1.0 - fract","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.563064Z","iopub.execute_input":"2021-08-11T19:51:40.563621Z","iopub.status.idle":"2021-08-11T19:51:40.625492Z","shell.execute_reply.started":"2021-08-11T19:51:40.563577Z","shell.execute_reply":"2021-08-11T19:51:40.624701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AvgStats(object):\n    def __init__(self):\n        self.reset()\n        \n    def reset(self):\n        self.losses =[]\n        self.its = []\n        \n    def append(self, loss, it):\n        self.losses.append(loss)\n        self.its.append(it)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.627084Z","iopub.execute_input":"2021-08-11T19:51:40.627772Z","iopub.status.idle":"2021-08-11T19:51:40.693655Z","shell.execute_reply.started":"2021-08-11T19:51:40.627720Z","shell.execute_reply":"2021-08-11T19:51:40.692771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# GAN Class","metadata":{}},{"cell_type":"code","source":"class CycleGAN(object):\n    def __init__(self, in_ch, out_ch, epochs, device, start_lr=2e-4, lmbda=10, idt_coef=0.5, decay_epoch=0):\n        self.epochs = epochs\n        self.decay_epoch = decay_epoch if decay_epoch > 0 else int(self.epochs/2)\n        self.lmbda = lmbda\n        self.idt_coef = idt_coef\n        self.device = device\n        self.gen_mtp = Generator(in_ch, out_ch)\n        self.gen_ptm = Generator(in_ch, out_ch)\n        self.desc_m = Discriminator(in_ch)\n        self.desc_p = Discriminator(in_ch)\n        self.init_models()\n        self.mse_loss = nn.MSELoss()\n        self.l1_loss = nn.L1Loss()\n        self.adam_gen = torch.optim.Adam(itertools.chain(self.gen_mtp.parameters(), self.gen_ptm.parameters()),\n                                         lr = start_lr, betas=(0.5, 0.999))\n        self.adam_desc = torch.optim.Adam(itertools.chain(self.desc_m.parameters(), self.desc_p.parameters()),\n                                          lr=start_lr, betas=(0.5, 0.999))\n        self.sample_monet = sample_fake()\n        self.sample_photo = sample_fake()\n        gen_lr = lr_sched(self.decay_epoch, self.epochs)\n        desc_lr = lr_sched(self.decay_epoch, self.epochs)\n        self.gen_lr_sched = torch.optim.lr_scheduler.LambdaLR(self.adam_gen, gen_lr.step)\n        self.desc_lr_sched = torch.optim.lr_scheduler.LambdaLR(self.adam_desc, desc_lr.step)\n        self.gen_stats = AvgStats()\n        self.desc_stats = AvgStats()\n        \n    def init_models(self):\n        init_weights(self.gen_mtp)\n        init_weights(self.gen_ptm)\n        init_weights(self.desc_m)\n        init_weights(self.desc_p)\n        self.gen_mtp = self.gen_mtp.to(self.device)\n        self.gen_ptm = self.gen_ptm.to(self.device)\n        self.desc_m = self.desc_m.to(self.device)\n        self.desc_p = self.desc_p.to(self.device)\n        \n    def train(self, photo_dl):\n        for epoch in range(self.epochs):\n            start_time = time.time()\n            avg_gen_loss = 0.0\n            avg_desc_loss = 0.0\n            t = tqdm(photo_dl, leave=False, total=photo_dl.__len__())\n            for i, (photo_real, monet_real) in enumerate(t):\n                photo_img, monet_img = photo_real.to(device), monet_real.to(device)\n                update_req_grad([self.desc_m, self.desc_p], False)\n                self.adam_gen.zero_grad()\n\n                # Forward pass through generator\n                fake_photo = self.gen_mtp(monet_img)\n                fake_monet = self.gen_ptm(photo_img)\n\n                cycl_monet = self.gen_ptm(fake_photo)\n                cycl_photo = self.gen_mtp(fake_monet)\n\n                id_monet = self.gen_ptm(monet_img)\n                id_photo = self.gen_mtp(photo_img)\n\n                # generator losses - identity, Adversarial, cycle consistency\n                idt_loss_monet = self.l1_loss(id_monet, monet_img) * self.lmbda * self.idt_coef\n                idt_loss_photo = self.l1_loss(id_photo, photo_img) * self.lmbda * self.idt_coef\n\n                cycle_loss_monet = self.l1_loss(cycl_monet, monet_img) * self.lmbda\n                cycle_loss_photo = self.l1_loss(cycl_photo, photo_img) * self.lmbda\n\n                monet_desc = self.desc_m(fake_monet)\n                photo_desc = self.desc_p(fake_photo)\n\n                real = torch.ones(monet_desc.size()).to(self.device)\n\n                adv_loss_monet = self.mse_loss(monet_desc, real)\n                adv_loss_photo = self.mse_loss(photo_desc, real)\n\n                # total generator loss\n                total_gen_loss = cycle_loss_monet + adv_loss_monet\\\n                              + cycle_loss_photo + adv_loss_photo\\\n                              + idt_loss_monet + idt_loss_photo\n                \n                avg_gen_loss += total_gen_loss.item()\n\n                # backward pass\n                total_gen_loss.backward()\n                self.adam_gen.step()\n\n                # Forward pass through Descriminator\n                update_req_grad([self.desc_m, self.desc_p], True)\n                self.adam_desc.zero_grad()\n\n                fake_monet = self.sample_monet([fake_monet.cpu().data.numpy()])[0]\n                fake_photo = self.sample_photo([fake_photo.cpu().data.numpy()])[0]\n                fake_monet = torch.tensor(fake_monet).to(self.device)\n                fake_photo = torch.tensor(fake_photo).to(self.device)\n\n                monet_desc_real = self.desc_m(monet_img)\n                monet_desc_fake = self.desc_m(fake_monet)\n                photo_desc_real = self.desc_p(photo_img)\n                photo_desc_fake = self.desc_p(fake_photo)\n\n                real = torch.ones(monet_desc_real.size()).to(self.device)\n                fake = torch.zeros(monet_desc_fake.size()).to(self.device)\n\n                # Descriminator losses\n                # --------------------\n                monet_desc_real_loss = self.mse_loss(monet_desc_real, real)\n                monet_desc_fake_loss = self.mse_loss(monet_desc_fake, fake)\n                photo_desc_real_loss = self.mse_loss(photo_desc_real, real)\n                photo_desc_fake_loss = self.mse_loss(photo_desc_fake, fake)\n\n                monet_desc_loss = (monet_desc_real_loss + monet_desc_fake_loss) / 2\n                photo_desc_loss = (photo_desc_real_loss + photo_desc_fake_loss) / 2\n                total_desc_loss = monet_desc_loss + photo_desc_loss\n                avg_desc_loss += total_desc_loss.item()\n\n                # Backward\n                monet_desc_loss.backward()\n                photo_desc_loss.backward()\n                self.adam_desc.step()\n                \n                t.set_postfix(gen_loss=total_gen_loss.item(), desc_loss=total_desc_loss.item())\n\n            save_dict = {\n                'epoch': epoch+1,\n                'gen_mtp': gan.gen_mtp.state_dict(),\n                'gen_ptm': gan.gen_ptm.state_dict(),\n                'desc_m': gan.desc_m.state_dict(),\n                'desc_p': gan.desc_p.state_dict(),\n                'optimizer_gen': gan.adam_gen.state_dict(),\n                'optimizer_desc': gan.adam_desc.state_dict()\n            }\n            save_checkpoint(save_dict, 'current.ckpt')\n            \n            avg_gen_loss /= photo_dl.__len__()\n            avg_desc_loss /= photo_dl.__len__()\n            time_req = time.time() - start_time\n            \n            self.gen_stats.append(avg_gen_loss, time_req)\n            self.desc_stats.append(avg_desc_loss, time_req)\n            \n            print(\"Epoch: (%d) | Generator Loss:%f | Discriminator Loss:%f\" % \n                                                (epoch+1, avg_gen_loss, avg_desc_loss))\n      \n            self.gen_lr_sched.step()\n            self.desc_lr_sched.step()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.695156Z","iopub.execute_input":"2021-08-11T19:51:40.695553Z","iopub.status.idle":"2021-08-11T19:51:40.795613Z","shell.execute_reply.started":"2021-08-11T19:51:40.695514Z","shell.execute_reply":"2021-08-11T19:51:40.794795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gan = CycleGAN(3, 3, 50, device)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:40.796988Z","iopub.execute_input":"2021-08-11T19:51:40.797487Z","iopub.status.idle":"2021-08-11T19:51:41.266958Z","shell.execute_reply.started":"2021-08-11T19:51:40.797450Z","shell.execute_reply":"2021-08-11T19:51:41.266160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save before train\nsave_dict = {\n    'epoch': 0,\n    'gen_mtp': gan.gen_mtp.state_dict(),\n    'gen_ptm': gan.gen_ptm.state_dict(),\n    'desc_m': gan.desc_m.state_dict(),\n    'desc_p': gan.desc_p.state_dict(),\n    'optimizer_gen': gan.adam_gen.state_dict(),\n    'optimizer_desc': gan.adam_desc.state_dict()\n}","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:41.268341Z","iopub.execute_input":"2021-08-11T19:51:41.268754Z","iopub.status.idle":"2021-08-11T19:51:41.338807Z","shell.execute_reply.started":"2021-08-11T19:51:41.268707Z","shell.execute_reply":"2021-08-11T19:51:41.337875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_checkpoint(save_dict, 'init.ckpt')","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:41.340604Z","iopub.execute_input":"2021-08-11T19:51:41.341150Z","iopub.status.idle":"2021-08-11T19:51:41.563642Z","shell.execute_reply.started":"2021-08-11T19:51:41.341109Z","shell.execute_reply":"2021-08-11T19:51:41.562472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gan.train(img_dl)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T19:51:41.564968Z","iopub.execute_input":"2021-08-11T19:51:41.565491Z","iopub.status.idle":"2021-08-11T20:46:59.721560Z","shell.execute_reply.started":"2021-08-11T19:51:41.565452Z","shell.execute_reply":"2021-08-11T20:46:59.720624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.xlabel(\"Epochs\")\nplt.ylabel(\"Losses\")\nplt.plot(gan.gen_stats.losses, 'r', label='Generator Loss')\nplt.plot(gan.desc_stats.losses, 'b', label='Descriminator Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:46:59.725433Z","iopub.execute_input":"2021-08-11T20:46:59.725836Z","iopub.status.idle":"2021-08-11T20:46:59.944403Z","shell.execute_reply.started":"2021-08-11T20:46:59.725791Z","shell.execute_reply":"2021-08-11T20:46:59.943347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_, ax = plt.subplots(5, 2, figsize=(12, 12))\nfor i in range(5):\n    photo_img, _ = next(iter(img_dl))\n    pred_monet = gan.gen_ptm(photo_img.to(device)).cpu().detach()\n    photo_img = unnorm(photo_img)\n    pred_monet = unnorm(pred_monet)\n    \n    ax[i, 0].imshow(photo_img[0].permute(1, 2, 0))\n    ax[i, 1].imshow(pred_monet[0].permute(1, 2, 0))\n    ax[i, 0].set_title(\"Input Photo\")\n    ax[i, 1].set_title(\"Monet-esque Photo\")\n    ax[i, 0].axis(\"off\")\n    ax[i, 1].axis(\"off\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:46:59.946192Z","iopub.execute_input":"2021-08-11T20:46:59.946615Z","iopub.status.idle":"2021-08-11T20:47:00.825657Z","shell.execute_reply.started":"2021-08-11T20:46:59.946571Z","shell.execute_reply":"2021-08-11T20:47:00.824789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Run Generator over all images","metadata":{}},{"cell_type":"code","source":"class PhotoDataset(Dataset):\n    def __init__(self, photo_dir, size=(256, 256), normalize=True):\n        super().__init__()\n        self.photo_dir = photo_dir\n        self.photo_idx = dict()\n        if normalize:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor(),\n                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))                                \n            ])\n        else:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor()                               \n            ])\n        for i, fl in enumerate(os.listdir(self.photo_dir)):\n            self.photo_idx[i] = fl\n\n    def __getitem__(self, idx):\n        photo_path = os.path.join(self.photo_dir, self.photo_idx[idx])\n        photo_img = Image.open(photo_path)\n        photo_img = self.transform(photo_img)\n        return photo_img\n\n    def __len__(self):\n        return len(self.photo_idx.keys())","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:47:00.827478Z","iopub.execute_input":"2021-08-11T20:47:00.827836Z","iopub.status.idle":"2021-08-11T20:47:00.896319Z","shell.execute_reply.started":"2021-08-11T20:47:00.827799Z","shell.execute_reply":"2021-08-11T20:47:00.895181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ph_ds = PhotoDataset('../input/gan-getting-started/photo_jpg/')","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:47:00.897876Z","iopub.execute_input":"2021-08-11T20:47:00.898291Z","iopub.status.idle":"2021-08-11T20:47:00.963569Z","shell.execute_reply.started":"2021-08-11T20:47:00.898252Z","shell.execute_reply":"2021-08-11T20:47:00.962770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ph_dl = DataLoader(ph_ds, batch_size=1, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:47:00.965043Z","iopub.execute_input":"2021-08-11T20:47:00.965623Z","iopub.status.idle":"2021-08-11T20:47:01.023651Z","shell.execute_reply.started":"2021-08-11T20:47:00.965576Z","shell.execute_reply":"2021-08-11T20:47:01.022865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir ../images","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:47:01.026117Z","iopub.execute_input":"2021-08-11T20:47:01.026411Z","iopub.status.idle":"2021-08-11T20:47:01.774575Z","shell.execute_reply.started":"2021-08-11T20:47:01.026380Z","shell.execute_reply":"2021-08-11T20:47:01.773609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trans = transforms.ToPILImage()","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:47:01.776118Z","iopub.execute_input":"2021-08-11T20:47:01.776510Z","iopub.status.idle":"2021-08-11T20:47:01.844454Z","shell.execute_reply.started":"2021-08-11T20:47:01.776465Z","shell.execute_reply":"2021-08-11T20:47:01.843763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"t = tqdm(ph_dl, leave=False, total=ph_dl.__len__())\nfor i, photo in enumerate(t):\n    with torch.no_grad():\n        pred_monet = gan.gen_ptm(photo.to(device)).cpu().detach()\n    pred_monet = unnorm(pred_monet)\n    img = trans(pred_monet[0]).convert(\"RGB\")\n    img.save(\"../images/\" + str(i+1) + \".jpg\")","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:47:01.845829Z","iopub.execute_input":"2021-08-11T20:47:01.846278Z","iopub.status.idle":"2021-08-11T20:51:03.403692Z","shell.execute_reply.started":"2021-08-11T20:47:01.846238Z","shell.execute_reply":"2021-08-11T20:51:03.402754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/images\")","metadata":{"execution":{"iopub.status.busy":"2021-08-11T20:51:03.405045Z","iopub.execute_input":"2021-08-11T20:51:03.405591Z","iopub.status.idle":"2021-08-11T20:51:06.814537Z","shell.execute_reply.started":"2021-08-11T20:51:03.405548Z","shell.execute_reply":"2021-08-11T20:51:06.813654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}