{"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 os\nimport shutil\nimport time\n\n\nimport pandas as pd\nimport numpy as np\nimport itertools\nimport matplotlib.pyplot as plt\n\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.nn.init as init\nfrom torch.nn import Conv2d, LeakyReLU, InstanceNorm2d\nfrom torch.utils.data import Dataset, DataLoader\n\nfrom torchvision import transforms as T\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.2156Z","start_time":"2022-09-04T09:58:02.682786Z"},"papermill":{"duration":2.034497,"end_time":"2022-09-22T09:21:30.743725","exception":false,"start_time":"2022-09-22T09:21:28.709228","status":"completed"},"scrolled":true,"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:08.200102Z","iopub.execute_input":"2023-04-13T16:53:08.200689Z","iopub.status.idle":"2023-04-13T16:53:09.829477Z","shell.execute_reply.started":"2023-04-13T16:53:08.200549Z","shell.execute_reply":"2023-04-13T16:53:09.828500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## \n<p id=\"toc\"></p>\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #8DE7E3; color: black;\" role=\"tab\" aria-controls=\"home\"><left><br>Constants and Variables</left></h2> ","metadata":{}},{"cell_type":"code","source":"MONET_DIR = '../input/gan-getting-started/monet_jpg/'\n\nPHOTO_DIR = '../input/gan-getting-started/photo_jpg/'\n\nSAVE_PATH = '/kaggle/working/result2-4'\n\ntest = '../input/ca3-test/CA3/Part 2-4'\n\nRADNOM_STATE = 12345\n\nIMAGE_SIZE = [256, 256]\n\nBATCH_SIZE = 1","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.220829Z","start_time":"2022-09-04T09:58:04.218018Z"},"papermill":{"duration":0.020824,"end_time":"2022-09-22T09:21:30.802146","exception":false,"start_time":"2022-09-22T09:21:30.781322","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.831810Z","iopub.execute_input":"2023-04-13T16:53:09.832360Z","iopub.status.idle":"2023-04-13T16:53:09.839305Z","shell.execute_reply.started":"2023-04-13T16:53:09.832321Z","shell.execute_reply":"2023-04-13T16:53:09.838286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\n\ndevice","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.279417Z","start_time":"2022-09-04T09:58:04.223734Z"},"papermill":{"duration":0.088082,"end_time":"2022-09-22T09:21:30.902763","exception":false,"start_time":"2022-09-22T09:21:30.814681","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.840699Z","iopub.execute_input":"2023-04-13T16:53:09.841117Z","iopub.status.idle":"2023-04-13T16:53:09.905516Z","shell.execute_reply.started":"2023-04-13T16:53:09.841075Z","shell.execute_reply":"2023-04-13T16:53:09.904585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## \n\n<p id=\"toc\"></p>\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #8DE7E3; color: black;\" role=\"tab\" aria-controls=\"home\"><left><br>Auxilary functions and classes</left></h2> ","metadata":{}},{"cell_type":"markdown","source":"### Visual","metadata":{"heading_collapsed":true,"papermill":{"duration":0.012426,"end_time":"2022-09-22T09:21:30.953475","exception":false,"start_time":"2022-09-22T09:21:30.941049","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"- Unnormalize image","metadata":{"hidden":true,"papermill":{"duration":0.012349,"end_time":"2022-09-22T09:21:30.978436","exception":false,"start_time":"2022-09-22T09:21:30.966087","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def unnormalize(img, mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]):\n    \n    # To normalize: X_norm = (X - mean) / std\n    # To unnormalize: X = (X_norm * std) + mean\n\n    for t, m, s in zip(img, mean, std):\n        t.mul_(s).add_(s)\n        \n    return img","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.33211Z","start_time":"2022-09-04T09:58:04.282551Z"},"hidden":true,"papermill":{"duration":0.021826,"end_time":"2022-09-22T09:21:31.012962","exception":false,"start_time":"2022-09-22T09:21:30.991136","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.910312Z","iopub.execute_input":"2023-04-13T16:53:09.912236Z","iopub.status.idle":"2023-04-13T16:53:09.918585Z","shell.execute_reply.started":"2023-04-13T16:53:09.912206Z","shell.execute_reply":"2023-04-13T16:53:09.917687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Show grid of images from dataloader","metadata":{"hidden":true,"papermill":{"duration":0.013668,"end_time":"2022-09-22T09:21:31.03901","exception":false,"start_time":"2022-09-22T09:21:31.025342","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def show_images(data):\n\n    fig, ax = plt.subplots(2, 4, figsize=(20, 12))\n    \n    it = iter(data)\n    \n    for i in range(4):\n        \n        p, m = next(it)\n\n        ax[0][i].imshow(unnormalize(p[0]).permute(1,2,0))\n        ax[1][i].imshow(unnormalize(m[0]).permute(1,2,0))\n        ax[0][i].set_title('Photo')\n        ax[1][i].set_title('Monet')\n\n    plt.show()","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.338485Z","start_time":"2022-09-04T09:58:04.333386Z"},"hidden":true,"papermill":{"duration":0.023498,"end_time":"2022-09-22T09:21:31.075373","exception":false,"start_time":"2022-09-22T09:21:31.051875","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:54:37.659329Z","iopub.execute_input":"2023-04-13T16:54:37.659720Z","iopub.status.idle":"2023-04-13T16:54:37.669449Z","shell.execute_reply.started":"2023-04-13T16:54:37.659688Z","shell.execute_reply":"2023-04-13T16:54:37.668472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Visualize training losses per epoch","metadata":{"hidden":true,"papermill":{"duration":0.012291,"end_time":"2022-09-22T09:21:31.100587","exception":false,"start_time":"2022-09-22T09:21:31.088296","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def plot_train_loss(log):\n    \n    df = pd.read_csv(log)\n\n    fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(7,6))\n\n    df.plot(x='epoch', y='loss_gen_total_avg', \n            kind='line', ax=ax[0], color='b', label='Total')\n\n    df.plot(x='epoch', y='loss_gen_photo_avg', \n            kind='line', ax=ax[0], color='r', label='Photo Generator')\n\n    df.plot(x='epoch', y='loss_gen_monet_avg', \n            kind='line', ax=ax[0], color='g', label='Monet Generator')\n\n\n    df.plot(x='epoch', y='loss_disc_total_avg', \n            kind='line', ax=ax[1], color='b', label='Total')\n\n    df.plot(x='epoch', y='loss_disc_photo_avg', \n            kind='line', ax=ax[1], color='r', label='Photo Discriminator')\n\n    df.plot(x='epoch', y='loss_disc_monet_avg', \n            kind='line', ax=ax[1], color='g', label='Monet Discriminator')\n\n\n    ax[0].set_title('Generator Losses')\n    ax[1].set_title('Discriminator Losses')\n\n    ax[0].set_ylabel('Loss')\n    ax[1].set_ylabel('Loss')\n\n    plt.tight_layout()\n    plt.show()","metadata":{"ExecuteTime":{"end_time":"2022-09-04T10:21:08.920149Z","start_time":"2022-09-04T10:21:08.911574Z"},"hidden":true,"papermill":{"duration":0.025202,"end_time":"2022-09-22T09:21:31.138383","exception":false,"start_time":"2022-09-22T09:21:31.113181","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.932423Z","iopub.execute_input":"2023-04-13T16:53:09.933160Z","iopub.status.idle":"2023-04-13T16:53:09.944669Z","shell.execute_reply.started":"2023-04-13T16:53:09.933115Z","shell.execute_reply":"2023-04-13T16:53:09.943598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading data","metadata":{"heading_collapsed":true,"papermill":{"duration":0.013845,"end_time":"2022-09-22T09:21:31.165942","exception":false,"start_time":"2022-09-22T09:21:31.152097","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"- Custom dataset class for training","metadata":{"hidden":true,"papermill":{"duration":0.01393,"end_time":"2022-09-22T09:21:31.193515","exception":false,"start_time":"2022-09-22T09:21:31.179585","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class ImageDatasetCV(Dataset):\n    \n    def __init__(self, monet_dir, photo_dir, size=(256, 256), normalize=True):\n        \n        super().__init__()\n        \n        self.monet_dir = None\n        \n        if monet_dir:\n            \n            self.monet_dir = monet_dir\n            self.monet_idx = dict()\n            \n            for i, filename in enumerate(os.listdir(self.monet_dir)):\n                self.monet_idx[i] = filename\n\n                \n        self.photo_dir = photo_dir\n        self.photo_idx = dict()\n        \n        for i, filename in enumerate(os.listdir(self.photo_dir)):\n            self.photo_idx[i] = filename\n        \n        \n        if normalize:\n            self.transforms = T.Compose([T.Resize(size), \n                                         T.ToTensor(), \n                                         T.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n                                        ])\n            \n        else:\n            self.transforms = T.Compose([T.Resize(size), \n                                         T.ToTensor()\n                                        ])    \n            \n        \n    def __getitem__(self, idx):\n        \n        random_idx = idx\n        \n        if self.monet_dir: \n            \n            random_idx = int(np.random.uniform(0, len(self.monet_idx.keys())))\n            \n            monet_path = os.path.join(self.monet_dir, self.monet_idx[random_idx])\n            monet_img = self.transforms(Image.open(monet_path))\n        \n        \n        photo_path = os.path.join(self.photo_dir, self.photo_idx[random_idx])\n        photo_img = self.transforms(Image.open(photo_path))\n        \n        if self.monet_dir:\n            return photo_img, monet_img\n        else:\n            return photo_img\n        \n    \n    def __len__(self):\n        \n        if self.monet_dir:\n            return min(len(self.monet_idx.keys()), len(self.photo_idx.keys()))\n        else:\n            return len(self.photo_idx.keys())","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.401528Z","start_time":"2022-09-04T09:58:04.346509Z"},"hidden":true,"papermill":{"duration":0.033407,"end_time":"2022-09-22T09:21:31.23966","exception":false,"start_time":"2022-09-22T09:21:31.206253","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.946130Z","iopub.execute_input":"2023-04-13T16:53:09.947034Z","iopub.status.idle":"2023-04-13T16:53:09.960105Z","shell.execute_reply.started":"2023-04-13T16:53:09.946999Z","shell.execute_reply":"2023-04-13T16:53:09.959279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Neural Netowork","metadata":{"heading_collapsed":true,"papermill":{"duration":0.0141,"end_time":"2022-09-22T09:21:31.268224","exception":false,"start_time":"2022-09-22T09:21:31.254124","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"- Save model state","metadata":{"hidden":true,"papermill":{"duration":0.012272,"end_time":"2022-09-22T09:21:31.293726","exception":false,"start_time":"2022-09-22T09:21:31.281454","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def save_checkpoint(state, save_path):\n    torch.save(state, save_path)","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.41062Z","start_time":"2022-09-04T09:58:04.40315Z"},"hidden":true,"papermill":{"duration":0.020855,"end_time":"2022-09-22T09:21:31.326855","exception":false,"start_time":"2022-09-22T09:21:31.306","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.961604Z","iopub.execute_input":"2023-04-13T16:53:09.962431Z","iopub.status.idle":"2023-04-13T16:53:09.970291Z","shell.execute_reply.started":"2023-04-13T16:53:09.962396Z","shell.execute_reply":"2023-04-13T16:53:09.969341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Load model state","metadata":{"hidden":true,"papermill":{"duration":0.012207,"end_time":"2022-09-22T09:21:31.35154","exception":false,"start_time":"2022-09-22T09:21:31.339333","status":"completed"},"tags":[]}},{"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":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.419223Z","start_time":"2022-09-04T09:58:04.412591Z"},"hidden":true,"papermill":{"duration":0.020911,"end_time":"2022-09-22T09:21:31.385478","exception":false,"start_time":"2022-09-22T09:21:31.364567","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.973308Z","iopub.execute_input":"2023-04-13T16:53:09.974100Z","iopub.status.idle":"2023-04-13T16:53:09.980452Z","shell.execute_reply.started":"2023-04-13T16:53:09.974064Z","shell.execute_reply":"2023-04-13T16:53:09.979357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## \n<p id=\"toc\"></p>\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #8DE7E3; color: black;\" role=\"tab\" aria-controls=\"home\"><left><br>Load Data</left></h2> ","metadata":{}},{"cell_type":"markdown","source":"### Create dataset","metadata":{"papermill":{"duration":0.012508,"end_time":"2022-09-22T09:21:31.435287","exception":false,"start_time":"2022-09-22T09:21:31.422779","status":"completed"},"tags":[]}},{"cell_type":"code","source":"img_dataset = ImageDatasetCV(monet_dir=MONET_DIR, photo_dir=PHOTO_DIR)","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.427721Z","start_time":"2022-09-04T09:58:04.421771Z"},"papermill":{"duration":0.355493,"end_time":"2022-09-22T09:21:31.803033","exception":false,"start_time":"2022-09-22T09:21:31.44754","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:53:09.983657Z","iopub.execute_input":"2023-04-13T16:53:09.984282Z","iopub.status.idle":"2023-04-13T16:53:10.551899Z","shell.execute_reply.started":"2023-04-13T16:53:09.984248Z","shell.execute_reply":"2023-04-13T16:53:10.550780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create Dataloader ","metadata":{"papermill":{"duration":0.012104,"end_time":"2022-09-22T09:21:31.82807","exception":false,"start_time":"2022-09-22T09:21:31.815966","status":"completed"},"tags":[]}},{"cell_type":"code","source":"img_dataloader = DataLoader(img_dataset, \n                            batch_size=BATCH_SIZE, \n                            pin_memory=True)\n\n# Enable pin_memory to automatically put the fetched data Tensors \n# in pinned memory, and thus enables faster data transfer \n# to CUDA-enabled GPUs","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:04.431722Z","start_time":"2022-09-04T09:58:04.429428Z"},"papermill":{"duration":0.020944,"end_time":"2022-09-22T09:21:31.861497","exception":false,"start_time":"2022-09-22T09:21:31.840553","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:54:47.595104Z","iopub.execute_input":"2023-04-13T16:54:47.595474Z","iopub.status.idle":"2023-04-13T16:54:47.600191Z","shell.execute_reply.started":"2023-04-13T16:54:47.595441Z","shell.execute_reply":"2023-04-13T16:54:47.599237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Check input images","metadata":{"papermill":{"duration":0.015594,"end_time":"2022-09-22T09:21:31.889855","exception":false,"start_time":"2022-09-22T09:21:31.874261","status":"completed"},"tags":[]}},{"cell_type":"code","source":"show_images(img_dataloader)","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:06.909069Z","start_time":"2022-09-04T09:58:04.433033Z"},"papermill":{"duration":3.90516,"end_time":"2022-09-22T09:21:35.80735","exception":false,"start_time":"2022-09-22T09:21:31.90219","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-13T16:54:49.130465Z","iopub.execute_input":"2023-04-13T16:54:49.131239Z","iopub.status.idle":"2023-04-13T16:54:52.889132Z","shell.execute_reply.started":"2023-04-13T16:54:49.131196Z","shell.execute_reply":"2023-04-13T16:54:52.887839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## \n<p id=\"toc\"></p>\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #8DE7E3; color: black;\" role=\"tab\" aria-controls=\"home\"><left><br>Build CycleGAN Model</left></h2> ","metadata":{}},{"cell_type":"markdown","source":"### Generator","metadata":{"papermill":{"duration":0.01632,"end_time":"2022-09-22T09:21:35.873773","exception":false,"start_time":"2022-09-22T09:21:35.857453","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"#### Convolutional Layer","metadata":{"heading_collapsed":true,"papermill":{"duration":0.016278,"end_time":"2022-09-22T09:21:35.906822","exception":false,"start_time":"2022-09-22T09:21:35.890544","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def Convlayer(in_ch, out_ch, kernel_size=3, stride=2, \n              use_leaky=True, use_inst_norm=True, use_pad=True):\n    \n    \n    # Convolution\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        \n    # Activation Function\n    if use_leaky:\n        actv = nn.LeakyReLU(negative_slope=0.2, inplace=True)\n    else:\n        actv = nn.GELU()\n        \n        \n    # Normalization\n    if use_inst_norm:\n        norm = nn.InstanceNorm2d(out_ch)\n    else:\n        norm = nn.BatchNorm2d(out_ch)\n        \n    \n    return nn.Sequential(conv, \n                         norm, \n                         actv)\n    ","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:06.915001Z","start_time":"2022-09-04T09:58:06.910822Z"},"hidden":true,"papermill":{"duration":0.026999,"end_time":"2022-09-22T09:21:35.950091","exception":false,"start_time":"2022-09-22T09:21:35.923092","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:22.551769Z","iopub.execute_input":"2023-04-11T05:37:22.552192Z","iopub.status.idle":"2023-04-11T05:37:22.561944Z","shell.execute_reply.started":"2023-04-11T05:37:22.552158Z","shell.execute_reply":"2023-04-11T05:37:22.560559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Transpose Convolutional Layer","metadata":{"heading_collapsed":true,"papermill":{"duration":0.016246,"end_time":"2022-09-22T09:21:35.982706","exception":false,"start_time":"2022-09-22T09:21:35.96646","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def Upsample(in_ch, out_ch, use_dropout=False, dropout_ratio=0.5):\n    \n    # Transposed Convolution\n    convtrans = nn.ConvTranspose2d(in_ch, out_ch, 3, stride=2, padding=1, output_padding=1)\n    \n    # Normalization\n    norm = nn.InstanceNorm2d(out_ch)\n    \n    # Activatin Function\n    actv = nn.GELU()\n    \n    \n    if use_dropout:\n        \n        # Dropout layer\n        drop = nn.Dropout(dropout_ratio)\n        \n        return nn.Sequential(convtrans, \n                             norm, \n                             drop, \n                             actv)\n\n    else:       \n        return nn.Sequential(convtrans, \n                             norm, \n                             actv)\n         ","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:06.921716Z","start_time":"2022-09-04T09:58:06.916634Z"},"hidden":true,"papermill":{"duration":0.026379,"end_time":"2022-09-22T09:21:36.0263","exception":false,"start_time":"2022-09-22T09:21:35.999921","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:22.563612Z","iopub.execute_input":"2023-04-11T05:37:22.564451Z","iopub.status.idle":"2023-04-11T05:37:22.574146Z","shell.execute_reply.started":"2023-04-11T05:37:22.564363Z","shell.execute_reply":"2023-04-11T05:37:22.572928Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Residual block","metadata":{"heading_collapsed":true,"papermill":{"duration":0.016933,"end_time":"2022-09-22T09:21:36.059461","exception":false,"start_time":"2022-09-22T09:21:36.042528","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class Resblock(nn.Module):\n    \n    def __init__(self, in_features, use_dropout=False, dropout_ratio=0.5):\n        super().__init__()\n        \n        layers = list()\n        \n        # Padding\n        layers.append(nn.ReflectionPad2d(1))\n        \n        # Convolution layer\n        layers.append(Convlayer(in_features, in_features, 3, 1, use_leaky=False, use_pad=False))\n        \n        # Dropout\n        if use_dropout:\n            layers.append(nn.Dropout(dropout_ratio))\n        \n        # Padding\n        layers.append(nn.ReflectionPad2d(1))\n        \n        # Convolution\n        layers.append(nn.Conv2d(in_features, in_features, 3, 1, padding=0, bias=True))\n        \n        # Normalization\n        layers.append(nn.InstanceNorm2d(in_features))\n        \n        \n        self.res = nn.Sequential(*layers)\n        \n        \n    def forward(self, x):\n        \n        return x + self.res(x)","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:06.931592Z","start_time":"2022-09-04T09:58:06.92351Z"},"hidden":true,"papermill":{"duration":0.028341,"end_time":"2022-09-22T09:21:36.104338","exception":false,"start_time":"2022-09-22T09:21:36.075997","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:22.575908Z","iopub.execute_input":"2023-04-11T05:37:22.576650Z","iopub.status.idle":"2023-04-11T05:37:22.587139Z","shell.execute_reply.started":"2023-04-11T05:37:22.576613Z","shell.execute_reply":"2023-04-11T05:37:22.586205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Generator","metadata":{"heading_collapsed":true,"papermill":{"duration":0.016184,"end_time":"2022-09-22T09:21:36.136869","exception":false,"start_time":"2022-09-22T09:21:36.120685","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class Generator(nn.Module):\n    \n    def __init__(self, in_ch, out_ch, num_res_blocks=6):\n        \n        super().__init__()\n        \n        model = list()\n        \n        # Padding layer\n        model.append(nn.ReflectionPad2d(3))\n        \n        \n        # Convolution input_channels -> 64\n        model.append(Convlayer(in_ch=in_ch, out_ch=64, \n                               kernel_size=7, stride=1, \n                               use_leaky=False, \n                               use_inst_norm=True, \n                               use_pad=False))\n        \n        # Convolution 64 -> 128\n        model.append(Convlayer(in_ch=64, out_ch=128, \n                               kernel_size=3, stride=2, \n                               use_leaky=False, \n                               use_inst_norm=True, \n                               use_pad=True))\n        \n        # Convolution 128 -> 256\n        model.append(Convlayer(in_ch=128, out_ch=256, \n                               kernel_size=3, stride=2, \n                               use_leaky=False, \n                               use_inst_norm=True, \n                               use_pad=True))\n        \n        # Residual Block\n        for _ in range(num_res_blocks):\n            model.append(Resblock(in_features=256))\n\n            \n        # Transposed convolution 256 -> 128\n        model.append(Upsample(in_ch=256, out_ch=128))  \n        \n        # Transposed convolution 128 -> 256\n        model.append(Upsample(in_ch=128, out_ch=64))    \n        \n        # Padding Layer\n        model.append(nn.ReflectionPad2d(3))\n        \n        # Convolutional layer\n        model.append(nn.Conv2d(in_channels=64, out_channels=out_ch, \n                               kernel_size=7, padding=0))\n        \n        # Activation function Tanh\n        model.append(nn.Tanh())\n        \n        \n        self.gen = nn.Sequential(*model)\n        \n        \n    def forward(self, x):\n        \n        return self.gen(x)","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:06.939138Z","start_time":"2022-09-04T09:58:06.933163Z"},"hidden":true,"papermill":{"duration":0.030768,"end_time":"2022-09-22T09:21:36.184","exception":false,"start_time":"2022-09-22T09:21:36.153232","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:22.588850Z","iopub.execute_input":"2023-04-11T05:37:22.589570Z","iopub.status.idle":"2023-04-11T05:37:22.600445Z","shell.execute_reply.started":"2023-04-11T05:37:22.589534Z","shell.execute_reply":"2023-04-11T05:37:22.599687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Discriminator","metadata":{"heading_collapsed":true,"papermill":{"duration":0.016517,"end_time":"2022-09-22T09:21:36.217472","exception":false,"start_time":"2022-09-22T09:21:36.200955","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    \n    def __init__(self, in_ch, num_layers=4):\n        \n        super().__init__()\n        \n        model = list()\n        \n        # Convolution in_channels -> 64\n        model.append(nn.Conv2d(in_channels=in_ch, out_channels=64, \n                               kernel_size=4, stride=2, padding=1))\n        \n        \n        # Convolutions i=1:  64 -> 64 \n        #              i=2:  64 -> 128\n        #              i=3: 128 -> 256 \n        #              i=4: 256 -> 512   \n        \n        for i in range(1, num_layers):\n            in_chs = 64 * 2**(i-1)\n            out_chs = in_chs * 2\n            \n            if i == num_layers - 1:\n                model.append(Convlayer(in_chs, out_chs, \n                                       kernel_size=4, stride=1))\n                \n            else:\n                model.append(Convlayer(in_chs, out_chs, \n                                       kernel_size=4, stride=2))\n        \n        # Convolution 512 -> 1\n        model.append(nn.Conv2d(in_channels=512, out_channels=1, \n                               kernel_size=4, stride=1, padding=1))\n        \n        self.disc = nn.Sequential(*model)\n        \n        \n    def forward(self, x):\n        \n        return self.disc(x)\n        ","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:06.946676Z","start_time":"2022-09-04T09:58:06.940743Z"},"hidden":true,"papermill":{"duration":0.028749,"end_time":"2022-09-22T09:21:36.263043","exception":false,"start_time":"2022-09-22T09:21:36.234294","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:22.602028Z","iopub.execute_input":"2023-04-11T05:37:22.602738Z","iopub.status.idle":"2023-04-11T05:37:22.614380Z","shell.execute_reply.started":"2023-04-11T05:37:22.602701Z","shell.execute_reply":"2023-04-11T05:37:22.613668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### CycleGAN","metadata":{"heading_collapsed":true,"papermill":{"duration":0.016845,"end_time":"2022-09-22T09:21:36.296411","exception":false,"start_time":"2022-09-22T09:21:36.279566","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class CycleGAN(object):\n    \n    def __init__(self, in_ch, out_ch, epochs, device, start_lr=0.01, lmbda=10, idt_coef=0.5, decay_epoch=0):\n        \n\n        \n        # Regularization coefficients\n        self.lmbda = lmbda\n        self.idt_coef = idt_coef\n        \n        # Set device\n        self.device = device\n        \n        # Generator Monet -> Photo\n        self.gen_mtp = Generator(in_ch, out_ch)\n        \n        # Generator Photo -> Monet\n        self.gen_ptm = Generator(in_ch, out_ch)\n        \n        # discriminator for Monet-generated images\n        self.disc_m = Discriminator(in_ch)\n        \n        # discriminator for Photo-generated images\n        self.disc_p = Discriminator(in_ch)\n        \n        # Initialize model weights\n        self.init_models()\n        \n        # Optimizator for generators\n        self.adam_gen = torch.optim.Adam(itertools.chain(self.gen_mtp.parameters(), \n                                                         self.gen_ptm.parameters()), \n                                         lr=start_lr, betas=(0.5, 0.999))\n        \n        # Optimizator for discriminator\n        self.adam_disc = torch.optim.Adam(itertools.chain(self.disc_m.parameters(), \n                                                          self.disc_p.parameters()), \n                                         lr=start_lr, betas=(0.5, 0.999))\n        \n        # Set number of epochs and start of learning rate decay \n        self.epochs = epochs\n        \n        # Set decay epoch \n        self.decay_epoch = decay_epoch if decay_epoch > 0 else int(self.epochs/2)\n        \n        # Set rule for learning step decay\n        lambda_decay = lambda epoch: start_lr/(epoch-self.decay_epoch) if epoch > self.decay_epoch else start_lr\n\n        \n        # Define scheduler for generator and discriminator\n        self.scheduler_gen = torch.optim.lr_scheduler.LambdaLR(self.adam_gen, lr_lambda=lambda_decay)\n        self.scheduler_disc = torch.optim.lr_scheduler.LambdaLR(self.adam_disc, lr_lambda=lambda_decay)\n\n    \n    # Initialize weights\n    def init_weights(self, net, gain=0.02):\n\n        def init_func(m):\n\n            # Name of the class\n            classname = m.__class__.__name__\n\n            # If class has attribute \"weight\" (to initialize) and \n            # has either convolutional layer or linear \n            if hasattr(m, 'weight') and \\\n               (classname.find('Conv') != -1 or classname.find('Linear') != -1):\n\n                # Initialize weights with values drawn from normal distribution N(mean, std)\n                init.normal_(m.weight.data, mean=0.0, std=gain)\n\n                # Set bias value with constant val\n                if hasattr(m, 'bias') and m.bias is not None:\n                    init.constant_(m.bias.data, val=0.0)\n\n            # Initialize BatchNorm weights\n            elif classname.find('BatchNorm2d') != -1:\n\n                init.normal_(m.weight.data, mean=1.0, std=gain)\n                init.constant_(m.bias.data, val=0.0)\n\n        # Apply weight initialization to every submodule of model\n        net.apply(init_func)\n            \n    \n    # Initialize models\n    def init_models(self):\n        \n        # Initialize weights\n        self.init_weights(self.gen_mtp)\n        self.init_weights(self.gen_ptm)\n        self.init_weights(self.disc_m)\n        self.init_weights(self.disc_p)\n        \n        # Set device for models\n        self.gen_mtp = self.gen_mtp.to(self.device)\n        self.gen_ptm = self.gen_ptm.to(self.device)\n        self.disc_m = self.disc_m.to(self.device)\n        self.disc_p = self.disc_p.to(self.device)        \n        \n        \n        \n    # Enable/ disable gradients for model parameters\n    def param_require_grad(self, models, requires_grad=True):\n        for model in models:\n            for param in model.parameters():\n                param.requires_grad = requires_grad\n\n        \n    # Cycle generation: x -> y_gen -> x_cycle\n    def cycle_gen(self, x, G_x_to_y, G_y_to_x):\n\n        y_gen = G_x_to_y(x)\n        x_cycle = G_y_to_x(y_gen)\n\n        return y_gen, x_cycle    \n    \n    \n    # Define BCE logistic loss\n    def mse_loss(self, x, target):\n        \n        if target == 1:\n            return nn.MSELoss()(x, torch.ones(x.size()).to(self.device))\n        else:\n            return nn.MSELoss()(x, torch.zeros(x.size()).to(self.device))\n    \n    \n    # Define Generator Loss\n    def loss_gen(self, idt, real, cycle, disc):\n        \n        \n        # Identity Losses:\n        loss_idt = nn.L1Loss()(idt, real) * self.lmbda * self.idt_coef\n        \n        # Cycle Losses:\n        loss_cycle = nn.L1Loss()(cycle, real) * self.lmbda\n        \n        # Adversarial Losses:                \n        loss_adv = self.mse_loss(disc, target=1)\n        \n        # Total Generator loss:\n        loss_gen = loss_cycle + loss_adv + loss_idt\n        \n        return loss_gen\n    \n    \n    # Discriminator Loss\n    # Ideal Discriminator will classify real image as 1 and fake as 0\n    def loss_disc(self, real, gen):\n\n        loss_real = self.mse_loss(real, target=1)\n        loss_gen = self.mse_loss(gen, target=0)\n\n        return (loss_real + loss_gen)/2\n    \n    \n    # Train\n    def train(self, img_dl):\n        \n        history = []\n        dataset_len = img_dl.__len__()\n        print_header = True\n        \n        for epoch in range(self.epochs):\n            \n            # Start measuring time for epoch\n            start_time = time.time()\n\n            \n            # Nulify average losses for an epoch\n            loss_gen_photo_avg = 0.0\n            loss_gen_monet_avg = 0.0\n            loss_gen_total_avg = 0.0\n            \n            loss_disc_photo_avg = 0.0\n            loss_disc_monet_avg = 0.0\n            loss_disc_total_avg = 0.0\n            \n            \n            # Iterate through dataloader with images\n            for i, (photo_real, monet_real) in enumerate(img_dl):\n\n                photo_real, monet_real = photo_real.to(device), monet_real.to(device)\n\n                \n                # Disable gradients for discriminators during generator training                \n                self.param_require_grad([self.disc_m, self.disc_p], requires_grad=False) \n\n                # Set gradients for generators to zero at the start of the training pass \n                self.adam_gen.zero_grad()\n\n\n                # =======================================\n\n                # FORWARD PASS THROUGH GENERATOR\n\n                # ----------- Cycle photo ---------------\n\n                monet_gen, photo_cycle = self.cycle_gen(photo_real, \n                                                        self.gen_ptm, \n                                                        self.gen_mtp)\n                \n                # ----------- Cycle Monet ---------------\n\n                photo_gen, monet_cycle = self.cycle_gen(monet_real, \n                                                        self.gen_mtp, \n                                                        self.gen_ptm)\n\n\n\n                # ----------- Generate itself ---------------\n\n                \n                # Real Monet -> Identical Monet\n                monet_idt = self.gen_ptm(monet_real)      \n                \n                # Real photo -> Identical photo\n                photo_idt = self.gen_mtp(photo_real)\n\n    \n                # =======================================\n\n                # DISCRIMINATOR PRECTION ON GENERATED IMAGES\n\n\n                # Discriminator M: Check generated Monet \n                monet_disc = self.disc_m(monet_gen)\n\n                # Discriminator P: Check generated photo\n                photo_disc = self.disc_p(photo_gen)\n\n\n                # =======================================\n\n                # CALCULATE LOSSES FOR GENERATORS\n\n                # Generator Losses\n                loss_gen_photo = self.loss_gen(photo_idt, photo_real, photo_cycle, photo_disc)\n                loss_gen_monet = self.loss_gen(monet_idt, monet_real, monet_cycle, monet_disc)\n                \n                \n                # Total Generator loss:\n                loss_gen_total = loss_gen_photo + loss_gen_monet\n            \n            \n                # Update average Generator loss:\n                loss_gen_photo_avg += loss_gen_photo.item()\n                loss_gen_monet_avg += loss_gen_monet.item()\n                loss_gen_total_avg += loss_gen_total.item()\n\n                \n                # =======================================\n\n                # GENERATOR BACKWARD PASS \n\n\n                # Propagate loss backward\n                loss_gen_total.backward()\n\n                # Make step with optimizer\n                self.adam_gen.step()\n\n                \n                # =======================================\n\n                # FORWARD PASS THROUGH DISCRIMINATORS\n\n                \n                # Enable gradients for discriminators during discriminator trainig\n                self.param_require_grad([self.disc_m, self.disc_p], requires_grad=True) \n                \n                # Set zero gradients\n                self.adam_disc.zero_grad()\n                \n                \n                # discriminator M: Predictions on real and generated Monet:\n                monet_disc_real = self.disc_m(monet_real)\n                monet_disc_gen = self.disc_m(monet_gen.detach())\n\n                # discriminator P: Predictions on real and generated photo:\n                photo_disc_real = self.disc_p(photo_real)\n                photo_disc_gen = self.disc_p(photo_gen.detach())\n\n       \n                # =======================================\n\n                # CALCULATE LOSSES FOR DISCRIMINATORS\n\n                # Discriminator losses\n                loss_disc_photo = self.loss_disc(photo_disc_real, photo_disc_gen)\n                loss_disc_monet = self.loss_disc(monet_disc_real, monet_disc_gen)\n\n\n                # Total discriminator loss:                \n                loss_disc_total = loss_disc_photo + loss_disc_monet\n\n                \n                # =======================================\n\n                # DISCRIMINATOR BACKWARD PASS \n\n\n                # Propagate losses backward\n                loss_disc_total.backward()\n                \n                # Make step with optimizer\n                self.adam_disc.step()\n                \n\n                # =======================================\n\n                # Update average Discriminator loss\n                loss_disc_photo_avg += loss_disc_photo.item()\n                loss_disc_monet_avg += loss_disc_monet.item()\n                loss_disc_total_avg += loss_disc_total.item()\n                \n                \n            # Calculate average losses per epoch \n            loss_gen_photo_avg /= dataset_len\n            loss_gen_monet_avg /= dataset_len\n            loss_gen_total_avg /= dataset_len\n            \n            loss_disc_photo_avg /= dataset_len\n            loss_disc_monet_avg /= dataset_len\n            loss_disc_total_avg /= dataset_len\n            \n            \n            # Estimate training time per epoch\n            time_req = time.time() - start_time\n            \n            \n            # Expand training history\n            history.append([epoch, loss_gen_photo_avg, \n                                   loss_gen_monet_avg, \n                                   loss_gen_total_avg,\n                                   loss_disc_photo_avg, \n                                   loss_disc_monet_avg, \n                                   loss_disc_total_avg ])\n            \n            \n            # Print statistics\n            if print_header:\n                print('EPOCH | LOSS: Gen photo | Gen Monet | Disc photo | Disc Monet | TIME MIN')\n                print_header = False\n                \n            print('------+-----------------+-----------+------------+------------+----------')\n            print('  {:3} |        {:>8.2f} |  {:>8.2f} |   {:>8.2f} |   {:>8.2f} |     {:4.0f}'.format(epoch+1, \n                                                                                        loss_gen_photo_avg, \n                                                                                        loss_gen_monet_avg, \n                                                                                        loss_disc_photo_avg, \n                                                                                        loss_disc_monet_avg, \n                                                                                        time_req//60))\n            # Step learning rate scheduler\n            self.scheduler_gen.step()\n            self.scheduler_disc.step()\n\n        # Save training history\n        history = pd.DataFrame(history, columns=['epoch',  \n                                                 'loss_gen_photo_avg', \n                                                 'loss_gen_monet_avg', \n                                                 'loss_gen_total_avg',\n                                                 'loss_disc_photo_avg', \n                                                 'loss_disc_monet_avg', \n                                                 'loss_disc_total_avg' ])\n        \n        history.to_csv('history.csv', index=False)\n        \n        \n    def predict(self, image):\n        \n        with torch.no_grad():\n            \n            self.gen_ptm.eval()\n                            \n            image = image.to(self.device)\n\n            monet_gen = self.gen_ptm(image)\n\n            \n        return monet_gen","metadata":{"ExecuteTime":{"end_time":"2022-09-04T09:58:06.965581Z","start_time":"2022-09-04T09:58:06.948177Z"},"hidden":true,"papermill":{"duration":0.054903,"end_time":"2022-09-22T09:21:36.367823","exception":false,"start_time":"2022-09-22T09:21:36.31292","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:22.616053Z","iopub.execute_input":"2023-04-11T05:37:22.616779Z","iopub.status.idle":"2023-04-11T05:37:22.653806Z","shell.execute_reply.started":"2023-04-11T05:37:22.616743Z","shell.execute_reply":"2023-04-11T05:37:22.652796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## \n<p id=\"toc\"></p>\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #8DE7E3; color: black;\" role=\"tab\" aria-controls=\"home\"><left><br>Train</left></h2> ","metadata":{}},{"cell_type":"markdown","source":"### Initialize model","metadata":{"papermill":{"duration":0.016367,"end_time":"2022-09-22T09:21:36.433808","exception":false,"start_time":"2022-09-22T09:21:36.417441","status":"completed"},"tags":[]}},{"cell_type":"code","source":"gan = CycleGAN(3, 3, epochs=30, device=device)","metadata":{"ExecuteTime":{"end_time":"2022-09-04T10:01:21.534356Z","start_time":"2022-09-04T10:01:21.265346Z"},"papermill":{"duration":0.42362,"end_time":"2022-09-22T09:21:36.874109","exception":false,"start_time":"2022-09-22T09:21:36.450489","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:22.656540Z","iopub.execute_input":"2023-04-11T05:37:22.657317Z","iopub.status.idle":"2023-04-11T05:37:23.038036Z","shell.execute_reply.started":"2023-04-11T05:37:22.657282Z","shell.execute_reply":"2023-04-11T05:37:23.037087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Train model","metadata":{"papermill":{"duration":0.016477,"end_time":"2022-09-22T09:21:36.907419","exception":false,"start_time":"2022-09-22T09:21:36.890942","status":"completed"},"tags":[]}},{"cell_type":"code","source":"gan.train(img_dataloader)","metadata":{"ExecuteTime":{"end_time":"2022-09-04T10:09:02.563358Z","start_time":"2022-09-04T10:01:22.788722Z"},"papermill":{"duration":7357.170172,"end_time":"2022-09-22T11:24:14.093958","exception":false,"start_time":"2022-09-22T09:21:36.923786","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T05:37:23.041442Z","iopub.execute_input":"2023-04-11T05:37:23.041720Z","iopub.status.idle":"2023-04-11T06:14:25.982438Z","shell.execute_reply.started":"2023-04-11T05:37:23.041696Z","shell.execute_reply":"2023-04-11T06:14:25.981316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## \n<p id=\"toc\"></p>\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #8DE7E3; color: black;\" role=\"tab\" aria-controls=\"home\"><left><br>Train results</left></h2> ","metadata":{}},{"cell_type":"markdown","source":"### Plot losses","metadata":{"papermill":{"duration":0.022408,"end_time":"2022-09-22T11:24:14.184496","exception":false,"start_time":"2022-09-22T11:24:14.162088","status":"completed"},"tags":[]}},{"cell_type":"code","source":"plot_train_loss(log='history.csv')","metadata":{"ExecuteTime":{"end_time":"2022-09-04T10:21:30.115051Z","start_time":"2022-09-04T10:21:29.865353Z"},"papermill":{"duration":0.542435,"end_time":"2022-09-22T11:24:14.803723","exception":false,"start_time":"2022-09-22T11:24:14.261288","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:25.984131Z","iopub.execute_input":"2023-04-11T06:14:25.984535Z","iopub.status.idle":"2023-04-11T06:14:26.445783Z","shell.execute_reply.started":"2023-04-11T06:14:25.984495Z","shell.execute_reply":"2023-04-11T06:14:26.444866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model predictions","metadata":{"papermill":{"duration":0.0238,"end_time":"2022-09-22T11:24:14.851963","exception":false,"start_time":"2022-09-22T11:24:14.828163","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"- Define dataset and dataloader for photos only","metadata":{"papermill":{"duration":0.022865,"end_time":"2022-09-22T11:24:14.898851","exception":false,"start_time":"2022-09-22T11:24:14.875986","status":"completed"},"tags":[]}},{"cell_type":"code","source":"photo_dataset = ImageDatasetCV(monet_dir=None, photo_dir=PHOTO_DIR)\n\nphoto_dataloader = DataLoader(photo_dataset, batch_size=BATCH_SIZE)","metadata":{"ExecuteTime":{"end_time":"2022-08-05T10:34:01.158951Z","start_time":"2022-08-05T10:34:01.143398Z"},"papermill":{"duration":0.038948,"end_time":"2022-09-22T11:24:14.961408","exception":false,"start_time":"2022-09-22T11:24:14.92246","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:26.447334Z","iopub.execute_input":"2023-04-11T06:14:26.447674Z","iopub.status.idle":"2023-04-11T06:14:26.456855Z","shell.execute_reply.started":"2023-04-11T06:14:26.447640Z","shell.execute_reply":"2023-04-11T06:14:26.455854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- View predicted results","metadata":{"ExecuteTime":{"end_time":"2022-08-05T10:34:05.699762Z","start_time":"2022-08-05T10:34:05.695726Z"},"papermill":{"duration":0.024769,"end_time":"2022-09-22T11:24:15.0101","exception":false,"start_time":"2022-09-22T11:24:14.985331","status":"completed"},"tags":[]}},{"cell_type":"code","source":"with torch.no_grad():\n    \n    j = 0\n    for photo in photo_dataloader:\n\n        photo = photo.to(device)\n        \n        monet_gen = gan.gen_ptm(photo)\n        \n        fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))\n        \n        ax[0].imshow(unnormalize(photo[0].cpu()).permute(1,2,0))\n        ax[1].imshow(unnormalize(monet_gen[0].cpu().detach()).permute(1,2,0))\n        \n        ax[0].set_title('Photo')\n        ax[1].set_title('Monetesque photo')\n        \n        plt.show()\n        j += 1\n        if j > 3:\n            break\n            \n","metadata":{"ExecuteTime":{"end_time":"2022-08-05T13:33:31.074983Z","start_time":"2022-08-05T13:33:28.082636Z"},"papermill":{"duration":1.587583,"end_time":"2022-09-22T11:24:16.621904","exception":false,"start_time":"2022-09-22T11:24:15.034321","status":"completed"},"scrolled":true,"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:26.458509Z","iopub.execute_input":"2023-04-11T06:14:26.458865Z","iopub.status.idle":"2023-04-11T06:14:27.887026Z","shell.execute_reply.started":"2023-04-11T06:14:26.458831Z","shell.execute_reply":"2023-04-11T06:14:27.886051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"photo_dataset = ImageDatasetCV(monet_dir=None, photo_dir=test)\n\nphoto_dataloader = DataLoader(photo_dataset, batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2023-04-11T06:14:27.888561Z","iopub.execute_input":"2023-04-11T06:14:27.889253Z","iopub.status.idle":"2023-04-11T06:14:27.908572Z","shell.execute_reply.started":"2023-04-11T06:14:27.889202Z","shell.execute_reply":"2023-04-11T06:14:27.907714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    \n    j = 0\n    for photo in photo_dataloader:\n\n        photo = photo.to(device)\n        \n        monet_gen = gan.gen_ptm(photo)\n        \n        fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))\n        \n        ax[0].imshow(unnormalize(photo[0].cpu()).permute(1,2,0))\n        ax[1].imshow(unnormalize(monet_gen[0].cpu().detach()).permute(1,2,0))\n        \n        ax[0].set_title('Photo')\n        ax[1].set_title('Monetesque photo')\n        \n        plt.show()\n        j += 1\n        if j > 3:\n            break","metadata":{"execution":{"iopub.status.busy":"2023-04-11T06:14:27.911552Z","iopub.execute_input":"2023-04-11T06:14:27.911821Z","iopub.status.idle":"2023-04-11T06:14:28.960101Z","shell.execute_reply.started":"2023-04-11T06:14:27.911796Z","shell.execute_reply":"2023-04-11T06:14:28.959180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SAVE_PATH = '/kaggle/working/result2-5'\n\ntest = '../input/ca3-test/CA3/Part 2-5'\n\nphoto_dataset = ImageDatasetCV(monet_dir=None, photo_dir=test)\n\nphoto_dataloader = DataLoader(photo_dataset, batch_size=BATCH_SIZE)\n\nwith torch.no_grad():\n    \n    j = 0\n    for photo in photo_dataloader:\n\n        photo = photo.to(device)\n        \n        monet_gen = gan.gen_ptm(photo)\n        \n        fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))\n        \n        ax[0].imshow(unnormalize(photo[0].cpu()).permute(1,2,0))\n        ax[1].imshow(unnormalize(monet_gen[0].cpu().detach()).permute(1,2,0))\n        \n        ax[0].set_title('Photo')\n        ax[1].set_title('Monetesque photo')\n        \n        plt.show()\n        j += 1\n        if j > 3:\n            break","metadata":{"execution":{"iopub.status.busy":"2023-04-11T06:14:28.961536Z","iopub.execute_input":"2023-04-11T06:14:28.962596Z","iopub.status.idle":"2023-04-11T06:14:30.024217Z","shell.execute_reply.started":"2023-04-11T06:14:28.962557Z","shell.execute_reply":"2023-04-11T06:14:30.023283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Save results","metadata":{"papermill":{"duration":0.040083,"end_time":"2022-09-22T11:24:16.700762","exception":false,"start_time":"2022-09-22T11:24:16.660679","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"### Save model","metadata":{"papermill":{"duration":0.041414,"end_time":"2022-09-22T11:24:16.781299","exception":false,"start_time":"2022-09-22T11:24:16.739885","status":"completed"},"tags":[]}},{"cell_type":"code","source":"save_dict = {\n    'epoch': 0,\n    'gen_mtp': gan.gen_mtp.state_dict(),\n    'gen_ptm': gan.gen_ptm.state_dict(),\n    'desc_m': gan.disc_m.state_dict(),\n    'desc_p': gan.disc_p.state_dict(),\n    'optimizer_gen': gan.adam_gen.state_dict(),\n    'optimizer_desc': gan.adam_disc.state_dict()\n    }","metadata":{"papermill":{"duration":0.050364,"end_time":"2022-09-22T11:24:16.869779","exception":false,"start_time":"2022-09-22T11:24:16.819415","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:30.025574Z","iopub.execute_input":"2023-04-11T06:14:30.026525Z","iopub.status.idle":"2023-04-11T06:14:30.034338Z","shell.execute_reply.started":"2023-04-11T06:14:30.026487Z","shell.execute_reply":"2023-04-11T06:14:30.033477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_checkpoint(save_dict, 'model.ckpt')","metadata":{"papermill":{"duration":0.428035,"end_time":"2022-09-22T11:24:17.335421","exception":false,"start_time":"2022-09-22T11:24:16.907386","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:30.039671Z","iopub.execute_input":"2023-04-11T06:14:30.039959Z","iopub.status.idle":"2023-04-11T06:14:30.416445Z","shell.execute_reply.started":"2023-04-11T06:14:30.039934Z","shell.execute_reply":"2023-04-11T06:14:30.415473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## \n<p id=\"toc\"></p>\n<h2 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style=\"font-family: Verdana; font-size: 24px; font-style: normal; font-weight: bold; text-decoration: none; text-transform: none; letter-spacing: 3px; background-color: #8DE7E3; color: black;\" role=\"tab\" aria-controls=\"home\"><left><br>Save results</left></h2> ","metadata":{}},{"cell_type":"markdown","source":"- Get prediction for all photos","metadata":{"papermill":{"duration":0.042631,"end_time":"2022-09-22T11:24:17.492999","exception":false,"start_time":"2022-09-22T11:24:17.450368","status":"completed"},"tags":[]}},{"cell_type":"code","source":"!mkdir ../images","metadata":{"papermill":{"duration":1.126057,"end_time":"2022-09-22T11:24:18.658335","exception":false,"start_time":"2022-09-22T11:24:17.532278","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:30.417939Z","iopub.execute_input":"2023-04-11T06:14:30.418614Z","iopub.status.idle":"2023-04-11T06:14:31.397534Z","shell.execute_reply.started":"2023-04-11T06:14:30.418577Z","shell.execute_reply":"2023-04-11T06:14:31.396202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not os.path.exists(SAVE_PATH):\n    os.makedirs(SAVE_PATH)\n    \n\nwith torch.no_grad():\n    \n    \n    for i, photo in enumerate(photo_dataloader):\n        \n        monet_gen = gan.predict(photo)\n\n        monet_gen = T.ToPILImage()(unnormalize(monet_gen[0].cpu().detach())).convert('RGB')\n        \n        monet_gen.save(os.path.join(SAVE_PATH, str(i+1) + \".jpg\"))\n        \n        ","metadata":{"ExecuteTime":{"end_time":"2022-08-05T13:41:34.450823Z","start_time":"2022-08-05T13:41:34.111492Z"},"papermill":{"duration":179.375339,"end_time":"2022-09-22T11:27:18.092107","exception":false,"start_time":"2022-09-22T11:24:18.716768","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:31.400513Z","iopub.execute_input":"2023-04-11T06:14:31.401584Z","iopub.status.idle":"2023-04-11T06:14:31.547769Z","shell.execute_reply.started":"2023-04-11T06:14:31.401542Z","shell.execute_reply":"2023-04-11T06:14:31.546776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- Create ZIP archive","metadata":{"papermill":{"duration":0.036608,"end_time":"2022-09-22T11:27:18.166327","exception":false,"start_time":"2022-09-22T11:27:18.129719","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# shutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/images\")\nimage1 = Image.open(os.path.join(SAVE_PATH, '1.jpg'))\nimage1.show()\n\n","metadata":{"papermill":{"duration":4.191949,"end_time":"2022-09-22T11:27:22.394669","exception":false,"start_time":"2022-09-22T11:27:18.20272","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-04-11T06:14:31.549472Z","iopub.execute_input":"2023-04-11T06:14:31.549869Z","iopub.status.idle":"2023-04-11T06:14:31.615995Z","shell.execute_reply.started":"2023-04-11T06:14:31.549834Z","shell.execute_reply":"2023-04-11T06:14:31.614369Z"},"trusted":true},"execution_count":null,"outputs":[]}]}