-
Notifications
You must be signed in to change notification settings - Fork 7
/
VAE.py
71 lines (46 loc) · 2.28 KB
/
VAE.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import os
import time
import numpy as np
from chainer import cuda, Variable, function, FunctionSet, optimizers
from chainer import functions as F
class VAE(FunctionSet):
def __init__(self, **layers):
super(VAE, self).__init__(**layers)
def softplus(self, x):
return F.log(F.exp(x) + 1)
def forward_one_step(self, x_data, y_data, n_layers_recog, n_layers_gen, nonlinear_q='softplus', nonlinear_p='softplus', gpu=False):
inputs = Variable(x_data)
y = Variable(y_data)
# set non-linear function
nonlinear = {'sigmoid': F.sigmoid, 'tanh': F.tanh, 'softplus': self.softplus, 'relu': F.relu}
nonlinear_f_q = nonlinear[nonlinear_q]
nonlinear_f_p = nonlinear[nonlinear_p]
chain = [inputs]
# compute q(z|x, y)
for i in range(n_layers_recog):
chain.append(nonlinear_f_q(getattr(self, 'recog_%i' % i)(chain[-1])))
recog_out = getattr(self, 'recog_%i' % n_layers_recog)(chain[-1])
log_sigma_out = 0.5 * (getattr(self, 'log_sigma')(chain[-1]))
eps = np.random.normal(0, 1, (inputs.data.shape[0], log_sigma_out.data.shape[1])).astype('float32')
if gpu >= 0:
eps = cuda.to_gpu(eps)
eps = Variable(eps)
z = recog_out + F.exp(log_sigma_out) * eps
chain += [recog_out, z]
for i in range(n_layers_gen):
chain.append(nonlinear_f_p(getattr(self, 'gen_%i' % i)(chain[-1])))
chain.append(F.sigmoid(getattr(self, 'gen_%i' % (n_layers_gen))(chain[-1])))
output = chain[-1]
rec_loss = F.mean_squared_error(output, y)
KLD = -0.5 * F.sum(1 + log_sigma_out - recog_out**2 - F.exp(log_sigma_out)) / (x_data.shape[0]*x_data.shape[1])
return rec_loss, KLD, output
def generate(self, latent_data, n_layers_gen, nonlinear_p='relu'):
latent = Variable(latent_data)
chain = [latent]
nonlinear = {'sigmoid': F.sigmoid, 'tanh': F.tanh, 'softplus': self.softplus, 'relu': F.relu}
nonlinear_f_p = nonlinear[nonlinear_p]
for i in range(n_layers_gen):
chain.append(nonlinear_f_p(getattr(self, 'gen_%i' % i)(chain[-1])))
chain.append(F.sigmoid(getattr(self, 'gen_%i' % (n_layers_gen))(chain[-1])))
output = chain[-1]
return output