# `RAR`

### *class* capymoa.ocl.strategy.RAR[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/ocl/strategy/_rar.py#L11)

Bases: [`BatchClassifier`](capymoa.base.BatchClassifier.md#capymoa.base.BatchClassifier), [`Handler`](capymoa.ocl.events.Handler.md#capymoa.ocl.events.Handler)

Repeated Augmented Rehearsal.

Repeated Augmented Rehearsal (RAR) <sup>[1](#f0)</sup> is a replay continual learning
strategy that combines data augmentation with repeated training on each
batch to mitigate catastrophic forgetting.

* Coreset Selection: Reservoir sampling is used to select a fixed-size
  buffer of past examples.
* Coreset Retrieval: During training, the learner samples uniformly from the
  buffer of past examples.
* Coreset Exploitation: The learner trains on the current batch of examples
  and the sampled buffer examples, performing multiple optimization steps
  per-batch using random augmentations of the examples. The original paper uses
  RandAugment <sup>[2](#f1)</sup> for augmentation but any randomized augmentation can be used.
  But the choice of augmentation is important and should be chosen based on the
  problem domain.

```pycon
>>> from capymoa.core.torch.ann import Perceptron
>>> from capymoa.classifier import Finetune
>>> from capymoa.ocl.strategy import RAR
>>> from capymoa.ocl.datasets import TinySplitMNIST
>>> from capymoa.ocl.evaluation import ocl_train_eval_loop
>>> import torchvision.transforms as T
>>> import torch
>>> _ = torch.manual_seed(0)
>>> scenario = TinySplitMNIST()
>>> model = Perceptron(scenario.schema)
>>> # You should use more complex augmentations for more challenging problems.
>>> augment = T.Compose([
...     T.RandomRotation(10),
... ])
>>> learner = RAR(Finetune(scenario.schema, model), augment=augment, repeats=5)
>>> results = ocl_train_eval_loop(
...     learner,
...     scenario.train_loaders(32),
...     scenario.test_loaders(32),
... )
>>> print(f"{results.accuracy_final*100:.1f}%")
39.5%
```

Usually more complex augmentations are used such as random crops and
rotations.

* <a id='f0'>**[1]**</a> Zhang, Yaqian, Bernhard Pfahringer, Eibe Frank, Albert Bifet, Nick Jin Sean Lim, and Yunzhe Jia. “A Simple but Strong Baseline for Online Continual Learning: Repeated Augmented Rehearsal.” In Advances in Neural Information Processing Systems 35: Annual Conference on Neural Information Processing Systems 2022, NeurIPS 2022, New Orleans, LA, USA, November 28 - December 9, 2022, edited by Sanmi Koyejo, S. Mohamed, A. Agarwal, Danielle Belgrave, K. Cho, and A. Oh, 2022. [https://doi.org/10.5555/3600270.3601344](https://doi.org/10.5555/3600270.3601344).
* <a id='f1'>**[2]**</a> Cubuk, E. D., Zoph, B., Shlens, J., & Le, Q. V. (2020). Randaugment: Practical automated data augmentation with a reduced search space. 2020 IEEE/CVF Conference on Computer Vision and Pattern Recognition Workshops (CVPRW), 3008-3017. [https://doi.org/10.1109/CVPRW50498.2020.00359](https://doi.org/10.1109/CVPRW50498.2020.00359)

#### \_\_init_\_(learner: [BatchClassifier](capymoa.base.BatchClassifier.md#capymoa.base.BatchClassifier), augment: [Callable](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)], [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor)], coreset_size: [int](https://docs.python.org/3/builtins/functions.html#int) = 200, repeats: [int](https://docs.python.org/3/builtins/functions.html#int) = 1) → [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/ocl/strategy/_rar.py#L72)

Initialize Repeated Augmented Rehearsal.

* **Parameters:**
  * **learner** – Underlying learner to be trained with RAR.
  * **augment** – Data augmentation function to apply to the samples. Should take
    a Tensor of shape `(batch_size, *schema.shape)` and return a Tensor of the
    same shape. Take a look at the PyTorch torchvision transforms for some
    building blocks for your pipeline ([https://docs.pytorch.org/vision/main/transforms.html](https://docs.pytorch.org/vision/main/transforms.html)).
  * **coreset_size** – Size of the coreset buffer.
  * **repeats** – Number of times to repeat training on each batch, defaults to 1.

#### attach_with(source: [Dispatcher](capymoa.ocl.events.Dispatcher.md#capymoa.ocl.events.Dispatcher)) → [RAR](#capymoa.ocl.strategy.RAR)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/ocl/strategy/_rar.py#L126)

Attach this sink to an event source.

Implementations should call
[`capymoa.ocl.events.Dispatcher.subscribe()`](capymoa.ocl.events.Dispatcher.md#capymoa.ocl.events.Dispatcher.subscribe) for each
event type the sink needs to handle.

* **Parameters:**
  **dispatcher** – The source this sink should subscribe to.

#### 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.ocl.strategy.RAR.x_dtype) valued feature vectors
  `(batch_size, num_features)`
* **Returns:**
  Predicted batch of [`y_dtype`](#capymoa.ocl.strategy.RAR.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/ocl/strategy/_rar.py#L121)

Predict the probabilities of the classes for a batch of instances.

* **Parameters:**
  **x** – Batch of [`x_dtype`](#capymoa.ocl.strategy.RAR.x_dtype) valued feature vectors
  `(batch_size, num_features)`
* **Returns:**
  Batch of [`x_dtype`](#capymoa.ocl.strategy.RAR.x_dtype) valued predicted probabilities
  `(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/ocl/strategy/_rar.py#L116)

Train with a batch of instances.

* **Parameters:**
  * **x** – Batch of [`x_dtype`](#capymoa.ocl.strategy.RAR.x_dtype) valued feature vectors
    `(batch_size, num_features)`
  * **y** – Batch of [`y_dtype`](#capymoa.ocl.strategy.RAR.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.ocl.strategy.RAR.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.ocl.strategy.RAR.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.ocl.strategy.RAR.batch_train) with a batch of size 1.

#### train_step(x_fresh: [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor), y_fresh: [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/ocl/strategy/_rar.py#L102)

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

Device on which the batch will be processed.

#### 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.
