Introduction

Fine-tuning plays a great role in model training, and realizing the meaning of each hyperparameter lets you succeed.

In this post, I am going to show you how I achieve 99% top-1 accuracy on MNIST hand-written number recognition by just fine-tuning three hyperparameters. I also try to implement a classic CNN model, LeNet-5, from scratch for making me familiarize the structure and the basic components of a CNN model. What’s more, I will build my LeNet-5 model in Flux.jl to show an example of Julia neural network framework.

Base Model

You can get the code from my repo.

The base model is the well-known 5-layer LeNet [^1], and the implementation is adopted from Flux.jl model zoo [^2]. As such, there are some differences between the original LeNet and the implementation in Flux.jl model zoo [^3]:

  1. The activation function of convolution layer in LeNet uses sigmoid, whilst in Flux.jl model zoo uses ReLU.
  2. The pooling layer in LeNet uses average pooling, whereas in Flux.jl mode zoo uses max pooling.
  3. The activation function of pooling layer in LeNet uses scaled hyperbolic tangent, while the one in Flux.jl model zoo uses identity (linear).
  4. The multi-class classification used in original LeNet paper uses Euclidean radial basis (RBF) function. [3] However, softmax is used in Flux.jl’s implementation.

For your ease, I list the structure of my implementation: model structure

