mirror of
https://github.com/labmlai/annotated_deep_learning_paper_implementations.git
synced 2025-08-15 18:27:20 +08:00
133 lines
3.6 KiB
Python
133 lines
3.6 KiB
Python
"""
|
|
---
|
|
title: MNIST example to test the optimizers
|
|
summary: This is a simple MNIST example with a CNN model to test the optimizers.
|
|
---
|
|
|
|
# MNIST example to test the optimizers
|
|
"""
|
|
import torch.nn as nn
|
|
import torch.utils.data
|
|
|
|
from labml import experiment, tracker
|
|
from labml.configs import option
|
|
from labml_nn.helpers.datasets import MNISTConfigs
|
|
from labml_nn.helpers.device import DeviceConfigs
|
|
from labml_nn.helpers.metrics import Accuracy
|
|
from labml_nn.helpers.trainer import TrainValidConfigs, BatchIndex
|
|
from labml_nn.optimizers.configs import OptimizerConfigs
|
|
|
|
|
|
class Model(nn.Module):
|
|
"""
|
|
## The model
|
|
"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.conv1 = nn.Conv2d(1, 20, 5, 1)
|
|
self.pool1 = nn.MaxPool2d(2)
|
|
self.conv2 = nn.Conv2d(20, 50, 5, 1)
|
|
self.pool2 = nn.MaxPool2d(2)
|
|
self.fc1 = nn.Linear(16 * 50, 500)
|
|
self.fc2 = nn.Linear(500, 10)
|
|
self.activation = nn.ReLU()
|
|
|
|
def forward(self, x):
|
|
x = self.activation(self.conv1(x))
|
|
x = self.pool1(x)
|
|
x = self.activation(self.conv2(x))
|
|
x = self.pool2(x)
|
|
x = self.activation(self.fc1(x.view(-1, 16 * 50)))
|
|
return self.fc2(x)
|
|
|
|
|
|
class Configs(MNISTConfigs, TrainValidConfigs):
|
|
"""
|
|
## Configurable Experiment Definition
|
|
"""
|
|
optimizer: torch.optim.Adam
|
|
model: nn.Module
|
|
device: torch.device = DeviceConfigs()
|
|
epochs: int = 10
|
|
|
|
is_save_models = True
|
|
model: nn.Module
|
|
inner_iterations = 10
|
|
|
|
accuracy_func = Accuracy()
|
|
loss_func = nn.CrossEntropyLoss()
|
|
|
|
def init(self):
|
|
tracker.set_queue("loss.*", 20, True)
|
|
tracker.set_scalar("accuracy.*", True)
|
|
self.state_modules = [self.accuracy_func]
|
|
|
|
def step(self, batch: any, batch_idx: BatchIndex):
|
|
# Get the batch
|
|
data, target = batch[0].to(self.device), batch[1].to(self.device)
|
|
|
|
# Add global step if we are in training mode
|
|
if self.mode.is_train:
|
|
tracker.add_global_step(len(data))
|
|
|
|
# Run the model
|
|
output = self.model(data)
|
|
|
|
# Calculate the loss
|
|
loss = self.loss_func(output, target)
|
|
# Calculate the accuracy
|
|
self.accuracy_func(output, target)
|
|
# Log the loss
|
|
tracker.add("loss.", loss)
|
|
|
|
# Optimize if we are in training mode
|
|
if self.mode.is_train:
|
|
# Calculate the gradients
|
|
loss.backward()
|
|
|
|
# Take optimizer step
|
|
self.optimizer.step()
|
|
# Log the parameter and gradient L2 norms once per epoch
|
|
if batch_idx.is_last:
|
|
tracker.add('model', self.model)
|
|
tracker.add('optimizer', (self.optimizer, {'model': self.model}))
|
|
# Clear the gradients
|
|
self.optimizer.zero_grad()
|
|
|
|
# Save logs
|
|
tracker.save()
|
|
|
|
|
|
@option(Configs.model)
|
|
def model(c: Configs):
|
|
return Model().to(c.device)
|
|
|
|
|
|
@option(Configs.optimizer)
|
|
def _optimizer(c: Configs):
|
|
"""
|
|
Create a configurable optimizer.
|
|
We can change the optimizer type and hyper-parameters using configurations.
|
|
"""
|
|
opt_conf = OptimizerConfigs()
|
|
opt_conf.parameters = c.model.parameters()
|
|
return opt_conf
|
|
|
|
|
|
def main():
|
|
conf = Configs()
|
|
conf.inner_iterations = 10
|
|
experiment.create(name='mnist_ada_belief')
|
|
experiment.configs(conf, {'inner_iterations': 10,
|
|
# Specify the optimizer
|
|
'optimizer.optimizer': 'Adam',
|
|
'optimizer.learning_rate': 1.5e-4})
|
|
experiment.add_pytorch_models(dict(model=conf.model))
|
|
with experiment.start():
|
|
conf.run()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|