# `L2P`

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

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

Learning to Prompt.

Learning to Prompt (L2P) <sup>[1](#f1)</sup> is a continual learning strategy that leverages a
pool of learnable prompts to adapt a pre-trained vision transformer (ViT) to new
tasks. For each input, the most relevant prompts are selected from the pool based on
the similarity between the input’s embedding and the prompt keys. The selected
prompts are then used to condition the ViT, allowing it to effectively learn new
tasks while mitigating catastrophic forgetting.

L2P relies on knowledge of the tasks during training to select task-specific prompts
but does not require task information during inference.

```python
# Please note this code block is not regularly tested.
from capymoa.ocl.strategy.l2p import L2P
from capymoa.ocl.datasets import SplitCIFAR100
from capymoa.ocl.evaluation import ocl_train_eval_loop
scenario = SplitCIFAR100()
learner = L2P(scenario.schema, scenario.task_mask, device="cuda")
results = ocl_train_eval_loop(
    learner,
    scenario.train_loaders(32),
    scenario.test_loaders(32),
    progress_bar=True
)
print(f"{results.accuracy_final*100:.1f}%")
```

* <a id='f1'>**[1]**</a> Wang, Z., Zhang, Z., Lee, C.-Y., Zhang, H., Sun, R., Ren, X., Su, G., Perot, V., Dy, J. G., & Pfister, T. (2022). Learning to prompt for continual learning. IEEE/CVF Conference on Computer Vision and Pattern Recognition, CVPR 2022, New Orleans, LA, USA, June 18-24, 2022, 139-149. [https://doi.org/10.1109/CVPR52688.2022.00024](https://doi.org/10.1109/CVPR52688.2022.00024)

#### \_\_init_\_(schema: [Schema](capymoa.stream.Schema.md#capymoa.stream.Schema), task_mask: [Tensor](https://docs.pytorch.org/docs/stable/tensors.html#torch.Tensor), vit: [L2PViT](capymoa.ocl.strategy.l2p.L2PViT.md#capymoa.ocl.strategy.l2p.L2PViT) | [str](https://docs.python.org/3/builtins/stdtypes.html#str) = 'facebook/dinov2-small', prompts_per_task: [int](https://docs.python.org/3/builtins/functions.html#int) = 5, prompt_length: [int](https://docs.python.org/3/builtins/functions.html#int) = 1, top_k: [int](https://docs.python.org/3/builtins/functions.html#int) = 3, pull_constraint_coeff: [float](https://docs.python.org/3/builtins/functions.html#float) = 0.1, optimizer: [Callable](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[Any](https://docs.python.org/3/library/typing.html#typing.Any)], [Optimizer](https://docs.pytorch.org/docs/stable/optim.html#torch.optim.Optimizer)] = lambda params: ..., device: [str](https://docs.python.org/3/builtins/stdtypes.html#str) = 'cpu', random_seed: [int](https://docs.python.org/3/builtins/functions.html#int) = 1)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/ocl/strategy/l2p.py#L248)

Construct L2P learner.

* **Parameters:**
  * **schema** – Schema describing the datastream.
  * **task_mask** – A boolean tensor of shape (num_tasks, num_classes) indicating
    which classes belong to each task.
  * **vit** – Vision transformer backbone or the name of a pretrained model from
    HuggingFace Transformers. Requires transformers to be installed.
  * **prompts_per_task** – Number of prompts per task in the prompt pool.
  * **prompt_length** – Length of each prompt (number of tokens/patches).
  * **top_k** – Number of top prompts to retrieve per query.
  * **pull_constraint_coeff** – Coefficient for the pull constraint loss term.
  * **optimizer** – Function that takes model parameters and returns an optimizer instance.
  * **device** – Device to run the model on, e.g., “cpu” or “cuda”.
  * **random_seed** – Random seed for reproducibility.
  * **logger** – Optional logger for tracking training metrics.

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

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

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

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

Train with a batch of instances.

* **Parameters:**
  * **x** – Batch of [`x_dtype`](#capymoa.ocl.strategy.l2p.L2P.x_dtype) valued feature vectors
    `(batch_size, num_features)`
  * **y** – Batch of [`y_dtype`](#capymoa.ocl.strategy.l2p.L2P.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.

#### on_train_task(task_id: [int](https://docs.python.org/3/builtins/functions.html#int))[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/ocl/strategy/l2p.py#L307)

#### 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.l2p.L2P.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.l2p.L2P.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.l2p.L2P.batch_train) with a batch of size 1.

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