How To Set Trainable Layers
Note: I wrote an app to
classify an object using transfer learning, and the model was trained on CIFAR-10 dataset, all by myself.
Here's the app:
Transfer Learning Experiments and Findings
Initial Model Comparison
I started by comparing several backbone architectures, including
MobileNet V3,
MobileNet V4,
ResNet-18, and
ResNet-34.
For the initial experiment, I set
TRAINABLE_LAYERS = 1 and ran training across all models.
The results were unexpected:
MobileNet achieved around
60% validation accuracy, while ResNet models struggled at
less than 20%.
Below is the corresponding configuration and training log:
# ======================
# Configuration
# ======================
NUM_CLASSES = 10
TRAINING_SAMPLE_PER_CLASS = 100
VALIDATION_SAMPLE_PER_CLASS = 100 # None = use all test samples
BATCH_SIZE = 256
EPOCHS = 20
LR = 1e-4
WEIGHT_DECAY = 1e-4
TRAINABLE_LAYERS = 1 # 1 = classifier only, 2 = last block + classifier
EARLY_STOPPING_PATIENCE = 10
SAVE_MODEL = False
USE_TQDM = False
Training mobilenet_v3_small
Epoch 1: Train Loss=2.3177 | Val Loss=2.3455 | Train Acc=11.70% | Val Acc=12.40%
Epoch 2: Train Loss=2.2768 | Val Loss=2.2837 | Train Acc=14.10% | Val Acc=16.10%
Epoch 3: Train Loss=2.2365 | Val Loss=2.2238 | Train Acc=18.60% | Val Acc=20.20%
Epoch 4: Train Loss=2.1967 | Val Loss=2.1654 | Train Acc=22.30% | Val Acc=25.30%
Epoch 5: Train Loss=2.1523 | Val Loss=2.1113 | Train Acc=24.30% | Val Acc=31.70%
Epoch 6: Train Loss=2.1234 | Val Loss=2.0633 | Train Acc=29.80% | Val Acc=35.50%
Epoch 7: Train Loss=2.0863 | Val Loss=2.0215 | Train Acc=32.00% | Val Acc=39.20%
Epoch 8: Train Loss=2.0450 | Val Loss=1.9847 | Train Acc=33.00% | Val Acc=41.70%
Epoch 9: Train Loss=2.0262 | Val Loss=1.9514 | Train Acc=34.40% | Val Acc=43.70%
Epoch 10: Train Loss=1.9843 | Val Loss=1.9185 | Train Acc=35.30% | Val Acc=46.20%
Epoch 11: Train Loss=1.9516 | Val Loss=1.8843 | Train Acc=37.30% | Val Acc=48.10%
Epoch 12: Train Loss=1.9329 | Val Loss=1.8500 | Train Acc=38.80% | Val Acc=49.10%
Epoch 13: Train Loss=1.8963 | Val Loss=1.8137 | Train Acc=40.10% | Val Acc=50.70%
Epoch 14: Train Loss=1.8791 | Val Loss=1.7757 | Train Acc=40.00% | Val Acc=52.40%
Epoch 15: Train Loss=1.8471 | Val Loss=1.7375 | Train Acc=40.40% | Val Acc=53.60%
Epoch 16: Train Loss=1.8110 | Val Loss=1.6985 | Train Acc=42.20% | Val Acc=55.40%
Epoch 17: Train Loss=1.7856 | Val Loss=1.6563 | Train Acc=45.10% | Val Acc=56.10%
Epoch 18: Train Loss=1.7596 | Val Loss=1.6157 | Train Acc=44.50% | Val Acc=57.30%
Epoch 19: Train Loss=1.7511 | Val Loss=1.5755 | Train Acc=45.40% | Val Acc=58.50%
Epoch 20: Train Loss=1.7217 | Val Loss=1.5379 | Train Acc=45.40% | Val Acc=59.90%
✅ Best validation accuracy for mobilenet_v3_small: 59.90%
Training mobilenet_v3_large
Epoch 1: Train Loss=2.3322 | Val Loss=2.3312 | Train Acc=10.20% | Val Acc=11.50%
Epoch 2: Train Loss=2.2975 | Val Loss=2.2714 | Train Acc=12.50% | Val Acc=14.60%
Epoch 3: Train Loss=2.2202 | Val Loss=2.2132 | Train Acc=19.00% | Val Acc=20.20%
Epoch 4: Train Loss=2.1667 | Val Loss=2.1558 | Train Acc=23.00% | Val Acc=23.80%
Epoch 5: Train Loss=2.1245 | Val Loss=2.0989 | Train Acc=25.60% | Val Acc=28.50%
Epoch 6: Train Loss=2.1060 | Val Loss=2.0423 | Train Acc=26.40% | Val Acc=33.10%
Epoch 7: Train Loss=2.0218 | Val Loss=1.9869 | Train Acc=33.70% | Val Acc=36.70%
Epoch 8: Train Loss=1.9899 | Val Loss=1.9310 | Train Acc=35.40% | Val Acc=40.00%
Epoch 9: Train Loss=1.9608 | Val Loss=1.8751 | Train Acc=37.20% | Val Acc=43.30%
Epoch 10: Train Loss=1.9172 | Val Loss=1.8214 | Train Acc=39.60% | Val Acc=46.30%
Epoch 11: Train Loss=1.8726 | Val Loss=1.7687 | Train Acc=41.30% | Val Acc=48.80%
Epoch 12: Train Loss=1.8210 | Val Loss=1.7177 | Train Acc=43.00% | Val Acc=50.00%
Epoch 13: Train Loss=1.7896 | Val Loss=1.6679 | Train Acc=43.60% | Val Acc=52.60%
Epoch 14: Train Loss=1.7819 | Val Loss=1.6190 | Train Acc=43.60% | Val Acc=54.80%
Epoch 15: Train Loss=1.7252 | Val Loss=1.5743 | Train Acc=46.90% | Val Acc=56.00%
Epoch 16: Train Loss=1.6957 | Val Loss=1.5286 | Train Acc=46.10% | Val Acc=57.10%
Epoch 17: Train Loss=1.6737 | Val Loss=1.4864 | Train Acc=48.30% | Val Acc=58.00%
Epoch 18: Train Loss=1.6600 | Val Loss=1.4458 | Train Acc=47.80% | Val Acc=58.70%
Epoch 19: Train Loss=1.6081 | Val Loss=1.4070 | Train Acc=50.10% | Val Acc=59.90%
Epoch 20: Train Loss=1.5894 | Val Loss=1.3731 | Train Acc=51.50% | Val Acc=60.60%
✅ Best validation accuracy for mobilenet_v3_large: 60.60%
Training resnet18
Epoch 1: Train Loss=2.5938 | Val Loss=2.6632 | Train Acc=9.40% | Val Acc=6.70%
Epoch 2: Train Loss=2.5043 | Val Loss=2.6326 | Train Acc=8.60% | Val Acc=6.30%
Epoch 3: Train Loss=2.4533 | Val Loss=2.5928 | Train Acc=9.60% | Val Acc=5.80%
Epoch 4: Train Loss=2.4286 | Val Loss=2.5558 | Train Acc=7.90% | Val Acc=6.70%
Epoch 5: Train Loss=2.3868 | Val Loss=2.5270 | Train Acc=8.80% | Val Acc=6.90%
Epoch 6: Train Loss=2.3919 | Val Loss=2.5020 | Train Acc=10.60% | Val Acc=8.00%
Epoch 7: Train Loss=2.3635 | Val Loss=2.4802 | Train Acc=9.00% | Val Acc=8.40%
Epoch 8: Train Loss=2.3750 | Val Loss=2.4584 | Train Acc=10.20% | Val Acc=8.40%
Epoch 9: Train Loss=2.3513 | Val Loss=2.4373 | Train Acc=11.90% | Val Acc=9.10%
Epoch 10: Train Loss=2.3520 | Val Loss=2.4176 | Train Acc=11.40% | Val Acc=10.00%
Epoch 11: Train Loss=2.3230 | Val Loss=2.4032 | Train Acc=11.40% | Val Acc=10.30%
Epoch 12: Train Loss=2.3147 | Val Loss=2.3892 | Train Acc=11.90% | Val Acc=10.20%
Epoch 13: Train Loss=2.3248 | Val Loss=2.3747 | Train Acc=12.10% | Val Acc=11.20%
Epoch 14: Train Loss=2.2925 | Val Loss=2.3654 | Train Acc=13.50% | Val Acc=11.70%
Epoch 15: Train Loss=2.2954 | Val Loss=2.3534 | Train Acc=12.10% | Val Acc=11.90%
Epoch 16: Train Loss=2.2970 | Val Loss=2.3411 | Train Acc=14.00% | Val Acc=12.10%
Epoch 17: Train Loss=2.2646 | Val Loss=2.3298 | Train Acc=14.90% | Val Acc=12.60%
Epoch 18: Train Loss=2.2509 | Val Loss=2.3168 | Train Acc=16.80% | Val Acc=13.50%
Epoch 19: Train Loss=2.2593 | Val Loss=2.3033 | Train Acc=16.00% | Val Acc=14.00%
Epoch 20: Train Loss=2.2471 | Val Loss=2.2936 | Train Acc=15.60% | Val Acc=14.50%
✅ Best validation accuracy for resnet18: 14.50%
Training resnet34
Epoch 1: Train Loss=2.4739 | Val Loss=2.6085 | Train Acc=8.60% | Val Acc=10.20%
Epoch 2: Train Loss=2.4427 | Val Loss=2.5449 | Train Acc=9.60% | Val Acc=9.50%
Epoch 3: Train Loss=2.4130 | Val Loss=2.4887 | Train Acc=8.70% | Val Acc=10.10%
Epoch 4: Train Loss=2.3812 | Val Loss=2.4540 | Train Acc=9.50% | Val Acc=10.50%
Epoch 5: Train Loss=2.3773 | Val Loss=2.4306 | Train Acc=9.60% | Val Acc=9.80%
Epoch 6: Train Loss=2.3660 | Val Loss=2.4094 | Train Acc=10.40% | Val Acc=10.90%
Epoch 7: Train Loss=2.3541 | Val Loss=2.3940 | Train Acc=10.90% | Val Acc=10.70%
Epoch 8: Train Loss=2.3292 | Val Loss=2.3753 | Train Acc=11.70% | Val Acc=11.20%
Epoch 9: Train Loss=2.3401 | Val Loss=2.3608 | Train Acc=12.60% | Val Acc=11.70%
Epoch 10: Train Loss=2.3171 | Val Loss=2.3462 | Train Acc=12.90% | Val Acc=12.40%
Epoch 11: Train Loss=2.3137 | Val Loss=2.3342 | Train Acc=11.20% | Val Acc=12.30%
Epoch 12: Train Loss=2.3121 | Val Loss=2.3198 | Train Acc=12.00% | Val Acc=12.90%
Epoch 13: Train Loss=2.2840 | Val Loss=2.3081 | Train Acc=14.70% | Val Acc=13.90%
Epoch 14: Train Loss=2.2589 | Val Loss=2.2929 | Train Acc=15.00% | Val Acc=14.20%
Epoch 15: Train Loss=2.2977 | Val Loss=2.2802 | Train Acc=13.00% | Val Acc=14.50%
Epoch 16: Train Loss=2.2577 | Val Loss=2.2687 | Train Acc=14.80% | Val Acc=15.70%
Epoch 17: Train Loss=2.2689 | Val Loss=2.2584 | Train Acc=15.20% | Val Acc=16.50%
Epoch 18: Train Loss=2.2601 | Val Loss=2.2445 | Train Acc=17.20% | Val Acc=16.90%
Epoch 19: Train Loss=2.2375 | Val Loss=2.2317 | Train Acc=17.10% | Val Acc=17.70%
Epoch 20: Train Loss=2.2133 | Val Loss=2.2165 | Train Acc=19.20% | Val Acc=18.50%
✅ Best validation accuracy for resnet34: 18.50%
Initial Hypothesis: Possible Code Issues
My first reaction was that something must be wrong with the code. I suspected issues such as:
– Incorrect freezing or unfreezing logic
– Misconfigured parameters not behaving as intended
– A potential bug in the training pipeline
I spent some time digging into the implementation but could not pinpoint any obvious bugs.
To further validate this, I experimented with
TRAINABLE_LAYERS = 2, but the results showed no meaningful improvement.
Root Cause: Understanding ResNet Architecture
Eventually, I realized the issue was not the code itself, but rather how
TRAINABLE_LAYERS interacted with the ResNet architecture.
A typical ResNet architecture is structured as follows:
[conv1, bn1, relu, maxpool, layer1, layer2, layer3, layer4, avgpool, fc]
When
TRAINABLE_LAYERS = 2, the last two modules are unfrozen:
[avgpool, fc]
However,
avgpool contains no trainable parameters. As a result, only the
fc layer is actually being trained. This means that
TRAINABLE_LAYERS = 1 and
TRAINABLE_LAYERS = 2 are effectively equivalent for ResNet.
Adjusting the Configuration
Based on this insight, I increased the setting to
TRAINABLE_LAYERS = 3,
which unfreezes
layer4 in addition to the classifier. After rerunning the experiments,
the results improved significantly:
–
ResNet-18 / ResNet-34: ~77%–79% validation accuracy
–
MobileNet: ~59%–67% validation accuracy
Below is the corresponding configuration and training log:
# ======================
# Configuration
# ======================
NUM_CLASSES = 10
TRAINING_SAMPLE_PER_CLASS = 100
VALIDATION_SAMPLE_PER_CLASS = 100 # None = use all test samples
BATCH_SIZE = 256
EPOCHS = 20
LR = 1e-4
WEIGHT_DECAY = 1e-4
TRAINABLE_LAYERS = 3 # 1 = classifier only, 2 = last block + classifier
EARLY_STOPPING_PATIENCE = 10
SAVE_MODEL = False
USE_TQDM = False
Training resnet34
Epoch 1: Train Loss=2.3162 | Val Loss=2.1400 | Train Acc=17.20% | Val Acc=25.60%
Epoch 2: Train Loss=1.8828 | Val Loss=1.6864 | Train Acc=36.20% | Val Acc=45.00%
Epoch 3: Train Loss=1.5692 | Val Loss=1.3554 | Train Acc=47.70% | Val Acc=55.00%
Epoch 4: Train Loss=1.4391 | Val Loss=1.1146 | Train Acc=50.40% | Val Acc=62.60%
Epoch 5: Train Loss=1.3089 | Val Loss=0.9411 | Train Acc=53.70% | Val Acc=69.00%
Epoch 6: Train Loss=1.2026 | Val Loss=0.8654 | Train Acc=58.30% | Val Acc=70.00%
Epoch 7: Train Loss=1.1422 | Val Loss=0.8201 | Train Acc=60.00% | Val Acc=71.70%
Epoch 8: Train Loss=1.1133 | Val Loss=0.7696 | Train Acc=60.00% | Val Acc=73.80%
Epoch 9: Train Loss=1.0301 | Val Loss=0.7183 | Train Acc=62.90% | Val Acc=75.10%
Epoch 10: Train Loss=0.9645 | Val Loss=0.7070 | Train Acc=65.70% | Val Acc=75.90%
Epoch 11: Train Loss=0.9190 | Val Loss=0.7042 | Train Acc=69.50% | Val Acc=75.50%
Epoch 12: Train Loss=0.9551 | Val Loss=0.6816 | Train Acc=66.80% | Val Acc=76.90%
Epoch 13: Train Loss=0.8687 | Val Loss=0.6409 | Train Acc=69.60% | Val Acc=77.80%
Epoch 14: Train Loss=0.8569 | Val Loss=0.6261 | Train Acc=70.60% | Val Acc=78.40%
Epoch 15: Train Loss=0.8373 | Val Loss=0.6420 | Train Acc=71.90% | Val Acc=77.70%
Epoch 16: Train Loss=0.8425 | Val Loss=0.6431 | Train Acc=69.40% | Val Acc=78.50%
Epoch 17: Train Loss=0.8111 | Val Loss=0.6212 | Train Acc=72.40% | Val Acc=78.70%
Epoch 18: Train Loss=0.8147 | Val Loss=0.6209 | Train Acc=72.60% | Val Acc=78.10%
Epoch 19: Train Loss=0.7565 | Val Loss=0.6064 | Train Acc=74.20% | Val Acc=79.10%
Epoch 20: Train Loss=0.7688 | Val Loss=0.6040 | Train Acc=73.20% | Val Acc=78.40%
✅ Best validation accuracy for resnet34: 79.10%
Training resnet18
Epoch 1: Train Loss=2.3781 | Val Loss=2.1589 | Train Acc=13.40% | Val Acc=21.10%
Epoch 2: Train Loss=2.0091 | Val Loss=1.8404 | Train Acc=29.50% | Val Acc=37.80%
Epoch 3: Train Loss=1.7592 | Val Loss=1.5395 | Train Acc=41.50% | Val Acc=50.40%
Epoch 4: Train Loss=1.5662 | Val Loss=1.3322 | Train Acc=48.10% | Val Acc=54.40%
Epoch 5: Train Loss=1.4427 | Val Loss=1.2093 | Train Acc=52.20% | Val Acc=56.10%
Epoch 6: Train Loss=1.3420 | Val Loss=1.1261 | Train Acc=54.00% | Val Acc=59.50%
Epoch 7: Train Loss=1.2779 | Val Loss=1.0259 | Train Acc=57.30% | Val Acc=62.20%
Epoch 8: Train Loss=1.2202 | Val Loss=0.9340 | Train Acc=57.50% | Val Acc=66.00%
Epoch 9: Train Loss=1.1343 | Val Loss=0.8823 | Train Acc=61.50% | Val Acc=68.50%
Epoch 10: Train Loss=1.1146 | Val Loss=0.8320 | Train Acc=62.00% | Val Acc=70.70%
Epoch 11: Train Loss=1.0479 | Val Loss=0.7855 | Train Acc=65.00% | Val Acc=71.70%
Epoch 12: Train Loss=1.0577 | Val Loss=0.7632 | Train Acc=63.30% | Val Acc=72.80%
Epoch 13: Train Loss=1.0376 | Val Loss=0.7399 | Train Acc=64.80% | Val Acc=74.20%
Epoch 14: Train Loss=0.9604 | Val Loss=0.7245 | Train Acc=67.50% | Val Acc=74.20%
Epoch 15: Train Loss=0.9722 | Val Loss=0.7163 | Train Acc=65.00% | Val Acc=73.90%
Epoch 16: Train Loss=0.9594 | Val Loss=0.7047 | Train Acc=65.70% | Val Acc=74.60%
Epoch 17: Train Loss=0.9024 | Val Loss=0.6948 | Train Acc=69.20% | Val Acc=74.70%
Epoch 18: Train Loss=0.8701 | Val Loss=0.6814 | Train Acc=71.10% | Val Acc=75.80%
Epoch 19: Train Loss=0.8892 | Val Loss=0.6533 | Train Acc=70.30% | Val Acc=77.10%
Epoch 20: Train Loss=0.8503 | Val Loss=0.6390 | Train Acc=71.70% | Val Acc=77.80%
✅ Best validation accuracy for resnet18: 77.80%
Training mobilenet_v3_small
Epoch 1: Train Loss=2.3416 | Val Loss=2.3322 | Train Acc=10.10% | Val Acc=9.20%
Epoch 2: Train Loss=2.2764 | Val Loss=2.2613 | Train Acc=14.20% | Val Acc=14.10%
Epoch 3: Train Loss=2.2238 | Val Loss=2.1926 | Train Acc=21.20% | Val Acc=17.60%
Epoch 4: Train Loss=2.1706 | Val Loss=2.1260 | Train Acc=24.00% | Val Acc=22.70%
Epoch 5: Train Loss=2.1219 | Val Loss=2.0639 | Train Acc=28.90% | Val Acc=28.60%
Epoch 6: Train Loss=2.0882 | Val Loss=2.0061 | Train Acc=28.90% | Val Acc=33.40%
Epoch 7: Train Loss=2.0264 | Val Loss=1.9526 | Train Acc=34.50% | Val Acc=39.30%
Epoch 8: Train Loss=1.9684 | Val Loss=1.9010 | Train Acc=40.80% | Val Acc=43.40%
Epoch 9: Train Loss=1.9319 | Val Loss=1.8502 | Train Acc=39.50% | Val Acc=46.20%
Epoch 10: Train Loss=1.8834 | Val Loss=1.7974 | Train Acc=40.50% | Val Acc=47.80%
Epoch 11: Train Loss=1.8380 | Val Loss=1.7407 | Train Acc=43.60% | Val Acc=49.80%
Epoch 12: Train Loss=1.7840 | Val Loss=1.6812 | Train Acc=45.30% | Val Acc=52.80%
Epoch 13: Train Loss=1.7225 | Val Loss=1.6224 | Train Acc=46.50% | Val Acc=54.10%
Epoch 14: Train Loss=1.6673 | Val Loss=1.5620 | Train Acc=49.10% | Val Acc=54.90%
Epoch 15: Train Loss=1.6407 | Val Loss=1.5045 | Train Acc=48.20% | Val Acc=55.70%
Epoch 16: Train Loss=1.5895 | Val Loss=1.4499 | Train Acc=51.30% | Val Acc=56.40%
Epoch 17: Train Loss=1.5427 | Val Loss=1.3994 | Train Acc=49.90% | Val Acc=57.60%
Epoch 18: Train Loss=1.5114 | Val Loss=1.3523 | Train Acc=52.20% | Val Acc=58.40%
Epoch 19: Train Loss=1.5042 | Val Loss=1.3115 | Train Acc=49.30% | Val Acc=58.80%
Epoch 20: Train Loss=1.4911 | Val Loss=1.2781 | Train Acc=48.80% | Val Acc=59.70%
✅ Best validation accuracy for mobilenet_v3_small: 59.70%
Training mobilenet_v3_large
Epoch 1: Train Loss=2.3189 | Val Loss=2.2779 | Train Acc=11.50% | Val Acc=14.90%
Epoch 2: Train Loss=2.2293 | Val Loss=2.1997 | Train Acc=17.20% | Val Acc=18.80%
Epoch 3: Train Loss=2.1549 | Val Loss=2.1214 | Train Acc=25.10% | Val Acc=23.90%
Epoch 4: Train Loss=2.0796 | Val Loss=2.0415 | Train Acc=29.80% | Val Acc=29.30%
Epoch 5: Train Loss=2.0196 | Val Loss=1.9608 | Train Acc=31.70% | Val Acc=36.20%
Epoch 6: Train Loss=1.9393 | Val Loss=1.8787 | Train Acc=39.20% | Val Acc=41.30%
Epoch 7: Train Loss=1.8813 | Val Loss=1.7961 | Train Acc=39.70% | Val Acc=45.80%
Epoch 8: Train Loss=1.8066 | Val Loss=1.7128 | Train Acc=44.10% | Val Acc=48.20%
Epoch 9: Train Loss=1.7320 | Val Loss=1.6270 | Train Acc=45.80% | Val Acc=50.90%
Epoch 10: Train Loss=1.6753 | Val Loss=1.5442 | Train Acc=46.60% | Val Acc=53.00%
Epoch 11: Train Loss=1.6035 | Val Loss=1.4612 | Train Acc=48.80% | Val Acc=55.90%
Epoch 12: Train Loss=1.5834 | Val Loss=1.3842 | Train Acc=48.60% | Val Acc=58.70%
Epoch 13: Train Loss=1.5157 | Val Loss=1.3150 | Train Acc=50.60% | Val Acc=60.60%
Epoch 14: Train Loss=1.4451 | Val Loss=1.2494 | Train Acc=51.90% | Val Acc=61.80%
Epoch 15: Train Loss=1.4311 | Val Loss=1.1944 | Train Acc=51.70% | Val Acc=63.40%
Epoch 16: Train Loss=1.3916 | Val Loss=1.1478 | Train Acc=53.60% | Val Acc=64.30%
Epoch 17: Train Loss=1.3497 | Val Loss=1.1040 | Train Acc=54.10% | Val Acc=65.90%
Epoch 18: Train Loss=1.3411 | Val Loss=1.0652 | Train Acc=54.00% | Val Acc=66.10%
Epoch 19: Train Loss=1.2860 | Val Loss=1.0295 | Train Acc=56.30% | Val Acc=66.90%
Epoch 20: Train Loss=1.2773 | Val Loss=1.0009 | Train Acc=55.00% | Val Acc=67.20%
✅ Best validation accuracy for mobilenet_v3_large: 67.20%
Key Takeaway
The main takeaway from this experiment is that poor performance does not always indicate a bug.
Sometimes, the issue lies in how configurable parameters interact with a specific model architecture.
A deeper understanding of the model’s internal structure is often necessary to make effective tuning decisions.
Any comments? Feel free to participate below in the Facebook comment section.