# `Finetune`

### *class* capymoa.classifier.Finetune[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/classifier/_finetune.py#L11)

Bases: [`BatchClassifier`](capymoa.base.BatchClassifier.md#capymoa.base.BatchClassifier)

Finetune a PyTorch neural network using stochastic gradient descent.

```pycon
>>> from capymoa.datasets import ElectricityTiny
>>> from capymoa.evaluation import prequential_evaluation
>>> from capymoa.classifier import Finetune
>>> from capymoa.core.torch.ann import Perceptron
>>> from torch import nn
>>> from torch.optim import Adam
>>> from functools import partial
>>>
>>> stream = ElectricityTiny()
>>> learner = Finetune(
...     stream.get_schema(),
...     model=Perceptron,
...     optimizer=partial(Adam, lr=0.01)
... )
>>> results = prequential_evaluation(stream, learner, batch_size=32)
>>> print(f"{results['cumulative'].accuracy():.1f}")
62.4
```

Alternatively, you can use a custom model and optimizer:

```pycon
>>> model = nn.Sequential(nn.Linear(6, 10), nn.ReLU(), nn.Linear(10, 2))
>>> optimizer = Adam(model.parameters(), lr=0.001)
>>> learner = Finetune(
...     schema=stream.get_schema(),
...     model=model,
...     optimizer=optimizer,
... )
>>> results = prequential_evaluation(stream, learner, batch_size=32)
>>> print(f"{results['cumulative'].accuracy():.1f}")
60.4
```

#### \_\_init_\_(schema: [Schema](capymoa.stream.Schema.md#capymoa.stream.Schema), model: [Module](https://docs.pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module) | [Callable](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[Schema](capymoa.stream.Schema.md#capymoa.stream.Schema)], [Module](https://docs.pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module)], optimizer: [Optimizer](https://docs.pytorch.org/docs/stable/optim.html#torch.optim.Optimizer) | [Callable](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[Iterator](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterator)[[Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)]], [Optimizer](https://docs.pytorch.org/docs/stable/optim.html#torch.optim.Optimizer)] = optim.Adam, criterion: [Module](https://docs.pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module) | [None](https://docs.python.org/3/builtins/constants.html#None) = None, device: [device](https://docs.pytorch.org/docs/stable/tensor_attributes.html#torch.device) | [str](https://docs.python.org/3/builtins/stdtypes.html#str) = 'cpu', random_seed: [int](https://docs.python.org/3/builtins/functions.html#int) = 0) → [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/classifier/_finetune.py#L47)

Construct a learner to finetune a neural network.

* **Parameters:**
  * **schema** – Describes streaming data types and shapes.
  * **model** – A classifier model that takes a `(bs, input_dim)` matrix
    and returns a `(bs, num_classes)` matrix. Alternatively, a
    constructor function that takes a schema and returns a model.
  * **optimizer** – A PyTorch gradient descent optimizer or a constructor
    function that takes the model parameters and returns an optimizer.
  * **criterion** – Loss function to use for training. Defaults to
    [`torch.nn.CrossEntropyLoss`](https://docs.pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html#torch.nn.CrossEntropyLoss).
  * **device** – Hardware for training.
  * **random_seed** – Seeds torch [`torch.manual_seed()`](https://docs.pytorch.org/docs/stable/generated/torch.manual_seed.html#torch.manual_seed).

#### batch_predict(x: [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)) → [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_batch_classifier.py#L115)

Predict the labels for a batch of instances.

* **Parameters:**
  **x** – Batch of [`x_dtype`](#capymoa.classifier.Finetune.x_dtype) valued feature vectors
  `(batch_size, num_features)`
* **Returns:**
  Predicted batch of [`y_dtype`](#capymoa.classifier.Finetune.y_dtype) valued labels
  `(batch_size,)`.

#### batch_predict_proba(x: [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)) → [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/classifier/_finetune.py#L105)

Predict the probabilities of the classes for the given batch of data.

* **Parameters:**
  * **x** – Input data of shape (batch_size, num_features).
  * **y** – Target labels of shape (batch_size,).
* **Returns:**
  Predicted probabilities of shape (batch_size, num_classes).

#### batch_train(x: [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor), y: [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)) → [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/classifier/_finetune.py#L90)

Train with a batch of instances.

* **Parameters:**
  * **x** – Batch of [`x_dtype`](#capymoa.classifier.Finetune.x_dtype) valued feature vectors
    `(batch_size, num_features)`
  * **y** – Batch of [`y_dtype`](#capymoa.classifier.Finetune.y_dtype) valued labels `(batch_size,)`.

#### *classmethod* from_params(schema: [Any](https://docs.python.org/3/library/typing.html#typing.Any) = None, params: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [Any](https://docs.python.org/3/library/typing.html#typing.Any)] | [None](https://docs.python.org/3/builtins/constants.html#None) = None, random_seed: [int](https://docs.python.org/3/builtins/functions.html#int) = 1) → [Any](https://docs.python.org/3/library/typing.html#typing.Any)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_learner_params.py#L170)

Construct an instance from parameters produced by `get_params`.

#### get_params() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [Any](https://docs.python.org/3/library/typing.html#typing.Any)][[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_learner_params.py#L163)

Return the hyper-parameters captured from the constructor.

#### predict(instance: [Instance](capymoa.core.Instance.md#capymoa.core.Instance)) → [int](https://docs.python.org/3/builtins/functions.html#int) | [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_classifier.py#L56)

Predict the label of an instance.

The base implementation calls [`predict_proba()`](#capymoa.classifier.Finetune.predict_proba) and returns the
label with the highest probability.

* **Parameters:**
  **instance** – The instance to predict the label for.
* **Returns:**
  The predicted label or `None` if the classifier is unable
  to make a prediction.

#### predict_proba(instance: [Instance](capymoa.core.Instance.md#capymoa.core.Instance)) → [ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)[[tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), ...], [dtype](https://numpy.org/doc/stable/reference/generated/numpy.dtype.html#numpy.dtype)[float64]] | [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_batch_classifier.py#L134)

Calls [`batch_predict_proba()`](#capymoa.classifier.Finetune.batch_predict_proba) with a batch of size 1.

#### train(instance: [LabeledInstance](capymoa.core.LabeledInstance.md#capymoa.core.LabeledInstance)) → [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_batch_classifier.py#L125)

Calls [`batch_train()`](#capymoa.classifier.Finetune.batch_train) with a batch of size 1.

#### criterion *: nn.Module*

The loss function to be used for training.

#### device *: [torch.device](https://docs.pytorch.org/docs/stable/tensor_attributes.html#torch.device)* *= device(type='cpu')*

The device to be used for training.

#### dtype *: [torch.dtype](https://docs.pytorch.org/docs/stable/tensor_attributes.html#torch.dtype)*

The data type to convert the input data to.

#### model *: nn.Module*

The model to be trained.

#### optimizer *: Optimizer*

The optimizer to be used for training.

#### random_seed *: [int](https://docs.python.org/3/builtins/functions.html#int)*

The random seed for reproducibility.

When implementing a classifier ensure random number generators are seeded.

#### schema *: [Schema](capymoa.stream.Schema.md#capymoa.stream.Schema)*

The schema representing the instances.

#### x_dtype *: [torch.dtype](https://docs.pytorch.org/docs/stable/tensor_attributes.html#torch.dtype)* *= torch.float32*

Data type for the input features.

#### y_dtype *: [torch.dtype](https://docs.pytorch.org/docs/stable/tensor_attributes.html#torch.dtype)* *= torch.int64*

Data type for the target value/labels.
