{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"},"celltoolbar":"Raw Cell Format","kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":7183.448642,"end_time":"2024-12-10T11:43:15.681213","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2024-12-10T09:43:32.232571","version":"2.4.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"8e432a5b","cell_type":"markdown","source":"# 环境准备","metadata":{"papermill":{"duration":0.006209,"end_time":"2024-12-10T09:43:35.267454","exception":false,"start_time":"2024-12-10T09:43:35.261245","status":"completed"},"tags":[]}},{"id":"deb91a34","cell_type":"code","source":"import os\nimport cv2\nimport torch\nimport torch.nn as nn\nimport numpy as np\nfrom PIL import Image\nimport shutil\nimport itertools\nfrom torch.utils.data import Dataset, DataLoader\nimport matplotlib.pyplot as plt\nimport torchvision.transforms as transforms\nfrom torchvision.utils import make_grid","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:35.282374Z","iopub.status.busy":"2024-12-10T09:43:35.281618Z","iopub.status.idle":"2024-12-10T09:43:38.996606Z","shell.execute_reply":"2024-12-10T09:43:38.995884Z"},"papermill":{"duration":3.724882,"end_time":"2024-12-10T09:43:38.998713","exception":false,"start_time":"2024-12-10T09:43:35.273831","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"e4aa16ef","cell_type":"code","source":"BATCH_SIZE = 5\nMONET_IMAGES_PATH = \"/kaggle/input/gan-getting-started/monet_jpg\"\nTEST_IMAGES_PATH = \"/kaggle/input/gan-getting-started/photo_jpg\"\n\nlr = 0.0001\nbeta1 = 0.5\nbeta2 = 0.996\nn_epoches = 160\ndecay_epoch = 55\ndisplay_epoch = 20","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.013879Z","iopub.status.busy":"2024-12-10T09:43:39.013542Z","iopub.status.idle":"2024-12-10T09:43:39.017864Z","shell.execute_reply":"2024-12-10T09:43:39.017224Z"},"papermill":{"duration":0.013788,"end_time":"2024-12-10T09:43:39.019576","exception":false,"start_time":"2024-12-10T09:43:39.005788","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"3de07141","cell_type":"markdown","source":"# 数据集准备","metadata":{"papermill":{"duration":0.00617,"end_time":"2024-12-10T09:43:39.032359","exception":false,"start_time":"2024-12-10T09:43:39.026189","status":"completed"},"tags":[]}},{"id":"f579bbca","cell_type":"code","source":"transforms_dataset = transforms.Compose([\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n])","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.045955Z","iopub.status.busy":"2024-12-10T09:43:39.045744Z","iopub.status.idle":"2024-12-10T09:43:39.049742Z","shell.execute_reply":"2024-12-10T09:43:39.048942Z"},"papermill":{"duration":0.012639,"end_time":"2024-12-10T09:43:39.051388","exception":false,"start_time":"2024-12-10T09:43:39.038749","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"91b3d6ba","cell_type":"code","source":"class ImageDataset(Dataset):\n    def __init__(self, directory_x, directory_y, test=False, transforms=None):\n        self.transforms = transforms\n        \n        if test:\n            self.monet_images_X = [directory_x + \"/\" + name for name in sorted(os.listdir(directory_x))[250:]]\n            self.test_images_Y = [directory_y + \"/\" + name for name in sorted(os.listdir(directory_y))[250:301]]\n        else:\n            self.monet_images_X = [directory_x + \"/\" + name for name in sorted(os.listdir(directory_x))[:250]]\n            self.test_images_Y = [directory_y + \"/\" + name for name in sorted(os.listdir(directory_y))[:250]]\n        \n    def __len__(self):\n        return len(self.monet_images_X)\n    \n    def __getitem__(self, index):\n        x_img =  Image.open(self.monet_images_X[index])\n        y_img =  Image.open(self.test_images_Y[index])\n        \n        if self.transforms is not None:\n            x_img = self.transforms(x_img)\n            y_img = self.transforms(y_img)\n        return x_img, y_img","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.064878Z","iopub.status.busy":"2024-12-10T09:43:39.064672Z","iopub.status.idle":"2024-12-10T09:43:39.072272Z","shell.execute_reply":"2024-12-10T09:43:39.071490Z"},"papermill":{"duration":0.016126,"end_time":"2024-12-10T09:43:39.073783","exception":false,"start_time":"2024-12-10T09:43:39.057657","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"87238f68","cell_type":"code","source":"train_loader = DataLoader(\n    ImageDataset(directory_x=MONET_IMAGES_PATH, directory_y=TEST_IMAGES_PATH, test=False, transforms=transforms_dataset),\n    batch_size = BATCH_SIZE,\n    shuffle = True,\n    num_workers = 3\n)\n\ntest_loader = DataLoader(\n    ImageDataset(directory_x=MONET_IMAGES_PATH, directory_y=TEST_IMAGES_PATH, test=True, transforms=transforms_dataset),\n    batch_size = BATCH_SIZE,\n    shuffle = False,\n    num_workers = 3\n)","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.087394Z","iopub.status.busy":"2024-12-10T09:43:39.087144Z","iopub.status.idle":"2024-12-10T09:43:39.146721Z","shell.execute_reply":"2024-12-10T09:43:39.145950Z"},"papermill":{"duration":0.068222,"end_time":"2024-12-10T09:43:39.148337","exception":false,"start_time":"2024-12-10T09:43:39.080115","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"48da1c9d","cell_type":"markdown","source":"# GAN模型定义","metadata":{"papermill":{"duration":0.006677,"end_time":"2024-12-10T09:43:39.195930","exception":false,"start_time":"2024-12-10T09:43:39.189253","status":"completed"},"tags":[]}},{"id":"3f34feda","cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self, in_channels):\n        super(Discriminator, self).__init__()\n        self.scale_factor = 16\n\n        self.model = nn.Sequential(\n            nn.Conv2d(in_channels, 64, 4, stride=2, padding=1),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Conv2d(64, 128, 4, stride=2, padding=1),\n            nn.InstanceNorm2d(128),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Conv2d(128, 256, 4, stride=2, padding=1),\n            nn.InstanceNorm2d(256),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Conv2d(256, 512, 4, stride=2, padding=1),\n            nn.InstanceNorm2d(512),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.ZeroPad2d((1,0,1,0)),\n            nn.Conv2d(512, 1, 4, padding=1),\n        )\n\n    def forward(self, x):\n        return self.model(x)\n    ","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.175867Z","iopub.status.busy":"2024-12-10T09:43:39.175231Z","iopub.status.idle":"2024-12-10T09:43:39.181185Z","shell.execute_reply":"2024-12-10T09:43:39.180417Z"},"papermill":{"duration":0.015105,"end_time":"2024-12-10T09:43:39.182779","exception":false,"start_time":"2024-12-10T09:43:39.167674","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"910cebba","cell_type":"code","source":"class ResidualBlock(nn.Module):\n    def __init__(self, in_channels):\n        super(ResidualBlock, self).__init__()\n        self.block = nn.Sequential(\n            nn.ReflectionPad2d(1),\n            nn.Conv2d(in_channels, in_channels, 3),\n            nn.InstanceNorm2d(in_channels),\n            nn.ReLU(inplace=True),\n            nn.ReflectionPad2d(1),\n            nn.Conv2d(in_channels, in_channels, 3),\n            nn.InstanceNorm2d(in_channels)\n        )\n\n    def forward(self, x):\n        return x + self.block(x)\n\nclass GeneratorResNet(nn.Module):\n    def __init__(self, in_channels, num_residual_blocks=9):\n        super(GeneratorResNet, self).__init__()\n\n        self.initial = nn.Sequential(\n            nn.ReflectionPad2d(in_channels),\n            nn.Conv2d(in_channels, 64, 2 * in_channels + 1),\n            nn.InstanceNorm2d(64),\n            nn.ReLU(inplace=True)\n        )\n\n        self.downsample_blocks = nn.Sequential(\n            nn.Conv2d(64, 128, 3, stride=2, padding=1),\n            nn.InstanceNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 256, 3, stride=2, padding=1),\n            nn.InstanceNorm2d(256),\n            nn.ReLU(inplace=True)\n        )\n\n        self.residual_blocks = nn.Sequential(*[ResidualBlock(256) for _ in range(num_residual_blocks)])\n\n        self.upsample_blocks = nn.Sequential(\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(256, 128, 3, stride=1, padding=1),\n            nn.InstanceNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(128, 64, 3, stride=1, padding=1),\n            nn.InstanceNorm2d(64),\n            nn.ReLU(inplace=True)\n        )\n\n        self.output = nn.Sequential(\n            nn.ReflectionPad2d(in_channels),\n            nn.Conv2d(64, in_channels, 2 * in_channels + 1),\n            nn.Tanh()\n        )\n\n    def forward(self, x):\n        x = self.initial(x)\n        x = self.downsample_blocks(x)\n        x = self.residual_blocks(x)\n        x = self.upsample_blocks(x)\n        return self.output(x)\n","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.215820Z","iopub.status.busy":"2024-12-10T09:43:39.215432Z","iopub.status.idle":"2024-12-10T09:43:39.231058Z","shell.execute_reply":"2024-12-10T09:43:39.230052Z"},"papermill":{"duration":0.027808,"end_time":"2024-12-10T09:43:39.232862","exception":false,"start_time":"2024-12-10T09:43:39.205054","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"37787475","cell_type":"markdown","source":"# 模型训练","metadata":{"papermill":{"duration":0.009058,"end_time":"2024-12-10T09:43:39.249477","exception":false,"start_time":"2024-12-10T09:43:39.240419","status":"completed"},"tags":[]}},{"id":"ace632eb","cell_type":"code","source":"G_XY = GeneratorResNet(3, num_residual_blocks=9)\nD_Y = Discriminator(3)\n\nG_YX = GeneratorResNet(3, num_residual_blocks=9)\nD_X = Discriminator(3)","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.265600Z","iopub.status.busy":"2024-12-10T09:43:39.265270Z","iopub.status.idle":"2024-12-10T09:43:39.592867Z","shell.execute_reply":"2024-12-10T09:43:39.591970Z"},"papermill":{"duration":0.33782,"end_time":"2024-12-10T09:43:39.595007","exception":false,"start_time":"2024-12-10T09:43:39.257187","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"5d3f94ec","cell_type":"code","source":"cuda_available = torch.cuda.is_available()\nTensor = torch.cuda.FloatTensor if cuda_available else torch.Tensor\nprint(f'CUDA Available: {cuda_available}')\n\nmodels = [G_XY, D_Y, G_YX, D_X]\nfor model in models:\n    if cuda_available:\n        model.cuda()\n\ngan_loss = nn.MSELoss().cuda()\ncycle_loss = nn.L1Loss().cuda()\nidentity_loss = nn.L1Loss().cuda()","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.609743Z","iopub.status.busy":"2024-12-10T09:43:39.609481Z","iopub.status.idle":"2024-12-10T09:43:39.877158Z","shell.execute_reply":"2024-12-10T09:43:39.876342Z"},"papermill":{"duration":0.277187,"end_time":"2024-12-10T09:43:39.879111","exception":false,"start_time":"2024-12-10T09:43:39.601924","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"94c626d7","cell_type":"code","source":"optimizer_G = torch.optim.Adam(itertools.chain(G_XY.parameters(), G_YX.parameters()), lr=lr, betas=(beta1, beta2))\noptimizer_D_X = torch.optim.Adam(D_X.parameters(), lr=lr, betas=(beta1, beta2))\noptimizer_D_Y = torch.optim.Adam(D_Y.parameters(), lr=lr, betas=(beta1, beta2))\n","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.894759Z","iopub.status.busy":"2024-12-10T09:43:39.893934Z","iopub.status.idle":"2024-12-10T09:43:39.899900Z","shell.execute_reply":"2024-12-10T09:43:39.899156Z"},"papermill":{"duration":0.015475,"end_time":"2024-12-10T09:43:39.901574","exception":false,"start_time":"2024-12-10T09:43:39.886099","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"96164c20","cell_type":"code","source":"def learning_rate_decay(epoch, decay_start_epoch, total_epochs):\n    if epoch < decay_start_epoch:\n        return 1\n    else:\n        return 1 - (epoch - decay_start_epoch) / (total_epochs - decay_start_epoch)\n\nlr_scheduler_G = torch.optim.lr_scheduler.LambdaLR(optimizer_G, lr_lambda=lambda epoch: learning_rate_decay(epoch, decay_epoch, n_epoches))\nlr_scheduler_D_X = torch.optim.lr_scheduler.LambdaLR(optimizer_D_X, lr_lambda=lambda epoch: learning_rate_decay(epoch, decay_epoch, n_epoches))\nlr_scheduler_D_Y = torch.optim.lr_scheduler.LambdaLR(optimizer_D_Y, lr_lambda=lambda epoch: learning_rate_decay(epoch, decay_epoch, n_epoches))","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.916185Z","iopub.status.busy":"2024-12-10T09:43:39.915886Z","iopub.status.idle":"2024-12-10T09:43:39.921184Z","shell.execute_reply":"2024-12-10T09:43:39.920297Z"},"papermill":{"duration":0.014541,"end_time":"2024-12-10T09:43:39.922876","exception":false,"start_time":"2024-12-10T09:43:39.908335","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"1f525587","cell_type":"code","source":"def sample_images(real_X, real_Y):    \n    G_XY.eval()\n    G_YX.eval()\n\n    real_X = real_X.type(Tensor)\n    fake_Y = G_XY(real_X).detach()\n\n    real_Y = real_Y.type(Tensor)\n    fake_X = G_YX(real_Y).detach()\n\n    ncols = real_X.size(0)\n    real_X_grid = make_grid(real_X, nrow=ncols, normalize=True)\n    fake_Y_grid = make_grid(fake_Y, nrow=ncols, normalize=True)\n    real_Y_grid = make_grid(real_Y, nrow=ncols, normalize=True)\n    fake_X_grid = make_grid(fake_X, nrow=ncols, normalize=True)\n\n    fig, axs = plt.subplots(2, 2, figsize=(8, 8))  \n\n    axs[0, 0].imshow(real_X_grid.permute(1, 2, 0).cpu())\n    axs[0, 0].set_title(\"Real Images from Domain X\")\n    axs[0, 0].axis('off')\n\n    axs[0, 1].imshow(fake_Y_grid.permute(1, 2, 0).cpu())\n    axs[0, 1].set_title(\"Generated Images to Domain Y\")\n    axs[0, 1].axis('off')\n\n    axs[1, 0].imshow(real_Y_grid.permute(1, 2, 0).cpu())\n    axs[1, 0].set_title(\"Real Images from Domain Y\")\n    axs[1, 0].axis('off')\n\n    axs[1, 1].imshow(fake_X_grid.permute(1, 2, 0).cpu())\n    axs[1, 1].set_title(\"Generated Images to Domain X\")\n    axs[1, 1].axis('off')\n\n    plt.tight_layout()\n    plt.show()\n\nreal_X, real_Y = next(iter(test_loader))\nsample_images(real_X, real_Y)\n","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:39.938134Z","iopub.status.busy":"2024-12-10T09:43:39.937533Z","iopub.status.idle":"2024-12-10T09:43:41.517857Z","shell.execute_reply":"2024-12-10T09:43:41.516858Z"},"papermill":{"duration":1.592477,"end_time":"2024-12-10T09:43:41.522352","exception":false,"start_time":"2024-12-10T09:43:39.929875","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"74c3e3a8","cell_type":"code","source":"real_X, real_Y = next(iter(test_loader))\nsample_images(real_X, real_Y)","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:41.546485Z","iopub.status.busy":"2024-12-10T09:43:41.546156Z","iopub.status.idle":"2024-12-10T09:43:42.360465Z","shell.execute_reply":"2024-12-10T09:43:42.359400Z"},"papermill":{"duration":0.830376,"end_time":"2024-12-10T09:43:42.364068","exception":false,"start_time":"2024-12-10T09:43:41.533692","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"80bbd2d7","cell_type":"code","source":"for epoch in range(n_epoches):\n    for i, (real_X, real_Y) in enumerate(train_loader):\n        real_X, real_Y = real_X.type(Tensor), real_Y.type(Tensor)\n        out_shape = [real_X.size(0), 1, real_X.size(2) // D_X.scale_factor, real_X.size(3) // D_X.scale_factor]\n        \n        valid = torch.ones(out_shape).type(Tensor)\n        fake = torch.zeros(out_shape).type(Tensor)\n        \n        # training generators\n        G_XY.train()\n        G_YX.train()\n        \n        optimizer_G.zero_grad()\n        \n        fake_Y = G_XY(real_X)\n        fake_X = G_YX(real_Y)\n        \n        # identity loss\n        loss_id_X = identity_loss(fake_Y, real_X)\n        loss_id_Y = identity_loss(fake_X, real_Y)\n        loss_identity = (loss_id_X + loss_id_Y) / 2\n        \n        # gan loss\n        loss_GAN_XY = gan_loss(D_Y(fake_Y), valid) \n        loss_GAN_YX = gan_loss(D_X(fake_X), valid)\n        loss_GAN = (loss_GAN_XY + loss_GAN_YX) / 2\n        \n        # cycle loss\n        recov_X = G_YX(fake_Y)\n        recov_Y = G_XY(fake_X)\n        \n        loss_cycle_X = cycle_loss(recov_X, real_X)\n        loss_cycle_Y = cycle_loss(recov_Y, real_Y)\n        loss_cycle = (loss_cycle_X + loss_cycle_Y) / 2\n        \n        # total gan loss\n        loss_G = 5.0 * loss_identity + loss_GAN + 10.0 * loss_cycle\n        \n        loss_G.backward()\n        optimizer_G.step()\n        \n        #training discriminator X\n        optimizer_D_X.zero_grad()\n        \n        loss_real = gan_loss(D_X(real_X), valid)\n        loss_fake = gan_loss(D_X(fake_X.detach()), fake)\n        loss_D_X = (loss_real + loss_fake) / 2\n        \n        loss_D_X.backward()\n        optimizer_D_X.step()\n        \n        #training discriminator Y\n        optimizer_D_Y.zero_grad()\n        \n        loss_real = gan_loss(D_Y(real_Y), valid)\n        loss_fake = gan_loss(D_Y(fake_Y.detach()), fake)\n        loss_D_Y = (loss_real + loss_fake) / 2\n        \n        loss_D_Y.backward()\n        optimizer_D_Y.step()\n    \n    lr_scheduler_G.step()\n    lr_scheduler_D_X.step()\n    lr_scheduler_D_Y.step()\n    \n    # display results every 20 epoch\n    if (epoch + 1) % display_epoch == 0:\n        test_real_X, test_real_Y = next(iter(test_loader))\n        sample_images(test_real_X, test_real_Y)\n\n        loss_D = (loss_D_X + loss_D_Y) / 2\n        print(f'[Epoch {epoch + 1} / {n_epoches}]')\n        print(f'[Generator loss: {loss_G.item()} | identity: {loss_identity.item()} GAN: {loss_GAN.item()} cycle: {loss_cycle.item()}]')\n        print(f'[Discriminator loss: {loss_D.item()} | D_X: {loss_D_X.item()} D_Y: {loss_D_Y.item()}]')    ","metadata":{"execution":{"iopub.execute_input":"2024-12-10T09:43:42.396638Z","iopub.status.busy":"2024-12-10T09:43:42.396333Z","iopub.status.idle":"2024-12-10T11:40:35.291766Z","shell.execute_reply":"2024-12-10T11:40:35.290823Z"},"papermill":{"duration":7012.971859,"end_time":"2024-12-10T11:40:35.351233","exception":false,"start_time":"2024-12-10T09:43:42.379374","status":"completed"},"scrolled":true,"tags":[]},"outputs":[],"execution_count":null},{"id":"0afbe6f9","cell_type":"markdown","source":"# 模型推理","metadata":{"papermill":{"duration":0.051983,"end_time":"2024-12-10T11:40:35.455343","exception":false,"start_time":"2024-12-10T11:40:35.403360","status":"completed"},"tags":[]}},{"id":"81dde0f4","cell_type":"code","source":"files = [TEST_IMAGES_PATH + \"/\" + name for name in os.listdir(TEST_IMAGES_PATH)]\n\n# 添加指定图片\nextra_files = [\n    \"/kaggle/input/gan-getting-started/photo_jpg/00882b7e1d.jpg\",\n    \"/kaggle/input/gan-getting-started/photo_jpg/012df5ce29.jpg\"\n]\nfor f in extra_files:\n    if f not in files:\n        files.append(f)\n\nlen(files)","metadata":{"execution":{"iopub.execute_input":"2024-12-10T11:40:35.564883Z","iopub.status.busy":"2024-12-10T11:40:35.564536Z","iopub.status.idle":"2024-12-10T11:40:35.574781Z","shell.execute_reply":"2024-12-10T11:40:35.573902Z"},"papermill":{"duration":0.068051,"end_time":"2024-12-10T11:40:35.576476","exception":false,"start_time":"2024-12-10T11:40:35.508425","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"cf699f7f","cell_type":"code","source":"save_dir = '../images'\nif not os.path.exists(save_dir):\n    os.makedirs(save_dir)","metadata":{"execution":{"iopub.execute_input":"2024-12-10T11:40:35.682978Z","iopub.status.busy":"2024-12-10T11:40:35.682654Z","iopub.status.idle":"2024-12-10T11:40:35.687225Z","shell.execute_reply":"2024-12-10T11:40:35.686414Z"},"papermill":{"duration":0.060581,"end_time":"2024-12-10T11:40:35.688963","exception":false,"start_time":"2024-12-10T11:40:35.628382","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"43a9f151","cell_type":"code","source":"transforms_dataset = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])\n])\n\ntensor_to_image = transforms.ToPILImage()\nG_YX.eval()\n\nfor batch_start in range(0, len(files), BATCH_SIZE):\n    batch_files = files[batch_start:batch_start + BATCH_SIZE]\n    batch_imgs = [transforms_dataset(Image.open(file)) for file in batch_files]\n    \n    batch_tensor = torch.stack(batch_imgs).type(Tensor)\n    generated_imgs = G_YX(batch_tensor).detach().cpu()\n    \n    for idx, tensor_img in enumerate(generated_imgs):\n        np_img = tensor_img.squeeze().permute(1, 2, 0).numpy()\n        np_img = ((np_img - np_img.min()) * 255 / (np_img.max() - np_img.min())).astype(np.uint8)\n        \n        # 保存生成图像\n        pil_img = tensor_to_image(np_img)\n        _, filename = os.path.split(files[batch_start + idx])\n        pil_img.save(os.path.join(save_dir, filename))","metadata":{"execution":{"iopub.execute_input":"2024-12-10T11:40:35.796297Z","iopub.status.busy":"2024-12-10T11:40:35.795448Z","iopub.status.idle":"2024-12-10T11:43:10.404002Z","shell.execute_reply":"2024-12-10T11:43:10.403324Z"},"papermill":{"duration":154.666151,"end_time":"2024-12-10T11:43:10.406220","exception":false,"start_time":"2024-12-10T11:40:35.740069","status":"completed"},"tags":[]},"outputs":[],"execution_count":null},{"id":"bb09f7fe","cell_type":"code","source":"shutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/images\")","metadata":{"execution":{"iopub.execute_input":"2024-12-10T11:43:10.510340Z","iopub.status.busy":"2024-12-10T11:43:10.509682Z","iopub.status.idle":"2024-12-10T11:43:14.299375Z","shell.execute_reply":"2024-12-10T11:43:14.298605Z"},"papermill":{"duration":3.843423,"end_time":"2024-12-10T11:43:14.301311","exception":false,"start_time":"2024-12-10T11:43:10.457888","status":"completed"},"tags":[]},"outputs":[],"execution_count":null}]}