{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/working'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-23T20:19:56.635653Z","iopub.execute_input":"2022-03-23T20:19:56.635901Z","iopub.status.idle":"2022-03-23T20:19:56.643646Z","shell.execute_reply.started":"2022-03-23T20:19:56.635874Z","shell.execute_reply":"2022-03-23T20:19:56.642837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport os\nfrom PIL import Image\nimport itertools\nfrom tqdm import tqdm\nimport cv2\n\n\nimport torch\nimport torchvision\n\nimport torch.optim.lr_scheduler as lr_scheduler\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.transforms as T\nimport torch.nn as nn\nimport torch.optim as optim","metadata":{"execution":{"iopub.status.busy":"2022-03-23T20:19:59.568016Z","iopub.execute_input":"2022-03-23T20:19:59.568713Z","iopub.status.idle":"2022-03-23T20:20:01.410121Z","shell.execute_reply.started":"2022-03-23T20:19:59.568677Z","shell.execute_reply":"2022-03-23T20:20:01.40932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#  Functii care ne ajuta sa vizualizam rezultatele retelei\n\ndef de_norm(input):\n    mean = 0.5 \n    std = 0.5\n    return input * std + mean\n\ndef visualization(x, y, z, save = False, path = ''):\n    x = torch.reshape(x, (3, 256, 256))\n    y = torch.reshape(y, (3, 256, 256))\n    z = torch.reshape(z, (3, 256, 256))\n\n    x = x.cpu().detach().numpy().transpose(1,2,0)\n    y = y.cpu().detach().numpy().transpose(1,2,0)\n    z = z.cpu().detach().numpy().transpose(1,2,0)\n\n    x = de_norm(x)\n    y = de_norm(y)\n    z = de_norm(z)\n    \n    plt.figure(figsize = (16,8))\n    plt.subplot(1,3,1)\n    plt.title('actual')\n    plt.imshow(x)\n    plt.tick_params(left = False, bottom = False, labelleft = False, labelbottom = False)\n    plt.subplot(1,3,2)\n    plt.title('fake')\n    plt.imshow(y)\n    plt.tick_params(left = False, bottom = False, labelleft = False, labelbottom = False)\n    plt.subplot(1,3,3)\n    plt.title('cycle')\n    plt.imshow(z)\n    plt.tick_params(left = False, bottom = False, labelleft = False, labelbottom = False)\n\n    if save == True:\n        plt.savefig(path)\n    else:\n        plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-23T20:20:06.207116Z","iopub.execute_input":"2022-03-23T20:20:06.207477Z","iopub.status.idle":"2022-03-23T20:20:06.219293Z","shell.execute_reply.started":"2022-03-23T20:20:06.207442Z","shell.execute_reply":"2022-03-23T20:20:06.218312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#  Inspiration: https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix/blob/003efc4c8819de47ff11b5a0af7ba09aee7f5fc1/models/networks.py#L436\nclass UnetSkipConnectionBlock(nn.Module):\n    def __init__(self, outer_nc, inner_nc, in_channels = None, submodule = None, outermost = False, innermost = False, use_dropout = False):\n        '''\n            Constructs a Unet submodule with skip connections.\n\n            Parameters:\n                outer_nc                                      --- number of channels in the outer conv layer\n                inner_nc                                      --- number of channels in the inner conv layer\n                in_channels                                   --- number of channels in input data\n                submodule (UnetSkipConnectionBlock)           --- previously defined submodules\n                outermost (bool)                              --- if this is the outermost module\n                innermost (bool)                              --- if this is the innermost module\n                use_dropout (bool)                            --- whether to use dropout layers or not\n        '''\n        super(UnetSkipConnectionBlock, self).__init__()\n        self.outermost = outermost\n\n        if in_channels is None:\n            in_channels = outer_nc\n\n        down_conv = nn.Conv2d(in_channels, inner_nc, kernel_size = 4, stride = 2, padding = 1, bias = False)\n        down_relu = nn.LeakyReLU(0.2, True)\n        down_norm = nn.InstanceNorm2d(inner_nc)\n        up_relu = nn.ReLU(True)\n        up_norm = nn.InstanceNorm2d(outer_nc)\n\n        if outermost:\n            up_conv = nn.ConvTranspose2d(inner_nc * 2, outer_nc, kernel_size = 4, stride = 2, padding = 1)\n            down = [down_conv]\n            #up = [up_relu, nn.Upsample(scale_factor = 2, mode='bilinear'), nn.ReflectionPad2d(1), nn.Conv2d(inner_nc * 2, outer_nc, kernel_size = 3, stride = 1, padding = 0, bias = False), nn.Tanh()]\n            up = [up_relu, up_conv, nn.Tanh()]\n            model = down + [submodule] + up\n        elif innermost:\n            up_conv = nn.ConvTranspose2d(inner_nc, outer_nc, kernel_size = 4, stride = 2, padding = 1, bias = False)\n            down = [down_relu, down_conv]\n            #up = [up_relu, nn.Upsample(scale_factor = 2, mode='bilinear'), nn.ReflectionPad2d(1), nn.Conv2d(inner_nc, outer_nc, kernel_size = 3, stride = 1, padding = 0, bias = False), up_norm]\n            up = [up_relu, up_conv, up_norm]\n            model = down + up\n        else:\n            up_conv = nn.ConvTranspose2d(inner_nc * 2, outer_nc, kernel_size = 4, stride = 2, padding = 1, bias = False)\n            down = [down_relu, down_conv, down_norm]\n            #up = [up_relu, nn.Upsample(scale_factor = 2, mode='bilinear'), nn.ReflectionPad2d(1), nn.Conv2d(inner_nc * 2, outer_nc, kernel_size = 3, stride = 1, padding = 0, bias = False), up_norm]\n            up = [up_relu, up_conv, up_norm]\n\n            if use_dropout:\n                model = down + [submodule] + up + [nn.Dropout(0.5)]\n            else:\n                model = down + [submodule] + up\n\n        self.model = nn.Sequential(*model)\n\n    def forward(self, x):\n        if self.outermost:\n            return self.model(x)\n        else:\n            return torch.cat([x, self.model(x)], 1)\n\n\nclass Generator(nn.Module):\n    def __init__(self, num_downs, in_channels = 3, out_channels = 3, use_dropout = False):\n        super(Generator, self).__init__()\n\n        #  Add the innermost layer\n        unet_block = UnetSkipConnectionBlock(512, 512, in_channels = None, submodule = None, innermost = True)\n        \n        #  Add intermediate layers with 512 filters\n        for i in range(num_downs - 5):\n            unet_block = UnetSkipConnectionBlock(512, 512, in_channels = None, submodule = unet_block, use_dropout = use_dropout)\n        \n        #  Gradually reduce the number of filters (channels)\n        unet_block = UnetSkipConnectionBlock(256, 512, in_channels = None, submodule = unet_block)\n        unet_block = UnetSkipConnectionBlock(128, 256, in_channels = None, submodule = unet_block)\n        unet_block = UnetSkipConnectionBlock(64, 128, in_channels = None, submodule = unet_block)\n\n        #  Add the outermost layer\n        self.model = UnetSkipConnectionBlock(out_channels, 64, in_channels = in_channels, submodule = unet_block, outermost = True)\n\n\n    def forward(self, input):\n        return self.model(input)","metadata":{"execution":{"iopub.status.busy":"2022-03-23T20:20:09.860998Z","iopub.execute_input":"2022-03-23T20:20:09.861296Z","iopub.status.idle":"2022-03-23T20:20:09.886023Z","shell.execute_reply.started":"2022-03-23T20:20:09.861264Z","shell.execute_reply":"2022-03-23T20:20:09.885273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#  PatchGAN\n\nclass Discriminator(nn.Module):\n    def __init__(self):\n        super(Discriminator, self).__init__()\n\n        self.layers = []\n        self.layers += self.conv_block(3, 64, stride = 2, use_norm = False)\n        self.layers += self.conv_block(64, 128, stride = 2)\n        self.layers += self.conv_block(128, 256, stride = 2)\n        self.layers += self.conv_block(256, 512)\n        self.layers += self.conv_block(512, 1, use_act = False, use_norm = False)\n        #self.layers += [nn.Sigmoid()]\n        self.net = nn.Sequential(*self.layers)\n\n\n    def forward(self, x):\n        return self.net(x)\n\n\n    def conv_block(self, in_channels, out_channels, stride = 1, padding = 2, use_norm = True, use_act = True):\n        layers = []\n\n        layers += [nn.Conv2d(\n            in_channels,\n            out_channels,\n            kernel_size = 4,\n            stride = stride,\n            padding = padding,\n            padding_mode = 'reflect',\n            bias = True\n        )]\n\n        if use_norm:\n            layers += [nn.InstanceNorm2d(out_channels)]\n\n        if use_act:\n            layers += [nn.LeakyReLU(0.2, inplace = True)]\n\n        return layers","metadata":{"execution":{"iopub.status.busy":"2022-03-19T09:23:50.040767Z","iopub.execute_input":"2022-03-19T09:23:50.041281Z","iopub.status.idle":"2022-03-19T09:23:50.05216Z","shell.execute_reply.started":"2022-03-19T09:23:50.041243Z","shell.execute_reply":"2022-03-19T09:23:50.050781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#disc_photo = Discriminator().cuda()  #  Is the image a real/fake photo?\n#disc_monet = Discriminator().cuda()  #  Is the image a real/fake Monet?\ngen_photo = Generator(8, use_dropout = True).cuda()  #  Monet ---> photo\ngen_monet = Generator(8, use_dropout = True).cuda()  #  photo ---> Monet\n\n# /kaggle/input/monettorchmodel/v2_29_gen_monet.pth\n# /kaggle/input/monettorchmodel/v2_29_disc_monet.pth\n# /kaggle/input/monettorchmodel/v2_29_disc_photo.pth\n# /kaggle/input/monettorchmodel/v2_29_gen_photo.pth\n\n#disc_photo.load_state_dict(torch.load('/kaggle/input/monettorchmodel/v2_29_disc_photo.pth'))\n#disc_monet.load_state_dict(torch.load('/kaggle/input/monettorchmodel/v2_29_disc_monet.pth'))\ngen_photo = torch.load('/kaggle/input/monettorchmodel/v18_249_gen_photo.pth')\ngen_monet = torch.load('/kaggle/input/monettorchmodel/v18_249_gen_monet.pth')","metadata":{"execution":{"iopub.status.busy":"2022-03-19T09:24:14.075364Z","iopub.execute_input":"2022-03-19T09:24:14.075612Z","iopub.status.idle":"2022-03-19T09:24:15.847817Z","shell.execute_reply.started":"2022-03-19T09:24:14.075583Z","shell.execute_reply":"2022-03-19T09:24:15.84708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir /kaggle/output","metadata":{"execution":{"iopub.status.busy":"2022-03-19T09:33:28.21175Z","iopub.execute_input":"2022-03-19T09:33:28.212517Z","iopub.status.idle":"2022-03-19T09:33:28.900767Z","shell.execute_reply.started":"2022-03-19T09:33:28.212478Z","shell.execute_reply":"2022-03-19T09:33:28.899834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\n\ntransforms = T.Compose([\n    T.Resize(size = (256, 256)),\n    T.ToTensor(),\n    T.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n])\n\n\n#  Make predictions\ndef make_predictions():\n    file_names = os.listdir('/kaggle/input/gan-getting-started/photo_jpg')\n        \n    to_image = T.ToPILImage()\n\n    for file_name in file_names:\n        path = '/kaggle/input/gan-getting-started/photo_jpg/' + file_name\n        image = Image.open(path).convert('RGB')\n        image = transforms(image)\n        image = image.unsqueeze(0)\n        image = image.cuda()\n        generated_monet = gen_monet(image)\n        #cycled_image = gen_photo(generated_monet)\n\n        #visualization(image, generated_monet, cycled_image)\n\n        generated_monet = torch.reshape(generated_monet, (3, 256, 256))\n        generated_monet = de_norm(generated_monet)\n        generated_monet = to_image(torch.tensor(generated_monet))\n        generated_monet = np.asarray(generated_monet)\n        generated_monet = cv2.cvtColor(generated_monet, cv2.COLOR_BGR2RGB)\n        \n        cv2.imwrite('/kaggle/output/' + file_name, generated_monet)\n    \n    print('Finished!')\n","metadata":{"execution":{"iopub.status.busy":"2022-03-19T09:33:31.852356Z","iopub.execute_input":"2022-03-19T09:33:31.853253Z","iopub.status.idle":"2022-03-19T09:33:31.863069Z","shell.execute_reply.started":"2022-03-19T09:33:31.85321Z","shell.execute_reply":"2022-03-19T09:33:31.862366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"make_predictions()","metadata":{"execution":{"iopub.status.busy":"2022-03-19T09:33:36.652427Z","iopub.execute_input":"2022-03-19T09:33:36.653161Z","iopub.status.idle":"2022-03-19T09:38:18.469973Z","shell.execute_reply.started":"2022-03-19T09:33:36.653112Z","shell.execute_reply":"2022-03-19T09:38:18.46796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nshutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/output\")\nprint(\"finished!\")","metadata":{"execution":{"iopub.status.busy":"2022-03-19T09:38:41.063778Z","iopub.execute_input":"2022-03-19T09:38:41.064222Z","iopub.status.idle":"2022-03-19T09:38:49.052831Z","shell.execute_reply.started":"2022-03-19T09:38:41.064186Z","shell.execute_reply":"2022-03-19T09:38:49.051304Z"},"trusted":true},"execution_count":null,"outputs":[]}]}