{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":2520560,"sourceType":"datasetVersion","datasetId":1526975}],"dockerImageVersionId":30787,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Biblioteku importavimas","metadata":{}},{"cell_type":"code","source":"!pip install pytorch-fid\n!pip install torchinfo","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:28.793541Z","iopub.execute_input":"2024-12-02T02:26:28.794382Z","iopub.status.idle":"2024-12-02T02:26:44.889354Z","shell.execute_reply.started":"2024-12-02T02:26:28.794346Z","shell.execute_reply":"2024-12-02T02:26:44.888188Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom torch.utils.data import DataLoader\nfrom torchvision.datasets import ImageFolder\nimport torchvision.transforms as tt\nimport torch\nimport torch.nn as nn\nimport cv2\nfrom tqdm.notebook import tqdm\nimport torch.nn.functional as F\nfrom torchvision.utils import save_image\nfrom torchvision.utils import make_grid\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom torch.utils.data import Dataset\nimport torchvision.transforms as tt\nfrom PIL import Image\nimport time\nimport torchvision  # Add this import\nimport torchvision.utils \n\nsns.set(style='darkgrid', font_scale=1.2)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.891328Z","iopub.execute_input":"2024-12-02T02:26:44.891645Z","iopub.status.idle":"2024-12-02T02:26:44.898974Z","shell.execute_reply.started":"2024-12-02T02:26:44.891614Z","shell.execute_reply":"2024-12-02T02:26:44.898096Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Duomenų apžvalga ir paruošimas","metadata":{}},{"cell_type":"code","source":"DATA_DIR = '/kaggle/input/portrait-paintings/Images'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.900226Z","iopub.execute_input":"2024-12-02T02:26:44.900569Z","iopub.status.idle":"2024-12-02T02:26:44.908909Z","shell.execute_reply.started":"2024-12-02T02:26:44.900532Z","shell.execute_reply":"2024-12-02T02:26:44.908040Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"image_size = 64\nbatch_size = 128\nstats = (0.5, 0.5, 0.5), (0.5, 0.5, 0.5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.910475Z","iopub.execute_input":"2024-12-02T02:26:44.910723Z","iopub.status.idle":"2024-12-02T02:26:44.922407Z","shell.execute_reply.started":"2024-12-02T02:26:44.910699Z","shell.execute_reply":"2024-12-02T02:26:44.921772Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class PortraitDataset(Dataset):\n    def __init__(self, root_dir, transform=None):\n        self.root_dir = root_dir\n        self.transform = transform\n        self.image_paths = [\n            os.path.join(root_dir, fname) for fname in os.listdir(root_dir) \n            if fname.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif'))\n        ]\n    \n    def __len__(self):\n        return len(self.image_paths)\n    \n    def __getitem__(self, idx):\n        img_path = self.image_paths[idx]\n        img = Image.open(img_path).convert('RGB')\n        \n        if self.transform:\n            img = self.transform(img)\n        \n        return img, 0  # Return 0 as a dummy label since you're doing unsupervised learning\n\n# Create the dataset\ntrain_ds = PortraitDataset(DATA_DIR, transform=tt.Compose([\n    tt.Resize(image_size),\n    tt.CenterCrop(image_size),\n    tt.ToTensor(),\n    tt.Normalize(*stats)]))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.923332Z","iopub.execute_input":"2024-12-02T02:26:44.923570Z","iopub.status.idle":"2024-12-02T02:26:44.944579Z","shell.execute_reply.started":"2024-12-02T02:26:44.923548Z","shell.execute_reply":"2024-12-02T02:26:44.943995Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dl = DataLoader(train_ds, batch_size, shuffle=True, num_workers=2, pin_memory=True, drop_last=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.945376Z","iopub.execute_input":"2024-12-02T02:26:44.945591Z","iopub.status.idle":"2024-12-02T02:26:44.949878Z","shell.execute_reply.started":"2024-12-02T02:26:44.945570Z","shell.execute_reply":"2024-12-02T02:26:44.949093Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def denorm(img_tensors):\n    return img_tensors * stats[1][0] + stats[0][0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.951019Z","iopub.execute_input":"2024-12-02T02:26:44.951396Z","iopub.status.idle":"2024-12-02T02:26:44.960703Z","shell.execute_reply.started":"2024-12-02T02:26:44.951360Z","shell.execute_reply":"2024-12-02T02:26:44.959920Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def show_images(images, nmax=64):\n    fig, ax = plt.subplots(figsize=(8, 8))\n    ax.set_xticks([]); ax.set_yticks([])\n    ax.imshow(make_grid(denorm(images.detach()[:nmax]), nrow=8).permute(1, 2, 0))\n\ndef show_batch(dl, nmax=64):\n    for images, _ in dl:\n        show_images(images, nmax)\n        break","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.961537Z","iopub.execute_input":"2024-12-02T02:26:44.961796Z","iopub.status.idle":"2024-12-02T02:26:44.970863Z","shell.execute_reply.started":"2024-12-02T02:26:44.961772Z","shell.execute_reply":"2024-12-02T02:26:44.970018Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"show_batch(train_dl)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:44.971960Z","iopub.execute_input":"2024-12-02T02:26:44.972314Z","iopub.status.idle":"2024-12-02T02:26:46.625890Z","shell.execute_reply.started":"2024-12-02T02:26:44.972275Z","shell.execute_reply":"2024-12-02T02:26:46.624796Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Duomenų krovimas į dataloaderį","metadata":{}},{"cell_type":"code","source":"def to_device(data, device):\n    \"\"\"Move tensor(s) to chosen device\"\"\"\n    if isinstance(data, (list,tuple)):\n        return [to_device(x, device) for x in data]\n    return data.to(device, non_blocking=True)\n\nclass DeviceDataLoader():\n    \"\"\"Wrap a dataloader to move data to a device\"\"\"\n    def __init__(self, dl, device):\n        self.dl = dl\n        self.device = device\n        \n    def __iter__(self):\n        \"\"\"Yield a batch of data after moving it to device\"\"\"\n        for b in self.dl: \n            yield to_device(b, self.device)\n\n    def __len__(self):\n        \"\"\"Number of batches\"\"\"\n        return len(self.dl)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.630595Z","iopub.execute_input":"2024-12-02T02:26:46.631639Z","iopub.status.idle":"2024-12-02T02:26:46.639264Z","shell.execute_reply.started":"2024-12-02T02:26:46.631581Z","shell.execute_reply":"2024-12-02T02:26:46.638119Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')\ndevice","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.640586Z","iopub.execute_input":"2024-12-02T02:26:46.640922Z","iopub.status.idle":"2024-12-02T02:26:46.661995Z","shell.execute_reply.started":"2024-12-02T02:26:46.640886Z","shell.execute_reply":"2024-12-02T02:26:46.661075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dl = DeviceDataLoader(train_dl, device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.663315Z","iopub.execute_input":"2024-12-02T02:26:46.663976Z","iopub.status.idle":"2024-12-02T02:26:46.671493Z","shell.execute_reply.started":"2024-12-02T02:26:46.663937Z","shell.execute_reply":"2024-12-02T02:26:46.670779Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Apsirašome diskriminatorių","metadata":{}},{"cell_type":"code","source":"from torchinfo import summary\n\ndiscriminator = nn.Sequential(\n    # Input: 3 x 64 x 64\n    nn.Conv2d(3, 128, kernel_size=4, stride=2, padding=1),  # Output: 128 x 32 x 32\n    nn.BatchNorm2d(128),\n    nn.LeakyReLU(0.2, inplace=True),\n    \n    nn.Conv2d(128, 256, kernel_size=4, stride=2, padding=1),  # Output: 256 x 16 x 16\n    nn.BatchNorm2d(256),\n    nn.LeakyReLU(0.2, inplace=True),\n    \n    nn.Conv2d(256, 512, kernel_size=4, stride=2, padding=1),  # Output: 512 x 8 x 8\n    nn.BatchNorm2d(512),\n    nn.LeakyReLU(0.2, inplace=True),\n    \n    nn.Conv2d(512, 1024, kernel_size=4, stride=2, padding=1),  # Output: 1024 x 4 x 4\n    nn.BatchNorm2d(1024),\n    nn.LeakyReLU(0.2, inplace=True),\n    \n    nn.Conv2d(1024, 1, kernel_size=4, stride=1, padding=0),  # Output: 1 x 1 x 1\n    nn.Flatten(),  # Output: (batch_size, 1)\n    nn.Sigmoid()   # Map output to [0, 1]\n)\nprint(summary(discriminator, input_size=(1, 3, 64, 64)))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.672549Z","iopub.execute_input":"2024-12-02T02:26:46.672862Z","iopub.status.idle":"2024-12-02T02:26:46.788242Z","shell.execute_reply.started":"2024-12-02T02:26:46.672821Z","shell.execute_reply":"2024-12-02T02:26:46.787390Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"discriminator = to_device(discriminator, device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.789295Z","iopub.execute_input":"2024-12-02T02:26:46.789559Z","iopub.status.idle":"2024-12-02T02:26:46.794388Z","shell.execute_reply.started":"2024-12-02T02:26:46.789534Z","shell.execute_reply":"2024-12-02T02:26:46.793484Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"latent_size = 128","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.795723Z","iopub.execute_input":"2024-12-02T02:26:46.796073Z","iopub.status.idle":"2024-12-02T02:26:46.804469Z","shell.execute_reply.started":"2024-12-02T02:26:46.796035Z","shell.execute_reply":"2024-12-02T02:26:46.803773Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Apsirašome generatorių","metadata":{}},{"cell_type":"code","source":"generator = nn.Sequential(\n    nn.ConvTranspose2d(latent_size, 1024, kernel_size=4, stride=1, padding=0),  # 1024 x 4 x 4\n    nn.BatchNorm2d(1024),\n    nn.ReLU(True),\n            \n    nn.ConvTranspose2d(1024, 512, kernel_size=4, stride=2, padding=1),  # 512 x 8 x 8\n    nn.BatchNorm2d(512),\n    nn.ReLU(True),\n            \n    nn.ConvTranspose2d(512, 256, kernel_size=4, stride=2, padding=1),  # 256 x 16 x 16\n    nn.BatchNorm2d(256),\n    nn.ReLU(True),\n            \n    nn.ConvTranspose2d(256, 128, kernel_size=4, stride=2, padding=1),  # 128 x 32 x 32\n    nn.BatchNorm2d(128),\n    nn.ReLU(True),\n            \n    nn.ConvTranspose2d(128, 3, kernel_size=4, stride=2, padding=1),  # 3 x 64 x 64\n    nn.Tanh()\n)\n\n\n# generator_summary = summary(generator, input_size=(1, latent_size, 1, 1))\n\n# generator_summary","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.805582Z","iopub.execute_input":"2024-12-02T02:26:46.805939Z","iopub.status.idle":"2024-12-02T02:26:46.919967Z","shell.execute_reply.started":"2024-12-02T02:26:46.805892Z","shell.execute_reply":"2024-12-02T02:26:46.919286Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Triukšmo pavaizdavimas neapmokytame modelyje","metadata":{}},{"cell_type":"code","source":"xb = torch.randn(batch_size, latent_size, 1, 1) \nfake_images = generator(xb)\nprint(fake_images.shape)\nshow_images(fake_images)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:46.921019Z","iopub.execute_input":"2024-12-02T02:26:46.921302Z","iopub.status.idle":"2024-12-02T02:26:49.094721Z","shell.execute_reply.started":"2024-12-02T02:26:46.921276Z","shell.execute_reply":"2024-12-02T02:26:49.093711Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"generator = to_device(generator, device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.096178Z","iopub.execute_input":"2024-12-02T02:26:49.096500Z","iopub.status.idle":"2024-12-02T02:26:49.117912Z","shell.execute_reply.started":"2024-12-02T02:26:49.096467Z","shell.execute_reply":"2024-12-02T02:26:49.117057Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_dir = 'generated'\nos.makedirs(sample_dir, exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.119186Z","iopub.execute_input":"2024-12-02T02:26:49.119530Z","iopub.status.idle":"2024-12-02T02:26:49.124561Z","shell.execute_reply.started":"2024-12-02T02:26:49.119493Z","shell.execute_reply":"2024-12-02T02:26:49.123636Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fixed_latent = torch.randn(64, latent_size, 1, 1, device=device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.125613Z","iopub.execute_input":"2024-12-02T02:26:49.126135Z","iopub.status.idle":"2024-12-02T02:26:49.135995Z","shell.execute_reply.started":"2024-12-02T02:26:49.126107Z","shell.execute_reply":"2024-12-02T02:26:49.135116Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Pagalbinės modelio apmokymo funkcijos","metadata":{}},{"cell_type":"code","source":"def save_samples(epoch, latent, show=True, path=\"samples/\", model=None):\n    os.makedirs(path, exist_ok=True)\n    fake_images = model[\"generator\"](latent).detach().cpu()[:16]\n    grid = torchvision.utils.make_grid(fake_images, nrow=4, normalize=True)\n    filename = f\"{path}/epoch_{epoch}.png\"\n    torchvision.utils.save_image(grid, filename)\n    if show:\n        plt.imshow(grid.permute(1, 2, 0))\n        plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.137330Z","iopub.execute_input":"2024-12-02T02:26:49.138008Z","iopub.status.idle":"2024-12-02T02:26:49.149216Z","shell.execute_reply.started":"2024-12-02T02:26:49.137959Z","shell.execute_reply":"2024-12-02T02:26:49.148392Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom pytorch_fid.fid_score import calculate_fid_given_paths\nimport tempfile\nimport os\nimport imageio\n\ndef calculate_metrics_pytorch_fid(real_images, fake_images):\n    # Ensure images are in the right format and range\n    if real_images.min() < 0:\n        real_images = (real_images + 1) / 2  # Assuming [-1,1] range, convert to [0,1]\n    if fake_images.min() < 0:\n        fake_images = (fake_images + 1) / 2\n    \n    # Convert tensors to numpy and scale to 0-255\n    real_images_np = (real_images.detach().cpu().numpy() * 255).astype(np.uint8)\n    fake_images_np = (fake_images.detach().cpu().numpy() * 255).astype(np.uint8)\n    \n    # Transpose to get (N, H, W, C) format\n    real_images_np = np.transpose(real_images_np, (0, 2, 3, 1))\n    fake_images_np = np.transpose(fake_images_np, (0, 2, 3, 1))\n    \n    # Create temporary directories to save images\n    with tempfile.TemporaryDirectory() as real_dir, tempfile.TemporaryDirectory() as fake_dir:\n        # Save real images\n        for i, img in enumerate(real_images_np):\n            imageio.imwrite(os.path.join(real_dir, f'real_{i}.png'), img)\n        \n        # Save fake images\n        for i, img in enumerate(fake_images_np):\n            imageio.imwrite(os.path.join(fake_dir, f'fake_{i}.png'), img)\n        \n        # Calculate FID\n        fid_value = calculate_fid_given_paths(\n            [real_dir, fake_dir],\n            batch_size=50,\n            device=torch.device('cuda' if torch.cuda.is_available() else 'cpu'),\n            dims=2048\n        )\n    \n    return fid_value","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.150363Z","iopub.execute_input":"2024-12-02T02:26:49.150911Z","iopub.status.idle":"2024-12-02T02:26:49.162817Z","shell.execute_reply.started":"2024-12-02T02:26:49.150874Z","shell.execute_reply":"2024-12-02T02:26:49.161975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn.functional as F\nimport torchvision.models as models\nimport numpy as np\nfrom torchvision import transforms\nfrom PIL import Image\n\ndef calculate_inception_score(images, model, device, splits=10):\n    # Define the preprocessing transform (resize, normalize)\n    transform = transforms.Compose([\n        transforms.Resize(299),  # Resize to 299x299 for InceptionV3\n        transforms.ToTensor(),\n        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),  # Normalization for InceptionV3\n    ])\n\n    # If images are tensors, convert them to PIL images\n    if isinstance(images, torch.Tensor):\n        images = [transforms.ToPILImage()(img) for img in images]\n\n    # Apply the transform to each image and stack them into a tensor\n    images = [transform(image).unsqueeze(0).to(device) for image in images]  # Transform each image\n    images = torch.cat(images, dim=0)  # Stack all images into a single tensor\n\n    # Get the model's predictions\n    model.eval()\n    with torch.no_grad():\n        preds = model(images)\n\n    # Compute the inception score\n    preds = torch.nn.functional.softmax(preds, dim=1)\n    kl_div = preds * (preds.log() - preds.mean(dim=0, keepdim=True).log())\n    kl_div = kl_div.sum(dim=1)\n    is_score = torch.exp(kl_div.mean()).item()\n\n    return is_score","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.163831Z","iopub.execute_input":"2024-12-02T02:26:49.164090Z","iopub.status.idle":"2024-12-02T02:26:49.175609Z","shell.execute_reply.started":"2024-12-02T02:26:49.164066Z","shell.execute_reply":"2024-12-02T02:26:49.174943Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"initial_lr = 0.0002\ngamma = 0.715\nmilestones = [50, 100, 150, 200, 250, 300, 350, 400, 450]\n\n# Calculate the learning rates at each milestone\nlr_values = [initial_lr]\nfor i in range(1, len(milestones) + 1):\n    new_lr = lr_values[i - 1] * gamma\n    lr_values.append(new_lr)\n\n\n\n# Plot the learning rate values\n\nplt.figure(figsize=(8, 6))\nplt.plot(milestones, lr_values[1:], marker='o', linestyle='-', color='b', label=\"Learning Rate\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Learning Rate\")\nplt.title(\"Learning Rate Decay over Epochs\")\nplt.grid(True)\nplt.xticks(milestones)\nplt.tight_layout()\n\n\n\n# Save the plot\n\nplt.savefig(\"/learning_rate_decay_plot.png\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.176528Z","iopub.execute_input":"2024-12-02T02:26:49.176757Z","iopub.status.idle":"2024-12-02T02:26:49.723868Z","shell.execute_reply.started":"2024-12-02T02:26:49.176734Z","shell.execute_reply":"2024-12-02T02:26:49.723025Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def fit(model, criterion, epochs, lr, start_idx=1, model_type=\"dcgan\", device='cuda'):\n    # Initialize learning rate schedulers\n    gamma_softened = 0.7 + 0.05 * (1 - 0.7)  # New gamma = 0.715\n    scheduler = {\n        \"discriminator\": torch.optim.lr_scheduler.MultiStepLR(\n            torch.optim.Adam(model[\"discriminator\"].parameters(), lr=lr, betas=(0.5, 0.999)),\n            milestones=[50, 100, 150, 200, 250, 300, 350, 400, 450],\n            gamma=gamma_softened\n        ),\n        \"generator\": torch.optim.lr_scheduler.MultiStepLR(\n            torch.optim.Adam(model[\"generator\"].parameters(), lr=lr, betas=(0.5, 0.999)),\n            milestones=[50, 100, 150, 200, 250, 300, 350, 400, 450],\n            gamma=gamma_softened\n        )\n    }\n    \n    # Extracting optimizers from schedulers\n    optimizer = {\n        \"discriminator\": scheduler[\"discriminator\"].optimizer,\n        \"generator\": scheduler[\"generator\"].optimizer\n    }\n\n    # Losses & scores\n    losses_g = []\n    losses_d = []\n    real_scores = []\n    fake_scores = []\n    current_lrs = {\n        \"discriminator\": [],\n        \"generator\": []\n    }\n\n    fid_scores = []\n    is_scores = []\n\n    start_time = time.time()\n\n    inception_model = models.inception_v3(pretrained=True).to(device)  # Load InceptionV3 model\n\n    for epoch in range(epochs):\n        loss_d_per_epoch = []\n        loss_g_per_epoch = []\n        real_score_per_epoch = []\n        fake_score_per_epoch = []\n\n        current_lrs[\"discriminator\"].append(scheduler[\"discriminator\"].get_last_lr()[0])\n        current_lrs[\"generator\"].append(scheduler[\"generator\"].get_last_lr()[0])\n\n        for real_images, _ in tqdm(train_dl):\n            # Train discriminator\n            optimizer[\"discriminator\"].zero_grad()\n            real_preds = model[\"discriminator\"](real_images)\n            real_targets = torch.ones(real_images.size(0), 1, device=device)\n            real_loss = criterion[\"discriminator\"](real_preds, real_targets)\n            cur_real_score = torch.mean(real_preds).item()\n\n            latent = torch.randn(batch_size, latent_size, 1, 1, device=device)\n            fake_images = model[\"generator\"](latent)\n            \n            fake_targets = torch.zeros(fake_images.size(0), 1, device=device)\n            fake_preds = model[\"discriminator\"](fake_images)\n            fake_loss = criterion[\"discriminator\"](fake_preds, fake_targets)\n            cur_fake_score = torch.mean(fake_preds).item()\n\n            real_score_per_epoch.append(cur_real_score)\n            fake_score_per_epoch.append(cur_fake_score)\n\n            loss_d = real_loss + fake_loss\n            loss_d.backward()\n            optimizer[\"discriminator\"].step()\n            loss_d_per_epoch.append(loss_d.item())\n\n            # Train generator\n            optimizer[\"generator\"].zero_grad()\n            latent = torch.randn(batch_size, latent_size, 1, 1, device=device)\n            fake_images = model[\"generator\"](latent)\n            preds = model[\"discriminator\"](fake_images)\n            targets = torch.ones(batch_size, 1, device=device)\n            loss_g = criterion[\"generator\"](preds, targets)\n            loss_g.backward()\n            optimizer[\"generator\"].step()\n            loss_g_per_epoch.append(loss_g.item())\n\n        scheduler[\"discriminator\"].step()\n        scheduler[\"generator\"].step()\n\n        losses_g.append(np.mean(loss_g_per_epoch))\n        losses_d.append(np.mean(loss_d_per_epoch))\n        real_scores.append(np.mean(real_score_per_epoch))\n        fake_scores.append(np.mean(fake_score_per_epoch))\n\n        # Calculate FID and IS\n        fid = calculate_metrics_pytorch_fid(real_images, fake_images)\n        is_score = calculate_inception_score(fake_images, inception_model, device)\n        fid_scores.append(fid)\n        is_scores.append(is_score)\n\n        # Log losses & scores\n        print(f\"Epoch [{epoch+1}/{epochs}], \"\n              f\"loss_g: {losses_g[-1]:.4f}, \"\n              f\"loss_d: {losses_d[-1]:.4f}, \"\n              f\"real_score: {real_scores[-1]:.4f}, \"\n              f\"fake_score: {fake_scores[-1]:.4f}, \"\n              f\"lr_d: {current_lrs['discriminator'][-1]:.6f}, \"\n              f\"lr_g: {current_lrs['generator'][-1]:.6f}, \"\n              f\"FID: {fid_scores[-1]:.4f}, \"\n              f\"IS: {is_scores[-1]:.4f}\")\n\n        # Save generated images\n        if epoch == 0 or (epoch + 1) % 20 == 0 or epoch == epochs - 1:\n            save_dir = f\"samples_{model_type}/\"\n            os.makedirs(save_dir, exist_ok=True)\n            save_samples(epoch + start_idx, fixed_latent, show=False, path=save_dir, model=model)\n\n    total_time = time.time() - start_time\n    print(f\"Training time for {model_type}: {total_time / 60:.2f} minutes\")\n\n    return {\n        'generator_losses': losses_g,\n        'discriminator_losses': losses_d,\n        'real_scores': real_scores,\n        'fake_scores': fake_scores,\n        'discriminator_lrs': current_lrs['discriminator'],\n        'generator_lrs': current_lrs['generator'],\n        'training_time': total_time,\n        'fid_scores': fid_scores,\n        'is_scores': is_scores,\n    }","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.725129Z","iopub.execute_input":"2024-12-02T02:26:49.725469Z","iopub.status.idle":"2024-12-02T02:26:49.741921Z","shell.execute_reply.started":"2024-12-02T02:26:49.725442Z","shell.execute_reply":"2024-12-02T02:26:49.741131Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Apmokymas","metadata":{}},{"cell_type":"code","source":"model = {\n    \"discriminator\": discriminator.to(device),\n    \"generator\": generator.to(device)\n}\n\ncriterion = {\n    \"discriminator\": nn.BCELoss(),\n    \"generator\": nn.BCELoss()\n}\nlr = 0.0002\nepochs = 500","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.743014Z","iopub.execute_input":"2024-12-02T02:26:49.743455Z","iopub.status.idle":"2024-12-02T02:26:49.757490Z","shell.execute_reply.started":"2024-12-02T02:26:49.743407Z","shell.execute_reply":"2024-12-02T02:26:49.756880Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = fit(model, criterion, epochs, lr, model_type=\"dcgan\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:26:49.758523Z","iopub.execute_input":"2024-12-02T02:26:49.758894Z","iopub.status.idle":"2024-12-02T02:31:07.388993Z","shell.execute_reply.started":"2024-12-02T02:26:49.758858Z","shell.execute_reply":"2024-12-02T02:31:07.387903Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Rezultatai","metadata":{}},{"cell_type":"code","source":"losses_g = history['generator_losses']\nlosses_d = history['discriminator_losses']\nreal_scores = history['real_scores']\nfake_scores = history['fake_scores']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:31:07.395293Z","iopub.execute_input":"2024-12-02T02:31:07.395597Z","iopub.status.idle":"2024-12-02T02:31:07.400337Z","shell.execute_reply.started":"2024-12-02T02:31:07.395567Z","shell.execute_reply":"2024-12-02T02:31:07.399372Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(15, 6))\nplt.plot(losses_d, '-')\nplt.plot(losses_g, '-')\nplt.xlabel('epoch')\nplt.ylabel('loss')\nplt.legend(['Discriminator', 'Generator'])\nplt.title('Losses');","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:31:07.401265Z","iopub.execute_input":"2024-12-02T02:31:07.401511Z","iopub.status.idle":"2024-12-02T02:31:07.778311Z","shell.execute_reply.started":"2024-12-02T02:31:07.401487Z","shell.execute_reply":"2024-12-02T02:31:07.777395Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(15, 6))\nplt.plot(real_scores, '-')\nplt.plot(fake_scores, '-')\nplt.xlabel('epoch')\nplt.ylabel('score')\nplt.legend(['Real', 'Fake'])\nplt.title('Scores');","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:31:07.779302Z","iopub.execute_input":"2024-12-02T02:31:07.779544Z","iopub.status.idle":"2024-12-02T02:31:08.152372Z","shell.execute_reply.started":"2024-12-02T02:31:07.779520Z","shell.execute_reply":"2024-12-02T02:31:08.151590Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"generated_img = cv2.imread(f'./samples_dcgan/epoch_{epochs}.png')\ngenerated_img = generated_img[:, :, [2, 1, 0]]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:31:08.153399Z","iopub.execute_input":"2024-12-02T02:31:08.153875Z","iopub.status.idle":"2024-12-02T02:31:08.173506Z","shell.execute_reply.started":"2024-12-02T02:31:08.153834Z","shell.execute_reply":"2024-12-02T02:31:08.172891Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(15, 12))  # Increased figure size\nax.set_xticks([]); ax.set_yticks([])  # Remove tick marks\nax.imshow(generated_img)\nplt.tight_layout()  # Adjust layout to use more space\nplt.subplots_adjust(left=0, right=1, top=1, bottom=0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:31:08.174377Z","iopub.execute_input":"2024-12-02T02:31:08.174635Z","iopub.status.idle":"2024-12-02T02:31:08.574785Z","shell.execute_reply.started":"2024-12-02T02:31:08.174610Z","shell.execute_reply":"2024-12-02T02:31:08.573937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport os\n\ndef plot_comparison_results(dcgan_results, save_dir='dcgan_plots'):\n    # Create save directory if it doesn't exist\n    os.makedirs(save_dir, exist_ok=True)\n    \n    # Plot and save generator losses\n    plt.figure(figsize=(10, 6))\n    plt.plot(dcgan_results['generator_losses'], label='DCGAN Generator', color='red')\n    plt.title('Generator Loss Comparison')\n    plt.xlabel('Epochs')\n    plt.ylabel('Loss')\n    plt.legend()\n    plt.tight_layout()\n    plt.savefig(os.path.join(save_dir, 'generator_losses.png'))\n    plt.show()  # Added to show the plot\n    plt.close()\n    \n    # Plot and save discriminator losses\n    plt.figure(figsize=(10, 6))\n    plt.plot(dcgan_results['discriminator_losses'], label='DCGAN Discriminator', color='red')\n    plt.title('Discriminator Loss Comparison')\n    plt.xlabel('Epochs')\n    plt.ylabel('Loss')\n    plt.legend()\n    plt.tight_layout()\n    plt.savefig(os.path.join(save_dir, 'discriminator_losses.png'))\n    plt.show()  # Added to show the plot\n    plt.close()\n    \n    # Plot and save real scores\n    plt.figure(figsize=(10, 6))\n    plt.plot(dcgan_results['real_scores'], label='DCGAN Real Score', color='red')\n    plt.title('Real Score Comparison')\n    plt.xlabel('Epochs')\n    plt.ylabel('Real Score')\n    plt.legend()\n    plt.tight_layout()\n    plt.savefig(os.path.join(save_dir, 'real_scores.png'))\n    plt.show()  # Added to show the plot\n    plt.close()\n    \n    # Plot and save fake scores\n    plt.figure(figsize=(10, 6))\n    plt.plot(dcgan_results['fake_scores'], label='DCGAN Fake Score', color='red')\n    plt.title('Fake Score Comparison')\n    plt.xlabel('Epochs')\n    plt.ylabel('Fake Score')\n    plt.legend()\n    plt.tight_layout()\n    plt.savefig(os.path.join(save_dir, 'fake_scores.png'))\n    plt.show()  # Added to show the plot\n    plt.close()\n    \n    # Plot and save FID scores\n    plt.figure(figsize=(10, 6))\n    plt.plot(dcgan_results['fid_scores'], label='DCGAN FID', color='red')\n    plt.title('FID Score Comparison')\n    plt.xlabel('Epochs')\n    plt.ylabel('FID')\n    plt.legend()\n    plt.tight_layout()\n    plt.savefig(os.path.join(save_dir, 'fid_scores.png'))\n    plt.show()  # Added to show the plot\n    plt.close()\n    \n    # Plot and save IS scores\n    plt.figure(figsize=(10, 6))\n    plt.plot(dcgan_results['is_scores'], label='DCGAN IS', color='red')\n    plt.title('IS Score Comparison')\n    plt.xlabel('Epochs')\n    plt.ylabel('IS')\n    plt.legend()\n    plt.tight_layout()\n    plt.savefig(os.path.join(save_dir, 'is_scores.png'))\n    plt.show()  # Added to show the plot\n    plt.close()\n    \n    # Plot and save training time comparison\n    plt.figure(figsize=(8, 6))\n    plt.bar(['DCGAN'], [dcgan_results['training_time'] / 60])\n    plt.title('Training Time Comparison')\n    plt.ylabel('Time (Minutes)')\n    plt.tight_layout()\n    plt.savefig(os.path.join(save_dir, 'training_time.png'))\n    plt.show()  # Added to show the plot\n    plt.close()\n    \n    print(f\"All plots have been saved in the '{save_dir}' directory.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:31:08.575951Z","iopub.execute_input":"2024-12-02T02:31:08.576257Z","iopub.status.idle":"2024-12-02T02:31:08.589208Z","shell.execute_reply.started":"2024-12-02T02:31:08.576231Z","shell.execute_reply":"2024-12-02T02:31:08.588303Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_comparison_results(history)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-02T02:31:08.590298Z","iopub.execute_input":"2024-12-02T02:31:08.590587Z","iopub.status.idle":"2024-12-02T02:31:12.215485Z","shell.execute_reply.started":"2024-12-02T02:31:08.590556Z","shell.execute_reply":"2024-12-02T02:31:12.214532Z"}},"outputs":[],"execution_count":null}]}