99# extension: .py
1010# format_name: percent
1111# format_version: '1.3'
12- # jupytext_version: 1.19 .2
12+ # jupytext_version: 1.11 .2
1313# kernelspec:
1414# display_name: 07_xai
1515# language: python
@@ -275,7 +275,7 @@ def forward(self, x):
275275# * However, sampling `z` directly from `mu` and $std$(`logvar`) does not allow for backpropagation (random sampling is not differentiable)
276276# * To allow for backpropagation, we isolate the non-differentiable random sampling node and sample $\epsilon$ from a Normal distritubion with mean 0 and standard deviation 1
277277# * We then use this $\epsilon$ to produce `z`: `z` $=$ `mu` $+ \epsilon * e^{logvar/2}$ (here, gradient can flow through `mu` and `logvar`)
278- #
278+ #
279279# 
280280# Source: [Wikipedia](https://en.wikipedia.org/wiki/Reparameterization_trick#).
281281#
@@ -285,36 +285,36 @@ def forward(self, x):
285285# %% [markdown]
286286# <div class="alert alert-block alert-info"><h2>Task – Fill in the gaps</h2>
287287#
288- # There are gaps marked as `...`.
288+ # There are gaps marked as `...`
289289# Fill them in:
290290#
291291# **Missing in `def __init__`**
292292#
293- # The encoder and decoder instance of the MLP are missing. Replace `...` with:
294- # `self.encoder`
295- # `self.decoder`.
293+ # The encoder and decoder instance of the MLP are missing. Replace `...` with:
294+ # `self.encoder`
295+ # `self.decoder`
296296#
297- # How can you tell which is which?
297+ # How can you tell which is which?
298298#
299299#
300300# **Missing in `def reparameterize`**
301301#
302- # `epsilon` (missing twice)
302+ # `epsilon` (missing twice)
303303# `std`
304304#
305305# Tip:
306306# $std = e^{logvar/2}$
307307# $z = mu + \epsilon * std$
308308#
309309#
310- # **Missing in `def forward`**
311- # `mu`
312- # `logvar`
313- # `z`
314- # `self.decode`
315- # `self.encode`
316- # `self.reparameterize`
317- # `xx` (this is the reconstructed image)
310+ # **Missing in `def forward`**
311+ # `mu`
312+ # `logvar`
313+ # `z`
314+ # `self.decode`
315+ # `self.encode`
316+ # `self.reparameterize`
317+ # `xx` (this is the reconstructed image)
318318#
319319# </div>
320320#
@@ -521,12 +521,12 @@ def rec_loss(xx, x):
521521
522522# %% [markdown]
523523#
524-
524+ #
525525# The KL loss
526526# %% tags=["task"]
527527def kl_loss (mu , logvar ):
528528 return ...
529-
529+
530530# %% tags=["solution"]
531531def kl_loss (mu , logvar ):
532532 # sum over latent dimensions, mean over batch
@@ -574,10 +574,11 @@ def loss(rec, kl, beta):
574574# Now we get to create and train our model on the MNIST dataset.
575575#
576576# #### A.2.3.1 Set the device
577- # As our model and dataset is small, CPUs are likely to outperform GPUs.
578- # The overhead of transferring the data to GPU might make the model slower than running it on CPU.
577+ # As our model and dataset is small, on many machines, CPUs are likely to outperform GPUs:
578+ # The overhead of transferring the data to GPU might make the model slower than running it on CPU.
579+ # However, on our virtual machines, running it on GPU is faster:
579580# %%
580- device = torch .device ("cpu" )
581+ device = torch .device ("cuda" if torch . cuda . is_available () else " cpu" )
581582
582583# %% [markdown]
583584# #### Part A.2.3.2: Model instance and optimizer
@@ -880,7 +881,7 @@ def view_test_sample(model, loader):
880881# </div>
881882
882883# %% [markdown]
883- # ### Part A.2.6: Train two models for 1000 epochs
884+ # ### Part A.2.6: Train two models for 500 epochs
884885
885886# %% [markdown]
886887# #### A.2.6.1: Train a model without regularized latent sapce
@@ -895,7 +896,7 @@ def view_test_sample(model, loader):
895896# * Keep `latent_dim = 2`. This is not ideal, but helps us better understand the latent space.
896897# * Instantiate a new optimizer
897898# * Pass `beta = 0`
898- # * Train your new model for `epochs = 1000 `
899+ # * Train your new model for `epochs = 500 `
899900#
900901#
901902#
@@ -915,7 +916,7 @@ def view_test_sample(model, loader):
915916model0 = VariationalAutoEncoder (w , h , latent_dim = 2 ).to (device ) # fresh weights
916917optimizer = Adam (model0 .parameters (), lr = 0.0001 ) # fresh optimizer
917918
918- epochs = 1000
919+ epochs = 500
919920beta = 0
920921losses0 = train_epochs (epochs , model0 , train_loader , optimizer , loss , beta = beta )
921922
@@ -956,14 +957,14 @@ def view_test_sample(model, loader):
956957#
957958# Tips:
958959# * Have a look at the overall loss function definitions
959- # * Look at the order of magnitude of the reconstruction loss and KL loss, for instance at epoch 1000 , to decide on a value
960- # * You can train for fewer epochs if you want to try multiple values. Train for 1000 epochs once you decided
960+ # * Look at the order of magnitude of the reconstruction loss and KL loss, for instance at epoch 500 , to decide on a value
961+ # * You can train for fewer epochs if you want to try multiple values. Train for 500 epochs once you decided
961962# </div>
962963
963964# %% tags=["task"]
964965model1 = VariationalAutoEncoder (w , h , latent_dim = 2 ).to (device )
965966optimizer = Adam (model1 .parameters (), lr = 0.0001 ) # fresh optimizer
966- epochs = 1000
967+ epochs = 500
967968beta = # TODO
968969losses1 = train_epochs (epochs , model1 , train_loader , optimizer , loss , beta = beta )
969970
@@ -972,7 +973,7 @@ def view_test_sample(model, loader):
972973# beta 1
973974model1 = VariationalAutoEncoder (w , h , latent_dim = 2 ).to (device )
974975optimizer = Adam (model1 .parameters (), lr = 0.0001 ) # fresh optimizer
975- epochs = 1000
976+ epochs = 500
976977beta = 1
977978losses1 = train_epochs (epochs , model1 , train_loader , optimizer , loss , beta = beta )
978979
@@ -1593,7 +1594,7 @@ def decode_point(z, model0, model1, mus_model0, lbls0, mu_mean0, mus_model1, lbl
15931594# * Instantiate a new variational autoencoder model and name it `model2`
15941595# * Instantiate a new optimizer
15951596# * Pass `beta = 1`
1596- # * Train your new model for `epochs = 1000 `
1597+ # * Train your new model for `epochs = 500 `
15971598
15981599# %% [markdown]
15991600# <div class="alert alert-block alert-info"><h2>Task</h2>
@@ -1609,7 +1610,7 @@ def decode_point(z, model0, model1, mus_model0, lbls0, mu_mean0, mus_model1, lbl
16091610model2 = VariationalAutoEncoder (w , h , latent_dim = latent_dim ).to (device )
16101611optimizer = Adam (model2 .parameters (), lr = 0.0001 )
16111612
1612- epochs = 1000
1613+ epochs = 500
16131614beta = 1
16141615
16151616train_epochs (epochs , model2 , train_loader , optimizer , loss , beta = beta );
@@ -1620,7 +1621,7 @@ def decode_point(z, model0, model1, mus_model0, lbls0, mu_mean0, mus_model1, lbl
16201621model2 = VariationalAutoEncoder (w , h , latent_dim = latent_dim ).to (device )
16211622optimizer = Adam (model2 .parameters (), lr = 0.0001 )
16221623
1623- epochs = 1000
1624+ epochs = 500
16241625beta = 1
16251626
16261627train_epochs (epochs , model2 , train_loader , optimizer , loss , beta = beta );
0 commit comments