{"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\n#for dirname, _, filenames in os.walk('/kaggle/input'):\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":"2023-05-15T18:13:00.569502Z","iopub.execute_input":"2023-05-15T18:13:00.569957Z","iopub.status.idle":"2023-05-15T18:13:00.577725Z","shell.execute_reply.started":"2023-05-15T18:13:00.569924Z","shell.execute_reply":"2023-05-15T18:13:00.576887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import wandb\nwith open('/root/.netrc', 'w', encoding='utf-8') as f:\n    f.write('''machine api.wandb.ai\n        login user\n        password 0f4414049a3825a7e2aee0fffc95f3843de2f566\n    ''')\nwandb.init(project = 'cycle-gan',entity=\"zhijiao\", name = 'model-gan')","metadata":{"execution":{"iopub.status.busy":"2023-05-15T18:13:03.327716Z","iopub.execute_input":"2023-05-15T18:13:03.328154Z","iopub.status.idle":"2023-05-15T18:13:41.227507Z","shell.execute_reply.started":"2023-05-15T18:13:03.328119Z","shell.execute_reply":"2023-05-15T18:13:41.226676Z"},"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\nfrom torch.autograd import Variable\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","metadata":{"execution":{"iopub.status.busy":"2023-05-15T18:13:45.676911Z","iopub.execute_input":"2023-05-15T18:13:45.677501Z","iopub.status.idle":"2023-05-15T18:13:49.954233Z","shell.execute_reply.started":"2023-05-15T18:13:45.677447Z","shell.execute_reply":"2023-05-15T18:13:49.953282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = ['/kaggle/input/gan-getting-started/monet_jpg/','/kaggle/input/gan-getting-started/photo_jpg/']\nmonet = os.listdir('/kaggle/input/gan-getting-started/monet_jpg')\nphoto = os.listdir('/kaggle/input/gan-getting-started/photo_jpg')","metadata":{"execution":{"iopub.status.busy":"2023-05-15T18:13:53.742737Z","iopub.execute_input":"2023-05-15T18:13:53.743494Z","iopub.status.idle":"2023-05-15T18:13:54.327837Z","shell.execute_reply.started":"2023-05-15T18:13:53.743454Z","shell.execute_reply":"2023-05-15T18:13:54.326827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 可视化部分\ndef de_norm(input): # 竟然没有使用imagenet的标配(!)\n    mean = 0.5 \n    std = 0.5\n    return input * std + mean\n\ndef visulization(x,y,z):\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    x = de_norm(x)\n    y = de_norm(y)\n    z = de_norm(z)\n    \n    print('photo Data Range', x.max(), x.min())\n    print('Fake monet Data Range',y.max(), y.min())\n    print('Cycle photo Data Range',z.max(), z.min())\n    plt.figure(figsize = (10,5))\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    plt.show()\n    \n# 模型权重初始化\ndef weight_init(m : 'model'):\n    classname = m.__class__.__name__\n    if classname.find('Conv') != -1:\n        nn.init.normal_(m.weight.data, 0.0, 0.02)\n    elif classname.find('Instance') != -1:\n        nn.init.normal_(m.weight.data, 1.0, 0.02)\n        nn.init.constant_(m.bias.data, 0)\n        \ndef weights_init_normal(m):\n    classname = m.__class__.__name__\n    if classname.find(\"Conv\") != -1:\n        torch.nn.init.normal_(m.weight.data, 0.0, 0.02)\n    elif classname.find(\"BatchNorm2d\") != -1:\n        torch.nn.init.normal_(m.weight.data, 1.0, 0.02)\n        torch.nn.init.constant_(m.bias.data, 0.0)\n        \n# 更新梯度\ndef 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":"2023-05-15T18:13:56.59279Z","iopub.execute_input":"2023-05-15T18:13:56.593206Z","iopub.status.idle":"2023-05-15T18:13:56.617483Z","shell.execute_reply.started":"2023-05-15T18:13:56.593173Z","shell.execute_reply":"2023-05-15T18:13:56.616478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 定义数据集\n# 数据增强部分\ntrain_transform = T.Compose([T.RandomHorizontalFlip(p = 0.5),\n                             T.RandomVerticalFlip(p = 0.5),\n                             T.RandomRotation(180),\n                             T.ToTensor(),\n                             T.Normalize((0.5), (0.5))])\n\n\n# 自定义数据集\nclass CustomDataset(Dataset):\n    def __init__(self, path, monet, photo, transforms = None, seed = 777):\n        self.path = path # 图片路径\n        self.monet = monet # 莫奈风格图片\n        self.photo = photo #  图片\n        self.seed = seed # 随机种子\n        self.transforms = transforms\n        self.photo_len = len(self.monet)\n        self.monet_len = len(self.photo)\n        self.length_dataset = max(self.photo_len, self.monet_len) # 获取数据集长度？\n        \n        \n    def __len__(self):\n        return len(self.monet)\n    \n    def __getitem__(self, idx):\n        # get path\n        monet_path = self.path[0] + self.monet[idx] # 获取一张莫奈风格的图\n        photo_idx = np.random.randint(0, len(self.photo)) # 随机获取一张图片 这大概是有一个1:n的随机\n        photo_path = self.path[1] + self.photo[photo_idx]\n        #get image 转成RGB类型图\n        monet = Image.open(monet_path).convert('L')\n        photo = Image.open(photo_path).convert('L')\n        #image Transform 数据增强部分，说实话，这个一个应该也可以的吧？\n        if self.transforms:\n            torch.manual_seed(self.seed)\n            monet = self.transforms(monet)\n        if self.transforms:\n            torch.manual_seed(self.seed)\n            photo = self.transforms(photo)\n        return monet, photo ","metadata":{"execution":{"iopub.status.busy":"2023-05-15T19:04:14.089617Z","iopub.execute_input":"2023-05-15T19:04:14.08997Z","iopub.status.idle":"2023-05-15T19:04:14.10407Z","shell.execute_reply.started":"2023-05-15T19:04:14.089941Z","shell.execute_reply":"2023-05-15T19:04:14.103135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self):\n        super(Generator, self).__init__()\n\n        self.init_size = 256 // 4\n        self.l1 = nn.Sequential(nn.Linear(100, 128 * self.init_size ** 2))\n\n        self.conv_blocks = nn.Sequential(\n            nn.BatchNorm2d(128),\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(128, 256, 3, stride=1, padding=1),\n            nn.BatchNorm2d(256, 0.8),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(256, 128, 3, stride=1, padding=1),\n            nn.BatchNorm2d(128, 0.8),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Conv2d(128, 64, 3, stride=1, padding=1),\n            nn.BatchNorm2d(64, 0.8),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Conv2d(64, 1, 3, stride=1, padding=1),\n            nn.Tanh(),\n        )\n\n    def forward(self, z):\n        out = self.l1(z)\n        out = out.view(out.shape[0], 128, self.init_size, self.init_size)\n        img = self.conv_blocks(out)\n        return img\n\n\nclass Discriminator(nn.Module):\n    def __init__(self):\n        super(Discriminator, self).__init__()\n\n        def discriminator_block(in_filters, out_filters, bn=True):\n            block = [nn.Conv2d(in_filters, out_filters, 3, 2, 1), nn.LeakyReLU(0.2, inplace=True), nn.Dropout2d(0.25)]\n            if bn:\n                block.append(nn.BatchNorm2d(out_filters, 0.8))\n            return block\n\n        self.model = nn.Sequential(\n            *discriminator_block(1, 16, bn=False),\n            *discriminator_block(16, 32),\n            *discriminator_block(32, 64),\n            *discriminator_block(64, 128),\n            *discriminator_block(128, 256),\n        )\n\n        # The height and width of downsampled image\n        ds_size = 256 // 2 ** 5\n        self.adv_layer = nn.Sequential(nn.Linear(256 * ds_size ** 2, 1), nn.Sigmoid())\n\n    def forward(self, img):\n        out = self.model(img)\n        out = out.view(out.shape[0], -1)\n        validity = self.adv_layer(out)\n\n        return validity","metadata":{"execution":{"iopub.status.busy":"2023-05-15T19:04:18.99343Z","iopub.execute_input":"2023-05-15T19:04:18.9941Z","iopub.status.idle":"2023-05-15T19:04:19.012491Z","shell.execute_reply.started":"2023-05-15T19:04:18.994066Z","shell.execute_reply":"2023-05-15T19:04:19.011565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cuda = True if torch.cuda.is_available() else False\n# Loss function\nadversarial_loss = torch.nn.BCELoss().to('cuda')\n\n# Initialize generator and discriminator\ngenerator = Generator()\ndiscriminator = Discriminator()\n\nif cuda:\n    generator.cuda()\n    discriminator.cuda()\n    adversarial_loss.cuda()\n\n# Initialize weights\ngenerator.apply(weights_init_normal)\ndiscriminator.apply(weights_init_normal)\n\n# Optimizers\noptimizer_G = torch.optim.Adam(generator.parameters(), lr=0.001, betas=(0.5, 0.999))\noptimizer_D = torch.optim.Adam(discriminator.parameters(), lr=0.001, betas=(0.5, 0.999))\n\nTensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor\n\n# Get Data from Dataloader\n# 装载数据\ntrain_dataset = CustomDataset(path, monet, photo, transforms = train_transform, seed = 26)\ntrain_dataloader = DataLoader(train_dataset, batch_size = 1, shuffle  = True, num_workers = 2)\ntrain_total_batch = len(train_dataloader)\nloss_G_list = []\nloss_D_list = []","metadata":{"execution":{"iopub.status.busy":"2023-05-15T19:24:44.32414Z","iopub.execute_input":"2023-05-15T19:24:44.324502Z","iopub.status.idle":"2023-05-15T19:24:44.917373Z","shell.execute_reply.started":"2023-05-15T19:24:44.324474Z","shell.execute_reply":"2023-05-15T19:24:44.916163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2023-05-15T19:24:50.197405Z","iopub.execute_input":"2023-05-15T19:24:50.197775Z","iopub.status.idle":"2023-05-15T19:38:40.26605Z","shell.execute_reply.started":"2023-05-15T19:24:50.197744Z","shell.execute_reply":"2023-05-15T19:38:40.264768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], 100))))\n\n# Generate a batch of images\ngen_imgs = generator(z)\ngen_imgs = gen_imgs[0,:,:,:]\nprint(gen_imgs.shape)\ngen_imgs = gen_imgs.cpu().detach().numpy().transpose(1,2,0)\nprint(gen_imgs.shape)\n#gen_imgs = de_norm(gen_imgs)\nplt.figure(figsize = (10,5))\nplt.imshow(gen_imgs,cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2023-05-15T19:48:04.416499Z","iopub.execute_input":"2023-05-15T19:48:04.41687Z","iopub.status.idle":"2023-05-15T19:48:04.721131Z","shell.execute_reply.started":"2023-05-15T19:48:04.41684Z","shell.execute_reply":"2023-05-15T19:48:04.719999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], 100))))\ngen = Generator()\ngen.cuda()\ngen.load_state_dict(torch.load('/kaggle/working/generator_epoch.pt'))\n# Generate a batch of images\ngen_imgs = gen(z)\ngen_imgs = gen_imgs[0,:,:,:]\nprint(gen_imgs.shape)\ngen_imgs = gen_imgs.cpu().detach().numpy().transpose(1,2,0)\nprint(gen_imgs.shape)\n#gen_imgs = de_norm(gen_imgs)\nplt.figure(figsize = (10,5))\nplt.imshow(gen_imgs,cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2023-05-15T19:47:47.269474Z","iopub.execute_input":"2023-05-15T19:47:47.270155Z","iopub.status.idle":"2023-05-15T19:47:48.341111Z","shell.execute_reply.started":"2023-05-15T19:47:47.270121Z","shell.execute_reply":"2023-05-15T19:47:48.340095Z"},"trusted":true},"execution_count":null,"outputs":[]}]}