{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "b773bf8e-c420-44e1-80a6-99f75dd12268", "metadata": {}, "source": [ "# 3. Using Pytorch with CapyMOA\n", "* This notebook demonstrates how use Pytorch with CapyMOA.\n", "* It contains examples showing \n", " * How to define a Pytorch Network to be used with CapyMOA\n", " * How a simple Pytorch model can be used in a CapyMOA ```Instance``` loop\n", " * How to define a Pytorch CapyMOA Classifier based on CapyMOA ```Classifier``` framework and how to use it with ```prequential_evaluation()```\n", " * How to use a Pytorch dataset with a CapyMOA classifier\n", "* **Tutorial 6**: `Exploring Advanced Features` includes an example using TensorBoard and a `PyTorchClassifier`\n", " \n", "---\n", "\n", "*More information about CapyMOA can be found in* https://www.capymoa.org\n", "\n", "**last update on 25/07/2024**" ] }, { "attachments": {}, "cell_type": "markdown", "id": "cd9a931c-7b86-4bd6-8cda-179154e4b513", "metadata": {}, "source": [ "## 1. Setup\n", "* Sets random seed for reproducibility\n", "* Sets Pytorch network " ] }, { "attachments": {}, "cell_type": "markdown", "id": "9b6d4a63467b23b5", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "### 1.1 Set random seeds" ] }, { "cell_type": "code", "execution_count": 1, "id": "2242896e95964ef4", "metadata": { "ExecuteTime": { "end_time": "2024-04-29T11:56:23.668712Z", "start_time": "2024-04-29T11:56:23.659844Z" }, "collapsed": false, "execution": { "iopub.execute_input": "2024-09-23T00:28:34.435464Z", "iopub.status.busy": "2024-09-23T00:28:34.434857Z", "iopub.status.idle": "2024-09-23T00:28:34.440944Z", "shell.execute_reply": "2024-09-23T00:28:34.440612Z" }, "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "import random\n", "\n", "random_seed = 1\n", "random.seed(random_seed)" ] }, { "attachments": {}, "cell_type": "markdown", "id": "ccbccfce41f2f18", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "### 1.2 Define network structure\n", "* Here, network uses the CPU device" ] }, { "cell_type": "code", "execution_count": 2, "id": "fbcd4d91-2b00-4d5a-9c54-f9dd6a291aa5", "metadata": { "ExecuteTime": { "end_time": "2024-04-29T11:24:39.060139Z", "start_time": "2024-04-29T11:24:39.035090Z" }, "execution": { "iopub.execute_input": "2024-09-23T00:28:34.442657Z", "iopub.status.busy": "2024-09-23T00:28:34.442418Z", "iopub.status.idle": "2024-09-23T00:28:35.180762Z", "shell.execute_reply": "2024-09-23T00:28:35.180261Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using cpu device\n" ] } ], "source": [ "import torch\n", "from torch import nn\n", "\n", "torch.manual_seed(random_seed)\n", "torch.use_deterministic_algorithms(True)\n", "\n", "# Get cpu device for training.\n", "device = \"cpu\"\n", "print(f\"Using {device} device\")\n", "\n", "\n", "# Define model\n", "class NeuralNetwork(nn.Module):\n", " def __init__(self, input_size=0, number_of_classes=0):\n", " super().__init__()\n", " self.flatten = nn.Flatten()\n", " self.linear_relu_stack = nn.Sequential(\n", " nn.Linear(input_size, 512),\n", " nn.ReLU(),\n", " nn.Linear(512, 512),\n", " nn.ReLU(),\n", " nn.Linear(512, number_of_classes),\n", " )\n", "\n", " def forward(self, x):\n", " x = self.flatten(x)\n", " logits = self.linear_relu_stack(x)\n", " return logits" ] }, { "attachments": {}, "cell_type": "markdown", "id": "882b6b292a2de100", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "### 1.3 Using instance loop\n", "* Model is initialized after receiving the first instance" ] }, { "cell_type": "code", "execution_count": 3, "id": "81092940-5a6b-4377-b550-ed6f5fee711a", "metadata": { "ExecuteTime": { "end_time": "2024-04-29T11:24:41.344634Z", "start_time": "2024-04-29T11:24:39.063330Z" }, "execution": { "iopub.execute_input": "2024-09-23T00:28:35.182576Z", "iopub.status.busy": "2024-09-23T00:28:35.182380Z", "iopub.status.idle": "2024-09-23T00:28:38.088429Z", "shell.execute_reply": "2024-09-23T00:28:38.088007Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "NeuralNetwork(\n", " (flatten): Flatten(start_dim=1, end_dim=-1)\n", " (linear_relu_stack): Sequential(\n", " (0): Linear(in_features=6, out_features=512, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=512, out_features=512, bias=True)\n", " (3): ReLU()\n", " (4): Linear(in_features=512, out_features=2, bias=True)\n", " )\n", ")\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Accuracy at 500 : 50.4\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Accuracy at 1000 : 55.2\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Accuracy at 1500 : 61.199999999999996\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Accuracy at 2000 : 61.1\n", "Accuracy at 2000 : 61.1\n" ] } ], "source": [ "from capymoa.evaluation import ClassificationEvaluator\n", "from capymoa.datasets import ElectricityTiny\n", "\n", "elec_stream = ElectricityTiny()\n", "\n", "# Creating the evaluator\n", "evaluator = ClassificationEvaluator(schema=elec_stream.get_schema())\n", "\n", "model = None\n", "optimizer = None\n", "loss_fn = nn.CrossEntropyLoss()\n", "\n", "i = 0\n", "while elec_stream.has_more_instances():\n", " i += 1\n", " instance = elec_stream.next_instance()\n", " if model is None:\n", " moa_instance = instance.java_instance.getData()\n", " # initialize the model and send it to the device\n", " model = NeuralNetwork(\n", " input_size=elec_stream.get_schema().get_num_attributes(),\n", " number_of_classes=elec_stream.get_schema().get_num_classes(),\n", " ).to(device)\n", " # set the optimizer\n", " optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)\n", " print(model)\n", "\n", " X = torch.tensor(instance.x, dtype=torch.float32)\n", " y = torch.tensor(instance.y_index, dtype=torch.long)\n", " # set the device and add a dimension to the tensor\n", " X, y = torch.unsqueeze(X.to(device), 0), torch.unsqueeze(y.to(device), 0)\n", "\n", " # turn off gradient collection for test\n", " with torch.no_grad():\n", " pred = model(X)\n", " prediction = torch.argmax(pred)\n", "\n", " # update evaluator with predicted class\n", " evaluator.update(instance.y_index, prediction.item())\n", "\n", " # Compute prediction error\n", " pred = model(X)\n", " loss = loss_fn(pred, y)\n", "\n", " # Backpropagation\n", " loss.backward()\n", " optimizer.step()\n", " optimizer.zero_grad()\n", "\n", " if i % 500 == 0:\n", " print(f\"Accuracy at {i} : {evaluator.accuracy()}\")\n", "\n", "print(f\"Accuracy at {i} : {evaluator.accuracy()}\")" ] }, { "attachments": {}, "cell_type": "markdown", "id": "2803eaab-eb2b-4c6e-a246-67f9ac71f70f", "metadata": {}, "source": [ "## 2. PyTorchClassifier\n", "* Defining a `PyTorchClassifier` using CapyMOA API makes it **compatibility** with CapyMOA functions like `prequential_evaluation()` without losing the **flexibility** of specifying the `architecture` and the `training` method\n", "* Model is initialized after receiving the first instance\n", "* `PyTorchClassifier` is based on `capymoa.base` ```Classifier``` abstract class\n", "\n", "* **Important**: We can access information about the stream through any of its instances. See `set_model(self, instance)` for an example: \n", "\n", "```python\n", "...\n", "moa_instance = instance.java_instance.getData()\n", "self.model = NeuralNetwork(input_size=moa_instance.get_num_attributes(), \n", " number_of_classes=moa_instance.get_num_classes()).to(self.device)\n", "...\n", "```" ] }, { "cell_type": "code", "execution_count": 4, "id": "1c75513c-58e8-4499-bb19-2c58aea4567b", "metadata": { "ExecuteTime": { "end_time": "2024-04-29T11:24:41.367535Z", "start_time": "2024-04-29T11:24:41.347463Z" }, "execution": { "iopub.execute_input": "2024-09-23T00:28:38.090257Z", "iopub.status.busy": "2024-09-23T00:28:38.090039Z", "iopub.status.idle": "2024-09-23T00:28:38.099048Z", "shell.execute_reply": "2024-09-23T00:28:38.098639Z" } }, "outputs": [], "source": [ "from capymoa.base import Classifier\n", "import numpy as np\n", "\n", "\n", "class PyTorchClassifier(Classifier):\n", " def __init__(\n", " self,\n", " schema=None,\n", " random_seed=1,\n", " nn_model: nn.Module = None,\n", " optimizer=None,\n", " loss_fn=nn.CrossEntropyLoss(),\n", " device=(\"cpu\"),\n", " lr=1e-3,\n", " ):\n", " super().__init__(schema, random_seed)\n", " self.model = None\n", " self.optimizer = None\n", " self.loss_fn = loss_fn\n", " self.lr = lr\n", " self.device = device\n", "\n", " torch.manual_seed(random_seed)\n", "\n", " if nn_model is None:\n", " self.set_model(None)\n", " else:\n", " self.model = nn_model.to(device)\n", " if optimizer is None:\n", " if self.model is not None:\n", " self.optimizer = torch.optim.SGD(self.model.parameters(), lr=lr)\n", " else:\n", " self.optimizer = optimizer\n", "\n", " def __str__(self):\n", " return str(self.model)\n", "\n", " def CLI_help(self):\n", " return str(\n", " 'schema=None, random_seed=1, nn_model: nn.Module = None, optimizer=None, loss_fn=nn.CrossEntropyLoss(), device=(\"cpu\"), lr=1e-3'\n", " )\n", "\n", " def set_model(self, instance):\n", " if self.schema is None:\n", " moa_instance = instance.java_instance.getData()\n", " self.model = NeuralNetwork(\n", " input_size=moa_instance.get_num_attributes(),\n", " number_of_classes=moa_instance.get_num_classes(),\n", " ).to(self.device)\n", " elif instance is not None:\n", " self.model = NeuralNetwork(\n", " input_size=self.schema.get_num_attributes(),\n", " number_of_classes=self.schema.get_num_classes(),\n", " ).to(self.device)\n", "\n", " def train(self, instance):\n", " if self.model is None:\n", " self.set_model(instance)\n", "\n", " X = torch.tensor(instance.x, dtype=torch.float32)\n", " y = torch.tensor(instance.y_index, dtype=torch.long)\n", " # set the device and add a dimension to the tensor\n", " X, y = (\n", " torch.unsqueeze(X.to(self.device), 0),\n", " torch.unsqueeze(y.to(self.device), 0),\n", " )\n", "\n", " # Compute prediction error\n", " pred = self.model(X)\n", " loss = self.loss_fn(pred, y)\n", "\n", " # Backpropagation\n", " loss.backward()\n", " self.optimizer.step()\n", " self.optimizer.zero_grad()\n", "\n", " def predict(self, instance):\n", " return np.argmax(self.predict_proba(instance))\n", "\n", " def predict_proba(self, instance):\n", " if self.model is None:\n", " self.set_model(instance)\n", " X = torch.unsqueeze(\n", " torch.tensor(instance.x, dtype=torch.float32).to(self.device), 0\n", " )\n", " # turn off gradient collection\n", " with torch.no_grad():\n", " pred = np.asarray(self.model(X).numpy(), dtype=np.double)\n", " return pred" ] }, { "attachments": {}, "cell_type": "markdown", "id": "75ee1eb154c01996", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "### 2.2 Using PyTorchClassifier + prequential_evaluation\n", "\n", "* We can access information about the stream through the `schema` directly, from the example below: \n", "```python\n", "...\n", "nn_model=NeuralNetwork(input_size=elec_stream.get_schema().get_num_attributes(),\n", " number_of_classes=elec_stream.get_schema().get_num_classes()).to(device)\n", "...\n", "```" ] }, { "cell_type": "code", "execution_count": 5, "id": "ece5b5ff-be24-439c-bf53-7bf5d4fbf858", "metadata": { "ExecuteTime": { "end_time": "2024-04-29T11:24:43.665700Z", "start_time": "2024-04-29T11:24:41.371991Z" }, "execution": { "iopub.execute_input": "2024-09-23T00:28:38.100830Z", "iopub.status.busy": "2024-09-23T00:28:38.100659Z", "iopub.status.idle": "2024-09-23T00:28:39.633560Z", "shell.execute_reply": "2024-09-23T00:28:39.633201Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Accuracy: 62.849999999999994\n" ] } ], "source": [ "from capymoa.evaluation import prequential_evaluation\n", "\n", "## Opening a file as a stream\n", "elec_stream = ElectricityTiny()\n", "\n", "# Creating a learner\n", "simple_pyTorch_classifier = PyTorchClassifier(\n", " schema=elec_stream.get_schema(),\n", " nn_model=NeuralNetwork(\n", " input_size=elec_stream.get_schema().get_num_attributes(),\n", " number_of_classes=elec_stream.get_schema().get_num_classes(),\n", " ).to(device),\n", ")\n", "\n", "evaluator = prequential_evaluation(\n", " stream=elec_stream,\n", " learner=simple_pyTorch_classifier,\n", " window_size=4500,\n", " optimise=False,\n", ")\n", "\n", "print(f\"Accuracy: {evaluator.cumulative.accuracy()}\")" ] }, { "cell_type": "markdown", "id": "a3a752afb7e7698d", "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false } }, "source": [ "## 3. How to use a Pytorch dataset with a CapyMOA classifier\n", "* One may want to use various Pytorch datasets with different CapyMOA classifiers\n", "* In this example we use Pytorch Dataset + prequential evaluation + CapyMOA Classifier\n", "\n", "**Observation**: *Using a learner like Online Bagging without any feature extraction is not going to yield meaningful performance*" ] }, { "cell_type": "code", "execution_count": 6, "id": "8a6fdd873625b07b", "metadata": { "ExecuteTime": { "end_time": "2024-04-29T11:24:56.571969Z", "start_time": "2024-04-29T11:24:49.646899Z" }, "execution": { "iopub.execute_input": "2024-09-23T00:28:39.635436Z", "iopub.status.busy": "2024-09-23T00:28:39.635283Z", "iopub.status.idle": "2024-09-23T00:28:43.949481Z", "shell.execute_reply": "2024-09-23T00:28:43.948975Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Accuracy: 43.5\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
instancesaccuracykappakappa_tkappa_mf1_scoref1_score_0f1_score_1f1_score_2f1_score_3...recall_0recall_1recall_2recall_3recall_4recall_5recall_6recall_7recall_8recall_9
0100.017.06.2676450.0000000.000000NaN23.18840630.76923146.15384612.500000...66.66666718.18181833.3333336.6666670.0000000.0000000.00000012.5000000.00000018.181818
1200.041.033.28810532.95454530.58823545.87966639.13043557.14285736.363636NaN...75.00000040.00000022.2222220.00000022.22222222.22222263.63636423.07692375.00000012.500000
2300.030.022.12704423.07692323.076923NaN24.39024472.72727351.851852NaN...62.50000057.14285753.8461540.0000009.09090918.18181833.33333322.22222218.18181850.000000
3400.048.041.77583743.47826142.22222254.21695836.36363670.58823522.22222215.384615...72.72727354.54545525.0000008.33333325.00000066.66666750.00000063.63636466.66666733.333333
4500.051.045.59182845.55555642.35294156.93295839.02439050.00000023.52941222.222222...88.88888940.00000016.66666712.50000050.00000075.00000025.00000062.50000078.57142954.545455
5600.048.042.16438739.53488436.585366NaN38.88888950.00000047.058824NaN...70.00000033.33333340.0000000.00000050.00000071.42857146.15384650.00000062.50000061.538462
6700.046.039.36671936.47058829.870130NaN42.10526380.00000050.000000NaN...88.88888966.66666757.1428570.00000061.53846225.00000033.33333322.22222268.75000042.857143
7800.055.049.30148749.43820247.058824NaN58.82352996.55172460.000000NaN...90.90909193.33333350.0000000.00000066.66666753.84615427.27272720.00000063.63636437.500000
8900.050.043.81391245.65217442.52873648.26127666.66666781.81818215.38461562.500000...87.50000069.23076916.66666745.45454516.66666750.00000033.33333330.00000044.44444450.000000
91000.049.043.11844746.87500042.04545554.45583059.25925985.71428655.55555622.222222...88.88888985.71428650.00000012.50000075.00000066.66666727.27272712.50000087.50000012.500000
\n", "

10 rows × 38 columns

\n", "
" ], "text/plain": [ " instances accuracy kappa kappa_t kappa_m f1_score \\\n", "0 100.0 17.0 6.267645 0.000000 0.000000 NaN \n", "1 200.0 41.0 33.288105 32.954545 30.588235 45.879666 \n", "2 300.0 30.0 22.127044 23.076923 23.076923 NaN \n", "3 400.0 48.0 41.775837 43.478261 42.222222 54.216958 \n", "4 500.0 51.0 45.591828 45.555556 42.352941 56.932958 \n", "5 600.0 48.0 42.164387 39.534884 36.585366 NaN \n", "6 700.0 46.0 39.366719 36.470588 29.870130 NaN \n", "7 800.0 55.0 49.301487 49.438202 47.058824 NaN \n", "8 900.0 50.0 43.813912 45.652174 42.528736 48.261276 \n", "9 1000.0 49.0 43.118447 46.875000 42.045455 54.455830 \n", "\n", " f1_score_0 f1_score_1 f1_score_2 f1_score_3 ... recall_0 recall_1 \\\n", "0 23.188406 30.769231 46.153846 12.500000 ... 66.666667 18.181818 \n", "1 39.130435 57.142857 36.363636 NaN ... 75.000000 40.000000 \n", "2 24.390244 72.727273 51.851852 NaN ... 62.500000 57.142857 \n", "3 36.363636 70.588235 22.222222 15.384615 ... 72.727273 54.545455 \n", "4 39.024390 50.000000 23.529412 22.222222 ... 88.888889 40.000000 \n", "5 38.888889 50.000000 47.058824 NaN ... 70.000000 33.333333 \n", "6 42.105263 80.000000 50.000000 NaN ... 88.888889 66.666667 \n", "7 58.823529 96.551724 60.000000 NaN ... 90.909091 93.333333 \n", "8 66.666667 81.818182 15.384615 62.500000 ... 87.500000 69.230769 \n", "9 59.259259 85.714286 55.555556 22.222222 ... 88.888889 85.714286 \n", "\n", " recall_2 recall_3 recall_4 recall_5 recall_6 recall_7 \\\n", "0 33.333333 6.666667 0.000000 0.000000 0.000000 12.500000 \n", "1 22.222222 0.000000 22.222222 22.222222 63.636364 23.076923 \n", "2 53.846154 0.000000 9.090909 18.181818 33.333333 22.222222 \n", "3 25.000000 8.333333 25.000000 66.666667 50.000000 63.636364 \n", "4 16.666667 12.500000 50.000000 75.000000 25.000000 62.500000 \n", "5 40.000000 0.000000 50.000000 71.428571 46.153846 50.000000 \n", "6 57.142857 0.000000 61.538462 25.000000 33.333333 22.222222 \n", "7 50.000000 0.000000 66.666667 53.846154 27.272727 20.000000 \n", "8 16.666667 45.454545 16.666667 50.000000 33.333333 30.000000 \n", "9 50.000000 12.500000 75.000000 66.666667 27.272727 12.500000 \n", "\n", " recall_8 recall_9 \n", "0 0.000000 18.181818 \n", "1 75.000000 12.500000 \n", "2 18.181818 50.000000 \n", "3 66.666667 33.333333 \n", "4 78.571429 54.545455 \n", "5 62.500000 61.538462 \n", "6 68.750000 42.857143 \n", "7 63.636364 37.500000 \n", "8 44.444444 50.000000 \n", "9 87.500000 12.500000 \n", "\n", "[10 rows x 38 columns]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA+QAAAHWCAYAAAD+cEOeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAACBw0lEQVR4nOzdd3hUVeLG8fdOMumNFBJKKqE3adLBAqJiRxRFsWLDBqs/7B0V69oBRVxcEAv2tVGk995bSCCUhISQ3iaZ+/sjkDULCIQkN5l8P8/DA5m5ufMOHGPenHvPMUzTNAUAAAAAAGqUzeoAAAAAAADURxRyAAAAAAAsQCEHAAAAAMACFHIAAAAAACxAIQcAAAAAwAIUcgAAAAAALEAhBwAAAADAAhRyAAAAAAAsQCEHAAAAAMACFHIAAAAAACxAIQcAAAAAwAIUcgAAAAAALEAhBwAAlZKXl2d1BAAA6jQKOQAAtcSePXt03333qWXLlvL29lZISIiGDh2qpKSk447NzMzU6NGjFRMTI09PTzVt2lQjRoxQenp6+TGFhYV67rnn1KJFC3l5ealRo0a65pprlJCQIEmaN2+eDMPQvHnzKpw7KSlJhmHos88+K3/s1ltvlZ+fnxISEnTppZfK399fw4cPlyQtXLhQQ4cOVVRUlDw9PRUZGanRo0eroKDguNzbtm3Tddddp7CwMHl7e6tly5Z68sknJUl//vmnDMPQd999d9znTZ8+XYZhaOnSpWf61woAQK3lbnUAAABQZuXKlVqyZImGDRumpk2bKikpSR999JHOO+88bdmyRT4+PpKk3Nxc9e3bV1u3btXtt9+uzp07Kz09XT/++KP27dun0NBQlZaW6rLLLtOcOXM0bNgwPfTQQ8rJydGsWbO0adMmNWvW7IzzlZSUaNCgQerTp4/eeOON8jxff/218vPzde+99yokJEQrVqzQe++9p3379unrr78u//wNGzaob9++stvtuuuuuxQTE6OEhAT99NNPGjdunM477zxFRkZq2rRpuvrqqyu89rRp09SsWTP17NnzLP6GAQCoXSjkAADUEoMHD9a1115b4bHLL79cPXv21MyZM3XzzTdLkl5//XVt2rRJ3377bYXi+tRTT8k0TUnS1KlTNWfOHL311lsaPXp0+TGPPfZY+TFnqqioSEOHDtUrr7xS4fHx48fL29u7/OO77rpL8fHxeuKJJ7R3715FRUVJkh544AGZpqk1a9aUPyZJr776qiTJMAzddNNNeuutt5SVlaXAwEBJUlpamv7444/ymXQAAFwFl6wDAFBL/LXUOhwOHT58WPHx8QoKCtKaNWvKn5s5c6Y6dux43CyyVFZqjx0TGhqqBx544KTHVMa99977t7nz8vKUnp6uXr16yTRNrV27VlJZqV6wYIFuv/32CmX8f/OMGDFCRUVF+uabb8of+/LLL1VSUqKbbrqp0rkBAKiNKOQAANQSBQUFeuaZZxQZGSlPT0+FhoYqLCxMmZmZysrKKj8uISFB7dq1+9tzJSQkqGXLlnJ3r7qL4dzd3dW0adPjHt+7d69uvfVWBQcHy8/PT2FhYerfv78klefevXu3JJ0yd6tWrdStWzdNmzat/LFp06apR48eio+Pr6q3AgBArcAl6wAA1BIPPPCApkyZoocfflg9e/ZUYGCgDMPQsGHD5HQ6q/z1TjZTXlpaesLHPT09ZbPZjjt24MCBysjI0NixY9WqVSv5+vpq//79uvXWWyuVe8SIEXrooYe0b98+FRUVadmyZXr//ffP+DwAANR2FHIAAGqJb775RrfccovefPPN8scKCwuVmZlZ4bhmzZpp06ZNf3uuZs2aafny5XI4HLLb7Sc8pkGDBpJ03Pn37Nlz2pk3btyoHTt26F//+pdGjBhR/visWbMqHBcXFydJp8wtScOGDdOYMWP0xRdfqKCgQHa7Xddff/1pZwIAoK7gknUAAGoJNze34xZce++9946bsR4yZIjWr19/wu3Bjn3+kCFDlJ6efsKZ5WPHREdHy83NTQsWLKjw/IcffnhGmf96zmN/fueddyocFxYWpn79+unTTz/V3r17T5jnmNDQUF1yySX697//rWnTpuniiy9WaGjoaWcCAKCuYIYcAIBa4rLLLtPnn3+uwMBAtWnTRkuXLtXs2bMVEhJS4bhHH31U33zzjYYOHarbb79dXbp0UUZGhn788UdNmDBBHTt21IgRIzR16lSNGTNGK1asUN++fZWXl6fZs2frvvvu05VXXqnAwEANHTpU7733ngzDULNmzfTzzz/r0KFDp525VatWatasmR555BHt379fAQEBmjlzpo4cOXLcse+++6769Omjzp0766677lJsbKySkpL0n//8R+vWratw7IgRI8pXnH/xxRfP/C8TAIA6gEIOAEAt8c4778jNzU3Tpk1TYWGhevfurdmzZ2vQoEEVjvPz89PChQv17LPP6rvvvtO//vUvNWzYUBdeeGH5omtubm765ZdfNG7cOE2fPl0zZ85USEiI+vTpo/bt25ef67333pPD4dCECRPk6emp6667Tq+//vopF187xm6366efftKDDz6oV155RV5eXrr66qt1//33q2PHjhWO7dixo5YtW6ann35aH330kQoLCxUdHa3rrrvuuPNefvnlatCggZxOp6644ooz/asEAKBOMMzKbkYKAABQTUpKStS4cWNdfvnlmjx5stVxAACoFtxDDgAAap3vv/9eaWlpFRaKAwDA1TBDDgAAao3ly5drw4YNevHFFxUaGqo1a9ZYHQkAgGrDDDkAAKg1PvroI917771q2LChpk6danUcAACqFTPkAAAAAABYgBlyAAAAAAAsQCEHAAAAAMACLr8PudPp1IEDB+Tv7y/DMKyOAwAAAABwcaZpKicnR40bN5bNdvJ5cJcv5AcOHFBkZKTVMQAAAAAA9UxycrKaNm160uddvpD7+/tLKvuLCAgIsDgNahuHw6E//vhDF110kex2u9VxgGrFeEd9wnhHfcJ4R31SV8Z7dna2IiMjy/voybh8IT92mXpAQACFHMdxOBzy8fFRQEBArf4PGqgKjHfUJ4x31CeMd9QndW28n+q2aRZ1AwAAAADAAhRyAAAAAAAsQCEHAAAAAMACLn8POQAAAID6rbS0VA6Hw+oYqAIOh0Pu7u4qLCxUaWmpZTnc3Nzk7u5+1ltrU8gBAAAAuKzc3Fzt27dPpmlaHQVVwDRNRUREKDk5+azL8Nny8fFRo0aN5OHhUelzUMgBAAAAuKTS0lLt27dPPj4+CgsLs7zA4ew5nU7l5ubKz89PNps1d2Cbpqni4mKlpaUpMTFRzZs3r3QWCjkAAAAAl+RwOGSapsLCwuTt7W11HFQBp9Op4uJieXl5WVbIJcnb21t2u1179uwpz1MZLOoGAAAAwKUxM47qUBU/EKCQAwAAAABgAQo5AAAAAAAWoJADAAAAgItKSkqSYRhat26dJGnevHkyDEOZmZmW5qpO//ueazMKOQAAAAD8jcT0PI3/bZse+GKtxv+2TYnpeTXyusnJybr99tvVuHFjeXh4KDo6Wg899JAOHz5c6XP26tVLBw8eVGBgYBUmLbtP/9gvd3d3RUVFacyYMSoqKqrS1zkdkZGROnjwoNq1a1fjr32mWGUdAAAAAE7iq1XJemzmBhmGIdM0ZRiGJs5P0PghHTS0a2S1ve7u3bvVs2dPtWjRQl988YViY2O1efNmPfroo/r111+1bNkyBQcHn/F5PTw8FBERUQ2JpSlTpujiiy+Ww+HQ+vXrddttt8nX11cvvvhitbzeybi5uVXbe6xqzJADAAAAqBdM01R+cclp/9pyMEuPzdwgpymVOs0Kv4+duUFbD2ad9rlM0zyjrKNGjZKHh4f++OMP9e/fX1FRUbrkkks0e/Zs7d+/X08++aQkKSYmRi+//LJuv/12+fv7KyoqSpMmTTrpef/3kvXPPvtMQUFB+v3339W6dWv5+fnp4osv1sGDByt83ieffKLWrVvLy8tLrVq10ocffnjcuYOCghQREaHIyEhddtlluvLKK7VmzZry5xMSEnTllVcqPDxcfn5+6tatm2bPnl3hHAcPHtTgwYPl7e2t2NhYTZ8+XTExMfrnP/9ZfsyOHTvUr18/eXl5qU2bNpo9e7YMw9D3338v6eSX6c+ZM0ddu3aVj4+PevXqpe3bt1d47ZdeekkNGzaUv7+/7rzzTj322GM655xz/u6f6awxQw4AAACgXihwlKrNM79XybmcpnTJO4tO+/gtLwySj8fp1a+MjAz9/vvvGjdu3HH7p0dERGj48OH68ssvy0vxm2++qRdffFFPPPGEvvnmG917773q37+/WrZseVqvl5+frzfeeEOff/65bDabbrrpJj3yyCOaNm2aJGnatGl65pln9P7776tTp05au3atRo4cKV9fX91yyy0nPOeOHTs0d+5c3XrrreWP5ebm6tJLL9W4cePk6empqVOn6vLLL9f27dsVFRUlSRoxYoTS09M1b9482e12jRkzRocOHSo/R2lpqW666SZFR0dr+fLlysnJ0T/+8Y/Tep9PPvmk3nzzTYWFhemee+7R7bffrsWLF5e/x3HjxunDDz9U7969NWPGDL355puKjY09rXNXFoUcAAAAAGqRnTt3yjRNtW7d+oTPt27dWkeOHFFaWpok6dJLL9V9990nSRo7dqzefvtt/fnnn6ddyB0OhyZMmKBmzZpJku6//3698MIL5c8/++yzevPNN3XNNddIkmJjY7VlyxZNnDixQiG/4YYb5ObmppKSEhUVFemyyy7T448/Xv58x44d1bFjx/KPX3zxRX333Xf68ccfdf/992vbtm2aPXu2Vq5cqa5du0oqm5lv3rx5+efMmjVLiYmJmjdvnho3bixJGjdunAYOHHjK9zlu3Dj1799fkvTYY49p8ODBKiwslJeXl9577z3dcccduu222yRJzzzzjP744w/l5uae1t9hZVHIAQAAANQL3nY3bXlh0Gkf/9asHZqyKEmlJ7jc3M0wdFufGI0Z2OK0X/tMne5l7h06dCj/s2EYioiIqDCrfCo+Pj7lZVySGjVqVP75eXl5SkhI0B133KGRI0eWH1NSUnLcwnBvv/22BgwYoNLSUu3atUtjxozRzTffrBkzZkgqmyF/7rnn9J///EcHDx5USUmJCgoKtHfvXknS9u3b5e7urs6dO5efMz4+Xg0aNCj/eMeOHWrSpEmFe8TPPffc03qff/17atSokSTp0KFDioqK0vbt28t/qPHX886dO/e0zl1ZFHIAAAAA9YJhGKd92bgkDe8erU8XJZ7wOVOmbuoefUbnO13x8fEyDENbt27V1VdffdzzW7duVYMGDRQWFiZJstvtFZ43DENOp/O0X+9En3/shwHHZog//vhjde/evcJxbm4Vf8gQERGh+Ph4SVLLli2Vk5OjG264QS+99JLi4+P1yCOPaNasWXrjjTcUHx8vb29vXXvttSouLj7trGfjr+/TMAxJOqO/p+rAom4AAAAAcAKxob4aP6SDbIbkZjMq/D5+SAfFhPpWy+uGhIRo4MCB+vDDD1VQUFDhuZSUFE2bNk3XX399eamsTuHh4WrcuLF2796t+Pj4Cr9OdX/1scJ+7D0sXrxYt956q66++mq1b99eERERSkpKKj++ZcuWKikp0dq1a8sf27Vrl44cOVL+cYsWLbR//36lpqaWP7Zy5cqzfp8tW7Y87jxVcd5TYYYcAAAAAE5iaNdIdYsJ1perkrXvSIGaNvDW9V0jq62MH/P++++rV69eGjRokF566aUK2541adJE48aNq9bX/6vnn39eDz74oAIDA3XxxRerqKhIq1at0pEjRzRmzJjy4zIzM5WSkiKn06mdO3fqhRdeUIsWLcrvhW/evLm+/fZbXX755TIMQ08//XSFGepWrVppwIABuuuuu/TRRx/JbrfrH//4h7y9vct/+DBw4EDFxsbq1ltv1euvv66cnBw99dRTknRW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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from capymoa.classifier import OnlineBagging\n", "from capymoa.stream import PytorchStream\n", "from capymoa.evaluation import prequential_evaluation\n", "from capymoa.evaluation.visualization import plot_windowed_results\n", "\n", "from torchvision import datasets\n", "from torchvision.transforms import ToTensor\n", "\n", "pytorchDtaset = datasets.FashionMNIST(\n", " root=\"data\", train=True, download=True, transform=ToTensor()\n", ")\n", "pytorch_stream = PytorchStream(dataset=pytorchDtaset)\n", "\n", "# Creating a learner\n", "ob_learner = OnlineBagging(schema=pytorch_stream.get_schema(), ensemble_size=5)\n", "\n", "results_ob_learner = prequential_evaluation(\n", " stream=pytorch_stream, learner=ob_learner, window_size=100, max_instances=1000\n", ")\n", "\n", "print(f\"Accuracy: {results_ob_learner.cumulative.accuracy()}\")\n", "display(results_ob_learner.windowed.metrics_per_window())\n", "plot_windowed_results(results_ob_learner, metric=\"accuracy\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.19" } }, "nbformat": 4, "nbformat_minor": 5 }