In [35]:
!pip3 uninstall -y torch;
!pip3 install torchvision;
!pip3 install matplotlib;
In [5]:
!mkdir quick_draw; !ls quick_draw;
from google.colab import files
uploaded = files.upload()
for fn in uploaded.keys():
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
In [0]:
!cd ..;
import PIL
import math
import numpy as np
import torch
from torch import nn
from torch import optim
from torch import Tensor
import torch.nn.functional as F
from collections import namedtuple
from matplotlib import pyplot as plt
In [0]:
## DATA PREPROCESSING FUNCTIONS
def max_size(data):
"""larger sequence length in the data set"""
sizes = [len(seq) for seq in data]
return max(sizes)
def purify(strokes):
"""removes to small or too long sequences + removes large gaps"""
data = []
for seq in strokes:
if len(seq[:,0]) <= hp.max_seq_length and len(seq[:,0])>10:
seq = np.minimum(seq, 1000)
seq = np.maximum(seq, -1000)
seq = np.array(seq, dtype=np.float32)
data.append(seq)
return data
def calculate_normalizing_scale_factor(strokes):
"""Calculate the normalizing factor explained in appendix of sketch-rnn."""
data = []
for i in range(len(strokes)):
for j in range(len(strokes[i])):
data.append(strokes[i][j, 0])
data.append(strokes[i][j, 1])
data = np.array(data)
return np.std(data)
def normalize(strokes):
"""Normalize entire dataset (delta_x, delta_y) by the scaling factor."""
data = []
scale_factor = calculate_normalizing_scale_factor(strokes)
for seq in strokes:
seq[:, 0:2] /= scale_factor
data.append(seq)
return data
def make_batch(batch_size):
batch_idx = np.random.choice(len(data),batch_size)
batch_sequences = [data[idx] for idx in batch_idx]
strokes = []
lengths = []
indice = 0
for seq in batch_sequences:
len_seq = len(seq[:,0])
new_seq = np.zeros((Nmax,5))
new_seq[:len_seq,:2] = seq[:,:2]
new_seq[:len_seq-1,2] = 1-seq[:-1,2]
new_seq[:len_seq,3] = seq[:,2]
new_seq[(len_seq-1):,4] = 1
new_seq[len_seq-1,2:4] = 0
lengths.append(len(seq[:,0]))
strokes.append(new_seq)
indice += 1
if use_cuda:
batch = torch.from_numpy(np.stack(strokes,1)).cuda().float()
else:
batch = torch.from_numpy(np.stack(strokes,1)).float()
return batch, lengths
################################ adaptive lr
def lr_decay(optimizer):
"""Decay learning rate by a factor of lr_decay"""
for param_group in optimizer.param_groups:
if param_group['lr']>hp.min_lr:
param_group['lr'] *= hp.lr_decay
return optimizer
In [0]:
class CPUForgetMult(torch.nn.Module):
def __init__(self):
super(CPUForgetMult, self).__init__()
def forward(self, f, x, hidden_init=None):
result = []
forgets = f.split(1, dim=0)
prev_h = hidden_init
for i, h in enumerate((f * x).split(1, dim=0)):
if prev_h is not None: h = h + (1 - forgets[i]) * prev_h
h = h.view(h.size()[1:])
result.append(h)
prev_h = h
return torch.stack(result)
class ForgetMult(torch.nn.Module):
r"""ForgetMult computes a simple recurrent equation:
h_t = f_t * x_t + (1 - f_t) * h_{t-1}
This equation is equivalent to dynamic weighted averaging.
Inputs: X, hidden
- X (seq_len, batch, input_size): tensor containing the features of the input sequence.
- F (seq_len, batch, input_size): tensor containing the forget gate values, assumed in range [0, 1].
- hidden_init (batch, input_size): tensor containing the initial hidden state for the recurrence (h_{t-1}).
- use_cuda: If True, use the fast element-wise CUDA kernel for recurrence. If False, uses naive for loop. Default: True.
"""
def __init__(self):
super(ForgetMult, self).__init__()
def forward(self, f, x, hidden_init=None, use_cuda=True):
#use_cuda = False
# Avoiding 'RuntimeError: expected a Variable argument, but got NoneType' when hidden_init is None
if hidden_init is None:
return CPUForgetMult()(f, x)
return CPUForgetMult()(f, x, hidden_init)
In [0]:
class QRNNLayer(nn.Module):
r"""Applies a single layer Quasi-Recurrent Neural Network (QRNN) to an input sequence.
Args:
input_size: The number of expected features in the input x.
hidden_size: The number of features in the hidden state h. If not specified, the input size is used.
save_prev_x: Whether to store previous inputs for use in future convolutional windows (i.e. for a continuing sequence such as in language modeling). If true, you must call reset to remove cached previous values of x. Default: False.
window: Defines the size of the convolutional window (how many previous tokens to look when computing the QRNN values). Supports 1 and 2. Default: 1.
zoneout: Whether to apply zoneout (i.e. failing to update elements in the hidden state) to the hidden state updates. Default: 0.
output_gate: If True, performs QRNN-fo (applying an output gate to the output). If False, performs QRNN-f. Default: True.
use_cuda: If True, uses fast custom CUDA kernel. If False, uses naive for loop. Default: True.
Inputs: X, hidden
- X (seq_len, batch, input_size): tensor containing the features of the input sequence.
- hidden (batch, hidden_size): tensor containing the initial hidden state for the QRNN.
Outputs: output, h_n
- output (seq_len, batch, hidden_size): tensor containing the output of the QRNN for each timestep.
- h_n (batch, hidden_size): tensor containing the hidden state for t=seq_len
"""
def __init__(self, input_size, hidden_size=None, save_prev_x=False, zoneout=0, window=2, output_gate=True, use_cuda=True):
super(QRNNLayer, self).__init__()
#assert window in [1, 2], "This QRNN implementation currently only handles convolutional window of size 1 or size 2"
self.window = window
self.input_size = input_size
self.hidden_size = hidden_size if hidden_size else input_size
self.zoneout = zoneout
self.save_prev_x = save_prev_x
self.prevX = None
self.output_gate = output_gate
self.use_cuda = use_cuda
# One large matmul with concat is faster than N small matmuls and no concat
self.linear = nn.Linear(self.window * self.input_size, 3 * self.hidden_size if self.output_gate else 2 * self.hidden_size)
def reset(self):
# If you are saving the previous value of x, you should call this when starting with a new state
self.prevX = None
def forward(self, X, hidden=None):
seq_len, batch_size, _ = X.size()
source = None
if self.window == 1:
source = X
elif self.window == 2:
# Construct the x_{t-1} tensor with optional x_{-1}, otherwise a zeroed out value for x_{-1}
Xm1 = []
Xm1.append(self.prevX if self.prevX is not None else X[:1, :, :] * 0)
# Note: in case of len(X) == 1, X[:-1, :, :] results in slicing of empty tensor == bad
if len(X) > 1:
Xm1.append(X[:-1, :, :])
Xm1 = torch.cat(Xm1, 0)
# Convert two (seq_len, batch_size, hidden) tensors to (seq_len, batch_size, 2 * hidden)
source = torch.cat([X, Xm1], 2)
# Matrix multiplication for the three outputs: Z, F, O
print(type(source))
Y = self.linear(Tensor(source))
# Convert the tensor back to (batch, seq_len, len([Z, F, O]) * hidden_size)
if self.output_gate:
Y = Y.view(seq_len, batch_size, 3 * self.hidden_size)
Z, F, O = Y.chunk(3, dim=2)
else:
Y = Y.view(seq_len, batch_size, 2 * self.hidden_size)
Z, F = Y.chunk(2, dim=2)
###
Z = torch.nn.functional.tanh(Z)
F = torch.nn.functional.sigmoid(F)
# If zoneout is specified, we perform dropout on the forget gates in F
# If an element of F is zero, that means the corresponding neuron keeps the old value
if self.zoneout:
if self.training:
mask = F.detach().new(*F.size()).bernoulli_(1 - self.zoneout)
F = F * mask
else:
F *= 1 - self.zoneout
# Ensure the memory is laid out as expected for the CUDA kernel
# This is a null op if the tensor is already contiguous
Z = Z.contiguous()
F = F.contiguous()
# The O gate doesn't need to be contiguous as it isn't used in the CUDA kernel
# Forget Mult
# For testing QRNN without ForgetMult CUDA kernel, C = Z * F may be useful
C = ForgetMult()(F, Z, hidden, use_cuda=self.use_cuda)
# Apply (potentially optional) output gate
if self.output_gate:
H = torch.nn.functional.sigmoid(O) * C
else:
H = C
# In an optimal world we may want to backprop to x_{t-1} but ...
if self.window > 1 and self.save_prev_x:
self.prevX = X[-1:, :, :].detach()
return H, C[-1:, :, :]
class QRNN(torch.nn.Module):
r"""Applies a multiple layer Quasi-Recurrent Neural Network (QRNN) to an input sequence.
Args:
input_size: The number of expected features in the input x.
hidden_size: The number of features in the hidden state h. If not specified, the input size is used.
num_layers: The number of QRNN layers to produce.
layers: List of preconstructed QRNN layers to use for the QRNN module (optional).
save_prev_x: Whether to store previous inputs for use in future convolutional windows (i.e. for a continuing sequence such as in language modeling). If true, you must call reset to remove cached previous values of x. Default: False.
window: Defines the size of the convolutional window (how many previous tokens to look when computing the QRNN values). Supports 1 and 2. Default: 1.
zoneout: Whether to apply zoneout (i.e. failing to update elements in the hidden state) to the hidden state updates. Default: 0.
output_gate: If True, performs QRNN-fo (applying an output gate to the output). If False, performs QRNN-f. Default: True.
use_cuda: If True, uses fast custom CUDA kernel. If False, uses naive for loop. Default: True.
Inputs: X, hidden
- X (seq_len, batch, input_size): tensor containing the features of the input sequence.
- hidden (layers, batch, hidden_size): tensor containing the initial hidden state for the QRNN.
Outputs: output, h_n
- output (seq_len, batch, hidden_size): tensor containing the output of the QRNN for each timestep.
- h_n (layers, batch, hidden_size): tensor containing the hidden state for t=seq_len
"""
def __init__(self, input_size, hidden_size,
num_layers=1, bias=True, batch_first=False,
dropout=0, bidirectional=False, layers=None, **kwargs):
#assert bidirectional == False, 'Bidirectional QRNN is not yet supported'
#assert batch_first == False, 'Batch first mode is not yet supported'
#assert bias == True, 'Removing underlying bias is not yet supported'
super(QRNN, self).__init__()
self.layers = torch.nn.ModuleList(layers if layers else [QRNNLayer(input_size if l == 0 else hidden_size, hidden_size, **kwargs) for l in range(num_layers)])
self.input_size = input_size
self.hidden_size = hidden_size
self.num_layers = len(layers) if layers else num_layers
self.bias = bias
self.batch_first = batch_first
self.dropout = dropout
self.bidirectional = bidirectional
def reset(self):
r'''If your convolutional window is greater than 1, you must reset at the beginning of each new sequence'''
[layer.reset() for layer in self.layers]
def forward(self, input, hidden=None):
next_hidden = []
for i, layer in enumerate(self.layers):
input, hn = layer(input, None if hidden is None else hidden[i])
next_hidden.append(hn)
if self.dropout != 0 and i < len(self.layers) - 1:
input = torch.nn.functional.dropout(input, p=self.dropout, training=self.training, inplace=False)
next_hidden = torch.cat(next_hidden, 0).view(self.num_layers, *next_hidden[0].size()[-2:])
return input, next_hidden
In [0]:
class EncoderRNN(nn.Module):
def __init__(self):
super(EncoderRNN, self).__init__()
# bidirectional lstm:
self.qrnn = QRNN(5,hp.enc_hidden_size,dropout=hp.dropout)#nn.LSTM(5, hp.enc_hidden_size, \
#dropout=hp.dropout, bidirectional=True)
# create mu and sigma from lstm's last output:
self.fc_mu = nn.Linear(2*hp.enc_hidden_size, hp.Nz)
self.fc_sigma = nn.Linear(2*hp.enc_hidden_size, hp.Nz)
# active dropout:
self.train()
def forward(self, inputs, batch_size, hidden_cell=None):
if hidden_cell is None:
# then must init with zeros
if use_cuda:
hidden = torch.zeros(2, batch_size, hp.enc_hidden_size).cuda()
#cell = Variable(torch.zeros(2, batch_size, hp.enc_hidden_size).cuda())
else:
hidden = torch.zeros(2, batch_size, hp.enc_hidden_size)
#cell = Variable(torch.zeros(2, batch_size, hp.enc_hidden_size))
hidden_cell = hidden#(hidden, cell)
_, hidden = self.qrnn(inputs.float(), hidden_cell)
# hidden is (2, batch_size, hidden_size), we want (batch_size, 2*hidden_size):
#hidden_forward, hidden_backward = torch.split(hidden,1,0)
#hidden_cat = torch.cat([hidden_forward.squeeze(0), hidden_backward.squeeze(0)],1)
hidden_cat = hidden
# mu and sigma:
mu = self.fc_mu(hidden_cat)
sigma_hat = self.fc_sigma(hidden_cat)
sigma = torch.exp(sigma_hat/2.)
# N ~ N(0,1)
z_size = mu.size()
if use_cuda:
N = torch.normal(torch.zeros(z_size),torch.ones(z_size)).cuda()
else:
N = torch.normal(torch.zeros(z_size),torch.ones(z_size))
z = mu + sigma*N
# mu and sigma_hat are needed for LKL loss
return z, mu, sigma_hat
class DecoderRNN(nn.Module):
def __init__(self):
super(DecoderRNN, self).__init__()
# to init hidden and cell from z:
self.fc_hc = nn.Linear(hp.Nz, 2*hp.dec_hidden_size)
# unidirectional lstm:
self.lstm = nn.LSTM(hp.Nz+5, hp.dec_hidden_size, dropout=hp.dropout)
# create proba distribution parameters from hiddens:
self.fc_params = nn.Linear(hp.dec_hidden_size,6*hp.M+3)
def forward(self, inputs, z, hidden_cell=None):
if hidden_cell is None:
# then we must init from z
hidden,cell = torch.split(F.tanh(self.fc_hc(z)),hp.dec_hidden_size,1)
hidden_cell = (hidden.unsqueeze(0).contiguous(), cell.unsqueeze(0).contiguous())
outputs,(hidden,cell) = self.lstm(inputs, hidden_cell)
# in training we feed the lstm with the whole input in one shot
# and use all outputs contained in 'outputs', while in generate
# mode we just feed with the last generated sample:
if self.training:
y = self.fc_params(outputs.view(-1, hp.dec_hidden_size))
else:
y = self.fc_params(hidden.view(-1, hp.dec_hidden_size))
# separate pen and mixture params:
params = torch.split(y,6,1)
params_mixture = torch.stack(params[:-1]) # trajectory
params_pen = params[-1] # pen up/down
# identify mixture params:
pi,mu_x,mu_y,sigma_x,sigma_y,rho_xy = torch.split(params_mixture,1,2)
# preprocess params::
if self.training:
len_out = Nmax+1
else:
len_out = 1
pi = F.softmax(pi.t().squeeze()).view(len_out,-1,hp.M)
sigma_x = torch.exp(sigma_x.t().squeeze()).view(len_out,-1,hp.M)
sigma_y = torch.exp(sigma_y.t().squeeze()).view(len_out,-1,hp.M)
rho_xy = torch.tanh(rho_xy.t().squeeze()).view(len_out,-1,hp.M)
mu_x = mu_x.t().squeeze().contiguous().view(len_out,-1,hp.M)
mu_y = mu_y.t().squeeze().contiguous().view(len_out,-1,hp.M)
q = F.softmax(params_pen).view(len_out,-1,3)
return pi,mu_x,mu_y,sigma_x,sigma_y,rho_xy,q,hidden,cell
class Model():
def __init__(self):
if use_cuda:
self.encoder = EncoderRNN().cuda()
self.decoder = DecoderRNN().cuda()
else:
self.encoder = EncoderRNN()
self.decoder = DecoderRNN()
self.encoder_optimizer = optim.Adam(self.encoder.parameters(), hp.lr)
self.decoder_optimizer = optim.Adam(self.decoder.parameters(), hp.lr)
self.eta_step = hp.eta_min
def make_target(self, batch, lengths):
if use_cuda:
eos = torch.stack([torch.Tensor([0,0,0,0,1])]*batch.size()[1]).cuda().unsqueeze(0)
else:
eos = torch.stack([torch.Tensor([0,0,0,0,1])]*batch.size()[1]).unsqueeze(0)
batch = torch.cat([batch, eos], 0)
mask = torch.zeros(Nmax+1, batch.size()[1])
for indice,length in enumerate(lengths):
mask[:length,indice] = 1
if use_cuda:
mask = Tensor(mask.cuda()).detach()
else:
mask = Tensor(mask).detach()
dx = torch.stack([batch[:,:,0]]*hp.M,2).detach()
dy = torch.stack([batch[:,:,1]]*hp.M,2).detach()
p1 = batch[:,:,2].detach()
p2 = batch[:,:,3].detach()
p3 = batch[:,:,4].detach()
p = torch.stack([p1,p2,p3],2)
return mask,dx,dy,p
def train(self, epoch):
self.encoder.train()
self.decoder.train()
batch, lengths = make_batch(hp.batch_size)
# encode:
z, self.mu, self.sigma = self.encoder(batch, hp.batch_size)
# create start of sequence:
if use_cuda:
sos = torch.stack([torch.Tensor([0,0,1,0,0])]*hp.batch_size).cuda().unsqueeze(0)
else:
sos = torch.stack([torch.Tensor([0,0,1,0,0])]*hp.batch_size).unsqueeze(0)
# had sos at the begining of the batch:
batch_init = torch.cat([sos, batch],0)
# expend z to be ready to concatenate with inputs:
z_stack = torch.stack([z]*(Nmax+1))
# inputs is concatenation of z and batch_inputs
inputs = torch.cat([batch_init, z_stack],2)
# decode:
self.pi, self.mu_x, self.mu_y, self.sigma_x, self.sigma_y, \
self.rho_xy, self.q, _, _ = self.decoder(inputs, z)
# prepare targets:
mask,dx,dy,p = self.make_target(batch, lengths)
# prepare optimizers:
self.encoder_optimizer.zero_grad()
self.decoder_optimizer.zero_grad()
# update eta for LKL:
self.eta_step = 1-(1-hp.eta_min)*hp.R
# compute losses:
LKL = self.kullback_leibler_loss()
LR = self.reconstruction_loss(mask,dx,dy,p,epoch)
loss = LR + LKL
# gradient step
loss.backward()
# gradient cliping
nn.utils.clip_grad_norm(self.encoder.parameters(), hp.grad_clip)
nn.utils.clip_grad_norm(self.decoder.parameters(), hp.grad_clip)
# optim step
self.encoder_optimizer.step()
self.decoder_optimizer.step()
# some print and save:
if epoch%1==0:
print('epoch',epoch,'loss',loss.data[0],'LR',LR.data[0],'LKL',LKL.data[0])
self.encoder_optimizer = lr_decay(self.encoder_optimizer)
self.decoder_optimizer = lr_decay(self.decoder_optimizer)
if epoch%100==0:
#self.save(epoch)
self.conditional_generation(epoch)
def bivariate_normal_pdf(self, dx, dy):
z_x = ((dx-self.mu_x)/self.sigma_x)**2
z_y = ((dy-self.mu_y)/self.sigma_y)**2
z_xy = (dx-self.mu_x)*(dy-self.mu_y)/(self.sigma_x*self.sigma_y)
z = z_x + z_y -2*self.rho_xy*z_xy
exp = torch.exp(-z/(2*(1-self.rho_xy**2)))
norm = 2*np.pi*self.sigma_x*self.sigma_y*torch.sqrt(1-self.rho_xy**2)
return exp/norm
def reconstruction_loss(self, mask, dx, dy, p, epoch):
pdf = self.bivariate_normal_pdf(dx, dy)
LS = -torch.sum(mask*torch.log(1e-5+torch.sum(self.pi * pdf, 2)))/float(Nmax*hp.batch_size)
LP = -torch.sum(p*torch.log(self.q))/float(Nmax*hp.batch_size)
return LS+LP
def kullback_leibler_loss(self):
LKL = -0.5*torch.sum(1+self.sigma-self.mu**2-torch.exp(self.sigma))\
/float(hp.Nz*hp.batch_size)
if use_cuda:
KL_min = torch.Tensor([hp.KL_min]).cuda().detach()
else:
KL_min = torch.Tensor([hp.KL_min]).detach()
return hp.wKL*self.eta_step * torch.max(LKL,KL_min)
def save(self, epoch):
sel = np.random.rand()
torch.save(self.encoder.state_dict(), \
'encoderRNN_sel_%3f_epoch_%d.pth' % (sel,epoch))
torch.save(self.decoder.state_dict(), \
'decoderRNN_sel_%3f_epoch_%d.pth' % (sel,epoch))
def load(self, encoder_name, decoder_name):
saved_encoder = torch.load(encoder_name)
saved_decoder = torch.load(decoder_name)
self.encoder.load_state_dict(saved_encoder)
self.decoder.load_state_dict(saved_decoder)
def conditional_generation(self, epoch):
batch,lengths = make_batch(1)
# should remove dropouts:
self.encoder.train(False)
self.decoder.train(False)
# encode:
z, _, _ = self.encoder(batch, 1)
if use_cuda:
sos = torch.Tensor([0,0,1,0,0]).view(1,1,-1).cuda()
else:
sos = torch.Tensor([0,0,1,0,0]).view(1,1,-1)
s = sos
seq_x = []
seq_y = []
seq_z = []
hidden_cell = None
for i in range(Nmax):
input = torch.cat([s,z.unsqueeze(0)],2)
# decode:
self.pi, self.mu_x, self.mu_y, self.sigma_x, self.sigma_y, \
self.rho_xy, self.q, hidden, cell = \
self.decoder(input, z, hidden_cell)
hidden_cell = (hidden, cell)
# sample from parameters:
s, dx, dy, pen_down, eos = self.sample_next_state()
#------
seq_x.append(dx)
seq_y.append(dy)
seq_z.append(pen_down)
if eos:
print(i)
break
# visualize result:
x_sample = np.cumsum(seq_x, 0)
y_sample = np.cumsum(seq_y, 0)
z_sample = np.array(seq_z)
sequence = np.stack([x_sample,y_sample,z_sample]).T
make_image(sequence, epoch)
def sample_next_state(self):
def adjust_temp(pi_pdf):
pi_pdf = np.log(pi_pdf)/hp.temperature
pi_pdf -= pi_pdf.max()
pi_pdf = np.exp(pi_pdf)
pi_pdf /= pi_pdf.sum()
return pi_pdf
# get mixture indice:
pi = self.pi[0,0,:].detach().cpu().numpy()
pi = adjust_temp(pi)
pi_idx = np.random.choice(hp.M, p=pi)
# get pen state:
q = self.q[0,0,:].detach().cpu().numpy()
q = adjust_temp(q)
q_idx = np.random.choice(3, p=q)
# get mixture params:
mu_x = self.mu_x[0,0,pi_idx]
mu_y = self.mu_y[0,0,pi_idx]
sigma_x = self.sigma_x[0,0,pi_idx]
sigma_y = self.sigma_y[0,0,pi_idx]
rho_xy = self.rho_xy[0,0,pi_idx]
x,y = sample_bivariate_normal(mu_x,mu_y,sigma_x,sigma_y,rho_xy,greedy=False)
next_state = torch.zeros(5)
next_state[0] = x
next_state[1] = y
next_state[q_idx+2] = 1
if use_cuda:
return Variable(next_state.cuda()).view(1,1,-1),x,y,q_idx==1,q_idx==2
else:
return Variable(next_state).view(1,1,-1),x,y,q_idx==1,q_idx==2
In [0]:
#@HyperParameters
class HParams():
def __init__(self):
self.data_location = 'ant.npz'
self.enc_hidden_size = 256 #@param {type:"number"}
self.dec_hidden_size = 512 #@param {type:"number"}
self.Nz = 128
self.M = 20
self.dropout = 0.9 #@param {type:"slider",min:0,max:1,step:0.1}
self.batch_size = 100 #@param {type:"number"}
self.eta_min = 0.01
self.R = 0.99995
self.KL_min = 0.2
self.wKL = 0.5
self.lr = 0.001
self.lr_decay = 0.9999
self.min_lr = 0.00001
self.grad_clip = 1.
self.temperature = 0.4 #@param {type:"slider",min:0,max:1,step:0.1}
self.max_seq_length = 200
hp = HParams()
dataset = np.load(hp.data_location, encoding='latin1')
data = dataset['train']
data = purify(data)
data = normalize(data)
Nmax = max_size(data)
In [30]:
def sample_bivariate_normal(mu_x,mu_y,sigma_x,sigma_y,rho_xy, greedy=False):
# inputs must be floats
if greedy:
return mu_x,mu_y
mean = [mu_x, mu_y]
sigma_x *= np.sqrt(hp.temperature)
sigma_y *= np.sqrt(hp.temperature)
cov = [[sigma_x * sigma_x, rho_xy * sigma_x * sigma_y],\
[rho_xy * sigma_x * sigma_y, sigma_y * sigma_y]]
x = np.random.multivariate_normal(mean, cov, 1)
return x[0][0], x[0][1]
def make_image(sequence, epoch, name='_output_'):
"""plot drawing with separated strokes"""
strokes = np.split(sequence, np.where(sequence[:,2]>0)[0]+1)
fig = plt.figure()
ax1 = fig.add_subplot(111)
for s in strokes:
plt.plot(s[:,0],-s[:,1])
canvas = plt.get_current_fig_manager().canvas
canvas.draw()
pil_image = PIL.Image.frombytes('RGB', canvas.get_width_height(),
canvas.tostring_rgb())
name = str(epoch)+name+'.jpg'
pil_image.save(name,"JPEG")
plt.close("all")
if __name__=="__main__":
use_cuda = False
model = Model()
for epoch in range(50001):
model.train(epoch)
model.load('encoder.pth','decoder.pth')
model.conditional_generation(50001)
'''
model.load('encoder.pth','decoder.pth')
model.conditional_generation(0)
#'''
In [32]:
layer = torch.nn.Linear(3,2)
x = torch.zeros(3,3)
print(torch.__version__)
y = layer(x)
print(type(y))
In [0]: