diff --git a/C3W3_MUNIT_(Optional).ipynb b/C3W3_MUNIT_(Optional).ipynb
new file mode 100644
index 0000000..0274ba4
--- /dev/null
+++ b/C3W3_MUNIT_(Optional).ipynb
@@ -0,0 +1,4463 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "C3W3: MUNIT (Optional).ipynb",
+ "provenance": [],
+ "collapsed_sections": [],
+ "toc_visible": true,
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "accelerator": "GPU"
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1czVdIlqnImH"
+ },
+ "source": [
+ "# Multi-modal Unsupervised Image-to-Image Translation (MUNIT)\n",
+ "\n",
+ "*Please note that this is an optional notebook, meant to introduce more advanced concepts if you're up for a challenge, so don't worry if you don't completely follow!*\n",
+ "\n",
+ "It is recommended that you should already be familiar with:\n",
+ " - Layer Normalization, from [Layer Normalization](https://arxiv.org/abs/1607.06450) (Ba et al. 2016)\n",
+ "\n",
+ "### Goals\n",
+ "\n",
+ "In this notebook, you will learn about and implement MUNIT, a method for unsupervised image-to-image translation, as proposed in [Multimodal Unsupervised Image-to-Image Translation](https://arxiv.org/abs/1804.04732) (Huang et al. 2018).\n",
+ "\n",
+ "### Background\n",
+ "\n",
+ "MUNIT builds off UNIT's proposition of a shared latent space, but MUNIT only uses a partially shared latent space. Specifically, the authors assume that the content latent space is shared between two domains, but the style latent spaces are unique to each domain.\n",
+ "\n",
+ "Don't worry if you aren't familiar with UNIT - there will be a section that briefly goes over it!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "r-UbOMuuD9Mt"
+ },
+ "source": [
+ "## Overview\n",
+ "\n",
+ "Let's begin with a quick overview of the UNIT framework and then move onto the MUNIT framework."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "g3PRXyfFNnBU"
+ },
+ "source": [
+ "### UNIT\n",
+ "\n",
+ "UNIT, proposed in [Unsupervised Image-to-Image Translation Networks](https://arxiv.org/abs/1703.00848) (Liu et al. 2018), is a method of image translation that assumes that images from different domains share a latent distribution.\n",
+ "\n",
+ "Suppose that there are two image domains, $\\mathcal{A}$ and $\\mathcal{B}$. Images $(x_a, x_b) \\in (\\mathcal{A}, \\mathcal{B})$ can be mapped to a shared latent space, $\\mathcal{Z}$ via encoders $E_a: x_a \\mapsto z$ and $E_b: x_b \\mapsto z$, respectively. Synthetic images can be produced via generators $G_a: z \\mapsto x_a'$ and $G_b: z \\mapsto x_b'$, respectively. Note that the generators can generate self-reconstructed or domain-translated images for their respective domains.\n",
+ "\n",
+ "And as per all other GAN frameworks, synthetic and real images, $(x_a',x_a)$, and $(x_b', x_b)$, are passed into discriminators, $D_a$ and $D_b$, respectively."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IpCebBIMNpMi"
+ },
+ "source": [
+ "### MUNIT\n",
+ "\n",
+ "Suppose that there are two image domains, $\\mathcal{A}$ and $\\mathcal{B}$. A pair of corresponding images $(x_a, x_b) \\in (\\mathcal{A}, \\mathcal{B})$ can be generated as $x_a = F_a(c, s_a)$ and $x_b = F_b(c, s_b)$ where $c$ is a content vector from a shared distribution, $s_a, s_b$ are style vectors from distinct distributions, and $F_a, F_b$ are decoders that synthesize images from the content and style vectors.\n",
+ "\n",
+ "The idea is that while the content between two domains can be shared (i.e. you can interchange horses and zebras in an image), the styles are different between the two (i.e. you would draw horses and zebras differently).\n",
+ "\n",
+ "To learn the content and style distributions in training, the authors also assume some $E_a, E_b$ invert $F_a, F_b$, respectively. Specifically, $E_a^c: x_a \\mapsto c$ extracts content and $E_a^s: x_a \\mapsto s_a$ extracts style from images in domain $\\mathcal{A}$. The same applies for $E_b^c(x_b)$ and $E_b^s(x_b)$ with images in domain $\\mathcal{B}$. You can mix and match the content and style vectors from the two domains to translate images from between the two.\n",
+ "\n",
+ "For example, if you take content $b$, $c_b = E_b^c(x_b)$, and style $a$, $s_a = E_a^s(x_a)$, and pass these through the horse decoder as $F_a(c_b, s_a)$, you should end up with the image $b$ drawn with characteristics of image $a$.\n",
+ "\n",
+ "Don't worry if this is still unclear now! You'll go over this in more detail later in the notebook.\n",
+ "\n",
+ "![Same- and cross-domain interaction of encoders and decoders](https://drive.google.com/uc?id=1gi5rHPiBdYtkLLok8ImSefnvUloScxm4)\n",
+ "\n",
+ "*Model overview, taken from Figure 2 of [Multimodal Unsupervised Image-to-Image Translation](https://arxiv.org/abs/1804.04732) (Huang et al. 2018). The red and blue arrows denote encoders-decoder pairs within the same domain. Left: same domain image reconstruction. Right: cross-domain latent (content and style) vector reconstruction.*"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "wU8DDM6l9rZb"
+ },
+ "source": [
+ "## Getting Started\n",
+ "You will start by importing libraries and defining a visualization function. This code is borrowed from the CycleGAN notebook so you should already be familiar with this!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "JfkorNJrnmNO"
+ },
+ "source": [
+ "import torch\n",
+ "import torch.nn as nn\n",
+ "import torch.nn.functional as F\n",
+ "from tqdm import tqdm\n",
+ "from torchvision import transforms\n",
+ "from torchvision.utils import make_grid\n",
+ "import matplotlib.pyplot as plt\n",
+ "torch.manual_seed(0)\n",
+ "\n",
+ "\n",
+ "def show_tensor_images(x_real, x_fake):\n",
+ " ''' For visualizing images '''\n",
+ " image_tensor = torch.cat((x_fake[:1, ...], x_real[:1, ...]), dim=0)\n",
+ " image_tensor = (image_tensor + 1) / 2\n",
+ " image_unflat = image_tensor.detach().cpu()\n",
+ " image_grid = make_grid(image_unflat, nrow=1)\n",
+ " plt.imshow(image_grid.permute(1, 2, 0).squeeze())\n",
+ " plt.show()\n",
+ "\n",
+ "\n",
+ "import glob\n",
+ "import random\n",
+ "import os\n",
+ "from torch.utils.data import Dataset, DataLoader\n",
+ "from PIL import Image\n",
+ "\n",
+ "# Inspired by https://github.com/aitorzip/PyTorch-CycleGAN/blob/master/datasets.py\n",
+ "class ImageDataset(Dataset):\n",
+ " def __init__(self, root, transform=None, mode='train'):\n",
+ " super().__init__()\n",
+ " self.transform = transform\n",
+ " self.files_A = sorted(glob.glob(os.path.join(root, '%sA' % mode) + '/*.*'))\n",
+ " self.files_B = sorted(glob.glob(os.path.join(root, '%sB' % mode) + '/*.*'))\n",
+ " if len(self.files_A) > len(self.files_B):\n",
+ " self.files_A, self.files_B = self.files_B, self.files_A\n",
+ " self.new_perm()\n",
+ " assert len(self.files_A) > 0, \"Make sure you downloaded the horse2zebra images!\"\n",
+ "\n",
+ " def new_perm(self):\n",
+ " self.randperm = torch.randperm(len(self.files_B))[:len(self.files_A)]\n",
+ "\n",
+ " def __getitem__(self, index):\n",
+ " item_A = self.transform(Image.open(self.files_A[index % len(self.files_A)]))\n",
+ " item_B = self.transform(Image.open(self.files_B[self.randperm[index]]))\n",
+ " if item_A.shape[0] != 3: \n",
+ " item_A = item_A.repeat(3, 1, 1)\n",
+ " if item_B.shape[0] != 3: \n",
+ " item_B = item_B.repeat(3, 1, 1)\n",
+ " if index == len(self) - 1:\n",
+ " self.new_perm()\n",
+ " return item_A, item_B\n",
+ "\n",
+ " def __len__(self):\n",
+ " return min(len(self.files_A), len(self.files_B))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "R1m6fuMHo_Y9"
+ },
+ "source": [
+ "if len(os.listdir(\".\")) < 3:\n",
+ " !wget https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets/horse2zebra.zip\n",
+ " !unzip horse2zebra.zip"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "hQOT4X49Qh1S"
+ },
+ "source": [
+ "## Subcomponents: Layers and Blocks\n",
+ "\n",
+ "MUNIT has a few key subcomponents that are used throughout the model. It'll generally make your life easier if you implement the smaller parts first!"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LE37vMTcQv6G"
+ },
+ "source": [
+ "### Adaptive Instance Normalization (AdaIN)\n",
+ "\n",
+ "You've already learned about this layer in StyleGAN and seen a very similar cousin - class-conditional batch normalization - in the BigGAN components notebook.\n",
+ "\n",
+ "The authors enhance the linear layers for scale and shift with a multi-layer perceptron (MLP), which is essentially just a series of linear layers to help learn more complex representations. See the figure in **Submodules** and the notes in **Submodules: Decoder** for more details."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "6N9KNJfoQ_-6"
+ },
+ "source": [
+ "class AdaptiveInstanceNorm2d(nn.Module):\n",
+ " '''\n",
+ " AdaptiveInstanceNorm2d Class\n",
+ " Values:\n",
+ " channels: the number of channels the image has, a scalar\n",
+ " s_dim: the dimension of the style tensor (s), a scalar\n",
+ " h_dim: the hidden dimension of the MLP, a scalar\n",
+ " '''\n",
+ "\n",
+ " def __init__(self, channels, s_dim=8, h_dim=256):\n",
+ " super().__init__()\n",
+ "\n",
+ " self.instance_norm = nn.InstanceNorm2d(channels, affine=False)\n",
+ " self.style_scale_transform = self.mlp(s_dim, h_dim, channels)\n",
+ " self.style_shift_transform = self.mlp(s_dim, h_dim, channels)\n",
+ "\n",
+ " @staticmethod\n",
+ " def mlp(self, in_dim, h_dim, out_dim):\n",
+ " return nn.Sequential(\n",
+ " nn.Linear(in_dim, h_dim),\n",
+ " nn.ReLU(inplace=True),\n",
+ " nn.Linear(h_dim, h_dim),\n",
+ " nn.ReLU(inplace=True),\n",
+ " nn.Linear(h_dim, out_dim),\n",
+ " )\n",
+ "\n",
+ " def forward(self, image, w):\n",
+ " '''\n",
+ " Function for completing a forward pass of AdaIN: Given an image and a style, \n",
+ " returns the normalized image that has been scaled and shifted by the style.\n",
+ " Parameters:\n",
+ " image: the feature map of shape (n_samples, channels, width, height)\n",
+ " w: the intermediate noise vector w to be made into the style (y)\n",
+ " '''\n",
+ " normalized_image = self.instance_norm(image)\n",
+ " style_scale = self.style_scale_transform(w)[:, :, None, None]\n",
+ " style_shift = self.style_shift_transform(w)[:, :, None, None]\n",
+ " transformed_image = style_scale * normalized_image + style_shift\n",
+ " return transformed_image"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "vPf-WwjWlNiN"
+ },
+ "source": [
+ "### Layer Normalization\n",
+ "\n",
+ "MUNIT uses layer normalization in the upsampling layers of the decoder. Proposed in [Layer Normalization](https://arxiv.org/abs/1607.06450) (Ba et al. 2016), layer normalization operates similarly to all other normalization techniques like batch normalization, but instead of normalizing across minibatch examples per channel, it normalizes across channels per minibatch example.\n",
+ "\n",
+ "Layer normalization is actually much more prevalent in NLP and but quite rare in computer vision. However, batch normalization is not viable here due to training batch sizes of 1 and instance normalization is undesirable because it normalizes the statistics at each position to a standard Gaussian, which removes style features.\n",
+ "\n",
+ "Pytorch implements this as [nn.LayerNorm](https://pytorch.org/docs/stable/generated/torch.nn.LayerNorm.html) but requires precomputed spatial size for initialization to accomodate for 1D, 2D, and 3D inputs. For convenience, let's implement a size-agnostic layer normalization module for 2D inputs (i.e. images)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EPHZpt-nmIEL"
+ },
+ "source": [
+ "class LayerNorm2d(nn.Module):\n",
+ " '''\n",
+ " LayerNorm2d Class\n",
+ " Values:\n",
+ " channels: number of channels in input, a scalar\n",
+ " affine: whether to apply affine denormalization, a bool\n",
+ " '''\n",
+ "\n",
+ " def __init__(self, channels, eps=1e-5, affine=True):\n",
+ " super().__init__()\n",
+ " self.affine = affine\n",
+ " self.eps = eps\n",
+ "\n",
+ " if self.affine:\n",
+ " self.gamma = nn.Parameter(torch.rand(channels))\n",
+ " self.beta = nn.Parameter(torch.zeros(channels))\n",
+ "\n",
+ " def forward(self, x):\n",
+ " mean = x.flatten(1).mean(1).reshape(-1, 1, 1, 1)\n",
+ " std = x.flatten(1).std(1).reshape(-1, 1, 1, 1)\n",
+ "\n",
+ " x = (x - mean) / (std + self.eps)\n",
+ "\n",
+ " if self.affine:\n",
+ " x = x * self.gamma.reshape(1, -1, 1, 1) + self.beta.reshape(1, -1, 1, 1)\n",
+ "\n",
+ " return x"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "TMWjIgMsKcGK"
+ },
+ "source": [
+ "### Residual Block\n",
+ "\n",
+ "By now, you should already be very familiar with residual blocks. Below is an implementation that supports both adaptive and non-adaptive instance normalization layers, since both are used throughout the model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dtwbXUTRK4a9"
+ },
+ "source": [
+ "class ResidualBlock(nn.Module):\n",
+ " '''\n",
+ " ResidualBlock Class\n",
+ " Values:\n",
+ " channels: number of channels throughout residual block, a scalar\n",
+ " s_dim: the dimension of the style tensor (s), a scalar\n",
+ " h_dim: the hidden dimension of the MLP, a scalar\n",
+ " '''\n",
+ "\n",
+ " def __init__(self, channels, s_dim=None, h_dim=None):\n",
+ " super().__init__()\n",
+ "\n",
+ " self.conv1 = nn.Sequential(\n",
+ " nn.ReflectionPad2d(1),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, channels, kernel_size=3)\n",
+ " ),\n",
+ " )\n",
+ " self.conv2 = nn.Sequential(\n",
+ " nn.ReflectionPad2d(1),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, channels, kernel_size=3)\n",
+ " ),\n",
+ " )\n",
+ " self.use_style = s_dim is not None and h_dim is not None\n",
+ " if self.use_style:\n",
+ " self.norm1 = AdaptiveInstanceNorm2d(channels, s_dim, h_dim)\n",
+ " self.norm2 = AdaptiveInstanceNorm2d(channels, s_dim, h_dim)\n",
+ " else:\n",
+ " self.norm1 = nn.InstanceNorm2d(channels)\n",
+ " self.norm2 = nn.InstanceNorm2d(channels)\n",
+ "\n",
+ " self.activation = nn.ReLU()\n",
+ "\n",
+ " def forward(self, x, s=None):\n",
+ " x_id = x\n",
+ " x = self.conv1(x)\n",
+ " x = self.norm1(x, s) if self.use_style else self.norm1(x)\n",
+ " x = self.activation(x)\n",
+ " x = self.conv2(x)\n",
+ " x = self.norm2(x, s) if self.use_style else self.norm2(x)\n",
+ " return x + x_id"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "faEGyHlHDmP9"
+ },
+ "source": [
+ "## Submodules: Encoders and Decoder\n",
+ "\n",
+ "Now that you're all set up and implemented some basic building blocks, let's take a look at the content encoder, style encoder, and decoder! These will be used in the generator.\n",
+ "\n",
+ "![Same- and cross-domain interaction of encoders and decoders](https://drive.google.com/uc?id=15y07M9dgnk8_HtatlDfEpN5mM-BFBnMG)\n",
+ "\n",
+ "*Generator architecture, taken from Figure 3 of [Multimodal Unsupervised Image-to-Image Translation](https://arxiv.org/abs/1804.04732) (Huang et al. 2018). Content encoder: generates a downsampled representation of the original. Style encoder: generates a style code from the original. Decoder: synthesizes a fake image from content code, infused with style info.*\n",
+ "\n",
+ "*Note: the official implementation feeds style code through a multi-layer perceptron (MLP) and assigns these values to the scale and shift parameters in the instance normalization layers. To be compatible with our previous definitions of* `AdaIN`*, your implementation will simply apply the MLP within* `AdaptiveInstanceNorm2d`."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "yZoAZwZgHJcM"
+ },
+ "source": [
+ "### Content Encoder\n",
+ "\n",
+ "The content encoder is similar to many encoders you've already seen: it simply downsamples the input image and feeds it through residual blocks to obtain a condensed representation."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "bCd393-QH_i0"
+ },
+ "source": [
+ "class ContentEncoder(nn.Module):\n",
+ " '''\n",
+ " ContentEncoder Class\n",
+ " Values:\n",
+ " base_channels: number of channels in first convolutional layer, a scalar\n",
+ " n_downsample: number of downsampling layers, a scalar\n",
+ " n_res_blocks: number of residual blocks, a scalar\n",
+ " '''\n",
+ "\n",
+ " def __init__(self, base_channels=64, n_downsample=2, n_res_blocks=4):\n",
+ " super().__init__()\n",
+ "\n",
+ " channels = base_channels\n",
+ "\n",
+ " # Input convolutional layer\n",
+ " layers = [\n",
+ " nn.ReflectionPad2d(3),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(3, channels, kernel_size=7)\n",
+ " ),\n",
+ " nn.InstanceNorm2d(channels),\n",
+ " nn.ReLU(inplace=True),\n",
+ " ]\n",
+ "\n",
+ " # Downsampling layers\n",
+ " for i in range(n_downsample):\n",
+ " layers += [\n",
+ " nn.ReflectionPad2d(1),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, 2 * channels, kernel_size=4, stride=2)\n",
+ " ),\n",
+ " nn.InstanceNorm2d(2 * channels),\n",
+ " nn.ReLU(inplace=True),\n",
+ " ]\n",
+ " channels *= 2\n",
+ "\n",
+ " # Residual blocks\n",
+ " layers += [\n",
+ " ResidualBlock(channels) for _ in range(n_res_blocks)\n",
+ " ]\n",
+ " self.layers = nn.Sequential(*layers)\n",
+ " self.out_channels = channels\n",
+ "\n",
+ " def forward(self, x):\n",
+ " return self.layers(x)\n",
+ "\n",
+ " @property\n",
+ " def channels(self):\n",
+ " return self.out_channels"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "VDaItt-rN9JD"
+ },
+ "source": [
+ "### Style Encoder\n",
+ "\n",
+ "The style encoder operates similarly to the content encoder but instead of residual blocks, it uses global pooling and fully-connected layers to distill the input image to its style vector. An important difference is that the style encoder doesn't use any normalization layers, since they will remove the feature statistics that encode style. This style code will be passed to the decoder, which use this along with the content code to synthesize a fake image."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "_cff4eEHOcLk"
+ },
+ "source": [
+ "class StyleEncoder(nn.Module):\n",
+ " '''\n",
+ " StyleEncoder Class\n",
+ " Values:\n",
+ " base_channels: number of channels in first convolutional layer, a scalar\n",
+ " n_downsample: number of downsampling layers, a scalar\n",
+ " s_dim: the dimension of the style tensor (s), a scalar\n",
+ " '''\n",
+ "\n",
+ " n_deepen_layers = 2\n",
+ "\n",
+ " def __init__(self, base_channels=64, n_downsample=4, s_dim=8):\n",
+ " super().__init__()\n",
+ "\n",
+ " channels = base_channels\n",
+ "\n",
+ " # Input convolutional layer\n",
+ " layers = [\n",
+ " nn.ReflectionPad2d(3),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(3, channels, kernel_size=7, padding=0)\n",
+ " ),\n",
+ " nn.ReLU(inplace=True),\n",
+ " ]\n",
+ "\n",
+ " # Downsampling layers\n",
+ " for i in range(self.n_deepen_layers):\n",
+ " layers += [\n",
+ " nn.ReflectionPad2d(1),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, 2 * channels, kernel_size=4, stride=2)\n",
+ " ),\n",
+ " nn.ReLU(inplace=True),\n",
+ " ]\n",
+ " channels *= 2\n",
+ " for i in range(n_downsample - self.n_deepen_layers):\n",
+ " layers += [\n",
+ " nn.ReflectionPad2d(1),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, channels, kernel_size=4, stride=2)\n",
+ " ),\n",
+ " nn.ReLU(inplace=True),\n",
+ " ]\n",
+ "\n",
+ " # Apply global pooling and pointwise convolution to style_channels\n",
+ " layers += [\n",
+ " nn.AdaptiveAvgPool2d(1),\n",
+ " nn.Conv2d(channels, s_dim, kernel_size=1),\n",
+ " ]\n",
+ "\n",
+ " self.layers = nn.Sequential(*layers)\n",
+ "\n",
+ " def forward(self, x):\n",
+ " return self.layers(x)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iW9B-i2tP1fM"
+ },
+ "source": [
+ "### Decoder\n",
+ "\n",
+ "As with all encoder-decoder frameworks, the decoder serves to synthesize images from the latent information passed through by the encoder. In this case, the decoder works with both content and style encodings.\n",
+ "\n",
+ "You can think of the content encoder and decoder as the backbone of the encoder-decoder framework with style information injected into the residual blocks via `AdaIN` layers.\n",
+ "\n",
+ "Note: the official implementation feeds style code through a multi-layer perceptron (MLP) and assigns these values to the scale and shift parameters in the instance normalization layers. To be compatible with the previous definitions of `AdaIN` in this course, your implementation will simply apply the MLP within `AdaptiveInstanceNorm2d`.\n",
+ "\n",
+ "Let's take a look at the implementation!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xf8KP7DRRrkn"
+ },
+ "source": [
+ "class Decoder(nn.Module):\n",
+ " '''\n",
+ " Decoder Class\n",
+ " Values:\n",
+ " in_channels: number of channels from encoder output, a scalar\n",
+ " n_upsample: number of upsampling layers, a scalar\n",
+ " n_res_blocks: number of residual blocks, a scalar\n",
+ " s_dim: the dimension of the style tensor (s), a scalar\n",
+ " h_dim: the hidden dimension of the MLP, a scalar\n",
+ " '''\n",
+ "\n",
+ " def __init__(self, in_channels, n_upsample=2, n_res_blocks=4, s_dim=8, h_dim=256):\n",
+ " super().__init__()\n",
+ "\n",
+ " channels = in_channels\n",
+ "\n",
+ " # Residual blocks with AdaIN\n",
+ " self.res_blocks = nn.ModuleList([\n",
+ " ResidualBlock(channels, s_dim) for _ in range(n_res_blocks)\n",
+ " ])\n",
+ "\n",
+ " # Upsampling blocks\n",
+ " layers = []\n",
+ " for i in range(n_upsample):\n",
+ " layers += [\n",
+ " nn.Upsample(scale_factor=2),\n",
+ " nn.ReflectionPad2d(2),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, channels // 2, kernel_size=5)\n",
+ " ),\n",
+ " LayerNorm2d(channels // 2),\n",
+ " ]\n",
+ " channels //= 2\n",
+ " \n",
+ " layers += [\n",
+ " nn.ReflectionPad2d(3),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, 3, kernel_size=7)\n",
+ " ),\n",
+ " nn.Tanh(),\n",
+ " ]\n",
+ " self.layers = nn.Sequential(*layers)\n",
+ "\n",
+ " def forward(self, x, s):\n",
+ " for res_block in self.res_blocks:\n",
+ " x = res_block(x, s=s)\n",
+ " x = self.layers(x)\n",
+ " return x"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0Ru1dJWZ0XGK"
+ },
+ "source": [
+ "## Modules: Generator, Discriminator, and Loss\n",
+ "\n",
+ "Now you're ready to implement MUNIT generator and discriminator, as well as the composite loss function that ties everything together in training."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "z8-de36ytk14"
+ },
+ "source": [
+ "### Generator\n",
+ "\n",
+ "The generator is essentially just comprised of the two encoders and one decoder implemented in the previous section, so let's wrap everything in a `Generator` module!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Rl_ZpENltpL_"
+ },
+ "source": [
+ "class Generator(nn.Module):\n",
+ " '''\n",
+ " Generator Class\n",
+ " Values:\n",
+ " base_channels: number of channels in first convolutional layer, a scalar\n",
+ " n_downsample: number of downsampling layers, a scalar\n",
+ " n_res_blocks: number of residual blocks, a scalar\n",
+ " s_dim: the dimension of the style tensor (s), a scalar\n",
+ " h_dim: the hidden dimension of the MLP, a scalar\n",
+ " '''\n",
+ "\n",
+ " def __init__(\n",
+ " self,\n",
+ " base_channels: int = 64,\n",
+ " n_c_downsample: int = 2,\n",
+ " n_s_downsample: int = 4,\n",
+ " n_res_blocks: int = 4,\n",
+ " s_dim: int = 8,\n",
+ " h_dim: int = 256,\n",
+ " ):\n",
+ " super().__init__()\n",
+ " self.c_enc = ContentEncoder(\n",
+ " base_channels=base_channels, n_downsample=n_c_downsample, n_res_blocks=n_res_blocks,\n",
+ " )\n",
+ " self.s_enc = StyleEncoder(\n",
+ " base_channels=base_channels, n_downsample=n_s_downsample, s_dim=s_dim,\n",
+ " )\n",
+ " self.dec = Decoder(\n",
+ " self.c_enc.channels, n_upsample=n_c_downsample, n_res_blocks=n_res_blocks, s_dim=s_dim, h_dim=h_dim,\n",
+ " )\n",
+ "\n",
+ " def encode(self, x):\n",
+ " content = self.c_enc(x)\n",
+ " style = self.s_enc(x)\n",
+ " return (content, style)\n",
+ " \n",
+ " def decode(self, content, style):\n",
+ " return self.dec(content, style)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "sE3H9XlVxuDM"
+ },
+ "source": [
+ "### Discriminator\n",
+ "\n",
+ "The discriminator, identical to the one used in Pix2PixHD, is comprised of several PatchGAN discriminators operating at different scales. For details on how these work together, take a look at the Pix2PixHD optional notebook.\n",
+ "\n",
+ "The discriminator is trained with the least squares objective."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mI-JT2VsyJil"
+ },
+ "source": [
+ "class Discriminator(nn.Module):\n",
+ " '''\n",
+ " Generator Class\n",
+ " Values:\n",
+ " base_channels: number of channels in first convolutional layer, a scalar\n",
+ " n_layers: number of downsampling layers, a scalar\n",
+ " n_discriminators: number of discriminators (all at different scales), a scalar\n",
+ " '''\n",
+ "\n",
+ " def __init__(\n",
+ " self,\n",
+ " base_channels: int = 64,\n",
+ " n_layers: int = 3,\n",
+ " n_discriminators: int = 3,\n",
+ " ):\n",
+ " super().__init__()\n",
+ "\n",
+ " self.discriminators = nn.ModuleList([\n",
+ " self.patchgan_discriminator(base_channels, n_layers) for _ in range(n_discriminators)\n",
+ " ])\n",
+ "\n",
+ " self.downsample = nn.AvgPool2d(3, stride=2, padding=1, count_include_pad=False)\n",
+ "\n",
+ " @staticmethod\n",
+ " def patchgan_discriminator(base_channels, n_layers):\n",
+ " '''\n",
+ " Function that constructs and returns one PatchGAN discriminator module.\n",
+ " '''\n",
+ " channels = base_channels\n",
+ " # Input convolutional layer\n",
+ " layers = [\n",
+ " nn.ReflectionPad2d(1),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(3, channels, kernel_size=4, stride=2),\n",
+ " ),\n",
+ " nn.LeakyReLU(0.2, inplace=True),\n",
+ " ]\n",
+ "\n",
+ " # Hidden convolutional layers\n",
+ " for _ in range(n_layers):\n",
+ " layers += [\n",
+ " nn.ReflectionPad2d(1),\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, 2 * channels, kernel_size=4, stride=2)\n",
+ " ),\n",
+ " nn.LeakyReLU(0.2, inplace=True),\n",
+ " ]\n",
+ " channels *= 2\n",
+ "\n",
+ " # Output projection layer\n",
+ " layers += [\n",
+ " nn.utils.spectral_norm(\n",
+ " nn.Conv2d(channels, 1, kernel_size=1)\n",
+ " ),\n",
+ " ]\n",
+ " return nn.Sequential(*layers)\n",
+ "\n",
+ " def forward(self, x):\n",
+ " outputs = []\n",
+ " for discriminator in self.discriminators:\n",
+ " outputs.append(discriminator(x))\n",
+ " x = self.downsample(x)\n",
+ " return outputs"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "FdafpxKB089k"
+ },
+ "source": [
+ "### Loss Functions\n",
+ "\n",
+ "There are a lot of moving parts in MUNIT so this section will break down which parts interact with which other parts. Recall from earlier our notation:\n",
+ " - Image domains:\n",
+ " \\begin{align*}\n",
+ " a &\\in \\mathcal{A} \\\\\n",
+ " b &\\in \\mathcal{B}\n",
+ " \\end{align*}\n",
+ " - Encoders ($E$):\n",
+ " \\begin{align*}\n",
+ " E_a^c: a \\mapsto c_a, &\\quad E_a^s: a \\mapsto s_a \\\\\n",
+ " E_b^c: b \\mapsto c_b, &\\quad E_b^s: b \\mapsto s_b\n",
+ " \\end{align*}\n",
+ " - Decoders ($F$):\n",
+ " \\begin{align*}\n",
+ " F_a&: (c_*, s_a) \\mapsto a' \\\\\n",
+ " F_b&: (c_*, s_b) \\mapsto b'\n",
+ " \\end{align*}\n",
+ " - Generators ($G$):\n",
+ " \\begin{align*}\n",
+ " G_a(a, b) &= F_a(E_b^c(b), E_a^s(a)) \\\\\n",
+ " G_b(b, a) &= F_b(E_a^c(a), E_b^s(b))\n",
+ " \\end{align*}\n",
+ " - Discriminators ($D$):\n",
+ " \\begin{align*}\n",
+ " D_a&: a' \\mapsto p \\in \\mathbb{R} \\\\\n",
+ " D_b&: b' \\mapsto p \\in \\mathbb{R}\n",
+ " \\end{align*}\n",
+ "\n",
+ "**Image Reconstruction Loss**\n",
+ "\n",
+ "The model should be able to encode and decode a reconstruction of the image. For domain $\\mathcal{A}$, this can be expressed as\n",
+ "\n",
+ "\\begin{align*}\n",
+ " \\mathcal{L}_{\\text{recon}}^a &= \\mathbb{E}_{a\\sim p(a)}\\left|\\left|F_a(E_a^c(a), E_a^s(a)) - a\\right|\\right|_1\n",
+ "\\end{align*}\n",
+ "\n",
+ "and for domain $\\mathcal{B}$, this can be expressed as\n",
+ "\n",
+ "\\begin{align*}\n",
+ " \\mathcal{L}_{\\text{recon}}^b &= \\mathbb{E}_{b\\sim p(b)}\\left|\\left|F_b(E_b^c(b), E_b^s(b)) - b\\right|\\right|_1.\n",
+ "\\end{align*}\n",
+ "\n",
+ "**Latent Reconstruction Loss**\n",
+ "\n",
+ "The same principle from above applies to the latent space: decoding and encoding a latent vector should reproduce the original. Don't worry if the equations look complicated! Just know that intuitively, passing in different content and style vectors through the encoders should yield those same input vectors. For domain $\\mathcal{A}$, this can be expressed as\n",
+ "\n",
+ "\\begin{align*}\n",
+ " \\mathcal{L}_{\\text{recon}}^{c_b} &= \\mathbb{E}_{c_b\\sim p(c_b),s_a\\sim q(s_a)}\\left|\\left|E_a^c(F_a(c_b, s_a)) - c_a\\right|\\right|_1 \\\\\n",
+ " \\mathcal{L}_{\\text{recon}}^{s_a} &= \\mathbb{E}_{c_b\\sim p(c_b),s_a\\sim q(s_a)}\\left|\\left|E_a^s(F_a(c_b, s_a)) - s_b\\right|\\right|_1\n",
+ "\\end{align*}\n",
+ "\n",
+ "and for domain $\\mathcal{B}$, this can be expressed as\n",
+ "\n",
+ "\\begin{align*}\n",
+ " \\mathcal{L}_{\\text{recon}}^{c_a} &= \\mathbb{E}_{c_a\\sim p(c_a),s_b\\sim q(s_b)}\\left|\\left|E_b^c(F_b(c_a, s_b)) - c_b\\right|\\right|_1 \\\\\n",
+ " \\mathcal{L}_{\\text{recon}}^{s_b} &= \\mathbb{E}_{c_a\\sim p(c_a),s_b\\sim q(s_b)}\\left|\\left|E_b^s(F_b(c_a, s_b)) - s_a\\right|\\right|_1\n",
+ "\\end{align*}\n",
+ "\n",
+ "**Adversarial Loss**\n",
+ "\n",
+ "As with all other GANs, MUNIT is trained with adversarial loss. The authors opt for the LSGAN least-squares objective. For domain $\\mathcal{A}$, this can be expressed as\n",
+ "\n",
+ "\\begin{align*}\n",
+ " \\mathcal{L}_{\\text{GAN}}^a &= \\mathbb{E}_{c_b\\sim p(c_b),s_a\\sim q(s_a)}\\left[(1 - D_a(G_a(c_b, s_a)))^2\\right] + \\mathbb{E}_{a\\sim p(a)}\\left[D_a(a)^2\\right]\n",
+ "\\end{align*}\n",
+ "\n",
+ "and for domain $\\mathcal{B}$, this can be expressed as\n",
+ "\n",
+ "\\begin{align*}\n",
+ " \\mathcal{L}_{\\text{GAN}}^b &= \\mathbb{E}_{c_a\\sim p(c_a),s_b\\sim q(s_b)}\\left[(1 - D_b(G_b(c_a, s_b)))^2\\right] + \\mathbb{E}_{b\\sim p(b)}\\left[D_b(b)^2\\right]\n",
+ "\\end{align*}\n",
+ "\n",
+ "**Total Loss**\n",
+ "\n",
+ "The total loss can now be expressed in terms of the individual losses from above, so the objective can be expressed as\n",
+ "\n",
+ "\\begin{align*}\n",
+ " \\mathcal{L}(E_a, E_b, F_a, F_b, D_a, D_b) &= \\mathcal{L}_{\\text{GAN}}^a + \\mathcal{L}_{\\text{GAN}}^b + \\lambda_x(\\mathcal{L}_{\\text{recon}}^a + \\mathcal{L}_{\\text{recon}}^b) + \\lambda_c(\\mathcal{L}_{\\text{recon}}^{c_a} + \\mathcal{L}_{\\text{recon}}^{c_b}) + \\lambda_s(\\mathcal{L}_{\\text{recon}}^{s_a} + \\mathcal{L}_{\\text{recon}}^{s_b})\n",
+ "\\end{align*}\n",
+ "\n",
+ "And now the fun part: implementing this ginormous composite loss!"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "CSZDUYjNWXgi"
+ },
+ "source": [
+ "class GinormousCompositeLoss(nn.Module):\n",
+ " '''\n",
+ " GinormousCompositeLoss Class: implements all losses for MUNIT\n",
+ " '''\n",
+ "\n",
+ " @staticmethod\n",
+ " def image_recon_loss(x, gen):\n",
+ " c, s = gen.encode(x)\n",
+ " recon = gen.decode(c, s)\n",
+ " return F.l1_loss(recon, x), c, s\n",
+ "\n",
+ " @staticmethod\n",
+ " def latent_recon_loss(c, s, gen):\n",
+ " x_fake = gen.decode(c, s)\n",
+ " recon = gen.encode(x_fake)\n",
+ " return F.l1_loss(recon[0], c), F.l1_loss(recon[1], s), x_fake\n",
+ "\n",
+ " @staticmethod\n",
+ " def adversarial_loss(x, dis, is_real):\n",
+ " preds = dis(x)\n",
+ " target = torch.ones_like if is_real else torch.zeros_like\n",
+ " loss = 0.0\n",
+ " for pred in preds:\n",
+ " loss += F.mse_loss(pred, target(pred))\n",
+ " return loss"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gttCYcvt-cTX"
+ },
+ "source": [
+ "### Optional Loss Functions\n",
+ "\n",
+ "The authors also propose a couple of auxiliary loss functions that can help improve convergence. This section will just go over these losses but implementation is left as an exercise for the curious reader :)\n",
+ "\n",
+ "**Style-augmented Cycle Consistency**\n",
+ "\n",
+ "You've already heard of cycle consistency from CycleGAN, which implies that an image translated to the target domain and back should be identical to the original.\n",
+ "\n",
+ "Intuitively, style-augmented cycle consistency implies that an image translated to the target domain and back using the original style should result in the original image. Style-augmented cycle consistency is implicitly encouraged\n",
+ "by the reconstruction losses, but the authors note that explicitly enforcing it could be useful in some cases.\n",
+ "\n",
+ "**Domain Invariant Perceptual Loss**\n",
+ "\n",
+ "You're probably already familiar with perceptual loss, which is usually implemented via MSE loss between feature maps of fake and real images. However, because the images in the domains are unpaired, pixel-wise loss may not be optimal, since each values at each position do not correspond spatially.\n",
+ "\n",
+ "The authors get around this discrepancy by applying instance normalization to the feature maps. This normalizes the values per channel for each position in the feature maps, so MSE loss penalizes the difference in statistics rather than raw pixel value."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1jbwOHEgffdx"
+ },
+ "source": [
+ "## Model: MUNIT\n",
+ "\n",
+ "Now that you've got all the necessary modules, let's see how we can put them all together."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "idFCK4ugfoUo"
+ },
+ "source": [
+ "class MUNIT(nn.Module):\n",
+ " def __init__(\n",
+ " self,\n",
+ " gen_channels: int = 64,\n",
+ " n_c_downsample: int = 2,\n",
+ " n_s_downsample: int = 4,\n",
+ " n_res_blocks: int = 4,\n",
+ " s_dim: int = 8,\n",
+ " h_dim: int = 256,\n",
+ " dis_channels: int = 64,\n",
+ " n_layers: int = 3,\n",
+ " n_discriminators: int = 3,\n",
+ " ):\n",
+ " super().__init__()\n",
+ "\n",
+ " self.gen_a = Generator(\n",
+ " base_channels=gen_channels, n_c_downsample=n_c_downsample, n_s_downsample=n_s_downsample, n_res_blocks=n_res_blocks, s_dim=s_dim, h_dim=h_dim,\n",
+ " )\n",
+ " self.gen_b = Generator(\n",
+ " base_channels=gen_channels, n_c_downsample=n_c_downsample, n_s_downsample=n_s_downsample, n_res_blocks=n_res_blocks, s_dim=s_dim, h_dim=h_dim,\n",
+ " )\n",
+ " self.dis_a = Discriminator(\n",
+ " base_channels=dis_channels, n_layers=n_layers, n_discriminators=n_discriminators,\n",
+ " )\n",
+ " self.dis_b = Discriminator(\n",
+ " base_channels=dis_channels, n_layers=n_layers, n_discriminators=n_discriminators,\n",
+ " )\n",
+ " self.s_dim = s_dim\n",
+ " self.loss = GinormousCompositeLoss\n",
+ "\n",
+ " def forward(self, x_a, x_b):\n",
+ " s_a = torch.randn(x_a.size(0), self.s_dim, 1, 1, device=x_a.device).to(x_a.dtype)\n",
+ " s_b = torch.randn(x_b.size(0), self.s_dim, 1, 1, device=x_b.device).to(x_b.dtype)\n",
+ "\n",
+ " # Encode real x and compute image reconstruction loss\n",
+ " x_a_loss, c_a, s_a_fake = self.loss.image_recon_loss(x_a, self.gen_a)\n",
+ " x_b_loss, c_b, s_b_fake = self.loss.image_recon_loss(x_b, self.gen_b)\n",
+ "\n",
+ " # Decode real (c, s) and compute latent reconstruction loss\n",
+ " c_b_loss, s_a_loss, x_ba = self.loss.latent_recon_loss(c_b, s_a, self.gen_a)\n",
+ " c_a_loss, s_b_loss, x_ab = self.loss.latent_recon_loss(c_a, s_b, self.gen_b)\n",
+ "\n",
+ " # Compute adversarial losses\n",
+ " gen_a_adv_loss = self.loss.adversarial_loss(x_ba, self.dis_a, False)\n",
+ " gen_b_adv_loss = self.loss.adversarial_loss(x_ab, self.dis_b, False)\n",
+ "\n",
+ " # Sum up losses for gen\n",
+ " gen_loss = (\n",
+ " 10 * x_a_loss + c_b_loss + s_a_loss + gen_a_adv_loss + \\\n",
+ " 10 * x_b_loss + c_a_loss + s_b_loss + gen_b_adv_loss\n",
+ " )\n",
+ "\n",
+ " # Sum up losses for dis\n",
+ " dis_loss = (\n",
+ " self.loss.adversarial_loss(x_ba.detach(), self.dis_a, False) + \\\n",
+ " self.loss.adversarial_loss(x_a.detach(), self.dis_a, True) + \\\n",
+ " self.loss.adversarial_loss(x_ab.detach(), self.dis_b, False) + \\\n",
+ " self.loss.adversarial_loss(x_b.detach(), self.dis_b, True)\n",
+ " )\n",
+ "\n",
+ " return gen_loss, dis_loss, x_ab, x_ba"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qHz9F4m9wvKO"
+ },
+ "source": [
+ "### Training\n",
+ "\n",
+ "Now you're ready to train MUNIT! Let's start by setting some optimization parameters and initializing everything you'll need for training."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "BYQrHbgPw5ie"
+ },
+ "source": [
+ "# Initialize model\n",
+ "def weights_init(m):\n",
+ " if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear):\n",
+ " nn.init.kaiming_normal_(m.weight, a=0, mode='fan_in')\n",
+ "\n",
+ "munit_config = {\n",
+ " 'gen_channels': 64,\n",
+ " 'n_c_downsample': 2,\n",
+ " 'n_s_downsample': 4,\n",
+ " 'n_res_blocks': 4,\n",
+ " 's_dim': 8,\n",
+ " 'h_dim': 256,\n",
+ " 'dis_channels': 64,\n",
+ " 'n_layers': 3,\n",
+ " 'n_discriminators': 3,\n",
+ "}\n",
+ "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
+ "munit = MUNIT(**munit_config).to(device).apply(weights_init)\n",
+ "\n",
+ "# Initialize dataloader\n",
+ "transform = transforms.Compose([\n",
+ " transforms.Resize(286),\n",
+ " transforms.RandomCrop(256),\n",
+ " transforms.RandomHorizontalFlip(),\n",
+ " transforms.ToTensor(),\n",
+ " transforms.Normalize((0.5), (0.5))\n",
+ "])\n",
+ "dataloader = DataLoader(\n",
+ " ImageDataset('horse2zebra', transform),\n",
+ " batch_size=1, pin_memory=True, shuffle=True,\n",
+ ")\n",
+ "\n",
+ "# Initialize optimizers\n",
+ "gen_params = list(munit.gen_a.parameters()) + list(munit.gen_b.parameters())\n",
+ "dis_params = list(munit.dis_a.parameters()) + list(munit.dis_b.parameters())\n",
+ "gen_optimizer = torch.optim.Adam(gen_params, lr=1e-4, betas=(0.5, 0.999))\n",
+ "dis_optimizer = torch.optim.Adam(dis_params, lr=1e-4, betas=(0.5, 0.999))"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "-9d8AneYxuuT",
+ "outputId": "dd07c208-3565-4aa7-b5ef-d526885fd3f5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 1000
+ }
+ },
+ "source": [
+ "# Parse torch version for autocast\n",
+ "# ######################################################\n",
+ "version = torch.__version__\n",
+ "version = tuple(int(n) for n in version.split('.')[:-1])\n",
+ "has_autocast = version >= (1, 6)\n",
+ "# ######################################################\n",
+ "\n",
+ "def train(munit, dataloader, optimizers, device):\n",
+ "\n",
+ " max_iters = 1000000\n",
+ " decay_every = 100000\n",
+ " cur_iter = 0\n",
+ "\n",
+ " display_every = 500\n",
+ " mean_losses = [0., 0.]\n",
+ "\n",
+ " while cur_iter < max_iters:\n",
+ " for (x_a, x_b) in tqdm(dataloader):\n",
+ " x_a = x_a.to(device)\n",
+ " x_b = x_b.to(device)\n",
+ "\n",
+ " # Enable autocast to FP16 tensors (new feature since torch==1.6.0)\n",
+ " # If you're running older versions of torch, comment this out\n",
+ " # and use NVIDIA apex for mixed/half precision training\n",
+ " if has_autocast:\n",
+ " with torch.cuda.amp.autocast(enabled=(device=='cuda')):\n",
+ " outputs = munit(x_a, x_b)\n",
+ " else:\n",
+ " outputs = munit(x_a, x_b)\n",
+ " \n",
+ " losses, x_ab, x_ba = outputs[:-2], outputs[-2], outputs[-1]\n",
+ " munit.zero_grad()\n",
+ "\n",
+ " for i, (optimizer, loss) in enumerate(zip(optimizers, losses)):\n",
+ " optimizer.zero_grad()\n",
+ " loss.backward()\n",
+ " optimizer.step()\n",
+ " mean_losses[i] += loss.item() / display_every\n",
+ "\n",
+ " cur_iter += 1\n",
+ "\n",
+ " if cur_iter % display_every == 0:\n",
+ " print('Step {}: [G loss: {:.5f}][D loss: {:.5f}]'\n",
+ " .format(cur_iter, *mean_losses))\n",
+ " show_tensor_images(x_ab, x_a)\n",
+ " show_tensor_images(x_ba, x_b)\n",
+ " mean_losses = [0., 0.]\n",
+ "\n",
+ " if cur_iter == max_iters:\n",
+ " break\n",
+ "\n",
+ " # Schedule learning rate by 0.5\n",
+ " if cur_iter % decay_every == 0:\n",
+ " for optimizer in optimizers:\n",
+ " for param_group in optimizer.param_groups:\n",
+ " param_group['lr'] *= 0.5\n",
+ "\n",
+ "train(\n",
+ " munit, dataloader,\n",
+ " [gen_optimizer, dis_optimizer],\n",
+ " device,\n",
+ ")"
+ ],
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ " 47%|████▋ | 499/1067 [05:06<05:48, 1.63it/s]"
+ ],
+ "name": "stderr"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "Step 500: [G loss: 11.74086][D loss: 0.30821]\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "