Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Open In Colab   Open in Kaggle

Tutorial 1: Task definition, application, relations and impacts on generalization

Week 1, Day 2: Comparing Tasks

By Neuromatch Academy

Content creators: Deying Song, Leila Wehbe

Content reviewers: Samuele Bolotta, Hlib Solodzhuk, RyeongKyung Yoon, Lily Chamakura, Yizhou Chen, Ruiyi Zhang, Patrick Mineault, Alex Murphy

Production editors: Konstantine Tsafatinos, Ella Batty, Spiros Chavlis, Samuele Bolotta, Hlib Solodzhuk, Patrick Mineault, Alex Murphy


Tutorial Objectives

Estimated time of tutorial: 90 minutes

In this tutorial, we’ll explore how task specification affects generalization in networks. We will use the same base architecture (a convolutional neural network / CNN) to perform multiple different tasks. We will explore the number of training points and number of epochs needed to train these networks up to a specific accuracy value. Additionally, we will explore how well representations learned for a given task generalize, and whether these representations can be used to solve the other tasks.

Today’s learning objectives are:

  1. Formulate different tasks in terms of cost functions

  2. Train a network to accomplish these tasks and compare the performance of these networks

  3. Measure how well different representations generalize

Let’s get started.


Setup

Install and import feedback gadget

Source

Import dependencies

Source

Figure settings

Source

Set device (GPU or CPU)

Source
GPU is not enabled in this notebook. 
If you want to enable it, in the menu under `Runtime` -> 
`Hardware accelerator.` and select `GPU` from the dropdown menu

Helper functions

Source

Plotting functions

Source

Data retrieval

Source

Set random seed

Source

Section 1: Tasks as Cost Functions

We formalize different tasks as cost functions and train the same base architecture on the same dataset. Check out the video below to learn more about how we will do this!

Tutorial Video

Youtube
Bilibili

Review of CNNs

In this tutorial, we will use a simple Convolutional Neural Network (CNN) architecture and a subset of the MNIST dataset, which consists of images of handwritten digits (See the Intro video for more information on MNIST). We will use the same base architecture and training dataset to accomplish different tasks by creating various output layers (heads) and train them with different cost functions, thereby specifying different tasks to be completed. With different cost functions, the networks are forced to pay attention to different things as their end goal has changed and it’s this property that changes what the network tries to do.

A Convolutional Neural Network (CNN) is a deep learning algorithm designed to process input images, assign importance (learnable weights and biases) to various features within the images, and distinguish between different objects. Unlike pure feedforward neural networks that flatten the input into a one-dimensional array, CNNs preserve the spatial structure of the input images. This makes them particularly effective for processing data with a grid-like structure, such as images. A CNN architecture is engineered to automatically and adaptively learn spatial hierarchies of features, ranging from low-level (basic) to high-level (complex) patterns.

The core components of CNNs are convolutional layers, pooling layers, and fully connected layers. A schematic of a CNN is shown below.

  • Convolutional layers apply convolution operations to the input and pass the results to the next layer. This enables the network to be deep with fewer parameters, enhancing the learning of feature hierarchies.

  • Pooling layers reduce the dimensions of the data by combining the outputs of neuron clusters at one layer into a single neuron in the next layer.

  • Fully connected layers connect every neuron in one layer to every neuron in the next layer and are typically used at the end of the network to make class predictions.

Due to their ability to capture the spatial (image) and temporal (video) dependencies through the application of relevant filters, CNNs are extensively used in image and video recognition, recommender systems, image classification, medical image analysis, and natural language processing.

LeNet.png

The first CNNs were devised in the late 1980s by Yann LeCun and they were designed to solve the digit recognition task present in the MNIST dataset. It’s a simple yet effective architecture that demonstrates the main concepts that still underly many more advanced CNN architectures today. Here we’ll replicate the structure of LeNet up to the fully connected fc2 layer. The latent representation in this layer is 84 dimensional. We’ll add various decoder heads and bottleneck layers to this core architecture (sometimes called a backbone) and then we will train on different objectives (cost functions), and we will see how the representations change.

Preparing the data

  0%|          | 0/9912422 [00:00<?, ?it/s]
100%|██████████| 9912422/9912422 [00:00<00:00, 131308167.79it/s]

  0%|          | 0/28881 [00:00<?, ?it/s]
100%|██████████| 28881/28881 [00:00<00:00, 6684823.90it/s]

  0%|          | 0/1648877 [00:00<?, ?it/s]
100%|██████████| 1648877/1648877 [00:00<00:00, 88426070.46it/s]

  0%|          | 0/4542 [00:00<?, ?it/s]
100%|██████████| 4542/4542 [00:00<00:00, 3404311.79it/s]

Visualizing some samples from the dataset

<Figure size 800x400 with 10 Axes>

Preparing the data loaders

Section 1.1: Classification

In this task, we’ll train the CNN to classify digits into one of 10 different classes.

Code exercise 1: Cost Function

Training

In this task, we aim to classify hand-written digits from images, where each digit ranges from 0 to 9. To achieve this, we add a classification head to the CNN.

We introduce an output layer Y with 10 nodes, each representing one of the possible digits. The output layer uses the softmax activation function to produce probability scores for each class:

p(y=j∣x)=eμj∑k=110eμkp(y=j|x) = \frac{e^{\mu_j}}{\sum_{k=1}^{10} e^{\mu_k}}

where μj=CNNj(x)\mu_j = \text{CNN}_j(x) is the output of the jthj^{th} node in the output layer.

Thus, the network outputs a probability distribution over the 10 possible classes for each input image.

Cost Function

To train the network effectively, we implement a cost function based the the concept of cross-entropy. The cost function is defined as:

L=−1N∑i=1N∑j=110yijlog⁡(p(yij∣xi))\mathcal{L} = -\frac{1}{N} \sum_{i=1}^{N} \sum_{j=1}^{10} y_{ij} \log(p(y_{ij}|x_i))

where:

  • NN is the number of samples

  • yijy_{ij} is the true label for the ithi^{th} sample, encoded as a one-hot vector

  • p(yij∣xi)p(y_{ij}|x_i) is the predicted probability of the jthj^{th} class for the ithi^{th} sample.

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[15], line 2
      1 ############################################################
----> 2 raise NotImplementedError("Student exercise: Calculate the loss using the criterion")
      3 ############################################################
      5 def cost_classification(output, target):

NotImplementedError: Student exercise: Calculate the loss using the criterion

By implementing this cost function, the model is trained to minimize the difference between the predicted probability distributions and the actual one-hot encoded targets (also a probability distribution, but with all of the weight on a single class).

Defining the model

We define a CNN model with a classification head to classify the digits.

Here, ConvNet represents the convolutional part of the network responsible for feature extraction, while Output is the classification output layer described earlier and implemented in code. In the slot for ConvNet, we will be passing the instantiated object ConvNeuralNet (see above) and in the slot for Output, we will be passing the instantiated object ClassificationOutputLayer (also defined above).

Training on different dataset sizes

We conduct training experiments with this model on varying dataset sizes (10, 100, 1000, 10000). This approach helps us understand how the model’s performance scales with the amount of training data available (sample complexity). Larger datasets typically improve the model’s ability to generalize to the test set.

Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:01<00:16,  1.82s/epoch]
Epoch: 1| Train cost:  2.30030| Train acc:  0.20000| Val cost:  2.30344| Val acc:  0.10000| Test cost:  2.30159| Test acc:  0.09972
Saving the model: models/ConvNet_classification_10_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:03<00:15,  2.00s/epoch]
Epoch: 2| Train cost:  2.29476| Train acc:  0.20000| Val cost:  2.30213| Val acc:  0.10000| Test cost:  2.30087| Test acc:  0.10171
Saving the model: models/ConvNet_classification_10_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:05<00:12,  1.83s/epoch]
Epoch: 3| Train cost:  2.28905| Train acc:  0.30000| Val cost:  2.30084| Val acc:  0.10000| Test cost:  2.30005| Test acc:  0.13256
Saving the model: models/ConvNet_classification_10_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:07<00:10,  1.77s/epoch]
Epoch: 4| Train cost:  2.28218| Train acc:  0.40000| Val cost:  2.29938| Val acc:  0.10000| Test cost:  2.29908| Test acc:  0.15545
Saving the model: models/ConvNet_classification_10_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:09<00:09,  1.88s/epoch]
Epoch: 5| Train cost:  2.27340| Train acc:  0.40000| Val cost:  2.29780| Val acc:  0.10000| Test cost:  2.29780| Test acc:  0.16939
Saving the model: models/ConvNet_classification_10_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:11<00:08,  2.06s/epoch]
Epoch: 6| Train cost:  2.26213| Train acc:  0.40000| Val cost:  2.29630| Val acc:  0.13333| Test cost:  2.29618| Test acc:  0.18312
Saving the model: models/ConvNet_classification_10_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:14<00:07,  2.42s/epoch]
Epoch: 7| Train cost:  2.24699| Train acc:  0.40000| Val cost:  2.29527| Val acc:  0.13333| Test cost:  2.29392| Test acc:  0.18710
Saving the model: models/ConvNet_classification_10_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:17<00:04,  2.48s/epoch]
Epoch: 8| Train cost:  2.22722| Train acc:  0.40000| Val cost:  2.29514| Val acc:  0.13333| Test cost:  2.29166| Test acc:  0.18869
Saving the model: models/ConvNet_classification_10_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:19<00:02,  2.33s/epoch]
Epoch: 9| Train cost:  2.20304| Train acc:  0.40000| Val cost:  2.29622| Val acc:  0.13333| Test cost:  2.28872| Test acc:  0.18969
Saving the model: models/ConvNet_classification_10_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:21<00:00,  2.22s/epoch]
Training epochs: 100%|██████████| 10/10 [00:21<00:00,  2.15s/epoch]

Epoch: 10| Train cost:  2.17485| Train acc:  0.40000| Val cost:  2.29858| Val acc:  0.13333| Test cost:  2.28652| Test acc:  0.18830
Saving the model: models/ConvNet_classification_10_epoch_10.pth
Elapsed: 21.48461604118347
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:03<00:32,  3.60s/epoch]
Epoch: 1| Train cost:  2.29918| Train acc:  0.23438| Val cost:  2.29809| Val acc:  0.16667| Test cost:  2.30008| Test acc:  0.09773
Saving the model: models/ConvNet_classification_100_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:06<00:24,  3.08s/epoch]
Epoch: 2| Train cost:  2.28924| Train acc:  0.16406| Val cost:  2.29134| Val acc:  0.16667| Test cost:  2.29702| Test acc:  0.09773
Saving the model: models/ConvNet_classification_100_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:08<00:18,  2.67s/epoch]
Epoch: 3| Train cost:  2.30070| Train acc:  0.10938| Val cost:  2.27972| Val acc:  0.16667| Test cost:  2.29231| Test acc:  0.09893
Saving the model: models/ConvNet_classification_100_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:10<00:14,  2.43s/epoch]
Epoch: 4| Train cost:  2.27172| Train acc:  0.16406| Val cost:  2.27588| Val acc:  0.16667| Test cost:  2.28427| Test acc:  0.09773
Saving the model: models/ConvNet_classification_100_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:14<00:14,  2.97s/epoch]
Epoch: 5| Train cost:  2.22435| Train acc:  0.21875| Val cost:  2.26439| Val acc:  0.16667| Test cost:  2.28069| Test acc:  0.09893
Saving the model: models/ConvNet_classification_100_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:17<00:11,  2.92s/epoch]
Epoch: 6| Train cost:  2.22952| Train acc:  0.16406| Val cost:  2.24435| Val acc:  0.16667| Test cost:  2.26329| Test acc:  0.10231
Saving the model: models/ConvNet_classification_100_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:19<00:08,  2.83s/epoch]
Epoch: 7| Train cost:  2.17872| Train acc:  0.27344| Val cost:  2.24259| Val acc:  0.20000| Test cost:  2.21076| Test acc:  0.27667
Saving the model: models/ConvNet_classification_100_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:23<00:05,  2.93s/epoch]
Epoch: 8| Train cost:  2.13272| Train acc:  0.32031| Val cost:  2.22052| Val acc:  0.20000| Test cost:  2.17802| Test acc:  0.28244
Saving the model: models/ConvNet_classification_100_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:26<00:03,  3.08s/epoch]
Epoch: 9| Train cost:  2.13415| Train acc:  0.33594| Val cost:  2.18109| Val acc:  0.23333| Test cost:  2.15290| Test acc:  0.28842
Saving the model: models/ConvNet_classification_100_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:28<00:00,  2.80s/epoch]
Training epochs: 100%|██████████| 10/10 [00:28<00:00,  2.87s/epoch]

Epoch: 10| Train cost:  2.08263| Train acc:  0.37500| Val cost:  2.17162| Val acc:  0.36667| Test cost:  2.13271| Test acc:  0.37142
Saving the model: models/ConvNet_classification_100_epoch_10.pth
Elapsed: 28.698782920837402
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:02<00:25,  2.84s/epoch]
Epoch: 1| Train cost:  2.22603| Train acc:  0.26465| Val cost:  2.02347| Val acc:  0.50521| Test cost:  2.02995| Test acc:  0.49542
Saving the model: models/ConvNet_classification_1000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:06<00:28,  3.57s/epoch]
Epoch: 2| Train cost:  1.87207| Train acc:  0.61523| Val cost:  1.77983| Val acc:  0.69219| Test cost:  1.78431| Test acc:  0.68869
Saving the model: models/ConvNet_classification_1000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:09<00:21,  3.07s/epoch]
Epoch: 3| Train cost:  1.70036| Train acc:  0.78027| Val cost:  1.69686| Val acc:  0.79271| Test cost:  1.70968| Test acc:  0.76154
Saving the model: models/ConvNet_classification_1000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:11<00:17,  2.85s/epoch]
Epoch: 4| Train cost:  1.68390| Train acc:  0.78418| Val cost:  1.62508| Val acc:  0.86719| Test cost:  1.66928| Test acc:  0.80195
Saving the model: models/ConvNet_classification_1000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:14<00:13,  2.78s/epoch]
Epoch: 5| Train cost:  1.64100| Train acc:  0.83008| Val cost:  1.67413| Val acc:  0.79271| Test cost:  1.67648| Test acc:  0.78861
Saving the model: models/ConvNet_classification_1000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:17<00:11,  2.92s/epoch]
Epoch: 6| Train cost:  1.63098| Train acc:  0.83398| Val cost:  1.66576| Val acc:  0.80260| Test cost:  1.65673| Test acc:  0.81150
Saving the model: models/ConvNet_classification_1000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:21<00:09,  3.17s/epoch]
Epoch: 7| Train cost:  1.61839| Train acc:  0.84961| Val cost:  1.65835| Val acc:  0.81615| Test cost:  1.63493| Test acc:  0.82902
Saving the model: models/ConvNet_classification_1000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:24<00:06,  3.01s/epoch]
Epoch: 8| Train cost:  1.60526| Train acc:  0.85742| Val cost:  1.64911| Val acc:  0.81615| Test cost:  1.64544| Test acc:  0.82006
Saving the model: models/ConvNet_classification_1000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:26<00:02,  2.91s/epoch]
Epoch: 9| Train cost:  1.61448| Train acc:  0.84766| Val cost:  1.61026| Val acc:  0.84948| Test cost:  1.62853| Test acc:  0.83599
Saving the model: models/ConvNet_classification_1000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:29<00:00,  2.81s/epoch]
Training epochs: 100%|██████████| 10/10 [00:29<00:00,  2.94s/epoch]

