Implementation:Junyanz Pytorch CycleGAN and pix2pix Define G and D
| Knowledge Sources | pytorch-CycleGAN-and-pix2pix |
|---|---|
| Domains | Image-to-Image Translation, Generative Adversarial Networks, Deep Learning Architecture |
| Last Updated | 2026-02-09 |
Overview
The models/networks.py module provides factory functions and class definitions for all generator and discriminator architectures used in CycleGAN and pix2pix, along with helper utilities for weight initialization, learning rate scheduling, and GAN loss computation.
Description
This module is the central definition point for all neural network architectures in the repository. It contains:
- Factory functions (define_G, define_D) that map string names to network classes
- Generator classes: ResnetGenerator (with ResnetBlock), UnetGenerator (with UnetSkipConnectionBlock)
- Discriminator classes: NLayerDiscriminator (PatchGAN), PixelDiscriminator
- GANLoss class unifying vanilla, LSGAN, and WGAN-GP objectives
- Helper functions: get_norm_layer, get_scheduler, init_weights, init_net
Usage
Called from model classes (CycleGANModel, Pix2PixModel) during __init__ to instantiate networks. The factory functions handle normalization layer selection, weight initialization, and GPU placement.
Code Reference
Source Location
| File | Lines |
|---|---|
| models/networks.py | L1-588 |
Signature
def define_G(input_nc, output_nc, ngf, netG, norm='batch', use_dropout=False,
init_type='normal', init_gain=0.02, gpu_ids=[]):
"""Create a generator.
Parameters:
input_nc (int) -- the number of channels in input images
output_nc (int) -- the number of channels in output images
ngf (int) -- the number of filters in the last conv layer
netG (str) -- the architecture name: resnet_9blocks | resnet_6blocks | unet_256 | unet_128
norm (str) -- the name of normalization layers: batch | instance | none
use_dropout (bool) -- if use dropout layers
init_type (str) -- the name of the initialization method: normal | xavier | kaiming | orthogonal
init_gain (float) -- scaling factor for normal, xavier, and orthogonal
gpu_ids (list) -- which GPUs the network runs on
Returns:
a generator network
"""
def define_D(input_nc, ndf, netD, n_layers_D=3, norm='batch',
init_type='normal', init_gain=0.02, gpu_ids=[]):
"""Create a discriminator.
Parameters:
input_nc (int) -- the number of channels in input images
ndf (int) -- the number of filters in the first conv layer
netD (str) -- the architecture name: basic | n_layers | pixel
n_layers_D (int) -- the number of conv layers in the discriminator (for n_layers type)
norm (str) -- the type of normalization layers
init_type (str) -- the name of the initialization method
init_gain (float) -- scaling factor for normal, xavier, and orthogonal
gpu_ids (list) -- which GPUs the network runs on
Returns:
a discriminator network
"""
Key Classes:
class ResnetGenerator(nn.Module):
"""Resnet-based generator (L313-361). Uses n residual blocks between
downsampling and upsampling convolutions."""
class UnetGenerator(nn.Module):
"""U-Net-based generator (L424-453). Encoder-decoder with skip connections."""
class NLayerDiscriminator(nn.Module):
"""PatchGAN discriminator (L518-555). Classifies NxN patches as real/fake."""
class PixelDiscriminator(nn.Module):
"""1x1 PatchGAN discriminator (L558-588). Per-pixel classification."""
class GANLoss(nn.Module):
"""GAN loss abstraction (L209-275). Supports vanilla, lsgan, wgangp."""
Helper Functions:
def get_norm_layer(norm_type='instance'):
"""Return a normalization layer (batch | instance | none)."""
def get_scheduler(optimizer, opt):
"""Return a learning rate scheduler (linear | step | plateau | cosine)."""
def init_weights(net, init_type='normal', init_gain=0.02):
"""Initialize network weights."""
def init_net(net, init_type='normal', init_gain=0.02, gpu_ids=[]):
"""Initialize a network: register to GPU, initialize weights."""
Import
from models import networks
# Create a ResNet generator
netG = networks.define_G(input_nc=3, output_nc=3, ngf=64,
netG='resnet_9blocks', norm='instance',
use_dropout=False, init_type='normal',
init_gain=0.02, gpu_ids=[0])
# Create a PatchGAN discriminator
netD = networks.define_D(input_nc=3, ndf=64, netD='basic',
n_layers_D=3, norm='instance',
init_type='normal', init_gain=0.02, gpu_ids=[0])
I/O Contract
| Parameter | Type | Description |
|---|---|---|
| input_nc | int | Number of input image channels (e.g., 3 for RGB) |
| output_nc | int | Number of output image channels |
| ngf | int | Number of generator filters in the last conv layer (default: 64) |
| netG | str | Architecture selector: resnet_9blocks, resnet_6blocks, unet_256, unet_128 |
| norm | str | Normalization type: batch, instance, none |
| use_dropout | bool | Whether to use dropout in residual blocks |
| init_type | str | Weight initialization: normal, xavier, kaiming, orthogonal |
| init_gain | float | Initialization scaling factor (default: 0.02) |
| gpu_ids | list of int | GPU device IDs |
| Parameter | Type | Description |
|---|---|---|
| input_nc | int | Number of input channels to discriminator |
| ndf | int | Number of discriminator filters in the first conv layer (default: 64) |
| netD | str | Architecture selector: basic (PatchGAN 70x70), n_layers, pixel |
| n_layers_D | int | Number of conv layers in discriminator (only for n_layers type, default: 3) |
| norm | str | Normalization type |
| init_type | str | Weight initialization method |
| init_gain | float | Initialization scaling factor |
| gpu_ids | list of int | GPU device IDs |
| Output | Type | Description |
|---|---|---|
| generator | nn.Module | Initialized generator network on specified GPU(s) |
| discriminator | nn.Module | Initialized discriminator network on specified GPU(s) |
Usage Examples
from models import networks
# CycleGAN default: ResNet generator + PatchGAN discriminator
netG_A = networks.define_G(3, 3, 64, 'resnet_9blocks', 'instance',
use_dropout=False, init_type='normal',
init_gain=0.02, gpu_ids=[0])
netD_A = networks.define_D(3, 64, 'basic', n_layers_D=3, norm='instance',
init_type='normal', init_gain=0.02, gpu_ids=[0])
# pix2pix default: U-Net generator + PatchGAN discriminator
netG = networks.define_G(3, 3, 64, 'unet_256', 'batch',
use_dropout=True, init_type='normal',
init_gain=0.02, gpu_ids=[0])
# Paired input for pix2pix discriminator (input_nc + output_nc)
netD = networks.define_D(6, 64, 'basic', n_layers_D=3, norm='batch',
init_type='normal', init_gain=0.02, gpu_ids=[0])
# GAN loss
criterionGAN = networks.GANLoss('lsgan').to(device)
loss_D = criterionGAN(pred_fake, False) + criterionGAN(pred_real, True)
Related Pages
- Principle:Junyanz_Pytorch_CycleGAN_and_pix2pix_GAN_Network_Architecture
- Implementation:Junyanz_Pytorch_CycleGAN_and_pix2pix_ImagePool_Query
- Environment:Junyanz_Pytorch_CycleGAN_and_pix2pix_Python_PyTorch_Runtime
- Environment:Junyanz_Pytorch_CycleGAN_and_pix2pix_DDP_Multi_GPU
- Heuristic:Junyanz_Pytorch_CycleGAN_and_pix2pix_Image_Size_Multiple_of_Four
- Heuristic:Junyanz_Pytorch_CycleGAN_and_pix2pix_Instance_Norm_for_Multi_GPU