The structure of base model. You can right-click to show the image in new tab. Sorry for your inconvenience because NN-SVG (http://alexlenail.me/NN-SVG/LeNet.html) does not have any options to resize the image.

Let’s fine tuning!

As such, hypermeter tuning plays a crucial role in machine learning model development. Though the LeNet implementation of Flux.jl can achieve 98% top-1 accuracy, I still want to try whether I can break the limits. What’s more, by experimenting fine tuning, I can attain the knowledge which parameters plays the major role in certain task.

baseline and its performance

Baseline model can be found here: https://github.com/FluxML/model-zoo/blob/master/vision/conv_mnist/conv_mnist.jl

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:41
Epoch: 1   Train: (loss = 0.1586f0, acc = 95.3417)   Test: (loss = 0.145f0, acc = 95.53)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 2   Train: (loss = 0.1079f0, acc = 96.7733)   Test: (loss = 0.0958f0, acc = 97.03)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 3   Train: (loss = 0.0829f0, acc = 97.515)   Test: (loss = 0.0717f0, acc = 97.75)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 4   Train: (loss = 0.0639f0, acc = 98.0883)   Test: (loss = 0.0573f0, acc = 98.21)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 5   Train: (loss = 0.0614f0, acc = 98.12)   Test: (loss = 0.0539f0, acc = 98.25)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 6   Train: (loss = 0.0593f0, acc = 98.2017)   Test: (loss = 0.058f0, acc = 98.13)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 7   Train: (loss = 0.0464f0, acc = 98.6083)   Test: (loss = 0.0464f0, acc = 98.52)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 8   Train: (loss = 0.04f0, acc = 98.7867)   Test: (loss = 0.039f0, acc = 98.77)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 9   Train: (loss = 0.0393f0, acc = 98.7833)   Test: (loss = 0.0416f0, acc = 98.63)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 10   Train: (loss = 0.0348f0, acc = 98.9667)   Test: (loss = 0.0388f0, acc = 98.67)

batch size

Batch size means how many training samples are used in one iteration. Furthermore, it represents you update, or formally, calculate the loss then back-propagate, the parameters of the model after ingest certain number of training samples. Therefore, assuming the following scenes:

  1. If you update the parameters after ingest the whole data. You may get a fast parameter updating time, but the model will perform poorly on actual case because the model falls into the trap of local minima. Besides, it needs a huge number of memory to load the data.
  2. If you update the parameters after ingest each number of data (only one data in each iteration). You may get a model with fantastic outcome, but it takes an extraordinary time to train as it updates the parameters in each iteration.

As such, choosing the right number of batch size can:

  • reduce the training time and memory
  • coverage in better performance

In this post, I tried different number of batch size, and the best batch size of my training platform is 32.

Batch Size Testing Accuracy (after training with 10 epoches)
32 98.94%
64 98.9%
256 98.54%
512 98.21%

And the following paragraphs are the training log of different batch size:

32

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:40
Epoch: 1   Train: (loss = 0.1069f0, acc = 96.725)   Test: (loss = 0.092f0, acc = 97.28)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 2   Train: (loss = 0.0645f0, acc = 98.0217)   Test: (loss = 0.0578f0, acc = 98.16)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 3   Train: (loss = 0.0467f0, acc = 98.6183)   Test: (loss = 0.0439f0, acc = 98.64)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 4   Train: (loss = 0.0407f0, acc = 98.7817)   Test: (loss = 0.0415f0, acc = 98.67)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 5   Train: (loss = 0.0392f0, acc = 98.8017)   Test: (loss = 0.0428f0, acc = 98.68)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 6   Train: (loss = 0.0329f0, acc = 98.915)   Test: (loss = 0.0408f0, acc = 98.71)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 7   Train: (loss = 0.0207f0, acc = 99.395)   Test: (loss = 0.0322f0, acc = 99.01)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 8   Train: (loss = 0.0196f0, acc = 99.3833)   Test: (loss = 0.0294f0, acc = 99.02)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 9   Train: (loss = 0.0179f0, acc = 99.45)   Test: (loss = 0.0345f0, acc = 98.92)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 10   Train: (loss = 0.0166f0, acc = 99.4283)   Test: (loss = 0.0328f0, acc = 98.94)

64

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:40
Epoch: 1   Train: (loss = 0.1307f0, acc = 96.045)   Test: (loss = 0.1139f0, acc = 96.49)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 2   Train: (loss = 0.0852f0, acc = 97.33)   Test: (loss = 0.0752f0, acc = 97.62)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 3   Train: (loss = 0.0617f0, acc = 98.1583)   Test: (loss = 0.0555f0, acc = 98.39)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 4   Train: (loss = 0.0485f0, acc = 98.5767)   Test: (loss = 0.0454f0, acc = 98.5)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 5   Train: (loss = 0.0515f0, acc = 98.3933)   Test: (loss = 0.0481f0, acc = 98.51)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 6   Train: (loss = 0.0464f0, acc = 98.545)   Test: (loss = 0.0469f0, acc = 98.56)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 7   Train: (loss = 0.0323f0, acc = 99.0033)   Test: (loss = 0.0365f0, acc = 98.77)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 8   Train: (loss = 0.0298f0, acc = 99.0417)   Test: (loss = 0.0337f0, acc = 98.96)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 9   Train: (loss = 0.0327f0, acc = 98.945)   Test: (loss = 0.0393f0, acc = 98.77)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 10   Train: (loss = 0.0273f0, acc = 99.1333)   Test: (loss = 0.0351f0, acc = 98.9)

256

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:38
Epoch: 1   Train: (loss = 0.2218f0, acc = 93.6817)   Test: (loss = 0.2066f0, acc = 94.14)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 2   Train: (loss = 0.137f0, acc = 95.965)   Test: (loss = 0.1233f0, acc = 96.37)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 3   Train: (loss = 0.1088f0, acc = 96.7117)   Test: (loss = 0.0953f0, acc = 97.17)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 4   Train: (loss = 0.0858f0, acc = 97.4033)   Test: (loss = 0.0755f0, acc = 97.7)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 5   Train: (loss = 0.0746f0, acc = 97.775)   Test: (loss = 0.0657f0, acc = 98.03)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 6   Train: (loss = 0.0665f0, acc = 98.0417)   Test: (loss = 0.0597f0, acc = 98.1)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 7   Train: (loss = 0.0603f0, acc = 98.2617)   Test: (loss = 0.0554f0, acc = 98.32)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 8   Train: (loss = 0.0535f0, acc = 98.4033)   Test: (loss = 0.0481f0, acc = 98.45)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 9   Train: (loss = 0.052f0, acc = 98.4883)   Test: (loss = 0.0496f0, acc = 98.47)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 10   Train: (loss = 0.047f0, acc = 98.5767)   Test: (loss = 0.0445f0, acc = 98.54)

512

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:38
Epoch: 1   Train: (loss = 0.3686f0, acc = 89.5733)   Test: (loss = 0.3486f0, acc = 90.57)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 2   Train: (loss = 0.2046f0, acc = 94.0917)   Test: (loss = 0.1919f0, acc = 94.34)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:11
Epoch: 3   Train: (loss = 0.1542f0, acc = 95.425)   Test: (loss = 0.1387f0, acc = 95.9)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 4   Train: (loss = 0.1233f0, acc = 96.3467)   Test: (loss = 0.1119f0, acc = 96.6)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 5   Train: (loss = 0.1032f0, acc = 96.9167)   Test: (loss = 0.0912f0, acc = 97.32)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 6   Train: (loss = 0.0923f0, acc = 97.2533)   Test: (loss = 0.0831f0, acc = 97.56)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 7   Train: (loss = 0.0831f0, acc = 97.5483)   Test: (loss = 0.074f0, acc = 97.82)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 8   Train: (loss = 0.0778f0, acc = 97.6967)   Test: (loss = 0.0709f0, acc = 97.84)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 9   Train: (loss = 0.0732f0, acc = 97.8883)   Test: (loss = 0.0674f0, acc = 97.94)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:10
Epoch: 10   Train: (loss = 0.0661f0, acc = 98.0383)   Test: (loss = 0.0594f0, acc = 98.21)

regularizer parameter

The regularizer is to add penalty so that the model reduce the probability to become overfitting. Usually, we can use L1 and L2 regularizer, and I choose L2 regularizer for my LeNet-5 model.

In this experiment, the best L2 regularizer parameter is 1e-6.

L2 Regularizer Parameter Testing Accuracy (after training with 10 epoches)
1e-2 97.68%
1e-4 98.87%
1e-6 99.05%

As usual, I put the training logs with different regularizer parameters:

1e-2

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:41
Epoch: 1   Train: (loss = 0.1379f0, acc = 96.1117)   Test: (loss = 0.123f0, acc = 96.52)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 2   Train: (loss = 0.1076f0, acc = 96.9583)   Test: (loss = 0.0933f0, acc = 97.28)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 3   Train: (loss = 0.1239f0, acc = 96.2667)   Test: (loss = 0.1089f0, acc = 96.64)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 4   Train: (loss = 0.1041f0, acc = 97.16)   Test: (loss = 0.0915f0, acc = 97.57)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 5   Train: (loss = 0.1092f0, acc = 96.965)   Test: (loss = 0.1014f0, acc = 97.17)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 6   Train: (loss = 0.0911f0, acc = 97.4883)   Test: (loss = 0.0808f0, acc = 97.74)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 7   Train: (loss = 0.0894f0, acc = 97.5717)   Test: (loss = 0.0816f0, acc = 97.79)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 8   Train: (loss = 0.0891f0, acc = 97.5483)   Test: (loss = 0.0796f0, acc = 97.79)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 9   Train: (loss = 0.0941f0, acc = 97.36)   Test: (loss = 0.0849f0, acc = 97.44)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 10   Train: (loss = 0.0955f0, acc = 97.3467)   Test: (loss = 0.0844f0, acc = 97.68)

1e-4

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:40
Epoch: 1   Train: (loss = 0.1079f0, acc = 96.7133)   Test: (loss = 0.0922f0, acc = 97.23)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 2   Train: (loss = 0.0633f0, acc = 98.055)   Test: (loss = 0.0565f0, acc = 98.19)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:12
Epoch: 3   Train: (loss = 0.0478f0, acc = 98.5733)   Test: (loss = 0.0448f0, acc = 98.52)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 4   Train: (loss = 0.041f0, acc = 98.7333)   Test: (loss = 0.0418f0, acc = 98.62)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 5   Train: (loss = 0.0394f0, acc = 98.7783)   Test: (loss = 0.0425f0, acc = 98.7)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 6   Train: (loss = 0.0351f0, acc = 98.88)   Test: (loss = 0.0424f0, acc = 98.55)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 7   Train: (loss = 0.0218f0, acc = 99.335)   Test: (loss = 0.0317f0, acc = 99.05)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 8   Train: (loss = 0.0214f0, acc = 99.35)   Test: (loss = 0.0304f0, acc = 98.9)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 9   Train: (loss = 0.0207f0, acc = 99.36)   Test: (loss = 0.0335f0, acc = 98.91)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 10   Train: (loss = 0.0206f0, acc = 99.3133)   Test: (loss = 0.0345f0, acc = 98.87)

1e-6

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:49
Epoch: 1   Train: (loss = 0.1077f0, acc = 96.72)   Test: (loss = 0.092f0, acc = 97.23)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:16
Epoch: 2   Train: (loss = 0.0647f0, acc = 98.005)   Test: (loss = 0.058f0, acc = 98.17)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 3   Train: (loss = 0.0449f0, acc = 98.67)   Test: (loss = 0.0419f0, acc = 98.62)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:16
Epoch: 4   Train: (loss = 0.0443f0, acc = 98.6667)   Test: (loss = 0.0451f0, acc = 98.53)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:16
Epoch: 5   Train: (loss = 0.0419f0, acc = 98.645)   Test: (loss = 0.043f0, acc = 98.76)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 6   Train: (loss = 0.0337f0, acc = 98.925)   Test: (loss = 0.0406f0, acc = 98.7)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 7   Train: (loss = 0.0214f0, acc = 99.3417)   Test: (loss = 0.0325f0, acc = 98.93)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 8   Train: (loss = 0.0211f0, acc = 99.345)   Test: (loss = 0.0303f0, acc = 99.06)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 9   Train: (loss = 0.0217f0, acc = 99.31)   Test: (loss = 0.0363f0, acc = 98.83)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 10   Train: (loss = 0.0154f0, acc = 99.51)   Test: (loss = 0.0317f0, acc = 99.05)

optimizer

Optimizer in machine learning is to change the learning rate according to pre-assigned parameter so that the learning rate of model can be changed and the model is more likely to generalize well. In this post, I choose three optimizers: ADAMW, NADAM, and AdaBelief among commonly-seen ADAM. For the description of these optimizers, you can visit the documentation of optimizer of Flux.jl.

In this post, the best optimizer is ADAMW.

Optimizer Type Testing Accuracy (after training with 10 epoches)
ADAMW 99.05%
NADAM 98.92%
AdaBelief 99.01%

And here are the training logs with different optimizer:

ADAMW

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:44
Epoch: 1   Train: (loss = 0.1077f0, acc = 96.72)   Test: (loss = 0.092f0, acc = 97.23)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 2   Train: (loss = 0.0647f0, acc = 98.005)   Test: (loss = 0.058f0, acc = 98.17)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 3   Train: (loss = 0.0449f0, acc = 98.67)   Test: (loss = 0.0419f0, acc = 98.62)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 4   Train: (loss = 0.0443f0, acc = 98.6667)   Test: (loss = 0.0451f0, acc = 98.53)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 5   Train: (loss = 0.0419f0, acc = 98.645)   Test: (loss = 0.043f0, acc = 98.76)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 6   Train: (loss = 0.0337f0, acc = 98.925)   Test: (loss = 0.0406f0, acc = 98.7)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:16
Epoch: 7   Train: (loss = 0.0214f0, acc = 99.3417)   Test: (loss = 0.0325f0, acc = 98.93)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 8   Train: (loss = 0.0211f0, acc = 99.345)   Test: (loss = 0.0303f0, acc = 99.06)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 9   Train: (loss = 0.0217f0, acc = 99.31)   Test: (loss = 0.0363f0, acc = 98.83)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 10   Train: (loss = 0.0154f0, acc = 99.51)   Test: (loss = 0.0317f0, acc = 99.05)

NADAM

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:43
Epoch: 1   Train: (loss = 0.108f0, acc = 96.6633)   Test: (loss = 0.0922f0, acc = 97.22)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 2   Train: (loss = 0.0616f0, acc = 98.145)   Test: (loss = 0.0547f0, acc = 98.3)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 3   Train: (loss = 0.0479f0, acc = 98.5433)   Test: (loss = 0.0454f0, acc = 98.5)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 4   Train: (loss = 0.0399f0, acc = 98.8417)   Test: (loss = 0.0407f0, acc = 98.61)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:16
Epoch: 5   Train: (loss = 0.0411f0, acc = 98.6967)   Test: (loss = 0.0435f0, acc = 98.67)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 6   Train: (loss = 0.0334f0, acc = 98.915)   Test: (loss = 0.0411f0, acc = 98.66)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 7   Train: (loss = 0.0211f0, acc = 99.3683)   Test: (loss = 0.0328f0, acc = 98.91)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 8   Train: (loss = 0.0205f0, acc = 99.355)   Test: (loss = 0.0307f0, acc = 98.98)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 9   Train: (loss = 0.0173f0, acc = 99.4767)   Test: (loss = 0.0316f0, acc = 99.01)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:16
Epoch: 10   Train: (loss = 0.0194f0, acc = 99.3567)   Test: (loss = 0.035f0, acc = 98.92)

AdaBelief

Epoch: 0   Train: (loss = 2.3162f0, acc = 12.1333)   Test: (loss = 2.316f0, acc = 12.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:47
Epoch: 1   Train: (loss = 0.0743f0, acc = 97.7433)   Test: (loss = 0.0636f0, acc = 98.11)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 2   Train: (loss = 0.0485f0, acc = 98.5567)   Test: (loss = 0.0448f0, acc = 98.56)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 3   Train: (loss = 0.0377f0, acc = 98.8583)   Test: (loss = 0.0399f0, acc = 98.78)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 4   Train: (loss = 0.0306f0, acc = 99.0483)   Test: (loss = 0.0333f0, acc = 98.97)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:17
Epoch: 5   Train: (loss = 0.0322f0, acc = 99.0167)   Test: (loss = 0.0403f0, acc = 98.84)
[ Info: Model saved in "runs/model.bson"
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 6   Train: (loss = 0.0254f0, acc = 99.2183)   Test: (loss = 0.0373f0, acc = 98.73)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:14
Epoch: 7   Train: (loss = 0.0159f0, acc = 99.53)   Test: (loss = 0.0299f0, acc = 99.08)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 8   Train: (loss = 0.0174f0, acc = 99.4417)   Test: (loss = 0.0314f0, acc = 99.03)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:15
Epoch: 9   Train: (loss = 0.0133f0, acc = 99.6033)   Test: (loss = 0.029f0, acc = 99.13)
Progress: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████| Time: 0:00:13
Epoch: 10   Train: (loss = 0.015f0, acc = 99.49)   Test: (loss = 0.0333f0, acc = 99.01)

Conclusion

In this post, I build the classic LeNet-5 model not only practice my machine learning skills but also make myself familiar with emerging Flux.jl framework. I also show three possible criteria – batch size, regularizer, and optimizer – for the procedures of hyper-parameter tuning, or fine-tuning. At last, I bring you my LeNet-5 model can achieve 99% top-1 accuracy on MNIST dataset.

List to Show the Training Environment

  • CPU: Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
  • RAM: 16 GiB
  • OS: Fedora 33 (Linux Kernel 5.13.12)
  • Julia version: 1.6.2
  • Flux.jl version: v0.12.4

References

[^1] http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdf

[^2] https://github.com/FluxML/model-zoo/blob/33f5c472c321a50fc2105358a00eb7b3ec0ffa5e/vision/conv_mnist/conv_mnist.jl#L21

[^3] https://pabloinsente.github.io/the-convolutional-network