Epoch: 10| Train cost:  1.59131| Train acc:  0.87305| Val cost:  1.62935| Val acc:  0.84062| Test cost:  1.62815| Test acc:  0.83380
Saving the model: models/ConvNet_classification_1000_epoch_10.pth
Elapsed: 29.385913848876953
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:10<01:31, 10.13s/epoch]
Epoch: 1| Train cost:  1.67816| Train acc:  0.80122| Val cost:  1.54842| Val acc:  0.91557| Test cost:  1.53607| Test acc:  0.93113
Saving the model: models/ConvNet_classification_10000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:20<01:20, 10.04s/epoch]
Epoch: 2| Train cost:  1.52944| Train acc:  0.93510| Val cost:  1.52355| Val acc:  0.94161| Test cost:  1.51787| Test acc:  0.94566
Saving the model: models/ConvNet_classification_10000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:29<01:09,  9.88s/epoch]
Epoch: 3| Train cost:  1.50815| Train acc:  0.95487| Val cost:  1.51061| Val acc:  0.94965| Test cost:  1.50064| Test acc:  0.96238
Saving the model: models/ConvNet_classification_10000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:42<01:06, 11.13s/epoch]
Epoch: 4| Train cost:  1.49887| Train acc:  0.96366| Val cost:  1.50931| Val acc:  0.95446| Test cost:  1.50399| Test acc:  0.95900
Saving the model: models/ConvNet_classification_10000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:50<00:49,  9.93s/epoch]
Epoch: 5| Train cost:  1.49510| Train acc:  0.96735| Val cost:  1.49687| Val acc:  0.96483| Test cost:  1.49927| Test acc:  0.96158
Saving the model: models/ConvNet_classification_10000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:56<00:34,  8.64s/epoch]
Epoch: 6| Train cost:  1.48914| Train acc:  0.97304| Val cost:  1.48913| Val acc:  0.97286| Test cost:  1.49043| Test acc:  0.97193
Saving the model: models/ConvNet_classification_10000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [01:04<00:24,  8.19s/epoch]
Epoch: 7| Train cost:  1.48572| Train acc:  0.97624| Val cost:  1.49966| Val acc:  0.96180| Test cost:  1.50696| Test acc:  0.95482
Saving the model: models/ConvNet_classification_10000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [01:11<00:15,  7.83s/epoch]
Epoch: 8| Train cost:  1.48543| Train acc:  0.97624| Val cost:  1.49145| Val acc:  0.96875| Test cost:  1.48952| Test acc:  0.97154
Saving the model: models/ConvNet_classification_10000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [01:18<00:07,  7.62s/epoch]
Epoch: 9| Train cost:  1.48626| Train acc:  0.97534| Val cost:  1.48897| Val acc:  0.97321| Test cost:  1.48998| Test acc:  0.97094
Saving the model: models/ConvNet_classification_10000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [01:26<00:00,  7.85s/epoch]
Training epochs: 100%|██████████| 10/10 [01:26<00:00,  8.66s/epoch]
Epoch: 10| Train cost:  1.47923| Train acc:  0.98263| Val cost:  1.49227| Val acc:  0.96875| Test cost:  1.48878| Test acc:  0.97253
Saving the model: models/ConvNet_classification_10000_epoch_10.pth
Elapsed: 86.64827084541321

Test performance

The test performance of the model is evaluated by plotting the test cost across training epochs for different sample sizes.

<Figure size 800x600 with 1 Axes>

Discussion point 1

Now that you have trained your network with different sample sizes, plot the performance on the test dataset for each network across epochs. How does sample size interact with number of training epochs?

Section 1.2: Regression

After examining the use of network architecture for digit classification, we now transition to a regression task using the same architecture. We are going to pick a very simple output task that is not directly related to the classification or the identification of the digits. In this task, given an image of a handwritten digit, our objective is to predict the number of pixels that are ‘ON’ (i.e., pixel values greater than 0.5). This can be achieved by the network performing operations similar to the simple addition of pixels (though it might still take time and data for the network to find this simple solution). Thus, we don’t expect that the network will learn rich representations that are useful for other tasks, such as classification.

Task objective

This regression task, while relatively simple as it involves summing pixel values, serves to illustrate how well a Convolutional Neural Network (CNN) can adapt to learning a continuous output instead of discrete class labels.

Output layer

The output layer for this regression task consists of a single node that predicts the number of ‘ON’ pixels in the image. This necessitates a different cost function compared to the classification task.

Here, RegressionOutputLayer outputs a single continuous value.

Code exercise 2: Cost function

Here we implement the mean squared error (MSE) loss, which measures the average squared difference between the predicted and actual pixel values:

L=1N∑i=1N(yi−μi)2\mathcal{L} = \frac{1}{N} \sum_{i=1}^{N} (y_i - \mu_i)^2

where:

  • NN is the number of sample images

  • yiy_i is the true label for the ithi^{th} sample, the number of “ON” pixels

  • μi=CNN(xi)\mu_i = \text{CNN}(x_i) is the output of the model for the ithi^{th} sample image

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[20], line 6
      1 ############################################################
      2 # Hint for criterion: The criterion used for regression tasks is designed
      3 # to minimize the average squared difference between predicted and actual values.
      4 # Hint for cost: To compute the cost, apply the criterion function to
      5 # the predicted output and the actual target values, which will return the mean squared error loss.
----> 6 raise NotImplementedError("Student exercise")
      7 ############################################################
      9 def cost_regression(output, target):

NotImplementedError: Student exercise

This cost function computes the MSE loss between the predicted number of ‘ON’ pixels and the actual count of ‘ON’ pixels in the image, guiding the model to make accurate continuous predictions.

Training

We train the network on varying dataset sizes (10, 100, 1000, 10000) to observe the impact of sample size on the model’s performance.

The RegressionConvNet integrates the convolutional feature extraction network with the regression output layer.

Dataset preparation

We adapt the MNIST dataset for the regression task by computing the number of ‘ON’ pixels for each image.

This custom Dataset class transforms the images and computes the target values required for our regression task.

Model training and evaluation

We initialize datasets and data loaders for the regression task, and define functions to evaluate models across different sample sizes.

Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([10])) that is different to the input size (torch.Size([10, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([30])) that is different to the input size (torch.Size([30, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([32])) that is different to the input size (torch.Size([32, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([16])) that is different to the input size (torch.Size([16, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
Training epochs:  10%|█         | 1/10 [00:04<00:38,  4.23s/epoch]
Epoch: 1| Train cost:  0.00267| Val cost:  0.02717| Test cost:  0.02624|
Saving the model: models/ConvNet_regression_10_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:08<00:34,  4.34s/epoch]
Epoch: 2| Train cost:  0.01898| Val cost:  0.00730| Test cost:  0.00691|
Saving the model: models/ConvNet_regression_10_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:12<00:28,  4.06s/epoch]
Epoch: 3| Train cost:  0.00361| Val cost:  0.00320| Test cost:  0.00301|
Saving the model: models/ConvNet_regression_10_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:17<00:27,  4.55s/epoch]
Epoch: 4| Train cost:  0.00313| Val cost:  0.00431| Test cost:  0.00419|
Saving the model: models/ConvNet_regression_10_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:21<00:21,  4.39s/epoch]
Epoch: 5| Train cost:  0.00580| Val cost:  0.00449| Test cost:  0.00437|
Saving the model: models/ConvNet_regression_10_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:25<00:17,  4.26s/epoch]
Epoch: 6| Train cost:  0.00594| Val cost:  0.00393| Test cost:  0.00380|
Saving the model: models/ConvNet_regression_10_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:30<00:13,  4.48s/epoch]
Epoch: 7| Train cost:  0.00483| Val cost:  0.00340| Test cost:  0.00324|
Saving the model: models/ConvNet_regression_10_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:35<00:08,  4.42s/epoch]
Epoch: 8| Train cost:  0.00368| Val cost:  0.00314| Test cost:  0.00295|
Saving the model: models/ConvNet_regression_10_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:38<00:04,  4.23s/epoch]
Epoch: 9| Train cost:  0.00282| Val cost:  0.00318| Test cost:  0.00295|
Saving the model: models/ConvNet_regression_10_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:43<00:00,  4.38s/epoch]
Training epochs: 100%|██████████| 10/10 [00:43<00:00,  4.35s/epoch]

