Skip to content

Instantly share code, notes, and snippets.

@yvan
Last active September 9, 2021 05:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yvan/68de45837dd6d98ef2b80e7374f613ed to your computer and use it in GitHub Desktop.
Save yvan/68de45837dd6d98ef2b80e7374f613ed to your computer and use it in GitHub Desktop.
# parameters for various parts of the model
n_epochs = 125
lr = 0.0002
label_smooth = 0.9
pokemon_models = os.path.join('/scratch', 'yns207', 'pokemon_models')
noise_dim = 100
d_filter_depth_in = 3
# create our generator network
# this network will take in
# random noise and output a
# monster.
class Generator(nn.Module):
# define the model it has 5 transpose
# convolutions and uses relu activations
# it has a TanH activation on the last
# layer
def __init__(self):
super(Generator, self).__init__()
self.main = nn.Sequential(
nn.ConvTranspose2d(noise_dim,
512,
kernel_size=4,
stride=1,
padding=0,
bias=False),
nn.BatchNorm2d(512),
nn.ReLU(),
nn.ConvTranspose2d(512,
256,
kernel_size=4,
stride=2,
padding=1,
bias=False),
nn.BatchNorm2d(256),
nn.ReLU(),
nn.ConvTranspose2d(256,
128,
kernel_size=4,
stride=2,
padding=1,
bias=False),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.ConvTranspose2d(128,
64,
kernel_size=4,
stride=2,
padding=1,
bias=False),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.ConvTranspose2d(64,
d_filter_depth_in,
kernel_size=4,
stride=2,
padding=1,
bias=False),
nn.Tanh()
)
# define how to propagate
# through this network
def forward(self, inputs):
output = self.main(inputs)
return output
# create the model that will evaluate
# the generated monsters
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.main = nn.Sequential(
nn.Conv2d(in_channels=d_filter_depth_in,
out_channels=64,
kernel_size=4,
stride=2,
padding=1,
bias=False),
nn.LeakyReLU(0.2),
nn.Conv2d(in_channels=64,
out_channels=128,
kernel_size=3,
stride=2,
padding=1,
bias=False),
nn.BatchNorm2d(128),
nn.LeakyReLU(0.2),
nn.Conv2d(in_channels=128,
out_channels=256,
kernel_size=4,
stride=2,
padding=1,
bias=False),
nn.BatchNorm2d(256),
nn.LeakyReLU(0.2),
nn.Conv2d(in_channels=256,
out_channels=512,
kernel_size=4,
stride=2,
padding=1,
bias=False),
nn.BatchNorm2d(512),
nn.LeakyReLU(0.2),
nn.Conv2d(in_channels=512,
out_channels=1,
kernel_size=4,
stride=1,
padding=0,
bias=False),
nn.Sigmoid()
)
# define forward porpagation
# through that model
def forward(self, inputs):
output = self.main(inputs)
return output.view(-1, 1).squeeze(1)
# utility functions
# this iniitilaizes the parameters
# to good rnadom values, you can
# do more research on your own
def weights_init(m):
classname = m.__class__.__name__
if classname.find('Conv2d') != -1:
m.weight.data.normal_(0.0, 0.02)
elif classname.find('BatchNorm2d') != -1:
m.weight.data.normal_(1.0,0.02)
m.bias.data.fill_(0)
# this converts any pytorch tensor,
# an n-dimensional array, to a
# variable and puts it on a gpu if
# a one is available
def to_variable(x):
'''
convert a tensor to a variable
with gradient tracking
'''
if torch.cuda.is_available():
x = x .cuda()
return Variable(x)
# we're going normalize our images
# to make training the generator easier
# this de-normalizes the images coming out
# of the generator so they look intelligble
def denorm_monsters(x):
renorm = (x*0.5)+0.5
return renorm.clamp(0,1)
# this plots a bunch of pokemon
# at the end of each trainign round so
# we can get a sense for how our network
# is doing.
def plot_figure(fixed_noise):
plt.figure()
fixed_imgs = generator(fixed_noise)
result = denorm_monsters(fixed_imgs.cpu().data)
result = make_grid(result)
result = transforms.Compose([transforms.ToPILImage()])(result)
plt.imshow(result)
plt.axis('off')
plt.show()
# create a generator and
# initialize its weights
generator = Generator()
generator = generator.apply(weights_init)
# create a discriminator and
# initialize its weights
discriminator = Discriminator()
discriminator = discriminator.apply(weights_init)
# create a loss object and optimizers
loss_func = nn.BCELoss()
d_optimizer = optim.Adam(discriminator.parameters(), lr=lr, betas=(0.5, 0.99))
g_optimizer = optim.Adam(generator.parameters(), lr=lr, betas=(0.5, 0.99))
# it a gpu is available, move all
# the models and the loss function
# to the gpu (more performant)
if torch.cuda.is_available():
generator.cuda()
discriminator.cuda()
loss_func.cuda()
# create a fixed_noise variable so we can evaluate results
# consistently. if we don't do this we'll get different monsters
# everytime we re-run and it will be hard to eavluate our generator
fixed_noise = to_variable(torch.randn(batch_size, noise_dim, 1, 1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment