mmacosha commited on
Commit
5e3f03f
·
verified ·
1 Parent(s): 6759aa6

add mnist_vae/ (checkpoint + code)

Browse files
Files changed (3) hide show
  1. mnist_vae/load.py +17 -0
  2. mnist_vae/mnist_vae.pkl +3 -0
  3. mnist_vae/vae.py +142 -0
mnist_vae/load.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pickle
2
+
3
+ from vae import VAE
4
+
5
+ with open("mnist_vae.pkl", "rb") as f:
6
+ bundle = pickle.load(f)
7
+ meta = bundle["meta"]
8
+ params = bundle["params"]
9
+
10
+ model = VAE(
11
+ latent_dim=meta["latent_dim"],
12
+ in_channels=meta["in_channels"],
13
+ base_channels=meta["base_channels"],
14
+ channel_mults=tuple(meta["channel_mults"]),
15
+ image_size=meta["image_size"],
16
+ obs_sigma=meta["obs_sigma"],
17
+ )
mnist_vae/mnist_vae.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:64a52c2eff25217b17fc727b168538fd87feb2a1a753fd8cd6fb608a0a038e05
3
+ size 867032
mnist_vae/vae.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any
2
+
3
+ import jax
4
+ import jax.numpy as jnp
5
+ from flax import linen as nn
6
+
7
+ Array = jax.Array
8
+
9
+
10
+ class ResBlock(nn.Module):
11
+ features: int
12
+ groups: int = 8
13
+
14
+ @nn.compact
15
+ def __call__(self, x: Array) -> Array:
16
+ residual = x
17
+ if x.shape[-1] != self.features:
18
+ residual = nn.Conv(self.features, kernel_size=(1, 1))(residual)
19
+ h = nn.GroupNorm(num_groups=min(self.groups, self.features))(x)
20
+ h = nn.swish(h)
21
+ h = nn.Conv(self.features, kernel_size=(3, 3))(h)
22
+ h = nn.GroupNorm(num_groups=min(self.groups, self.features))(h)
23
+ h = nn.swish(h)
24
+ h = nn.Conv(self.features, kernel_size=(3, 3))(h)
25
+ return h + residual
26
+
27
+
28
+ class Downsample(nn.Module):
29
+ features: int
30
+
31
+ @nn.compact
32
+ def __call__(self, x: Array) -> Array:
33
+ return nn.Conv(self.features, kernel_size=(3, 3), strides=(2, 2))(x)
34
+
35
+
36
+ class Upsample(nn.Module):
37
+ features: int
38
+
39
+ @nn.compact
40
+ def __call__(self, x: Array) -> Array:
41
+ b, h, w, _ = x.shape
42
+ x = jax.image.resize(x, (b, h * 2, w * 2, x.shape[-1]), method="nearest")
43
+ return nn.Conv(self.features, kernel_size=(3, 3))(x)
44
+
45
+
46
+ class Encoder(nn.Module):
47
+ latent_dim: int
48
+ base_channels: int = 64
49
+ channel_mults: tuple[int, ...] = (1, 2, 4)
50
+
51
+ @nn.compact
52
+ def __call__(self, x: Array) -> tuple[Array, Array]:
53
+ h = nn.Conv(self.base_channels, kernel_size=(3, 3))(x)
54
+ for i, mult in enumerate(self.channel_mults):
55
+ features = self.base_channels * mult
56
+ h = ResBlock(features)(h)
57
+ h = ResBlock(features)(h)
58
+ if i < len(self.channel_mults) - 1:
59
+ h = Downsample(features)(h)
60
+ h = Downsample(self.base_channels * self.channel_mults[-1])(h)
61
+ h = nn.GroupNorm(num_groups=8)(h)
62
+ h = nn.swish(h)
63
+ h = h.reshape(h.shape[0], -1)
64
+ mu = nn.Dense(self.latent_dim)(h)
65
+ log_var = nn.Dense(self.latent_dim)(h)
66
+ log_var = jnp.clip(log_var, -10.0, 10.0)
67
+ return mu, log_var
68
+
69
+
70
+ class Decoder(nn.Module):
71
+ out_channels: int
72
+ base_channels: int = 64
73
+ channel_mults: tuple[int, ...] = (1, 2, 4)
74
+ image_size: int = 32
75
+
76
+ @nn.compact
77
+ def __call__(self, z: Array) -> Array:
78
+ n_down = len(self.channel_mults)
79
+ start = self.image_size // (2**n_down)
80
+ features_top = self.base_channels * self.channel_mults[-1]
81
+ h = nn.Dense(start * start * features_top)(z)
82
+ h = h.reshape(z.shape[0], start, start, features_top)
83
+ h = Upsample(features_top)(h)
84
+ for i, mult in enumerate(reversed(self.channel_mults)):
85
+ features = self.base_channels * mult
86
+ h = ResBlock(features)(h)
87
+ h = ResBlock(features)(h)
88
+ if i < len(self.channel_mults) - 1:
89
+ next_features = self.base_channels * list(reversed(self.channel_mults))[i + 1]
90
+ h = Upsample(next_features)(h)
91
+ h = nn.GroupNorm(num_groups=8)(h)
92
+ h = nn.swish(h)
93
+ h = nn.Conv(self.out_channels, kernel_size=(3, 3))(h)
94
+ return nn.sigmoid(h)
95
+
96
+
97
+ class VAE(nn.Module):
98
+ latent_dim: int = 128
99
+ in_channels: int = 3
100
+ base_channels: int = 64
101
+ channel_mults: tuple[int, ...] = (1, 2, 4)
102
+ image_size: int = 32
103
+ obs_sigma: float = 0.1
104
+
105
+ def setup(self):
106
+ self.encoder = Encoder(
107
+ latent_dim=self.latent_dim,
108
+ base_channels=self.base_channels,
109
+ channel_mults=self.channel_mults,
110
+ )
111
+ self.decoder = Decoder(
112
+ out_channels=self.in_channels,
113
+ base_channels=self.base_channels,
114
+ channel_mults=self.channel_mults,
115
+ image_size=self.image_size,
116
+ )
117
+
118
+ def encode(self, x: Array) -> tuple[Array, Array]:
119
+ return self.encoder(x)
120
+
121
+ def decode(self, z: Array) -> Array:
122
+ return self.decoder(z)
123
+
124
+ def reparameterize(self, rng: Array, mu: Array, log_var: Array) -> Array:
125
+ eps = jax.random.normal(rng, mu.shape)
126
+ return mu + jnp.exp(0.5 * log_var) * eps
127
+
128
+ def __call__(self, x: Array, rng: Array) -> dict[str, Array]:
129
+ mu, log_var = self.encode(x)
130
+ z = self.reparameterize(rng, mu, log_var)
131
+ x_hat = self.decode(z)
132
+ return {"x_hat": x_hat, "mu": mu, "log_var": log_var, "z": z}
133
+
134
+ def sample_prior(self, rng: Array, n: int) -> Array:
135
+ z = jax.random.normal(rng, (n, self.latent_dim))
136
+ return self.decode(z)
137
+
138
+
139
+ def latent_log_prior(z: Array) -> Array:
140
+ """Standard normal prior log density, summed over latent dimensions."""
141
+ d = z.shape[-1]
142
+ return -0.5 * (jnp.sum(z * z, axis=-1) + d * jnp.log(2 * jnp.pi))