Epoch: 10| Train cost:  0.00229| Val cost:  0.00346| Test cost:  0.00318|
Saving the model: models/ConvNet_regression_10_epoch_10.pth
Elapsed: 43.54073619842529
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([4])) that is different to the input size (torch.Size([4, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
Training epochs:  10%|█         | 1/10 [00:04<00:36,  4.09s/epoch]
Epoch: 1| Train cost:  0.00471| Val cost:  0.00265| Test cost:  0.00336|
Saving the model: models/ConvNet_regression_100_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:07<00:31,  3.92s/epoch]
Epoch: 2| Train cost:  0.00352| Val cost:  0.00230| Test cost:  0.00295|
Saving the model: models/ConvNet_regression_100_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:13<00:31,  4.51s/epoch]
Epoch: 3| Train cost:  0.00279| Val cost:  0.00258| Test cost:  0.00311|
Saving the model: models/ConvNet_regression_100_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:17<00:27,  4.60s/epoch]
Epoch: 4| Train cost:  0.00251| Val cost:  0.00248| Test cost:  0.00302|
Saving the model: models/ConvNet_regression_100_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:26<00:29,  5.99s/epoch]
Epoch: 5| Train cost:  0.00324| Val cost:  0.00231| Test cost:  0.00290|
Saving the model: models/ConvNet_regression_100_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:30<00:21,  5.49s/epoch]
Epoch: 6| Train cost:  0.00261| Val cost:  0.00227| Test cost:  0.00290|
Saving the model: models/ConvNet_regression_100_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:35<00:15,  5.10s/epoch]
Epoch: 7| Train cost:  0.00248| Val cost:  0.00228| Test cost:  0.00291|
Saving the model: models/ConvNet_regression_100_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:38<00:09,  4.69s/epoch]
Epoch: 8| Train cost:  0.00289| Val cost:  0.00228| Test cost:  0.00289|
Saving the model: models/ConvNet_regression_100_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:43<00:04,  4.69s/epoch]
Epoch: 9| Train cost:  0.00256| Val cost:  0.00230| Test cost:  0.00289|
Saving the model: models/ConvNet_regression_100_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:47<00:00,  4.55s/epoch]
Training epochs: 100%|██████████| 10/10 [00:47<00:00,  4.79s/epoch]

Epoch: 10| Train cost:  0.00286| Val cost:  0.00235| Test cost:  0.00292|
Saving the model: models/ConvNet_regression_100_epoch_10.pth
Elapsed: 47.865981578826904
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([8])) that is different to the input size (torch.Size([8, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([15])) that is different to the input size (torch.Size([15, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
Training epochs:  10%|█         | 1/10 [00:05<00:48,  5.44s/epoch]
Epoch: 1| Train cost:  0.00513| Val cost:  0.00351| Test cost:  0.00298|
Saving the model: models/ConvNet_regression_1000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:10<00:44,  5.50s/epoch]
Epoch: 2| Train cost:  0.00303| Val cost:  0.00361| Test cost:  0.00293|
Saving the model: models/ConvNet_regression_1000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:17<00:40,  5.85s/epoch]
Epoch: 3| Train cost:  0.00303| Val cost:  0.00372| Test cost:  0.00308|
Saving the model: models/ConvNet_regression_1000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:24<00:37,  6.29s/epoch]
Epoch: 4| Train cost:  0.00310| Val cost:  0.00321| Test cost:  0.00292|
Saving the model: models/ConvNet_regression_1000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:28<00:28,  5.67s/epoch]
Epoch: 5| Train cost:  0.00306| Val cost:  0.00325| Test cost:  0.00294|
Saving the model: models/ConvNet_regression_1000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:33<00:21,  5.42s/epoch]
Epoch: 6| Train cost:  0.00331| Val cost:  0.00386| Test cost:  0.00306|
Saving the model: models/ConvNet_regression_1000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:38<00:15,  5.30s/epoch]
Epoch: 7| Train cost:  0.00305| Val cost:  0.00322| Test cost:  0.00290|
Saving the model: models/ConvNet_regression_1000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:44<00:10,  5.42s/epoch]
Epoch: 8| Train cost:  0.00304| Val cost:  0.00315| Test cost:  0.00291|
Saving the model: models/ConvNet_regression_1000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:51<00:05,  5.92s/epoch]
Epoch: 9| Train cost:  0.00305| Val cost:  0.00306| Test cost:  0.00293|
Saving the model: models/ConvNet_regression_1000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:57<00:00,  5.86s/epoch]
Training epochs: 100%|██████████| 10/10 [00:57<00:00,  5.72s/epoch]

Epoch: 10| Train cost:  0.00295| Val cost:  0.00342| Test cost:  0.00293|
Saving the model: models/ConvNet_regression_1000_epoch_10.pth
Elapsed: 57.215006589889526
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
/opt/hostedtoolcache/Python/3.10.22/x64/lib/python3.10/site-packages/torch/nn/modules/loss.py:535: UserWarning: Using a target size (torch.Size([23])) that is different to the input size (torch.Size([23, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.
  return F.mse_loss(input, target, reduction=self.reduction)
Training epochs:  10%|█         | 1/10 [00:13<02:05, 13.93s/epoch]
Epoch: 1| Train cost:  0.00293| Val cost:  0.00310| Test cost:  0.00293|
Saving the model: models/ConvNet_regression_10000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:30<02:02, 15.32s/epoch]
Epoch: 2| Train cost:  0.00290| Val cost:  0.00307| Test cost:  0.00291|
Saving the model: models/ConvNet_regression_10000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:49<01:59, 17.09s/epoch]
Epoch: 3| Train cost:  0.00290| Val cost:  0.00306| Test cost:  0.00289|
Saving the model: models/ConvNet_regression_10000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [01:06<01:43, 17.28s/epoch]
Epoch: 4| Train cost:  0.00289| Val cost:  0.00306| Test cost:  0.00288|
Saving the model: models/ConvNet_regression_10000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [01:26<01:30, 18.15s/epoch]
Epoch: 5| Train cost:  0.00289| Val cost:  0.00307| Test cost:  0.00289|
Saving the model: models/ConvNet_regression_10000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [01:38<01:04, 16.15s/epoch]
Epoch: 6| Train cost:  0.00288| Val cost:  0.00305| Test cost:  0.00288|
Saving the model: models/ConvNet_regression_10000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [01:51<00:44, 14.95s/epoch]
Epoch: 7| Train cost:  0.00289| Val cost:  0.00307| Test cost:  0.00289|
Saving the model: models/ConvNet_regression_10000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [02:06<00:30, 15.00s/epoch]
Epoch: 8| Train cost:  0.00289| Val cost:  0.00309| Test cost:  0.00290|
Saving the model: models/ConvNet_regression_10000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [02:18<00:14, 14.08s/epoch]
Epoch: 9| Train cost:  0.00289| Val cost:  0.00307| Test cost:  0.00289|
Saving the model: models/ConvNet_regression_10000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [02:27<00:00, 12.52s/epoch]
Training epochs: 100%|██████████| 10/10 [02:27<00:00, 14.76s/epoch]
Epoch: 10| Train cost:  0.00288| Val cost:  0.00307| Test cost:  0.00289|
Saving the model: models/ConvNet_regression_10000_epoch_10.pth
Elapsed: 147.6378402709961

Discussion point 2

Now that you have trained your network with different sample sizes, plot the test performance for each network across epochs. How does sample size interact with the number of training epochs?

<Figure size 800x600 with 1 Axes>

Section 1.3: Auto-encoder

Now, we extend our network architecture to an unsupervised learning task. Specifically, we aim to develop an autoencoder capable of compressing an image of a handwritten digit into a lower-dimensional representation of size MM and then reconstructing the original image with minimal error.

Autoencoder architecture

An autoencoder consists of three main components: an encoder, a bottleneck layer, and a decoder. The encoder compresses the input into a smaller representation, the bottleneck layer holds this compressed representation, and the decoder reconstructs the original image from this representation.

In our architecture:

  • The encoder will be a CNN

  • The bottleneck layer will be a fully connected layer of size MM.

  • The decoder layer will be a deconvolutional neural network, which does the operations of a CNN in reverse: it goes from a dense representation to a low-resolution image, and then upsamples that image in subsequent layers.

Code exercise 3: Cost Function

We’ll use Mean Squared Error (MSE) loss for the autoencoder. This loss function measures the average squared difference between the original and reconstructed images, guiding the network to minimize the reconstruction error.

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
Cell In[26], line 6
      1 ############################################################
      2 # Hint for output_flat: To flatten the output tensor for comparison, reshape it to
      3 # have a size of (batch_size, -1) where batch_size is the number of samples.
      4 # Hint for target_flat: Similarly, flatten the target tensor to match the shape
      5 # of the flattened output tensor, ensuring it has a size of (batch_size, -1).
----> 6 raise NotImplementedError("Student exercise")
      7 ############################################################
      9 def cost_autoencoder(output, target):

NotImplementedError: Student exercise

Dataset

This custom Dataset class prepares the MNIST images for the autoencoder task, applying necessary transformations and using the images themselves as targets for reconstruction.

Model training and evaluation

We train separate autoencoder networks on different dataset sizes (10, 100, 1000, 10000) to analyze how the amount of data influences the model’s performance. The training continues until the validation performance ceases to improve, and test performance is recorded at each epoch.

Note: we also plot here some of the original validation images and how well they were reconstructed by each network after 10 iterations.

Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:01<00:14,  1.57s/epoch]
Epoch: 1| Train cost:  0.82655| Val cost:  0.93275| Test cost:  0.91777|
Saving the model: models/ConvNet_autoencoder_10_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:03<00:12,  1.57s/epoch]
Epoch: 2| Train cost:  0.82601| Val cost:  0.93241| Test cost:  0.91647|
Saving the model: models/ConvNet_autoencoder_10_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:04<00:10,  1.47s/epoch]
Epoch: 3| Train cost:  0.82552| Val cost:  0.93208| Test cost:  0.91641|
Saving the model: models/ConvNet_autoencoder_10_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:05<00:08,  1.46s/epoch]
Epoch: 4| Train cost:  0.82504| Val cost:  0.93175| Test cost:  0.91530|
Saving the model: models/ConvNet_autoencoder_10_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:07<00:07,  1.44s/epoch]
Epoch: 5| Train cost:  0.82457| Val cost:  0.93140| Test cost:  0.91583|
Saving the model: models/ConvNet_autoencoder_10_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:08<00:05,  1.42s/epoch]
Epoch: 6| Train cost:  0.82409| Val cost:  0.93102| Test cost:  0.91561|
Saving the model: models/ConvNet_autoencoder_10_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:10<00:04,  1.43s/epoch]
Epoch: 7| Train cost:  0.82359| Val cost:  0.93060| Test cost:  0.91493|
Saving the model: models/ConvNet_autoencoder_10_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:11<00:02,  1.44s/epoch]
Epoch: 8| Train cost:  0.82304| Val cost:  0.93011| Test cost:  0.91440|
Saving the model: models/ConvNet_autoencoder_10_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:13<00:01,  1.48s/epoch]
Epoch: 9| Train cost:  0.82244| Val cost:  0.92949| Test cost:  0.91384|
Saving the model: models/ConvNet_autoencoder_10_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:14<00:00,  1.53s/epoch]
Training epochs: 100%|██████████| 10/10 [00:14<00:00,  1.48s/epoch]
Epoch: 10| Train cost:  0.82173| Val cost:  0.92875| Test cost:  0.91289|
Saving the model: models/ConvNet_autoencoder_10_epoch_10.pth
Elapsed: 14.83527135848999

