|
| 1 | +"""Optimisers demo.""" |
| 2 | + |
| 3 | +import torch |
| 4 | + |
| 5 | +# We define: |
| 6 | +# - the input as as a vector of ones, |
| 7 | +# - the target as a vector where each element is the index value, |
| 8 | +# - a tensor to transform from input to target by elementwise multiplication |
| 9 | +# initialised as a vector of ones |
| 10 | +# This is a contrived example, but provides a simple demo of optimiser functionality |
| 11 | +input_vec = torch.ones(4) |
| 12 | +target_vec = torch.tensor([1.0, 2.0, 3.0, 4.0]) |
| 13 | +scaling_tensor = torch.ones(4, requires_grad=True) |
| 14 | + |
| 15 | +# Set the optimiser as torch's stochastic gradient descent (SGD) |
| 16 | +# The parameters to tune will be the values of `tensor`, and we also set a learning rate |
| 17 | +# Since this is a simple elemetwise example we can get away with a large learning rate |
| 18 | +optimizer = torch.optim.SGD([scaling_tensor], lr=1.0) |
| 19 | + |
| 20 | +# Training loop |
| 21 | +# Run n_iter times printing every n_print steps |
| 22 | +n_iter = 15 |
| 23 | +n_print = 1 |
| 24 | +for epoch in range(n_iter + 1): |
| 25 | + # Zero any previously stored gradients ready for a new iteration |
| 26 | + optimizer.zero_grad() |
| 27 | + |
| 28 | + # Forward pass: multiply the input of ones by the tensor (elementwise) |
| 29 | + output = input_vec * scaling_tensor |
| 30 | + |
| 31 | + # Create a loss tensor as computed mean square error (MSE) between target and input |
| 32 | + # Then perform backward step on loss to propogate gradients using autograd |
| 33 | + # |
| 34 | + # We could use the following 2 lines to do this by explicitly specifying a |
| 35 | + # gradient of ones to start the process: |
| 36 | + # loss = ((output - target) ** 2) / 4.0 |
| 37 | + # loss.backward(gradient=torch.ones(4)) |
| 38 | + # |
| 39 | + # However, we can avoid explicitly passing an initial gradient and instead do this |
| 40 | + # implicitly by aggregating the loss vector into a scalar value: |
| 41 | + loss = ((output - target_vec) ** 2).mean() |
| 42 | + loss.backward() |
| 43 | + |
| 44 | + # Step the optimiser to update the values in `tensor` |
| 45 | + optimizer.step() |
| 46 | + |
| 47 | + if (epoch) % n_print == 0: |
| 48 | + print(f"========================") |
| 49 | + print(f"Epoch: {epoch}") |
| 50 | + print(f"\tOutput:\n\t\t{output}") |
| 51 | + print(f"\tloss:\n\t\t{loss}") |
| 52 | + print(f"\ttensor gradient:\n\t\t{scaling_tensor.grad}") |
| 53 | + print(f"\tscaling_tensor:\n\t\t{scaling_tensor}") |
| 54 | + |
| 55 | +print("Training complete.") |
0 commit comments