Conversation
| import pyro | ||
| from torch.autograd import Variable | ||
| from pyro.infer.kl_qp import KL_QP | ||
| from pyro.infer.abstract_infer import lw_expectation |
| import pyro | ||
| from torch.autograd import Variable | ||
| from pyro.infer.kl_qp import KL_QP | ||
| from pyro.infer.abstract_infer import lw_expectation |
|
I added some notes on the math contained in the Kingma paper to #79 , to keep them permanent. |
| pyro.observe("obs", Bernoulli(img_mu), data.view(-1, 784)) | ||
|
|
||
|
|
||
| def model_latent(data): |
There was a problem hiding this comment.
This here is supposed to be the barefoot bit. About line 170 currently.
def model_latent(data):
"""
analytically integrate over all classes
"""
nr_classes = 10
alpha = Variable(torch.ones([data.size(0), 10])) / 10.
#cll = pyro.sample('latent_class', Categorical(alpha))
for ic in range(nr_classes):
cll = Variable(torch.zeros([data.size(0), 10]))
cll[:,ic] = 1
pyro.observe("latent_class", Categorical(alpha), cll)
model_observed(data, cll)
passHave a look in the code [edited by jpchen: got it to show correctly]. It comments that it suppsoedly does that. All it does is score each choice of extra.
So I am calculating this here:
Sum_y [ log P(x|y,z) + logP(y|x) ]
|
Note: The reason is that I replaced a sample statement over a latent variable with a sum of observes, which will do the 'right thing' only for some terms in the ELBO: I am working out if I can change this to similar logic to still asymptote to an approximation. |
…f the sin gle layer model, one with the joint loss included in model so it looks like the kingma paper and one that adds an auxiliary loss so we can train both the model and the guide but do not mix the loss functions
|
Update: I removed the non-functioning integrated version and added 2 new files. vae_bernoulli_ss_extra_loss_one_kl.py is a version of the single hidden layer model that looks like the kingma paper int hat I made the classifier be trained as part of the model. vae_bernoulli_ss_extra_loss_seperate_kl.py has a new model_classifier() and guide_classifier() and an auxiliary inference class which is called at each observed update to also train a classifier. It thius does not mix the models. @rohitsingh0812 check it out. T. |
…observed data and (2) print accuracy at every training step and finally when testing. Also, added outputs for 3 short runs -- these should be removed from the repo later but can be used now for debugging.
|
I have modified one of the files to show how running the one-loss KL with 5% supervised data leads to (1) negative and increasing loss (2) bad accuracy numbers I'm guessing that there is some sort of scaling issue since we have different losses for the supervised and unsupervised case. But, it does seem like at least one of them is increasing while the other one may be decreasing. The loss decreases steadily for the 100% supervised case -- but the accuracy doesn't improve sequentially. |
… KL_QP. _m2_kingma.py file implements the experiment (M2 model) from the Kingma 2014 paper. unsup_vae file is a simple example with no supervision on y's -- this run has a negative loss value that increases (possibly a bug somewhere)
|
I have also added the code for running the experiments for a model from the Kingma paper -- there is an issue with running a simple model (with no supervision) - the output of the run looks like this - there is a negative loss that is increasing in value: (penv) rohits@rohits-desktop:~/Uber/pyro-ss-vae/examples/ss-vae$ python unsup_vae_simple.py |
|
@rohitsingh0812 that setting should reduce to a standard VAE right? you could try running the VAE example on the same data, to make sure it behaves reasonably. (and double check your optimizer (adam) and step size choices -- one reason for diverging objectives can be an oscillating optimizer.) |
|
@ngoodman -- The pure VAE works fine (in my implementation) as you expected but this model is slightly different : in the unsup VAE we have p(z) = Normal(0,I) and p(x|z) = Bernoulli(nn_mu(z)) in the model but for any % of supervision, we have to add a "y" random variable to the model and make the nn_mu a function of both y and z. This seems to lead to a blow up and weird behavior with the loss. Essentially, the above version with y may not make sense as a model but it might be the easiest thing to debug if we agree that the model with "y" when "y" is not observed should still give a reasonable loss value that should decrease. I see the same negative loss in the SS-VAE model with 5% supervision -- maybe I'm doing something wrong. I'll try the original simple model and see how my implementation might differ from it. |
…dular version. The accuracies are not good and it seems like enumeration might be the only missing part that may have an impact on them
|
The latest run with enumeration and the loss hacked to be exactly as in the paper looks like this: the accuracies go up to 91% for now and will probably go further if we tune parameters or debug the nan loss issue. This is way better than running this without enumeration where the accuracies were 10-20%. This run was using 50% supervision and the annealed extra loss term. I'll run some instances overnight but we may setup the pipeline tomorrow for running this on OPUS GPUs. (penv) rohits@rohits-desktop:~/Uber/pyro-ss-vae/examples/ss-vae$ python partial_sup_vae_simple.py --hack 1 -n 100 -sup 50 |
|
progress! any idea where that nan error is coming from? (that's the sort of thing we want to track down and squash before release!) |
…ical distribution -- trying to see if this stabilizes the issue of NNs eventually learning nan weights. Also, implemented checkpointing.
…- no more nans in the outputs and the accuracy matches the paper.
| assert np.isfinite(self.nn_mu_x.sum_params()) | ||
|
|
||
| """ | ||
| The model corresponds to: |
There was a problem hiding this comment.
It would be helpful to comment the meanings, which as I understand are
p(z) = DiagNormal(0,I) # handwriting style
p(y|x) = Categorical(I/10.) # which digit
p(x|y,z) = Bernoulli(mu(y,z)) # a binarized image
also nit: move this down to be the docstring of model()
| alpha_prior = Variable(torch.ones([self.batch_size, self.output_size]) | ||
| / (1.0 * self.output_size)) | ||
|
|
||
| if not is_supervised: |
There was a problem hiding this comment.
it would be kind of cool in a python way to define
def model(self, xs, ys=None):
is_supervised = (ys is not None)
...
if ys is None:
ys = pyro.sample(...)This is nice in that it generalizes well to more variables, where each may or may not be observed.
|
|
||
|
|
||
|
|
||
| """ |
There was a problem hiding this comment.
ditto: add comments on meaning and move below into guide()
|
|
||
| zs = pyro.sample("z", DiagNormal(mu, sigma)) | ||
|
|
||
| """ |
There was a problem hiding this comment.
nit: move into optimize() body so that it's a pythonic docstring
|
|
||
| parser = argparse.ArgumentParser(description="parse args") | ||
| parser.add_argument('--seed', default=None, type=int) | ||
| parser.add_argument('-cuda',action='store_true') #default is False |
There was a problem hiding this comment.
Could you please name this --cuda rather than -cuda so that this example will be discovered by test_examples.py?
| import torch | ||
| import pyro | ||
| from torch.autograd import Variable | ||
| from pyro.distributions import DiagNormal |
There was a problem hiding this comment.
We're trying to migrate to lower-case diagnormal functions etc. rather than uppercase DiagNormal classes.
| assert not np.isnan(torch.sum(mu).data[0]), "mu nn z produced a nan" | ||
| assert not np.isnan(torch.sum(sigma).data[0]), "sigma nn z produced a nan" | ||
|
|
||
| zs = pyro.sample("z", DiagNormal(mu, sigma)) |
There was a problem hiding this comment.
we're trying to migrate to the function-versions in examples:
zs = pyro.sample("z", diagnormal, mu, sigma)|
I've updated the code with comments and I've removed the low-level debugging code. |
… accuracy computation
…e) (2) ClippedNN utilities -- depends on PRs 444, 452, 453
| import torch.optim as optim | ||
| import numpy as np | ||
| import visdom | ||
| import pdb as pdb |
| from functools import reduce | ||
| from torch.utils.data import DataLoader | ||
|
|
||
|
|
There was a problem hiding this comment.
maybe add a high level comment about the purpose of the code in this file?
| :param ys: (optional) a batch of the class labels i.e. | ||
| the digit corresponding to the image(s) | ||
| :return: None | ||
| """ |
There was a problem hiding this comment.
do we need a comment re: iarange here?
| output_activation=ClippedSoftmax, epsilon_scale=self.epsilon_scale, | ||
| use_cuda=self.use_cuda) | ||
|
|
||
| # a split in the final layer's size is used foir multiple outputs |
| from pyro.nn import ClippedSoftmax, ClippedSigmoid | ||
|
|
||
|
|
||
| def is_variable(val): |
There was a problem hiding this comment.
is this different from
type(val) == torch.autograd.Variable
??
|
We've unified this branch (manually) with vae-examples #448. Closing this PR and branch. |
DO NOT MERGE YET, WIP
Closes #210
Added some lacking stuff.
a version with the hypothetical integrated out done barefoot variable in "examples/vae_bernoulli_ss_integrated.py" . A clean version would be Summing out discrete variables in ELBo #99
a 2layer deep ss-vae with the model P(x,z1, z2, class) = P(x|z1) P(z1|z2, class) P(class) P(z2)
This matches what the Kingma paper has as the M2 model closer, but is trained jointly instead of pretraining M1 and then learning M2.
some visualization and t-sne routines in workflow which analyze what is going on. This can be improved, obviously.
Still pending:
We can either leave this pr open until it is complete or we can do many smaller PRs until all the issues related to SS-learning are resolved.
References issue #79 , #94