<Figure size 1000x500 with 12 Axes>
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:01<00:14,  1.67s/epoch]
Epoch: 1| Train cost:  0.94496| Val cost:  1.09508| Test cost:  0.92759|
Saving the model: models/ConvNet_autoencoder_100_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:03<00:13,  1.68s/epoch]
Epoch: 2| Train cost:  0.84873| Val cost:  1.08896| Test cost:  0.92309|
Saving the model: models/ConvNet_autoencoder_100_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:04<00:10,  1.57s/epoch]
Epoch: 3| Train cost:  0.89585| Val cost:  1.08088| Test cost:  0.91713|
Saving the model: models/ConvNet_autoencoder_100_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:06<00:09,  1.52s/epoch]
Epoch: 4| Train cost:  0.89527| Val cost:  1.06307| Test cost:  0.90104|
Saving the model: models/ConvNet_autoencoder_100_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:07<00:07,  1.48s/epoch]
Epoch: 5| Train cost:  0.90988| Val cost:  0.99760| Test cost:  0.84872|
Saving the model: models/ConvNet_autoencoder_100_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:09<00:05,  1.44s/epoch]
Epoch: 6| Train cost:  0.80133| Val cost:  0.85810| Test cost:  0.75280|
Saving the model: models/ConvNet_autoencoder_100_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:10<00:04,  1.42s/epoch]
Epoch: 7| Train cost:  0.73808| Val cost:  0.82491| Test cost:  0.72001|
Saving the model: models/ConvNet_autoencoder_100_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:11<00:02,  1.40s/epoch]
Epoch: 8| Train cost:  0.67040| Val cost:  0.83882| Test cost:  0.72085|
Saving the model: models/ConvNet_autoencoder_100_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:13<00:01,  1.39s/epoch]
Epoch: 9| Train cost:  0.68790| Val cost:  0.80060| Test cost:  0.69180|
Saving the model: models/ConvNet_autoencoder_100_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:14<00:00,  1.40s/epoch]
Training epochs: 100%|██████████| 10/10 [00:14<00:00,  1.45s/epoch]
Epoch: 10| Train cost:  0.67945| Val cost:  0.77658| Test cost:  0.67812|
Saving the model: models/ConvNet_autoencoder_100_epoch_10.pth
Elapsed: 14.539740085601807

<Figure size 1000x500 with 12 Axes>
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:01<00:16,  1.86s/epoch]
Epoch: 1| Train cost:  0.79917| Val cost:  0.67037| Test cost:  0.67448|
Saving the model: models/ConvNet_autoencoder_1000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:03<00:14,  1.82s/epoch]
Epoch: 2| Train cost:  0.62655| Val cost:  0.61430| Test cost:  0.61075|
Saving the model: models/ConvNet_autoencoder_1000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:05<00:12,  1.81s/epoch]
Epoch: 3| Train cost:  0.59072| Val cost:  0.59552| Test cost:  0.58794|
Saving the model: models/ConvNet_autoencoder_1000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:07<00:10,  1.80s/epoch]
Epoch: 4| Train cost:  0.57191| Val cost:  0.58535| Test cost:  0.57859|
Saving the model: models/ConvNet_autoencoder_1000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:09<00:09,  1.88s/epoch]
Epoch: 5| Train cost:  0.56554| Val cost:  0.56753| Test cost:  0.56739|
Saving the model: models/ConvNet_autoencoder_1000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:11<00:07,  1.98s/epoch]
Epoch: 6| Train cost:  0.53882| Val cost:  0.54184| Test cost:  0.52921|
Saving the model: models/ConvNet_autoencoder_1000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:13<00:06,  2.06s/epoch]
Epoch: 7| Train cost:  0.50869| Val cost:  0.52191| Test cost:  0.51086|
Saving the model: models/ConvNet_autoencoder_1000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:15<00:04,  2.10s/epoch]
Epoch: 8| Train cost:  0.48314| Val cost:  0.47686| Test cost:  0.47093|
Saving the model: models/ConvNet_autoencoder_1000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:17<00:02,  2.03s/epoch]
Epoch: 9| Train cost:  0.44747| Val cost:  0.44217| Test cost:  0.43576|
Saving the model: models/ConvNet_autoencoder_1000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:19<00:00,  2.01s/epoch]
Training epochs: 100%|██████████| 10/10 [00:19<00:00,  1.97s/epoch]
Epoch: 10| Train cost:  0.41884| Val cost:  0.43198| Test cost:  0.42414|
Saving the model: models/ConvNet_autoencoder_1000_epoch_10.pth
Elapsed: 19.699796438217163

<Figure size 1000x500 with 12 Axes>
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:07<01:07,  7.53s/epoch]
Epoch: 1| Train cost:  0.56517| Val cost:  0.41709| Test cost:  0.42086|
Saving the model: models/ConvNet_autoencoder_10000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:14<00:56,  7.07s/epoch]
Epoch: 2| Train cost:  0.35980| Val cost:  0.30554| Test cost:  0.30210|
Saving the model: models/ConvNet_autoencoder_10000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:20<00:46,  6.59s/epoch]
Epoch: 3| Train cost:  0.27801| Val cost:  0.26395| Test cost:  0.25817|
Saving the model: models/ConvNet_autoencoder_10000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:27<00:41,  6.88s/epoch]
Epoch: 4| Train cost:  0.24818| Val cost:  0.24584| Test cost:  0.24140|
Saving the model: models/ConvNet_autoencoder_10000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:33<00:33,  6.63s/epoch]
Epoch: 5| Train cost:  0.23459| Val cost:  0.23393| Test cost:  0.23006|
Saving the model: models/ConvNet_autoencoder_10000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:39<00:24,  6.22s/epoch]
Epoch: 6| Train cost:  0.22556| Val cost:  0.22720| Test cost:  0.22361|
Saving the model: models/ConvNet_autoencoder_10000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:44<00:17,  5.94s/epoch]
Epoch: 7| Train cost:  0.21961| Val cost:  0.22285| Test cost:  0.21948|
Saving the model: models/ConvNet_autoencoder_10000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:49<00:11,  5.73s/epoch]
Epoch: 8| Train cost:  0.21452| Val cost:  0.21692| Test cost:  0.21400|
Saving the model: models/ConvNet_autoencoder_10000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:55<00:05,  5.58s/epoch]
Epoch: 9| Train cost:  0.20975| Val cost:  0.21320| Test cost:  0.21058|
Saving the model: models/ConvNet_autoencoder_10000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [01:00<00:00,  5.49s/epoch]
Training epochs: 100%|██████████| 10/10 [01:00<00:00,  6.04s/epoch]
Epoch: 10| Train cost:  0.20529| Val cost:  0.21036| Test cost:  0.20666|
Saving the model: models/ConvNet_autoencoder_10000_epoch_10.pth
Elapsed: 60.412267208099365

