noxer.gm.acgan module
Implementation of ACGAN, based on https://github.com/znxlwm/pytorch-generative-model-collections.
""" Implementation of ACGAN, based on https://github.com/znxlwm/pytorch-generative-model-collections. """ from sklearn.preprocessing import LabelBinarizer import torch, time, os, pickle import numpy as np import torch.nn as nn import torch.optim as optim from torch.autograd import Variable from torch.utils.data import DataLoader, TensorDataset from torchvision import datasets, transforms def initialize_weights(net): for m in net.modules(): if isinstance(m, nn.Conv2d): m.weight.data.normal_(0, 0.02) m.bias.data.zero_() elif isinstance(m, nn.ConvTranspose2d): m.weight.data.normal_(0, 0.02) m.bias.data.zero_() elif isinstance(m, nn.Linear): m.weight.data.normal_(0, 0.02) m.bias.data.zero_() class generator(nn.Module): # Network Architecture is exactly same as in infoGAN (https://arxiv.org/abs/1606.03657) # Architecture : FC1024_BR-FC7x7x128_BR-(64)4dc2s_BR-(1)4dc2s_S def __init__(self, height, width, channels): super(generator, self).__init__() self.input_height = height self.input_width = width self.input_dim = 62 + 10 self.output_dim = channels self.fc = nn.Sequential( nn.Linear(self.input_dim, 1024), nn.BatchNorm1d(1024), nn.ReLU(), nn.Linear(1024, 128 * (self.input_height // 4) * (self.input_width // 4)), nn.BatchNorm1d(128 * (self.input_height // 4) * (self.input_width // 4)), nn.ReLU(), ) self.deconv = nn.Sequential( nn.ConvTranspose2d(128, 64, 4, 2, 1), nn.BatchNorm2d(64), nn.ReLU(), nn.ConvTranspose2d(64, self.output_dim, 4, 2, 1), nn.Sigmoid(), ) initialize_weights(self) def forward(self, input, label): x = torch.cat([input, label], 1) x = self.fc(x) x = x.view(-1, 128, (self.input_height // 4), (self.input_width // 4)) x = self.deconv(x) return x class discriminator(nn.Module): # Network Architecture is exactly same as in infoGAN (https://arxiv.org/abs/1606.03657) # Architecture : (64)4c2s-(128)4c2s_BL-FC1024_BL-FC1_S def __init__(self, height, width, channels): super(discriminator, self).__init__() self.input_height = height self.input_width = width self.input_dim = channels self.output_dim = 1 self.class_num = 10 self.conv = nn.Sequential( nn.Conv2d(self.input_dim, 64, 4, 2, 1), nn.LeakyReLU(0.2), nn.Conv2d(64, 128, 4, 2, 1), nn.BatchNorm2d(128), nn.LeakyReLU(0.2), ) self.fc1 = nn.Sequential( nn.Linear(128 * (self.input_height // 4) * (self.input_width // 4), 1024), nn.BatchNorm1d(1024), nn.LeakyReLU(0.2), ) self.dc = nn.Sequential( nn.Linear(1024, self.output_dim), nn.Sigmoid(), ) self.cl = nn.Sequential( nn.Linear(1024, self.class_num), ) initialize_weights(self) def forward(self, input): x = self.conv(input) x = x.view(-1, 128 * (self.input_height // 4) * (self.input_width // 4)) x = self.fc1(x) d = self.dc(x) c = self.cl(x) return d, c class ACGAN(object): def __init__(self, height, width, channels, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0): # parameters self.height = height self.width= width self.channels = channels self.epoch = epochs self.sample_num = 100 self.batch_size = batch_size self.gpu_mode = use_gpu self.verbosity = verbose self.lrG = lrG self.lrD = lrD self.beta1 = beta1 self.beta2 = beta2 self.verbose = beta2 def notify(self, message, verbosity=1): if self.verbosity >= verbosity: print(message) def train(self, X, Y, callback=None): self.train_hist = {} self.train_hist['D_loss'] = [] self.train_hist['G_loss'] = [] self.train_hist['per_epoch_time'] = [] self.train_hist['total_time'] = [] # networks init self.G = generator(self.height, self.width, self.channels) self.D = discriminator(self.height, self.width, self.channels) G_optimizer = optim.Adam(self.G.parameters(), lr=self.lrG, betas=(self.beta1, self.beta2)) D_optimizer = optim.Adam(self.D.parameters(), lr=self.lrD, betas=(self.beta1, self.beta2)) if self.gpu_mode: self.G.cuda() self.D.cuda() BCE_loss = nn.BCELoss().cuda() CE_loss = nn.CrossEntropyLoss().cuda() else: BCE_loss = nn.BCELoss() CE_loss = nn.CrossEntropyLoss() # print('---------- Networks architecture -------------') # utils.print_network(self.G) # utils.print_network(self.D) # print('-----------------------------------------------') # load mnist self.z_dim = 62 self.y_dim = 10 # fixed noise & condition sample_z_ = torch.zeros((self.sample_num, self.z_dim)) for i in range(10): sample_z_[i * self.y_dim] = torch.rand(1, self.z_dim) for j in range(1, self.y_dim): sample_z_[i * self.y_dim + j] = sample_z_[i * self.y_dim] temp = torch.zeros((10, 1)) for i in range(self.y_dim): temp[i, 0] = i temp_y = torch.zeros((self.sample_num, 1)) for i in range(10): temp_y[i * self.y_dim: (i + 1) * self.y_dim] = temp sample_y_ = torch.zeros((self.sample_num, self.y_dim)) sample_y_.scatter_(1, temp_y.type(torch.LongTensor), 1) # setup dataset data_Y, data_X = torch.FloatTensor(X), torch.FloatTensor(Y) if self.gpu_mode: y_real_, y_fake_ = Variable(torch.ones(self.batch_size, 1).cuda()), Variable(torch.zeros(self.batch_size, 1).cuda()) else: y_real_, y_fake_ = Variable(torch.ones(self.batch_size, 1)), Variable(torch.zeros(self.batch_size, 1)) self.D.train() self.notify('training start!!') start_time = time.time() for epoch in range(self.epoch): self.G.train() epoch_start_time = time.time() for iter in range(len(data_X) // self.batch_size): x_ = data_X[iter*self.batch_size:(iter+1)*self.batch_size] z_ = torch.rand((self.batch_size, self.z_dim)) y_vec_ = data_Y[iter*self.batch_size:(iter+1)*self.batch_size] if self.gpu_mode: x_, z_, y_vec_ = Variable(x_.cuda()), Variable(z_.cuda()), Variable(y_vec_.cuda()) else: x_, z_, y_vec_ = Variable(x_), Variable(z_), Variable(y_vec_) # update D network D_optimizer.zero_grad() D_real, C_real = self.D(x_) D_real_loss = BCE_loss(D_real, y_real_) mxv = torch.max(y_vec_, 1)[1] C_real_loss = CE_loss(C_real, mxv) G_ = self.G(z_, y_vec_) D_fake, C_fake = self.D(G_) D_fake_loss = BCE_loss(D_fake, y_fake_) mxv = torch.max(y_vec_, 1)[1] C_fake_loss = CE_loss(C_fake, mxv) D_loss = D_real_loss + C_real_loss + D_fake_loss + C_fake_loss self.train_hist['D_loss'].append(D_loss.data[0]) D_loss.backward() D_optimizer.step() # update G network G_optimizer.zero_grad() G_ = self.G(z_, y_vec_) D_fake, C_fake = self.D(G_) G_loss = BCE_loss(D_fake, y_real_) C_fake_loss = CE_loss(C_fake, torch.max(y_vec_, 1)[1]) G_loss += C_fake_loss self.train_hist['G_loss'].append(G_loss.data[0]) G_loss.backward() G_optimizer.step() if ((iter + 1) % 10) == 0: self.notify("Epoch: [%2d] [%4d/%4d] D_loss: %.8f, G_loss: %.8f" % ((epoch + 1), (iter + 1), len(data_X) // self.batch_size, D_loss.data[0], G_loss.data[0])) if callback is not None: callback() self.train_hist['per_epoch_time'].append(time.time() - epoch_start_time) self.notify(epoch) self.train_hist['total_time'].append(time.time() - start_time) self.notify("Avg one epoch time: %.2f, total %d epochs time: %.2f" % (np.mean(self.train_hist['per_epoch_time']), self.epoch, self.train_hist['total_time'][0])) from .base import GeneratorBase def gpu_setting(kwargs): if 'gpu' in kwargs: use_gpu = kwargs['gpu'] else: use_gpu = True return use_gpu def get_callback(kwargs): if 'callback' in kwargs: return kwargs['callback'] return None class ACGANCategoryToImageGenerator(GeneratorBase): def __init__(self, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0): self.use_gpu = use_gpu self.epochs = epochs self.batch_size = batch_size self.lrG = lrG self.lrD = lrD self.beta1 = beta1 self.beta2 = beta2 self.verbose = verbose self.net = None self.bin = None def fit(self, X, Y, **kwargs): # shuffle dimensions to fit to pytorch conventions Y = np.transpose(Y, (0, 3, 1, 2)) height = Y.shape[2] width = Y.shape[3] channels = Y.shape[1] # binarize the labels self.bin = LabelBinarizer() X = self.bin.fit_transform(X) self.net = ACGAN( height, width, channels, use_gpu=gpu_setting(kwargs), epochs = self.epochs, batch_size = self.batch_size, lrG = self.lrG, lrD = self.lrD, beta1 = self.beta1, beta2 = self.beta2, verbose = self.verbose, ) self.net.train(X, Y, callback=get_callback(kwargs)) self.net.D.eval() self.net.G.eval() def predict_noise(self, X, Z, **kwargs): if self.net is None: raise RuntimeError("Please run the fitting procedure first!") self.net.G.eval() iX = torch.FloatTensor(self.bin.transform(X)) if gpu_setting(kwargs): iZ, iX = Variable(Z.cuda(), volatile=True), Variable(iX.cuda(), volatile=True) else: iZ, iX = Variable(Z, volatile=True), Variable(iX, volatile=True) Y = self.net.G(iZ, iX) Y = Y.cpu().data.numpy() Y = np.transpose(Y, (0, 2, 3, 1)) return Y def predict(self, X, **kwargs): # generate noise Z = torch.rand((len(X), self.net.z_dim)) # make generation return self.predict_noise(X, Z, **kwargs)
Functions
def get_callback(
kwargs)
def get_callback(kwargs): if 'callback' in kwargs: return kwargs['callback'] return None
def gpu_setting(
kwargs)
def gpu_setting(kwargs): if 'gpu' in kwargs: use_gpu = kwargs['gpu'] else: use_gpu = True return use_gpu
def initialize_weights(
net)
def initialize_weights(net): for m in net.modules(): if isinstance(m, nn.Conv2d): m.weight.data.normal_(0, 0.02) m.bias.data.zero_() elif isinstance(m, nn.ConvTranspose2d): m.weight.data.normal_(0, 0.02) m.bias.data.zero_() elif isinstance(m, nn.Linear): m.weight.data.normal_(0, 0.02) m.bias.data.zero_()
Classes
class ACGAN
class ACGAN(object): def __init__(self, height, width, channels, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0): # parameters self.height = height self.width= width self.channels = channels self.epoch = epochs self.sample_num = 100 self.batch_size = batch_size self.gpu_mode = use_gpu self.verbosity = verbose self.lrG = lrG self.lrD = lrD self.beta1 = beta1 self.beta2 = beta2 self.verbose = beta2 def notify(self, message, verbosity=1): if self.verbosity >= verbosity: print(message) def train(self, X, Y, callback=None): self.train_hist = {} self.train_hist['D_loss'] = [] self.train_hist['G_loss'] = [] self.train_hist['per_epoch_time'] = [] self.train_hist['total_time'] = [] # networks init self.G = generator(self.height, self.width, self.channels) self.D = discriminator(self.height, self.width, self.channels) G_optimizer = optim.Adam(self.G.parameters(), lr=self.lrG, betas=(self.beta1, self.beta2)) D_optimizer = optim.Adam(self.D.parameters(), lr=self.lrD, betas=(self.beta1, self.beta2)) if self.gpu_mode: self.G.cuda() self.D.cuda() BCE_loss = nn.BCELoss().cuda() CE_loss = nn.CrossEntropyLoss().cuda() else: BCE_loss = nn.BCELoss() CE_loss = nn.CrossEntropyLoss() # print('---------- Networks architecture -------------') # utils.print_network(self.G) # utils.print_network(self.D) # print('-----------------------------------------------') # load mnist self.z_dim = 62 self.y_dim = 10 # fixed noise & condition sample_z_ = torch.zeros((self.sample_num, self.z_dim)) for i in range(10): sample_z_[i * self.y_dim] = torch.rand(1, self.z_dim) for j in range(1, self.y_dim): sample_z_[i * self.y_dim + j] = sample_z_[i * self.y_dim] temp = torch.zeros((10, 1)) for i in range(self.y_dim): temp[i, 0] = i temp_y = torch.zeros((self.sample_num, 1)) for i in range(10): temp_y[i * self.y_dim: (i + 1) * self.y_dim] = temp sample_y_ = torch.zeros((self.sample_num, self.y_dim)) sample_y_.scatter_(1, temp_y.type(torch.LongTensor), 1) # setup dataset data_Y, data_X = torch.FloatTensor(X), torch.FloatTensor(Y) if self.gpu_mode: y_real_, y_fake_ = Variable(torch.ones(self.batch_size, 1).cuda()), Variable(torch.zeros(self.batch_size, 1).cuda()) else: y_real_, y_fake_ = Variable(torch.ones(self.batch_size, 1)), Variable(torch.zeros(self.batch_size, 1)) self.D.train() self.notify('training start!!') start_time = time.time() for epoch in range(self.epoch): self.G.train() epoch_start_time = time.time() for iter in range(len(data_X) // self.batch_size): x_ = data_X[iter*self.batch_size:(iter+1)*self.batch_size] z_ = torch.rand((self.batch_size, self.z_dim)) y_vec_ = data_Y[iter*self.batch_size:(iter+1)*self.batch_size] if self.gpu_mode: x_, z_, y_vec_ = Variable(x_.cuda()), Variable(z_.cuda()), Variable(y_vec_.cuda()) else: x_, z_, y_vec_ = Variable(x_), Variable(z_), Variable(y_vec_) # update D network D_optimizer.zero_grad() D_real, C_real = self.D(x_) D_real_loss = BCE_loss(D_real, y_real_) mxv = torch.max(y_vec_, 1)[1] C_real_loss = CE_loss(C_real, mxv) G_ = self.G(z_, y_vec_) D_fake, C_fake = self.D(G_) D_fake_loss = BCE_loss(D_fake, y_fake_) mxv = torch.max(y_vec_, 1)[1] C_fake_loss = CE_loss(C_fake, mxv) D_loss = D_real_loss + C_real_loss + D_fake_loss + C_fake_loss self.train_hist['D_loss'].append(D_loss.data[0]) D_loss.backward() D_optimizer.step() # update G network G_optimizer.zero_grad() G_ = self.G(z_, y_vec_) D_fake, C_fake = self.D(G_) G_loss = BCE_loss(D_fake, y_real_) C_fake_loss = CE_loss(C_fake, torch.max(y_vec_, 1)[1]) G_loss += C_fake_loss self.train_hist['G_loss'].append(G_loss.data[0]) G_loss.backward() G_optimizer.step() if ((iter + 1) % 10) == 0: self.notify("Epoch: [%2d] [%4d/%4d] D_loss: %.8f, G_loss: %.8f" % ((epoch + 1), (iter + 1), len(data_X) // self.batch_size, D_loss.data[0], G_loss.data[0])) if callback is not None: callback() self.train_hist['per_epoch_time'].append(time.time() - epoch_start_time) self.notify(epoch) self.train_hist['total_time'].append(time.time() - start_time) self.notify("Avg one epoch time: %.2f, total %d epochs time: %.2f" % (np.mean(self.train_hist['per_epoch_time']), self.epoch, self.train_hist['total_time'][0]))
Ancestors (in MRO)
- ACGAN
- builtins.object
Static methods
def __init__(
self, height, width, channels, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, height, width, channels, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0): # parameters self.height = height self.width= width self.channels = channels self.epoch = epochs self.sample_num = 100 self.batch_size = batch_size self.gpu_mode = use_gpu self.verbosity = verbose self.lrG = lrG self.lrD = lrD self.beta1 = beta1 self.beta2 = beta2 self.verbose = beta2
def notify(
self, message, verbosity=1)
def notify(self, message, verbosity=1): if self.verbosity >= verbosity: print(message)
def train(
self, X, Y, callback=None)
def train(self, X, Y, callback=None): self.train_hist = {} self.train_hist['D_loss'] = [] self.train_hist['G_loss'] = [] self.train_hist['per_epoch_time'] = [] self.train_hist['total_time'] = [] # networks init self.G = generator(self.height, self.width, self.channels) self.D = discriminator(self.height, self.width, self.channels) G_optimizer = optim.Adam(self.G.parameters(), lr=self.lrG, betas=(self.beta1, self.beta2)) D_optimizer = optim.Adam(self.D.parameters(), lr=self.lrD, betas=(self.beta1, self.beta2)) if self.gpu_mode: self.G.cuda() self.D.cuda() BCE_loss = nn.BCELoss().cuda() CE_loss = nn.CrossEntropyLoss().cuda() else: BCE_loss = nn.BCELoss() CE_loss = nn.CrossEntropyLoss() # print('---------- Networks architecture -------------') # utils.print_network(self.G) # utils.print_network(self.D) # print('-----------------------------------------------') # load mnist self.z_dim = 62 self.y_dim = 10 # fixed noise & condition sample_z_ = torch.zeros((self.sample_num, self.z_dim)) for i in range(10): sample_z_[i * self.y_dim] = torch.rand(1, self.z_dim) for j in range(1, self.y_dim): sample_z_[i * self.y_dim + j] = sample_z_[i * self.y_dim] temp = torch.zeros((10, 1)) for i in range(self.y_dim): temp[i, 0] = i temp_y = torch.zeros((self.sample_num, 1)) for i in range(10): temp_y[i * self.y_dim: (i + 1) * self.y_dim] = temp sample_y_ = torch.zeros((self.sample_num, self.y_dim)) sample_y_.scatter_(1, temp_y.type(torch.LongTensor), 1) # setup dataset data_Y, data_X = torch.FloatTensor(X), torch.FloatTensor(Y) if self.gpu_mode: y_real_, y_fake_ = Variable(torch.ones(self.batch_size, 1).cuda()), Variable(torch.zeros(self.batch_size, 1).cuda()) else: y_real_, y_fake_ = Variable(torch.ones(self.batch_size, 1)), Variable(torch.zeros(self.batch_size, 1)) self.D.train() self.notify('training start!!') start_time = time.time() for epoch in range(self.epoch): self.G.train() epoch_start_time = time.time() for iter in range(len(data_X) // self.batch_size): x_ = data_X[iter*self.batch_size:(iter+1)*self.batch_size] z_ = torch.rand((self.batch_size, self.z_dim)) y_vec_ = data_Y[iter*self.batch_size:(iter+1)*self.batch_size] if self.gpu_mode: x_, z_, y_vec_ = Variable(x_.cuda()), Variable(z_.cuda()), Variable(y_vec_.cuda()) else: x_, z_, y_vec_ = Variable(x_), Variable(z_), Variable(y_vec_) # update D network D_optimizer.zero_grad() D_real, C_real = self.D(x_) D_real_loss = BCE_loss(D_real, y_real_) mxv = torch.max(y_vec_, 1)[1] C_real_loss = CE_loss(C_real, mxv) G_ = self.G(z_, y_vec_) D_fake, C_fake = self.D(G_) D_fake_loss = BCE_loss(D_fake, y_fake_) mxv = torch.max(y_vec_, 1)[1] C_fake_loss = CE_loss(C_fake, mxv) D_loss = D_real_loss + C_real_loss + D_fake_loss + C_fake_loss self.train_hist['D_loss'].append(D_loss.data[0]) D_loss.backward() D_optimizer.step() # update G network G_optimizer.zero_grad() G_ = self.G(z_, y_vec_) D_fake, C_fake = self.D(G_) G_loss = BCE_loss(D_fake, y_real_) C_fake_loss = CE_loss(C_fake, torch.max(y_vec_, 1)[1]) G_loss += C_fake_loss self.train_hist['G_loss'].append(G_loss.data[0]) G_loss.backward() G_optimizer.step() if ((iter + 1) % 10) == 0: self.notify("Epoch: [%2d] [%4d/%4d] D_loss: %.8f, G_loss: %.8f" % ((epoch + 1), (iter + 1), len(data_X) // self.batch_size, D_loss.data[0], G_loss.data[0])) if callback is not None: callback() self.train_hist['per_epoch_time'].append(time.time() - epoch_start_time) self.notify(epoch) self.train_hist['total_time'].append(time.time() - start_time) self.notify("Avg one epoch time: %.2f, total %d epochs time: %.2f" % (np.mean(self.train_hist['per_epoch_time']), self.epoch, self.train_hist['total_time'][0]))
Instance variables
var batch_size
var beta1
var beta2
var channels
var epoch
var gpu_mode
var height
var lrD
var lrG
var sample_num
var verbose
var verbosity
var width
class ACGANCategoryToImageGenerator
Base class for all estimators in scikit-learn
Notes
All estimators should specify all the parameters that can be set
at the class level in their __init__
as explicit keyword
arguments (no *args
or **kwargs
).
class ACGANCategoryToImageGenerator(GeneratorBase): def __init__(self, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0): self.use_gpu = use_gpu self.epochs = epochs self.batch_size = batch_size self.lrG = lrG self.lrD = lrD self.beta1 = beta1 self.beta2 = beta2 self.verbose = verbose self.net = None self.bin = None def fit(self, X, Y, **kwargs): # shuffle dimensions to fit to pytorch conventions Y = np.transpose(Y, (0, 3, 1, 2)) height = Y.shape[2] width = Y.shape[3] channels = Y.shape[1] # binarize the labels self.bin = LabelBinarizer() X = self.bin.fit_transform(X) self.net = ACGAN( height, width, channels, use_gpu=gpu_setting(kwargs), epochs = self.epochs, batch_size = self.batch_size, lrG = self.lrG, lrD = self.lrD, beta1 = self.beta1, beta2 = self.beta2, verbose = self.verbose, ) self.net.train(X, Y, callback=get_callback(kwargs)) self.net.D.eval() self.net.G.eval() def predict_noise(self, X, Z, **kwargs): if self.net is None: raise RuntimeError("Please run the fitting procedure first!") self.net.G.eval() iX = torch.FloatTensor(self.bin.transform(X)) if gpu_setting(kwargs): iZ, iX = Variable(Z.cuda(), volatile=True), Variable(iX.cuda(), volatile=True) else: iZ, iX = Variable(Z, volatile=True), Variable(iX, volatile=True) Y = self.net.G(iZ, iX) Y = Y.cpu().data.numpy() Y = np.transpose(Y, (0, 2, 3, 1)) return Y def predict(self, X, **kwargs): # generate noise Z = torch.rand((len(X), self.net.z_dim)) # make generation return self.predict_noise(X, Z, **kwargs)
Ancestors (in MRO)
- ACGANCategoryToImageGenerator
- noxer.gm.base.GeneratorBase
- sklearn.base.BaseEstimator
- builtins.object
Static methods
def __init__(
self, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, use_gpu=True, epochs=32, batch_size=64, lrG=0.0002, lrD=0.0002, beta1=0.5, beta2=0.999, verbose=0): self.use_gpu = use_gpu self.epochs = epochs self.batch_size = batch_size self.lrG = lrG self.lrD = lrD self.beta1 = beta1 self.beta2 = beta2 self.verbose = verbose self.net = None self.bin = None
def fit(
self, X, Y, **kwargs)
Fit generative model to the data.
Parameters
Y : {array-like, sparse matrix}, shape [n_samples, ...] The data that should be generated by particular model.
X : {array-like, sparse matrix}, shape [n_samples, ...] The data used to condition the generative model's outputs.
def fit(self, X, Y, **kwargs): # shuffle dimensions to fit to pytorch conventions Y = np.transpose(Y, (0, 3, 1, 2)) height = Y.shape[2] width = Y.shape[3] channels = Y.shape[1] # binarize the labels self.bin = LabelBinarizer() X = self.bin.fit_transform(X) self.net = ACGAN( height, width, channels, use_gpu=gpu_setting(kwargs), epochs = self.epochs, batch_size = self.batch_size, lrG = self.lrG, lrD = self.lrD, beta1 = self.beta1, beta2 = self.beta2, verbose = self.verbose, ) self.net.train(X, Y, callback=get_callback(kwargs)) self.net.D.eval() self.net.G.eval()
def get_params(
self, deep=True)
Get parameters for this estimator.
Parameters
deep : boolean, optional If True, will return the parameters for this estimator and contained subobjects that are estimators.
Returns
params : mapping of string to any Parameter names mapped to their values.
def get_params(self, deep=True): """Get parameters for this estimator. Parameters ---------- deep : boolean, optional If True, will return the parameters for this estimator and contained subobjects that are estimators. Returns ------- params : mapping of string to any Parameter names mapped to their values. """ out = dict() for key in self._get_param_names(): # We need deprecation warnings to always be on in order to # catch deprecated param values. # This is set in utils/__init__.py but it gets overwritten # when running under python3 somehow. warnings.simplefilter("always", DeprecationWarning) try: with warnings.catch_warnings(record=True) as w: value = getattr(self, key, None) if len(w) and w[0].category == DeprecationWarning: # if the parameter is deprecated, don't show it continue finally: warnings.filters.pop(0) # XXX: should we rather test if instance of estimator? if deep and hasattr(value, 'get_params'): deep_items = value.get_params().items() out.update((key + '__' + k, val) for k, val in deep_items) out[key] = value return out
def predict(
self, X, **kwargs)
Make estimations with generative model.
Parameters
X : {array-like, sparse matrix}, shape [n_samples, ...] The data used to condition the generative model's outputs.
Returns
Y : {array-like, sparse matrix}, shape [n_samples, ...] The data that is generated by a generative model.
def predict(self, X, **kwargs): # generate noise Z = torch.rand((len(X), self.net.z_dim)) # make generation return self.predict_noise(X, Z, **kwargs)
def predict_noise(
self, X, Z, **kwargs)
def predict_noise(self, X, Z, **kwargs): if self.net is None: raise RuntimeError("Please run the fitting procedure first!") self.net.G.eval() iX = torch.FloatTensor(self.bin.transform(X)) if gpu_setting(kwargs): iZ, iX = Variable(Z.cuda(), volatile=True), Variable(iX.cuda(), volatile=True) else: iZ, iX = Variable(Z, volatile=True), Variable(iX, volatile=True) Y = self.net.G(iZ, iX) Y = Y.cpu().data.numpy() Y = np.transpose(Y, (0, 2, 3, 1)) return Y
def score(
self, X, Y, **kwargs)
Score the generative model on the real data.
Parameters
Y : {array-like, sparse matrix}, shape [n_samples, ...] The data that should be generated by particular model.
X : {array-like, sparse matrix}, shape [n_samples, ...] The data used to condition the generative model's outputs.
def score(self, X, Y, **kwargs): """Score the generative model on the real data. Parameters ---------- Y : {array-like, sparse matrix}, shape [n_samples, ...] The data that should be generated by particular model. X : {array-like, sparse matrix}, shape [n_samples, ...] The data used to condition the generative model's outputs. """ Yp = self.predict(X, **kwargs) score = distribution_similarity(Y, Yp) return score
def set_params(
self, **params)
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects
(such as pipelines). The latter have parameters of the form
<component>__<parameter>
so that it's possible to update each
component of a nested object.
Returns
self
def set_params(self, **params): """Set the parameters of this estimator. The method works on simple estimators as well as on nested objects (such as pipelines). The latter have parameters of the form ``<component>__<parameter>`` so that it's possible to update each component of a nested object. Returns ------- self """ if not params: # Simple optimization to gain speed (inspect is slow) return self valid_params = self.get_params(deep=True) nested_params = defaultdict(dict) # grouped by prefix for key, value in params.items(): key, delim, sub_key = key.partition('__') if key not in valid_params: raise ValueError('Invalid parameter %s for estimator %s. ' 'Check the list of available parameters ' 'with `estimator.get_params().keys()`.' % (key, self)) if delim: nested_params[key][sub_key] = value else: setattr(self, key, value) for key, sub_params in nested_params.items(): valid_params[key].set_params(**sub_params) return self
Instance variables
var batch_size
var beta1
var beta2
var bin
var epochs
var lrD
var lrG
var net
var use_gpu
var verbose
class discriminator
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self): super(Model, self).__init__() self.conv1 = nn.Conv2d(1, 20, 5) self.conv2 = nn.Conv2d(20, 20, 5) def forward(self, x): x = F.relu(self.conv1(x)) return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will have their parameters converted too when you call .cuda(), etc.
class discriminator(nn.Module): # Network Architecture is exactly same as in infoGAN (https://arxiv.org/abs/1606.03657) # Architecture : (64)4c2s-(128)4c2s_BL-FC1024_BL-FC1_S def __init__(self, height, width, channels): super(discriminator, self).__init__() self.input_height = height self.input_width = width self.input_dim = channels self.output_dim = 1 self.class_num = 10 self.conv = nn.Sequential( nn.Conv2d(self.input_dim, 64, 4, 2, 1), nn.LeakyReLU(0.2), nn.Conv2d(64, 128, 4, 2, 1), nn.BatchNorm2d(128), nn.LeakyReLU(0.2), ) self.fc1 = nn.Sequential( nn.Linear(128 * (self.input_height // 4) * (self.input_width // 4), 1024), nn.BatchNorm1d(1024), nn.LeakyReLU(0.2), ) self.dc = nn.Sequential( nn.Linear(1024, self.output_dim), nn.Sigmoid(), ) self.cl = nn.Sequential( nn.Linear(1024, self.class_num), ) initialize_weights(self) def forward(self, input): x = self.conv(input) x = x.view(-1, 128 * (self.input_height // 4) * (self.input_width // 4)) x = self.fc1(x) d = self.dc(x) c = self.cl(x) return d, c
Ancestors (in MRO)
- discriminator
- torch.nn.modules.module.Module
- builtins.object
Class variables
var dump_patches
Static methods
def __init__(
self, height, width, channels)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, height, width, channels): super(discriminator, self).__init__() self.input_height = height self.input_width = width self.input_dim = channels self.output_dim = 1 self.class_num = 10 self.conv = nn.Sequential( nn.Conv2d(self.input_dim, 64, 4, 2, 1), nn.LeakyReLU(0.2), nn.Conv2d(64, 128, 4, 2, 1), nn.BatchNorm2d(128), nn.LeakyReLU(0.2), ) self.fc1 = nn.Sequential( nn.Linear(128 * (self.input_height // 4) * (self.input_width // 4), 1024), nn.BatchNorm1d(1024), nn.LeakyReLU(0.2), ) self.dc = nn.Sequential( nn.Linear(1024, self.output_dim), nn.Sigmoid(), ) self.cl = nn.Sequential( nn.Linear(1024, self.class_num), ) initialize_weights(self)
def add_module(
self, name, module)
Adds a child module to the current module.
The module can be accessed as an attribute using the given name.
Args: name (string): name of the child module. The child module can be accessed from this module using the given name parameter (Module): child module to be added to the module.
def add_module(self, name, module): """Adds a child module to the current module. The module can be accessed as an attribute using the given name. Args: name (string): name of the child module. The child module can be accessed from this module using the given name parameter (Module): child module to be added to the module. """ if not isinstance(module, Module) and module is not None: raise TypeError("{} is not a Module subclass".format( torch.typename(module))) if hasattr(self, name) and name not in self._modules: raise KeyError("attribute '{}' already exists".format(name)) self._modules[name] = module
def apply(
self, fn)
Applies fn
recursively to every submodule (as returned by .children()
)
as well as self. Typical use includes initializing the parameters of a model
(see also :ref:torch-nn-init
).
Args:
fn (:class:Module
-> None): function to be applied to each submodule
Returns: Module: self
Example: >>> def init_weights(m): >>> print(m) >>> if type(m) == nn.Linear: >>> m.weight.data.fill_(1.0) >>> print(m.weight) >>> >>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2)) >>> net.apply(init_weights) Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) )
def apply(self, fn): """Applies ``fn`` recursively to every submodule (as returned by ``.children()``) as well as self. Typical use includes initializing the parameters of a model (see also :ref:`torch-nn-init`). Args: fn (:class:`Module` -> None): function to be applied to each submodule Returns: Module: self Example: >>> def init_weights(m): >>> print(m) >>> if type(m) == nn.Linear: >>> m.weight.data.fill_(1.0) >>> print(m.weight) >>> >>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2)) >>> net.apply(init_weights) Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) ) """ for module in self.children(): module.apply(fn) fn(self) return self
def children(
self)
Returns an iterator over immediate children modules.
Yields: Module: a child module
def children(self): """Returns an iterator over immediate children modules. Yields: Module: a child module """ for name, module in self.named_children(): yield module
def cpu(
self)
Moves all model parameters and buffers to the CPU.
Returns: Module: self
def cpu(self): """Moves all model parameters and buffers to the CPU. Returns: Module: self """ return self._apply(lambda t: t.cpu())
def cuda(
self, device=None)
Moves all model parameters and buffers to the GPU.
This also makes associated parameters and buffers different objects. So it should be called before constructing optimizer if the module will live on GPU while being optimized.
Arguments: device (int, optional): if specified, all parameters will be copied to that device
Returns: Module: self
def cuda(self, device=None): """Moves all model parameters and buffers to the GPU. This also makes associated parameters and buffers different objects. So it should be called before constructing optimizer if the module will live on GPU while being optimized. Arguments: device (int, optional): if specified, all parameters will be copied to that device Returns: Module: self """ return self._apply(lambda t: t.cuda(device))
def double(
self)
Casts all parameters and buffers to double datatype.
Returns: Module: self
def double(self): """Casts all parameters and buffers to double datatype. Returns: Module: self """ return self._apply(lambda t: t.double())
def eval(
self)
Sets the module in evaluation mode.
This has any effect only on modules such as Dropout or BatchNorm.
def eval(self): """Sets the module in evaluation mode. This has any effect only on modules such as Dropout or BatchNorm. """ return self.train(False)
def float(
self)
Casts all parameters and buffers to float datatype.
Returns: Module: self
def float(self): """Casts all parameters and buffers to float datatype. Returns: Module: self """ return self._apply(lambda t: t.float())
def forward(
self, input)
Defines the computation performed at every call.
Should be overriden by all subclasses.
.. note::
Although the recipe for forward pass needs to be defined within
this function, one should call the :class:Module
instance afterwards
instead of this since the former takes care of running the
registered hooks while the latter silently ignores them.
def forward(self, input): x = self.conv(input) x = x.view(-1, 128 * (self.input_height // 4) * (self.input_width // 4)) x = self.fc1(x) d = self.dc(x) c = self.cl(x) return d, c
def half(
self)
Casts all parameters and buffers to half datatype.
Returns: Module: self
def half(self): """Casts all parameters and buffers to half datatype. Returns: Module: self """ return self._apply(lambda t: t.half())
def load_state_dict(
self, state_dict, strict=True)
Copies parameters and buffers from :attr:state_dict
into
this module and its descendants. If :attr:strict
is True
then
the keys of :attr:state_dict
must exactly match the keys returned
by this module's :func:state_dict()
function.
Arguments:
state_dict (dict): A dict containing parameters and
persistent buffers.
strict (bool): Strictly enforce that the keys in :attr:state_dict
match the keys returned by this module's :func:
state_dict()`
function.
def load_state_dict(self, state_dict, strict=True): """Copies parameters and buffers from :attr:`state_dict` into this module and its descendants. If :attr:`strict` is ``True`` then the keys of :attr:`state_dict` must exactly match the keys returned by this module's :func:`state_dict()` function. Arguments: state_dict (dict): A dict containing parameters and persistent buffers. strict (bool): Strictly enforce that the keys in :attr:`state_dict` match the keys returned by this module's `:func:`state_dict()` function. """ own_state = self.state_dict() for name, param in state_dict.items(): if name in own_state: if isinstance(param, Parameter): # backwards compatibility for serialized parameters param = param.data try: own_state[name].copy_(param) except Exception: raise RuntimeError('While copying the parameter named {}, ' 'whose dimensions in the model are {} and ' 'whose dimensions in the checkpoint are {}.' .format(name, own_state[name].size(), param.size())) elif strict: raise KeyError('unexpected key "{}" in state_dict' .format(name)) if strict: missing = set(own_state.keys()) - set(state_dict.keys()) if len(missing) > 0: raise KeyError('missing keys in state_dict: "{}"'.format(missing))
def modules(
self)
Returns an iterator over all modules in the network.
Yields: Module: a module in the network
Note:
Duplicate modules are returned only once. In the following
example, l
will be returned only once.
>>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.modules()): >>> print(idx, '->', m) 0 -> Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) ) 1 -> Linear (2 -> 2)
def modules(self): """Returns an iterator over all modules in the network. Yields: Module: a module in the network Note: Duplicate modules are returned only once. In the following example, ``l`` will be returned only once. >>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.modules()): >>> print(idx, '->', m) 0 -> Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) ) 1 -> Linear (2 -> 2) """ for name, module in self.named_modules(): yield module
def named_children(
self)
Returns an iterator over immediate children modules, yielding both the name of the module as well as the module itself.
Yields: (string, Module): Tuple containing a name and child module
Example: >>> for name, module in model.named_children(): >>> if name in ['conv4', 'conv5']: >>> print(module)
def named_children(self): """Returns an iterator over immediate children modules, yielding both the name of the module as well as the module itself. Yields: (string, Module): Tuple containing a name and child module Example: >>> for name, module in model.named_children(): >>> if name in ['conv4', 'conv5']: >>> print(module) """ memo = set() for name, module in self._modules.items(): if module is not None and module not in memo: memo.add(module) yield name, module
def named_modules(
self, memo=None, prefix='')
Returns an iterator over all modules in the network, yielding both the name of the module as well as the module itself.
Yields: (string, Module): Tuple of name and module
Note:
Duplicate modules are returned only once. In the following
example, l
will be returned only once.
>>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.named_modules()): >>> print(idx, '->', m) 0 -> ('', Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) )) 1 -> ('0', Linear (2 -> 2))
def named_modules(self, memo=None, prefix=''): """Returns an iterator over all modules in the network, yielding both the name of the module as well as the module itself. Yields: (string, Module): Tuple of name and module Note: Duplicate modules are returned only once. In the following example, ``l`` will be returned only once. >>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.named_modules()): >>> print(idx, '->', m) 0 -> ('', Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) )) 1 -> ('0', Linear (2 -> 2)) """ if memo is None: memo = set() if self not in memo: memo.add(self) yield prefix, self for name, module in self._modules.items(): if module is None: continue submodule_prefix = prefix + ('.' if prefix else '') + name for m in module.named_modules(memo, submodule_prefix): yield m
def named_parameters(
self, memo=None, prefix='')
Returns an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself
Yields: (string, Parameter): Tuple containing the name and parameter
Example: >>> for name, param in self.named_parameters(): >>> if name in ['bias']: >>> print(param.size())
def named_parameters(self, memo=None, prefix=''): """Returns an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself Yields: (string, Parameter): Tuple containing the name and parameter Example: >>> for name, param in self.named_parameters(): >>> if name in ['bias']: >>> print(param.size()) """ if memo is None: memo = set() for name, p in self._parameters.items(): if p is not None and p not in memo: memo.add(p) yield prefix + ('.' if prefix else '') + name, p for mname, module in self.named_children(): submodule_prefix = prefix + ('.' if prefix else '') + mname for name, p in module.named_parameters(memo, submodule_prefix): yield name, p
def parameters(
self)
Returns an iterator over module parameters.
This is typically passed to an optimizer.
Yields: Parameter: module parameter
Example:
>>> for param in model.parameters():
>>> print(type(param.data), param.size())
def parameters(self): """Returns an iterator over module parameters. This is typically passed to an optimizer. Yields: Parameter: module parameter Example: >>> for param in model.parameters(): >>> print(type(param.data), param.size()) <class 'torch.FloatTensor'> (20L,) <class 'torch.FloatTensor'> (20L, 1L, 5L, 5L) """ for name, param in self.named_parameters(): yield param
def register_backward_hook(
self, hook)
Registers a backward hook on the module.
The hook will be called every time the gradients with respect to module inputs are computed. The hook should have the following signature::
hook(module, grad_input, grad_output) -> Tensor or None
The :attr:grad_input
and :attr:grad_output
may be tuples if the
module has multiple inputs or outputs. The hook should not modify its
arguments, but it can optionally return a new gradient with respect to
input that will be used in place of :attr:grad_input
in subsequent
computations.
Returns:
:class:torch.utils.hooks.RemovableHandle
:
a handle that can be used to remove the added hook by calling
handle.remove()
def register_backward_hook(self, hook): """Registers a backward hook on the module. The hook will be called every time the gradients with respect to module inputs are computed. The hook should have the following signature:: hook(module, grad_input, grad_output) -> Tensor or None The :attr:`grad_input` and :attr:`grad_output` may be tuples if the module has multiple inputs or outputs. The hook should not modify its arguments, but it can optionally return a new gradient with respect to input that will be used in place of :attr:`grad_input` in subsequent computations. Returns: :class:`torch.utils.hooks.RemovableHandle`: a handle that can be used to remove the added hook by calling ``handle.remove()`` """ handle = hooks.RemovableHandle(self._backward_hooks) self._backward_hooks[handle.id] = hook return handle
def register_buffer(
self, name, tensor)
Adds a persistent buffer to the module.
This is typically used to register a buffer that should not to be
considered a model parameter. For example, BatchNorm's running_mean
is not a parameter, but is part of the persistent state.
Buffers can be accessed as attributes using given names.
Args: name (string): name of the buffer. The buffer can be accessed from this module using the given name tensor (Tensor): buffer to be registered.
Example: >>> self.register_buffer('running_mean', torch.zeros(num_features))
def register_buffer(self, name, tensor): """Adds a persistent buffer to the module. This is typically used to register a buffer that should not to be considered a model parameter. For example, BatchNorm's ``running_mean`` is not a parameter, but is part of the persistent state. Buffers can be accessed as attributes using given names. Args: name (string): name of the buffer. The buffer can be accessed from this module using the given name tensor (Tensor): buffer to be registered. Example: >>> self.register_buffer('running_mean', torch.zeros(num_features)) """ if hasattr(self, name) and name not in self._buffers: raise KeyError("attribute '{}' already exists".format(name)) self._buffers[name] = tensor
def register_forward_hook(
self, hook)
Registers a forward hook on the module.
The hook will be called every time after :func:forward
has computed an output.
It should have the following signature::
hook(module, input, output) -> None
The hook should not modify the input or output.
Returns:
:class:torch.utils.hooks.RemovableHandle
:
a handle that can be used to remove the added hook by calling
handle.remove()
def register_forward_hook(self, hook): r"""Registers a forward hook on the module. The hook will be called every time after :func:`forward` has computed an output. It should have the following signature:: hook(module, input, output) -> None The hook should not modify the input or output. Returns: :class:`torch.utils.hooks.RemovableHandle`: a handle that can be used to remove the added hook by calling ``handle.remove()`` """ handle = hooks.RemovableHandle(self._forward_hooks) self._forward_hooks[handle.id] = hook return handle
def register_forward_pre_hook(
self, hook)
Registers a forward pre-hook on the module.
The hook will be called every time before :func:forward
is invoked.
It should have the following signature::
hook(module, input) -> None
The hook should not modify the input.
Returns:
:class:torch.utils.hooks.RemovableHandle
:
a handle that can be used to remove the added hook by calling
handle.remove()
def register_forward_pre_hook(self, hook): """Registers a forward pre-hook on the module. The hook will be called every time before :func:`forward` is invoked. It should have the following signature:: hook(module, input) -> None The hook should not modify the input. Returns: :class:`torch.utils.hooks.RemovableHandle`: a handle that can be used to remove the added hook by calling ``handle.remove()`` """ handle = hooks.RemovableHandle(self._forward_pre_hooks) self._forward_pre_hooks[handle.id] = hook return handle
def register_parameter(
self, name, param)
Adds a parameter to the module.
The parameter can be accessed as an attribute using given name.
Args: name (string): name of the parameter. The parameter can be accessed from this module using the given name parameter (Parameter): parameter to be added to the module.
def register_parameter(self, name, param): """Adds a parameter to the module. The parameter can be accessed as an attribute using given name. Args: name (string): name of the parameter. The parameter can be accessed from this module using the given name parameter (Parameter): parameter to be added to the module. """ if '_parameters' not in self.__dict__: raise AttributeError( "cannot assign parameter before Module.__init__() call") if hasattr(self, name) and name not in self._parameters: raise KeyError("attribute '{}' already exists".format(name)) if param is None: self._parameters[name] = None elif not isinstance(param, Parameter): raise TypeError("cannot assign '{}' object to parameter '{}' " "(torch.nn.Parameter or None required)" .format(torch.typename(param), name)) elif param.grad_fn: raise ValueError( "Cannot assign non-leaf Variable to parameter '{0}'. Model " "parameters must be created explicitly. To express '{0}' " "as a function of another variable, compute the value in " "the forward() method.".format(name)) else: self._parameters[name] = param
def state_dict(
self, destination=None, prefix='', keep_vars=False)
Returns a dictionary containing a whole state of the module.
Both parameters and persistent buffers (e.g. running averages) are included. Keys are corresponding parameter and buffer names.
When keep_vars is True
, it returns a Variable for each parameter
(rather than a Tensor).
Args:
destination (dict, optional):
if not None, the return dictionary is stored into destination.
Default: None
prefix (string, optional): Adds a prefix to the key (name) of every
parameter and buffer in the result dictionary. Default: ''
keep_vars (bool, optional): if True
, returns a Variable for each
parameter. If False
, returns a Tensor for each parameter.
Default: False
Returns: dict: a dictionary containing a whole state of the module
Example: >>> module.state_dict().keys() ['bias', 'weight']
def state_dict(self, destination=None, prefix='', keep_vars=False): """Returns a dictionary containing a whole state of the module. Both parameters and persistent buffers (e.g. running averages) are included. Keys are corresponding parameter and buffer names. When keep_vars is ``True``, it returns a Variable for each parameter (rather than a Tensor). Args: destination (dict, optional): if not None, the return dictionary is stored into destination. Default: None prefix (string, optional): Adds a prefix to the key (name) of every parameter and buffer in the result dictionary. Default: '' keep_vars (bool, optional): if ``True``, returns a Variable for each parameter. If ``False``, returns a Tensor for each parameter. Default: ``False`` Returns: dict: a dictionary containing a whole state of the module Example: >>> module.state_dict().keys() ['bias', 'weight'] """ if destination is None: destination = OrderedDict() for name, param in self._parameters.items(): if param is not None: destination[prefix + name] = param if keep_vars else param.data for name, buf in self._buffers.items(): if buf is not None: destination[prefix + name] = buf for name, module in self._modules.items(): if module is not None: module.state_dict(destination, prefix + name + '.', keep_vars=keep_vars) return destination
def train(
self, mode=True)
Sets the module in training mode.
This has any effect only on modules such as Dropout or BatchNorm.
Returns: Module: self
def train(self, mode=True): """Sets the module in training mode. This has any effect only on modules such as Dropout or BatchNorm. Returns: Module: self """ self.training = mode for module in self.children(): module.train(mode) return self
def type(
self, dst_type)
Casts all parameters and buffers to dst_type.
Arguments: dst_type (type or string): the desired type
Returns: Module: self
def type(self, dst_type): """Casts all parameters and buffers to dst_type. Arguments: dst_type (type or string): the desired type Returns: Module: self """ return self._apply(lambda t: t.type(dst_type))
def zero_grad(
self)
Sets gradients of all model parameters to zero.
def zero_grad(self): """Sets gradients of all model parameters to zero.""" for p in self.parameters(): if p.grad is not None: if p.grad.volatile: p.grad.data.zero_() else: data = p.grad.data p.grad = Variable(data.new().resize_as_(data).zero_())
Instance variables
var cl
var class_num
var conv
var dc
var fc1
var input_dim
var input_height
var input_width
var output_dim
class generator
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn import torch.nn.functional as F class Model(nn.Module): def __init__(self): super(Model, self).__init__() self.conv1 = nn.Conv2d(1, 20, 5) self.conv2 = nn.Conv2d(20, 20, 5) def forward(self, x): x = F.relu(self.conv1(x)) return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will have their parameters converted too when you call .cuda(), etc.
class generator(nn.Module): # Network Architecture is exactly same as in infoGAN (https://arxiv.org/abs/1606.03657) # Architecture : FC1024_BR-FC7x7x128_BR-(64)4dc2s_BR-(1)4dc2s_S def __init__(self, height, width, channels): super(generator, self).__init__() self.input_height = height self.input_width = width self.input_dim = 62 + 10 self.output_dim = channels self.fc = nn.Sequential( nn.Linear(self.input_dim, 1024), nn.BatchNorm1d(1024), nn.ReLU(), nn.Linear(1024, 128 * (self.input_height // 4) * (self.input_width // 4)), nn.BatchNorm1d(128 * (self.input_height // 4) * (self.input_width // 4)), nn.ReLU(), ) self.deconv = nn.Sequential( nn.ConvTranspose2d(128, 64, 4, 2, 1), nn.BatchNorm2d(64), nn.ReLU(), nn.ConvTranspose2d(64, self.output_dim, 4, 2, 1), nn.Sigmoid(), ) initialize_weights(self) def forward(self, input, label): x = torch.cat([input, label], 1) x = self.fc(x) x = x.view(-1, 128, (self.input_height // 4), (self.input_width // 4)) x = self.deconv(x) return x
Ancestors (in MRO)
- generator
- torch.nn.modules.module.Module
- builtins.object
Class variables
var dump_patches
Static methods
def __init__(
self, height, width, channels)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, height, width, channels): super(generator, self).__init__() self.input_height = height self.input_width = width self.input_dim = 62 + 10 self.output_dim = channels self.fc = nn.Sequential( nn.Linear(self.input_dim, 1024), nn.BatchNorm1d(1024), nn.ReLU(), nn.Linear(1024, 128 * (self.input_height // 4) * (self.input_width // 4)), nn.BatchNorm1d(128 * (self.input_height // 4) * (self.input_width // 4)), nn.ReLU(), ) self.deconv = nn.Sequential( nn.ConvTranspose2d(128, 64, 4, 2, 1), nn.BatchNorm2d(64), nn.ReLU(), nn.ConvTranspose2d(64, self.output_dim, 4, 2, 1), nn.Sigmoid(), ) initialize_weights(self)
def add_module(
self, name, module)
Adds a child module to the current module.
The module can be accessed as an attribute using the given name.
Args: name (string): name of the child module. The child module can be accessed from this module using the given name parameter (Module): child module to be added to the module.
def add_module(self, name, module): """Adds a child module to the current module. The module can be accessed as an attribute using the given name. Args: name (string): name of the child module. The child module can be accessed from this module using the given name parameter (Module): child module to be added to the module. """ if not isinstance(module, Module) and module is not None: raise TypeError("{} is not a Module subclass".format( torch.typename(module))) if hasattr(self, name) and name not in self._modules: raise KeyError("attribute '{}' already exists".format(name)) self._modules[name] = module
def apply(
self, fn)
Applies fn
recursively to every submodule (as returned by .children()
)
as well as self. Typical use includes initializing the parameters of a model
(see also :ref:torch-nn-init
).
Args:
fn (:class:Module
-> None): function to be applied to each submodule
Returns: Module: self
Example: >>> def init_weights(m): >>> print(m) >>> if type(m) == nn.Linear: >>> m.weight.data.fill_(1.0) >>> print(m.weight) >>> >>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2)) >>> net.apply(init_weights) Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) )
def apply(self, fn): """Applies ``fn`` recursively to every submodule (as returned by ``.children()``) as well as self. Typical use includes initializing the parameters of a model (see also :ref:`torch-nn-init`). Args: fn (:class:`Module` -> None): function to be applied to each submodule Returns: Module: self Example: >>> def init_weights(m): >>> print(m) >>> if type(m) == nn.Linear: >>> m.weight.data.fill_(1.0) >>> print(m.weight) >>> >>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2)) >>> net.apply(init_weights) Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Linear (2 -> 2) Parameter containing: 1 1 1 1 [torch.FloatTensor of size 2x2] Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) ) """ for module in self.children(): module.apply(fn) fn(self) return self
def children(
self)
Returns an iterator over immediate children modules.
Yields: Module: a child module
def children(self): """Returns an iterator over immediate children modules. Yields: Module: a child module """ for name, module in self.named_children(): yield module
def cpu(
self)
Moves all model parameters and buffers to the CPU.
Returns: Module: self
def cpu(self): """Moves all model parameters and buffers to the CPU. Returns: Module: self """ return self._apply(lambda t: t.cpu())
def cuda(
self, device=None)
Moves all model parameters and buffers to the GPU.
This also makes associated parameters and buffers different objects. So it should be called before constructing optimizer if the module will live on GPU while being optimized.
Arguments: device (int, optional): if specified, all parameters will be copied to that device
Returns: Module: self
def cuda(self, device=None): """Moves all model parameters and buffers to the GPU. This also makes associated parameters and buffers different objects. So it should be called before constructing optimizer if the module will live on GPU while being optimized. Arguments: device (int, optional): if specified, all parameters will be copied to that device Returns: Module: self """ return self._apply(lambda t: t.cuda(device))
def double(
self)
Casts all parameters and buffers to double datatype.
Returns: Module: self
def double(self): """Casts all parameters and buffers to double datatype. Returns: Module: self """ return self._apply(lambda t: t.double())
def eval(
self)
Sets the module in evaluation mode.
This has any effect only on modules such as Dropout or BatchNorm.
def eval(self): """Sets the module in evaluation mode. This has any effect only on modules such as Dropout or BatchNorm. """ return self.train(False)
def float(
self)
Casts all parameters and buffers to float datatype.
Returns: Module: self
def float(self): """Casts all parameters and buffers to float datatype. Returns: Module: self """ return self._apply(lambda t: t.float())
def forward(
self, input, label)
Defines the computation performed at every call.
Should be overriden by all subclasses.
.. note::
Although the recipe for forward pass needs to be defined within
this function, one should call the :class:Module
instance afterwards
instead of this since the former takes care of running the
registered hooks while the latter silently ignores them.
def forward(self, input, label): x = torch.cat([input, label], 1) x = self.fc(x) x = x.view(-1, 128, (self.input_height // 4), (self.input_width // 4)) x = self.deconv(x) return x
def half(
self)
Casts all parameters and buffers to half datatype.
Returns: Module: self
def half(self): """Casts all parameters and buffers to half datatype. Returns: Module: self """ return self._apply(lambda t: t.half())
def load_state_dict(
self, state_dict, strict=True)
Copies parameters and buffers from :attr:state_dict
into
this module and its descendants. If :attr:strict
is True
then
the keys of :attr:state_dict
must exactly match the keys returned
by this module's :func:state_dict()
function.
Arguments:
state_dict (dict): A dict containing parameters and
persistent buffers.
strict (bool): Strictly enforce that the keys in :attr:state_dict
match the keys returned by this module's :func:
state_dict()`
function.
def load_state_dict(self, state_dict, strict=True): """Copies parameters and buffers from :attr:`state_dict` into this module and its descendants. If :attr:`strict` is ``True`` then the keys of :attr:`state_dict` must exactly match the keys returned by this module's :func:`state_dict()` function. Arguments: state_dict (dict): A dict containing parameters and persistent buffers. strict (bool): Strictly enforce that the keys in :attr:`state_dict` match the keys returned by this module's `:func:`state_dict()` function. """ own_state = self.state_dict() for name, param in state_dict.items(): if name in own_state: if isinstance(param, Parameter): # backwards compatibility for serialized parameters param = param.data try: own_state[name].copy_(param) except Exception: raise RuntimeError('While copying the parameter named {}, ' 'whose dimensions in the model are {} and ' 'whose dimensions in the checkpoint are {}.' .format(name, own_state[name].size(), param.size())) elif strict: raise KeyError('unexpected key "{}" in state_dict' .format(name)) if strict: missing = set(own_state.keys()) - set(state_dict.keys()) if len(missing) > 0: raise KeyError('missing keys in state_dict: "{}"'.format(missing))
def modules(
self)
Returns an iterator over all modules in the network.
Yields: Module: a module in the network
Note:
Duplicate modules are returned only once. In the following
example, l
will be returned only once.
>>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.modules()): >>> print(idx, '->', m) 0 -> Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) ) 1 -> Linear (2 -> 2)
def modules(self): """Returns an iterator over all modules in the network. Yields: Module: a module in the network Note: Duplicate modules are returned only once. In the following example, ``l`` will be returned only once. >>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.modules()): >>> print(idx, '->', m) 0 -> Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) ) 1 -> Linear (2 -> 2) """ for name, module in self.named_modules(): yield module
def named_children(
self)
Returns an iterator over immediate children modules, yielding both the name of the module as well as the module itself.
Yields: (string, Module): Tuple containing a name and child module
Example: >>> for name, module in model.named_children(): >>> if name in ['conv4', 'conv5']: >>> print(module)
def named_children(self): """Returns an iterator over immediate children modules, yielding both the name of the module as well as the module itself. Yields: (string, Module): Tuple containing a name and child module Example: >>> for name, module in model.named_children(): >>> if name in ['conv4', 'conv5']: >>> print(module) """ memo = set() for name, module in self._modules.items(): if module is not None and module not in memo: memo.add(module) yield name, module
def named_modules(
self, memo=None, prefix='')
Returns an iterator over all modules in the network, yielding both the name of the module as well as the module itself.
Yields: (string, Module): Tuple of name and module
Note:
Duplicate modules are returned only once. In the following
example, l
will be returned only once.
>>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.named_modules()): >>> print(idx, '->', m) 0 -> ('', Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) )) 1 -> ('0', Linear (2 -> 2))
def named_modules(self, memo=None, prefix=''): """Returns an iterator over all modules in the network, yielding both the name of the module as well as the module itself. Yields: (string, Module): Tuple of name and module Note: Duplicate modules are returned only once. In the following example, ``l`` will be returned only once. >>> l = nn.Linear(2, 2) >>> net = nn.Sequential(l, l) >>> for idx, m in enumerate(net.named_modules()): >>> print(idx, '->', m) 0 -> ('', Sequential ( (0): Linear (2 -> 2) (1): Linear (2 -> 2) )) 1 -> ('0', Linear (2 -> 2)) """ if memo is None: memo = set() if self not in memo: memo.add(self) yield prefix, self for name, module in self._modules.items(): if module is None: continue submodule_prefix = prefix + ('.' if prefix else '') + name for m in module.named_modules(memo, submodule_prefix): yield m
def named_parameters(
self, memo=None, prefix='')
Returns an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself
Yields: (string, Parameter): Tuple containing the name and parameter
Example: >>> for name, param in self.named_parameters(): >>> if name in ['bias']: >>> print(param.size())
def named_parameters(self, memo=None, prefix=''): """Returns an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself Yields: (string, Parameter): Tuple containing the name and parameter Example: >>> for name, param in self.named_parameters(): >>> if name in ['bias']: >>> print(param.size()) """ if memo is None: memo = set() for name, p in self._parameters.items(): if p is not None and p not in memo: memo.add(p) yield prefix + ('.' if prefix else '') + name, p for mname, module in self.named_children(): submodule_prefix = prefix + ('.' if prefix else '') + mname for name, p in module.named_parameters(memo, submodule_prefix): yield name, p
def parameters(
self)
Returns an iterator over module parameters.
This is typically passed to an optimizer.
Yields: Parameter: module parameter
Example:
>>> for param in model.parameters():
>>> print(type(param.data), param.size())
def parameters(self): """Returns an iterator over module parameters. This is typically passed to an optimizer. Yields: Parameter: module parameter Example: >>> for param in model.parameters(): >>> print(type(param.data), param.size()) <class 'torch.FloatTensor'> (20L,) <class 'torch.FloatTensor'> (20L, 1L, 5L, 5L) """ for name, param in self.named_parameters(): yield param
def register_backward_hook(
self, hook)
Registers a backward hook on the module.
The hook will be called every time the gradients with respect to module inputs are computed. The hook should have the following signature::
hook(module, grad_input, grad_output) -> Tensor or None
The :attr:grad_input
and :attr:grad_output
may be tuples if the
module has multiple inputs or outputs. The hook should not modify its
arguments, but it can optionally return a new gradient with respect to
input that will be used in place of :attr:grad_input
in subsequent
computations.
Returns:
:class:torch.utils.hooks.RemovableHandle
:
a handle that can be used to remove the added hook by calling
handle.remove()
def register_backward_hook(self, hook): """Registers a backward hook on the module. The hook will be called every time the gradients with respect to module inputs are computed. The hook should have the following signature:: hook(module, grad_input, grad_output) -> Tensor or None The :attr:`grad_input` and :attr:`grad_output` may be tuples if the module has multiple inputs or outputs. The hook should not modify its arguments, but it can optionally return a new gradient with respect to input that will be used in place of :attr:`grad_input` in subsequent computations. Returns: :class:`torch.utils.hooks.RemovableHandle`: a handle that can be used to remove the added hook by calling ``handle.remove()`` """ handle = hooks.RemovableHandle(self._backward_hooks) self._backward_hooks[handle.id] = hook return handle
def register_buffer(
self, name, tensor)
Adds a persistent buffer to the module.
This is typically used to register a buffer that should not to be
considered a model parameter. For example, BatchNorm's running_mean
is not a parameter, but is part of the persistent state.
Buffers can be accessed as attributes using given names.
Args: name (string): name of the buffer. The buffer can be accessed from this module using the given name tensor (Tensor): buffer to be registered.
Example: >>> self.register_buffer('running_mean', torch.zeros(num_features))
def register_buffer(self, name, tensor): """Adds a persistent buffer to the module. This is typically used to register a buffer that should not to be considered a model parameter. For example, BatchNorm's ``running_mean`` is not a parameter, but is part of the persistent state. Buffers can be accessed as attributes using given names. Args: name (string): name of the buffer. The buffer can be accessed from this module using the given name tensor (Tensor): buffer to be registered. Example: >>> self.register_buffer('running_mean', torch.zeros(num_features)) """ if hasattr(self, name) and name not in self._buffers: raise KeyError("attribute '{}' already exists".format(name)) self._buffers[name] = tensor
def register_forward_hook(
self, hook)
Registers a forward hook on the module.
The hook will be called every time after :func:forward
has computed an output.
It should have the following signature::
hook(module, input, output) -> None
The hook should not modify the input or output.
Returns:
:class:torch.utils.hooks.RemovableHandle
:
a handle that can be used to remove the added hook by calling
handle.remove()
def register_forward_hook(self, hook): r"""Registers a forward hook on the module. The hook will be called every time after :func:`forward` has computed an output. It should have the following signature:: hook(module, input, output) -> None The hook should not modify the input or output. Returns: :class:`torch.utils.hooks.RemovableHandle`: a handle that can be used to remove the added hook by calling ``handle.remove()`` """ handle = hooks.RemovableHandle(self._forward_hooks) self._forward_hooks[handle.id] = hook return handle
def register_forward_pre_hook(
self, hook)
Registers a forward pre-hook on the module.
The hook will be called every time before :func:forward
is invoked.
It should have the following signature::
hook(module, input) -> None
The hook should not modify the input.
Returns:
:class:torch.utils.hooks.RemovableHandle
:
a handle that can be used to remove the added hook by calling
handle.remove()
def register_forward_pre_hook(self, hook): """Registers a forward pre-hook on the module. The hook will be called every time before :func:`forward` is invoked. It should have the following signature:: hook(module, input) -> None The hook should not modify the input. Returns: :class:`torch.utils.hooks.RemovableHandle`: a handle that can be used to remove the added hook by calling ``handle.remove()`` """ handle = hooks.RemovableHandle(self._forward_pre_hooks) self._forward_pre_hooks[handle.id] = hook return handle
def register_parameter(
self, name, param)
Adds a parameter to the module.
The parameter can be accessed as an attribute using given name.
Args: name (string): name of the parameter. The parameter can be accessed from this module using the given name parameter (Parameter): parameter to be added to the module.
def register_parameter(self, name, param): """Adds a parameter to the module. The parameter can be accessed as an attribute using given name. Args: name (string): name of the parameter. The parameter can be accessed from this module using the given name parameter (Parameter): parameter to be added to the module. """ if '_parameters' not in self.__dict__: raise AttributeError( "cannot assign parameter before Module.__init__() call") if hasattr(self, name) and name not in self._parameters: raise KeyError("attribute '{}' already exists".format(name)) if param is None: self._parameters[name] = None elif not isinstance(param, Parameter): raise TypeError("cannot assign '{}' object to parameter '{}' " "(torch.nn.Parameter or None required)" .format(torch.typename(param), name)) elif param.grad_fn: raise ValueError( "Cannot assign non-leaf Variable to parameter '{0}'. Model " "parameters must be created explicitly. To express '{0}' " "as a function of another variable, compute the value in " "the forward() method.".format(name)) else: self._parameters[name] = param
def state_dict(
self, destination=None, prefix='', keep_vars=False)
Returns a dictionary containing a whole state of the module.
Both parameters and persistent buffers (e.g. running averages) are included. Keys are corresponding parameter and buffer names.
When keep_vars is True
, it returns a Variable for each parameter
(rather than a Tensor).
Args:
destination (dict, optional):
if not None, the return dictionary is stored into destination.
Default: None
prefix (string, optional): Adds a prefix to the key (name) of every
parameter and buffer in the result dictionary. Default: ''
keep_vars (bool, optional): if True
, returns a Variable for each
parameter. If False
, returns a Tensor for each parameter.
Default: False
Returns: dict: a dictionary containing a whole state of the module
Example: >>> module.state_dict().keys() ['bias', 'weight']
def state_dict(self, destination=None, prefix='', keep_vars=False): """Returns a dictionary containing a whole state of the module. Both parameters and persistent buffers (e.g. running averages) are included. Keys are corresponding parameter and buffer names. When keep_vars is ``True``, it returns a Variable for each parameter (rather than a Tensor). Args: destination (dict, optional): if not None, the return dictionary is stored into destination. Default: None prefix (string, optional): Adds a prefix to the key (name) of every parameter and buffer in the result dictionary. Default: '' keep_vars (bool, optional): if ``True``, returns a Variable for each parameter. If ``False``, returns a Tensor for each parameter. Default: ``False`` Returns: dict: a dictionary containing a whole state of the module Example: >>> module.state_dict().keys() ['bias', 'weight'] """ if destination is None: destination = OrderedDict() for name, param in self._parameters.items(): if param is not None: destination[prefix + name] = param if keep_vars else param.data for name, buf in self._buffers.items(): if buf is not None: destination[prefix + name] = buf for name, module in self._modules.items(): if module is not None: module.state_dict(destination, prefix + name + '.', keep_vars=keep_vars) return destination
def train(
self, mode=True)
Sets the module in training mode.
This has any effect only on modules such as Dropout or BatchNorm.
Returns: Module: self
def train(self, mode=True): """Sets the module in training mode. This has any effect only on modules such as Dropout or BatchNorm. Returns: Module: self """ self.training = mode for module in self.children(): module.train(mode) return self
def type(
self, dst_type)
Casts all parameters and buffers to dst_type.
Arguments: dst_type (type or string): the desired type
Returns: Module: self
def type(self, dst_type): """Casts all parameters and buffers to dst_type. Arguments: dst_type (type or string): the desired type Returns: Module: self """ return self._apply(lambda t: t.type(dst_type))
def zero_grad(
self)
Sets gradients of all model parameters to zero.
def zero_grad(self): """Sets gradients of all model parameters to zero.""" for p in self.parameters(): if p.grad is not None: if p.grad.volatile: p.grad.data.zero_() else: data = p.grad.data p.grad = Variable(data.new().resize_as_(data).zero_())
Instance variables
var deconv
var fc
var input_dim
var input_height
var input_width
var output_dim