<Figure size 1000x500 with 12 Axes>

Discussion point 3

  • Plot the performance of the network across epochs. What’s the relationship between sample size and iteration complexity?

  • What do you think of the images plotted above? Does the autoencoding task require more or less data than the two previous tasks (classification of digit and regression of number of ON pixels)?

<Figure size 800x600 with 1 Axes>

Section 1.4: Self-supervised - Inpainting

In this section, we implement a self-supervised task using the same architecture. We define a patch of an image to be a small portion of the main image, of a specific patch window size. Given an full image of a handwritten digit with a patch of size N×NN×N masked out, the objective is to reconstruct the image by accurately predicting the pixel values in the masked region. Thus, the network must use the surrounding context to effectively “inpaint” the missing portion.

Task objective

The task is to build an autoencoder that can fill in missing parts of an image, a process known as inpainting. This involves training the model to reconstruct the entire image. Implicitly, the model will predict and reconstruct the masked regions of the image using the contextual information from the non-masked parts.

Important note: this is a simplified inpainting task and not how inpainting is usually defined. Usually, the region to be inpainted is provided as part of the input.

Random masking

First, we implement a function to randomly mask a part of the image. This function will be used to generate the training data for our inpainting task.

Here’s one example of a masked image.

<Figure size 400x200 with 2 Axes>

This function randomly places a N×N mask in each image by setting the pixel values within this region to zero (black).

Autoencoder Cost Function

We re-use the same autoencoder architecture as in the previous sections, with an encoder, bottleneck layer, and decoder. We also use the Mean Squared Error (MSE) loss, as it measures the reconstruction error between the predicted and actual pixel values.

Dataset

This custom Dataset class prepares the MNIST images for the inpainting task, applying necessary transformations and adding random masking to create the training data. We specify mask_size to be 8 in the __getitem__ function. This could be specified in the Dataset initializer (__init__) if we wanted to change it. For now, we will keep it to be 8.

Model training and evaluation

We train the autoencoder on different dataset sizes (10, 100, 1000, 10000) to evaluate how the sample size affects the model’s performance. Training continues until validation performance stops improving, and test performance is recorded at each epoch.

Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:01<00:13,  1.45s/epoch]
Epoch: 1| Train cost:  0.82655| Val cost:  0.93275| Test cost:  0.91777|
Saving the model: models/ConvNet_inpainting_10_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:03<00:12,  1.55s/epoch]
Epoch: 2| Train cost:  0.82601| Val cost:  0.93241| Test cost:  0.91647|
Saving the model: models/ConvNet_inpainting_10_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:04<00:11,  1.59s/epoch]
Epoch: 3| Train cost:  0.82552| Val cost:  0.93208| Test cost:  0.91641|
Saving the model: models/ConvNet_inpainting_10_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:06<00:09,  1.55s/epoch]
Epoch: 4| Train cost:  0.82504| Val cost:  0.93175| Test cost:  0.91530|
Saving the model: models/ConvNet_inpainting_10_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:07<00:07,  1.52s/epoch]
Epoch: 5| Train cost:  0.82457| Val cost:  0.93140| Test cost:  0.91583|
Saving the model: models/ConvNet_inpainting_10_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:09<00:05,  1.50s/epoch]
Epoch: 6| Train cost:  0.82409| Val cost:  0.93103| Test cost:  0.91561|
Saving the model: models/ConvNet_inpainting_10_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:10<00:04,  1.48s/epoch]
Epoch: 7| Train cost:  0.82359| Val cost:  0.93061| Test cost:  0.91493|
Saving the model: models/ConvNet_inpainting_10_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:12<00:02,  1.48s/epoch]
Epoch: 8| Train cost:  0.82305| Val cost:  0.93013| Test cost:  0.91441|
Saving the model: models/ConvNet_inpainting_10_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:13<00:01,  1.48s/epoch]
Epoch: 9| Train cost:  0.82245| Val cost:  0.92950| Test cost:  0.91386|
Saving the model: models/ConvNet_inpainting_10_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:15<00:00,  1.49s/epoch]
Training epochs: 100%|██████████| 10/10 [00:15<00:00,  1.50s/epoch]

Epoch: 10| Train cost:  0.82175| Val cost:  0.92875| Test cost:  0.91291|
Saving the model: models/ConvNet_inpainting_10_epoch_10.pth
Elapsed: 15.0294828414917
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:01<00:13,  1.50s/epoch]
Epoch: 1| Train cost:  0.94496| Val cost:  1.09508| Test cost:  0.92759|
Saving the model: models/ConvNet_inpainting_100_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:03<00:12,  1.51s/epoch]
Epoch: 2| Train cost:  0.84873| Val cost:  1.08895| Test cost:  0.92308|
Saving the model: models/ConvNet_inpainting_100_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:04<00:10,  1.51s/epoch]
Epoch: 3| Train cost:  0.89581| Val cost:  1.08073| Test cost:  0.91698|
Saving the model: models/ConvNet_inpainting_100_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:06<00:08,  1.50s/epoch]
Epoch: 4| Train cost:  0.89478| Val cost:  1.06119| Test cost:  0.89939|
Saving the model: models/ConvNet_inpainting_100_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:07<00:07,  1.50s/epoch]
Epoch: 5| Train cost:  0.90555| Val cost:  0.98824| Test cost:  0.84085|
Saving the model: models/ConvNet_inpainting_100_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:08<00:05,  1.49s/epoch]
Epoch: 6| Train cost:  0.79199| Val cost:  0.86862| Test cost:  0.76460|
Saving the model: models/ConvNet_inpainting_100_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:10<00:04,  1.49s/epoch]
Epoch: 7| Train cost:  0.73877| Val cost:  0.82494| Test cost:  0.71873|
Saving the model: models/ConvNet_inpainting_100_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:11<00:02,  1.50s/epoch]
Epoch: 8| Train cost:  0.67005| Val cost:  0.83807| Test cost:  0.71954|
Saving the model: models/ConvNet_inpainting_100_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:13<00:01,  1.48s/epoch]
Epoch: 9| Train cost:  0.68633| Val cost:  0.79788| Test cost:  0.69004|
Saving the model: models/ConvNet_inpainting_100_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:14<00:00,  1.48s/epoch]
Training epochs: 100%|██████████| 10/10 [00:14<00:00,  1.49s/epoch]

Epoch: 10| Train cost:  0.67919| Val cost:  0.77445| Test cost:  0.67776|
Saving the model: models/ConvNet_inpainting_100_epoch_10.pth
Elapsed: 14.92612075805664
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:01<00:16,  1.84s/epoch]
Epoch: 1| Train cost:  0.79506| Val cost:  0.67492| Test cost:  0.67748|
Saving the model: models/ConvNet_inpainting_1000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:03<00:14,  1.86s/epoch]
Epoch: 2| Train cost:  0.62760| Val cost:  0.61575| Test cost:  0.61304|
Saving the model: models/ConvNet_inpainting_1000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:05<00:13,  1.88s/epoch]
Epoch: 3| Train cost:  0.59319| Val cost:  0.59748| Test cost:  0.59038|
Saving the model: models/ConvNet_inpainting_1000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:07<00:11,  1.88s/epoch]
Epoch: 4| Train cost:  0.57480| Val cost:  0.58742| Test cost:  0.58225|
Saving the model: models/ConvNet_inpainting_1000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:09<00:09,  1.89s/epoch]
Epoch: 5| Train cost:  0.57000| Val cost:  0.57417| Test cost:  0.57503|
Saving the model: models/ConvNet_inpainting_1000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:11<00:07,  1.89s/epoch]
Epoch: 6| Train cost:  0.56177| Val cost:  0.56145| Test cost:  0.55548|
Saving the model: models/ConvNet_inpainting_1000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:13<00:05,  1.91s/epoch]
Epoch: 7| Train cost:  0.53659| Val cost:  0.54408| Test cost:  0.53667|
Saving the model: models/ConvNet_inpainting_1000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:15<00:03,  1.92s/epoch]
Epoch: 8| Train cost:  0.52694| Val cost:  0.53012| Test cost:  0.52454|
Saving the model: models/ConvNet_inpainting_1000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:17<00:01,  1.91s/epoch]
Epoch: 9| Train cost:  0.50664| Val cost:  0.50016| Test cost:  0.49167|
Saving the model: models/ConvNet_inpainting_1000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:18<00:00,  1.90s/epoch]
Training epochs: 100%|██████████| 10/10 [00:18<00:00,  1.90s/epoch]

Epoch: 10| Train cost:  0.47016| Val cost:  0.48963| Test cost:  0.47331|
Saving the model: models/ConvNet_inpainting_1000_epoch_10.pth
Elapsed: 18.96262264251709
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:06<00:55,  6.14s/epoch]
Epoch: 1| Train cost:  0.58190| Val cost:  0.47491| Test cost:  0.48022|
Saving the model: models/ConvNet_inpainting_10000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:12<00:51,  6.49s/epoch]
Epoch: 2| Train cost:  0.42642| Val cost:  0.37903| Test cost:  0.37737|
Saving the model: models/ConvNet_inpainting_10000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:19<00:46,  6.58s/epoch]
Epoch: 3| Train cost:  0.32236| Val cost:  0.28765| Test cost:  0.28499|
Saving the model: models/ConvNet_inpainting_10000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:25<00:39,  6.52s/epoch]
Epoch: 4| Train cost:  0.27336| Val cost:  0.26973| Test cost:  0.26776|
Saving the model: models/ConvNet_inpainting_10000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:32<00:31,  6.35s/epoch]
Epoch: 5| Train cost:  0.25403| Val cost:  0.25183| Test cost:  0.24719|
Saving the model: models/ConvNet_inpainting_10000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:38<00:25,  6.29s/epoch]
Epoch: 6| Train cost:  0.23719| Val cost:  0.23522| Test cost:  0.23156|
Saving the model: models/ConvNet_inpainting_10000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:44<00:18,  6.24s/epoch]
Epoch: 7| Train cost:  0.22873| Val cost:  0.22697| Test cost:  0.22421|
Saving the model: models/ConvNet_inpainting_10000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:50<00:12,  6.20s/epoch]
Epoch: 8| Train cost:  0.22193| Val cost:  0.23003| Test cost:  0.22663|
Saving the model: models/ConvNet_inpainting_10000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:56<00:06,  6.16s/epoch]
Epoch: 9| Train cost:  0.21578| Val cost:  0.21727| Test cost:  0.21399|
Saving the model: models/ConvNet_inpainting_10000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [01:02<00:00,  6.15s/epoch]
Training epochs: 100%|██████████| 10/10 [01:02<00:00,  6.27s/epoch]
Epoch: 10| Train cost:  0.21112| Val cost:  0.21485| Test cost:  0.21163|
Saving the model: models/ConvNet_inpainting_10000_epoch_10.pth
Elapsed: 62.66530251502991

<Figure size 800x400 with 12 Axes>
<Figure size 800x400 with 12 Axes>
<Figure size 800x400 with 12 Axes>
<Figure size 800x400 with 12 Axes>

Discussion point 4

  • Plot the performance of the model on the test dataset for each network across epochs. What’s the relationship between sample size and number of training epochs?

  • How do these compare with the other examples above?

<Figure size 800x600 with 1 Axes>

Section 2: Generalization of representations

In the first part of this tutorial, we focused on training the same backbone architecture (a CNN) on different tasks, measuring how fast these networks learned in terms of training samples and training epochs. Here, we shift our attention to how well these representations generalize across the different tasks. To make this idea more concrete, think of a model that has learned to identify objects in images. Its early layers will be sensitive to basic blocks and lines, orientations, colors etc. The later layers in the model make use of these more basic shapes and gradually build up more complex patterns. Now, if the task changes to estimating the size of objects found in images, then the representations in those early layers (which capture basic shape information) are very useful to this new task, though some of the later layers will need to be tuned to better carry out the task. This is what we mean when we talk about generalizable representations - what learned patterns are useful for multiple (general) tasks - versus representations that are only uniquely relevant for other tasks.

Section 2.1: Transfer

Taskonomy

Humans can perform a wide range of tasks. The representations within this system must be general enough to handle multiple tasks, yet specific enough to accommodate differing requirements. We assess the ability of the representations we have learned to perform different tasks by testing generalization from one model to another.

Transfer learning

We’ll measure the ability of a model’s representations learned for one task by its ability to transfer to other tasks. For each of the four tasks, we’ll use the network trained for the highest number of training points (largest dataset size) and epochs. We define the source task to be the task the model was already trained on and the destination task to be the one we want to compare via transfer learning. A new test set will be provided for each task. To test generalization, we follow these steps:

  1. Create a new network for the destination task using the same architecture as in part 1.

  2. Copy the weights for the first N layers from the source network.

  3. Freeze these copied weights so they do not change during training.

  4. Train the remaining layers on the destination network.

After training, we’ll compare the new performance to the original performance to assess transfer performance (generalization) between each pair of networks.

Because we have N=4 different models, we could measure 2∗(N−1)∗(N−2)=122*(N-1)*(N-2)=12 transfer directions. In the interest of time, we’ll concentrate on measuring 3 transfer performances from the last 3 models to the classification model.

Copy weights

We start by defining a function to copy the weights and freeze the layers from the source model to the destination model.

Transfer example 1: regression to classification

We first copy the weights from a regression network to a classification network and freeze them.

['conv1.weight', 'conv1.bias', 'conv2.weight', 'conv2.bias', 'fc1.weight', 'fc1.bias', 'fc2.weight', 'fc2.bias', 'fc.weight', 'fc.bias']
Copied conv1.weight
Copied conv1.bias
Copied conv2.weight
Copied conv2.bias
Copied fc1.weight
Copied fc1.bias
Copied fc2.weight
Copied fc2.bias
8
froze  ConvNet.conv1.weight
froze  ConvNet.conv1.bias
froze  ConvNet.conv2.weight
froze  ConvNet.conv2.bias
froze  ConvNet.fc1.weight
froze  ConvNet.fc1.bias
froze  ConvNet.fc2.weight
froze  ConvNet.fc2.bias
Copied and froze 8 layers.

Training

We train the destination network on the classification task with the transferred weights.

Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:03<00:32,  3.57s/epoch]
Epoch: 1| Train cost:  2.30229| Val cost:  2.30211| Test cost:  2.30199|
Saving the model: models/ConvNet_regression_classification_10000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:07<00:29,  3.63s/epoch]
Epoch: 2| Train cost:  2.30187| Val cost:  2.30188| Test cost:  2.30149|
Saving the model: models/ConvNet_regression_classification_10000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:11<00:26,  3.73s/epoch]
Epoch: 3| Train cost:  2.30146| Val cost:  2.30165| Test cost:  2.30109|
Saving the model: models/ConvNet_regression_classification_10000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:14<00:21,  3.64s/epoch]
Epoch: 4| Train cost:  2.30102| Val cost:  2.30138| Test cost:  2.30061|
Saving the model: models/ConvNet_regression_classification_10000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:18<00:18,  3.62s/epoch]
Epoch: 5| Train cost:  2.30045| Val cost:  2.30101| Test cost:  2.29985|
Saving the model: models/ConvNet_regression_classification_10000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:21<00:14,  3.61s/epoch]
Epoch: 6| Train cost:  2.30005| Val cost:  2.30059| Test cost:  2.29962|
Saving the model: models/ConvNet_regression_classification_10000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:25<00:10,  3.57s/epoch]
Epoch: 7| Train cost:  2.29954| Val cost:  2.29975| Test cost:  2.29884|
Saving the model: models/ConvNet_regression_classification_10000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:28<00:07,  3.56s/epoch]
Epoch: 8| Train cost:  2.29901| Val cost:  2.30042| Test cost:  2.29814|
Saving the model: models/ConvNet_regression_classification_10000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:32<00:03,  3.55s/epoch]
Epoch: 9| Train cost:  2.29859| Val cost:  2.29936| Test cost:  2.29805|
Saving the model: models/ConvNet_regression_classification_10000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:35<00:00,  3.55s/epoch]
Training epochs: 100%|██████████| 10/10 [00:35<00:00,  3.59s/epoch]
Epoch: 10| Train cost:  2.29814| Val cost:  2.29870| Test cost:  2.29756|
Saving the model: models/ConvNet_regression_classification_10000_epoch_10.pth
Elapsed: 35.875877380371094

We compare the performance of the transferred model with the original network.

<Figure size 800x600 with 1 Axes>

Discussion point 5

What did the regression model learn? What does its performance on the classification task after fine-tuning indicate?

Transfer example 2: autoencoder to classification

Now we do the same, but we transfer the weights of the network to predict the total number of “ON” pixels to the autoencoder task. How well do you think this will work? Think about the necessary features required to solve the task and consider if there could be much overlap. There is no clear answer to this question, but thinking about it will be useful.

['conv1.weight', 'conv1.bias', 'conv2.weight', 'conv2.bias', 'fc1.weight', 'fc1.bias', 'fc2.weight', 'fc2.bias', 'fc.weight', 'fc.bias']
Copied conv1.weight
Copied conv1.bias
Copied conv2.weight
Copied conv2.bias
Copied fc1.weight
Copied fc1.bias
Copied fc2.weight
Copied fc2.bias
8
froze  ConvNet.conv1.weight
froze  ConvNet.conv1.bias
froze  ConvNet.conv2.weight
froze  ConvNet.conv2.bias
froze  ConvNet.fc1.weight
froze  ConvNet.fc1.bias
froze  ConvNet.fc2.weight
froze  ConvNet.fc2.bias
Copied and froze 8 layers.
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:03<00:32,  3.62s/epoch]
Epoch: 1| Train cost:  2.11301| Val cost:  2.06528| Test cost:  2.05310|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:07<00:29,  3.64s/epoch]
Epoch: 2| Train cost:  2.06735| Val cost:  2.05482| Test cost:  2.04824|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:10<00:25,  3.61s/epoch]
Epoch: 3| Train cost:  2.01539| Val cost:  1.99300| Test cost:  1.96829|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:14<00:21,  3.61s/epoch]
Epoch: 4| Train cost:  1.98055| Val cost:  1.99027| Test cost:  1.97140|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:18<00:18,  3.61s/epoch]
Epoch: 5| Train cost:  1.97799| Val cost:  1.98077| Test cost:  1.96582|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:21<00:14,  3.60s/epoch]
Epoch: 6| Train cost:  1.97830| Val cost:  1.98092| Test cost:  1.96194|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:25<00:10,  3.59s/epoch]
Epoch: 7| Train cost:  1.97619| Val cost:  1.97761| Test cost:  1.96093|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:28<00:07,  3.63s/epoch]
Epoch: 8| Train cost:  1.97587| Val cost:  1.97696| Test cost:  1.96575|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:32<00:03,  3.68s/epoch]
Epoch: 9| Train cost:  1.97350| Val cost:  1.98023| Test cost:  1.96468|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:36<00:00,  3.66s/epoch]
Training epochs: 100%|██████████| 10/10 [00:36<00:00,  3.63s/epoch]
Epoch: 10| Train cost:  1.97369| Val cost:  1.97199| Test cost:  1.96318|
Saving the model: models/ConvNet_autoencoder_classification_10000_epoch_10.pth
Elapsed: 36.34789323806763

We compare the performance of the transferred model with the original network.

<Figure size 800x600 with 1 Axes>

Discussion point 6

How well does the representation learned on the autoencoder transfer to classification?

Transfer example 3: inpainting to classification

Finally, we’ll transfer the weights of the inpainting network to the classification network. How well do you think this will work? Again, consider the breakdown of the features that would need to support both tasks. Is there an overlap?

['conv1.weight', 'conv1.bias', 'conv2.weight', 'conv2.bias', 'fc1.weight', 'fc1.bias', 'fc2.weight', 'fc2.bias', 'fc.weight', 'fc.bias']
Copied conv1.weight
Copied conv1.bias
Copied conv2.weight
Copied conv2.bias
Copied fc1.weight
Copied fc1.bias
Copied fc2.weight
Copied fc2.bias
8
froze  ConvNet.conv1.weight
froze  ConvNet.conv1.bias
froze  ConvNet.conv2.weight
froze  ConvNet.conv2.bias
froze  ConvNet.fc1.weight
froze  ConvNet.fc1.bias
froze  ConvNet.fc2.weight
froze  ConvNet.fc2.bias
Copied and froze 8 layers.
Training epochs:   0%|          | 0/10 [00:00<?, ?epoch/s]
Training epochs:  10%|█         | 1/10 [00:03<00:32,  3.57s/epoch]
Epoch: 1| Train cost:  2.08974| Val cost:  2.01776| Test cost:  1.99194|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_1.pth
Training epochs:  20%|██        | 2/10 [00:07<00:28,  3.57s/epoch]
Epoch: 2| Train cost:  2.00194| Val cost:  1.99326| Test cost:  1.97184|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_2.pth
Training epochs:  30%|███       | 3/10 [00:10<00:25,  3.57s/epoch]
Epoch: 3| Train cost:  1.99250| Val cost:  1.99701| Test cost:  1.96457|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_3.pth
Training epochs:  40%|████      | 4/10 [00:14<00:21,  3.58s/epoch]
Epoch: 4| Train cost:  1.98851| Val cost:  1.99065| Test cost:  1.96949|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_4.pth
Training epochs:  50%|█████     | 5/10 [00:17<00:18,  3.62s/epoch]
Epoch: 5| Train cost:  1.98501| Val cost:  1.98452| Test cost:  1.96313|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_5.pth
Training epochs:  60%|██████    | 6/10 [00:21<00:14,  3.63s/epoch]
Epoch: 6| Train cost:  1.98496| Val cost:  1.98256| Test cost:  1.96016|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_6.pth
Training epochs:  70%|███████   | 7/10 [00:25<00:10,  3.65s/epoch]
Epoch: 7| Train cost:  1.98236| Val cost:  1.98380| Test cost:  1.96117|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_7.pth
Training epochs:  80%|████████  | 8/10 [00:29<00:07,  3.66s/epoch]
Epoch: 8| Train cost:  1.96874| Val cost:  1.91986| Test cost:  1.89770|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_8.pth
Training epochs:  90%|█████████ | 9/10 [00:32<00:03,  3.67s/epoch]
Epoch: 9| Train cost:  1.90781| Val cost:  1.89947| Test cost:  1.88844|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_9.pth
Training epochs: 100%|██████████| 10/10 [00:36<00:00,  3.66s/epoch]
Training epochs: 100%|██████████| 10/10 [00:36<00:00,  3.64s/epoch]
Epoch: 10| Train cost:  1.90122| Val cost:  1.89825| Test cost:  1.88662|
Saving the model: models/ConvNet_inpainting_classification_10000_epoch_10.pth
Elapsed: 36.36067986488342

<Figure size 800x600 with 1 Axes>

Discussion point 7

Consider the test loss across these three networks (regression, autoencoder, inpainting). What does this test loss tell us about the representations learned by these networks?

Bonus discussion point 8

How would you find out if the representations learned by the networks are similar or different, apart from their performance on downstream tasks?


The Big Picture

In this tutorial, we explored the concept of generalization of representation in AI, namely the concept of representational transfer. We trained networks on several distinct tasks including classification, regression, autoencoding, and inpainting. We showed how the specification of different cost functions on the output layers can make a network perform a completely different task. We specified multiple different cost functions that were each associated with defining one of the tasks outlined earler.

We explored how a network trained on one task might transfer to another task / network. We found that richer tasks, including inpainting and autoencoding, lead to more useful representations for downstream tasks like classification. These tasks involve needing to capture multiple pieces of information across local and global contexts, big picture features as well as smaller details.

Humans are great at generalization and we have limited neural networks that are re-used across many different tasks. Is this an idea we can take forward to creating better AI models?