From 8c987c257d502336e0d9fdc26e695e3331452275 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Mon, 16 Jan 2023 23:52:36 +0530 Subject: [PATCH 01/23] Update README.md --- apps/accelerate/forward_forward/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/accelerate/forward_forward/README.md b/apps/accelerate/forward_forward/README.md index a752c959..d1b0c21d 100644 --- a/apps/accelerate/forward_forward/README.md +++ b/apps/accelerate/forward_forward/README.md @@ -31,6 +31,10 @@ At the current stage, this implementation supports the main architectures discus ```python from forward_forward import train_with_forward_forward_algorithm +import os +import torch + +device = "cuda" if torch.cuda.is_available() else "cpu" trained_model = train_with_forward_forward_algorithm( @@ -38,7 +42,7 @@ trained_model = train_with_forward_forward_algorithm( n_layers=3, hidden_size=2000, lr=0.03, - device="cuda", + device=device, epochs=100, batch_size=5000, theta=2., From 05667f0835c6a9f0dd4f8ac3b2fac2f09dca78e6 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:04:12 +0530 Subject: [PATCH 02/23] Update README.md In this I added ```import os import torch device = "cuda" if torch.cuda.is_available() else "cpu"``` so that if someone is using m1 macOS then they do not have to worry about the errors that I previously got which include problems with torch vision and `ImportError: cannot import name 'COMMON_SAFE_ASCII_CHARACTERS' from 'charset_normalizer.constant'` --- apps/accelerate/forward_forward/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/accelerate/forward_forward/README.md b/apps/accelerate/forward_forward/README.md index d1b0c21d..1bf30f24 100644 --- a/apps/accelerate/forward_forward/README.md +++ b/apps/accelerate/forward_forward/README.md @@ -36,7 +36,6 @@ import torch device = "cuda" if torch.cuda.is_available() else "cpu" - trained_model = train_with_forward_forward_algorithm( model_type="progressive", n_layers=3, From 6f41a1b1637afa339c28ecd557992c63d7770ed1 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Tue, 17 Jan 2023 12:06:23 +0530 Subject: [PATCH 03/23] Add files via upload --- .../forward_forward/forward_forward/api/ffa.py | 14 ++++++++++++++ .../forward_forward/forward_forward/api/ffa2.py | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 apps/accelerate/forward_forward/forward_forward/api/ffa.py create mode 100644 apps/accelerate/forward_forward/forward_forward/api/ffa2.py diff --git a/apps/accelerate/forward_forward/forward_forward/api/ffa.py b/apps/accelerate/forward_forward/forward_forward/api/ffa.py new file mode 100644 index 00000000..0812cad5 --- /dev/null +++ b/apps/accelerate/forward_forward/forward_forward/api/ffa.py @@ -0,0 +1,14 @@ +from forward_forward import train_with_forward_forward_algorithm +import os +os.environ["CUDA"]="-1" + +trained_model = train_with_forward_forward_algorithm( + model_type="progressive", + n_layers=3, + hidden_size=2000, + lr=0.03, + device="cpu", + epochs=100, + batch_size=5000, + theta=2., +) \ No newline at end of file diff --git a/apps/accelerate/forward_forward/forward_forward/api/ffa2.py b/apps/accelerate/forward_forward/forward_forward/api/ffa2.py new file mode 100644 index 00000000..a597cdb2 --- /dev/null +++ b/apps/accelerate/forward_forward/forward_forward/api/ffa2.py @@ -0,0 +1,17 @@ +from forward_forward import train_with_forward_forward_algorithm +import os +import torch + +device = "cuda" if torch.cuda.is_available() else "cpu" + + +trained_model = train_with_forward_forward_algorithm( + model_type="progressive", + n_layers=3, + hidden_size=2000, + lr=0.03, + device=device, + epochs=100, + batch_size=5000, + theta=2., +) \ No newline at end of file From 97646bdb2ddfe45d845bb2b04e5d89a18973c6fa Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:50:05 +0530 Subject: [PATCH 04/23] Update root_op.py --- apps/accelerate/forward_forward/forward_forward/root_op.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/accelerate/forward_forward/forward_forward/root_op.py b/apps/accelerate/forward_forward/forward_forward/root_op.py index aaf2633b..0b8c5932 100644 --- a/apps/accelerate/forward_forward/forward_forward/root_op.py +++ b/apps/accelerate/forward_forward/forward_forward/root_op.py @@ -6,6 +6,7 @@ FCNetFFProgressiveBuildOperation, RecurrentFCNetFFBuildOperation, LMFFNetBuildOperation, + CNNBuildOperation ) from forward_forward.operations.data import ( MNISTDataLoaderOperation, @@ -15,6 +16,7 @@ ForwardForwardTrainer, RecurrentForwardForwardTrainer, NLPForwardForwardTrainer, + CNNForwardForwardTrainer ) @@ -22,6 +24,7 @@ class ForwardForwardModelType(Enum): PROGRESSIVE = "progressive" RECURRENT = "recurrent" NLP = "nlp" + CNN = "cnn" class ForwardForwardRootOp(Operation): @@ -40,6 +43,10 @@ def __init__(self, model_type: ForwardForwardModelType): self.build_model = LMFFNetBuildOperation() self.train_model = NLPForwardForwardTrainer() self.load_data = AesopFablesDataLoaderOperation() + elif model_type is ForwardForwardModelType.CNN: + self.build_model = CNNBuildOperation() + self.train_model = CNNForwardForwardTrainer() + self.load_data = MNISTDataLoaderOperation() def execute( self, From 5b87ee3119ddc59b563dbc46babd0487c638b125 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:54:33 +0530 Subject: [PATCH 05/23] Update functions.py --- .../forward_forward/forward_forward/api/functions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/accelerate/forward_forward/forward_forward/api/functions.py b/apps/accelerate/forward_forward/forward_forward/api/functions.py index 51f11f65..68d74a58 100644 --- a/apps/accelerate/forward_forward/forward_forward/api/functions.py +++ b/apps/accelerate/forward_forward/forward_forward/api/functions.py @@ -27,6 +27,9 @@ def train_with_forward_forward_algorithm( elif model_type is ForwardForwardModelType.RECURRENT: input_size = 28 * 28 output_size = len(datasets.MNIST.classes) + elif model_type is ForwardForwardModelType.CNN: + input_size = 28 * 28 * 1 + output_size = len(datasets.MNIST.classes) else: # model_type is ForwardForwardModelType.NLP input_size = 10 # number of characters output_size = 30 # length of vocabulary From 9834b2fc4150736470cebfbd01baa2abeb227831 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Mon, 6 Feb 2023 21:05:41 +0530 Subject: [PATCH 06/23] Update modules.py --- .../forward_forward/utils/modules.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/apps/accelerate/forward_forward/forward_forward/utils/modules.py b/apps/accelerate/forward_forward/forward_forward/utils/modules.py index 38b97ed9..199977e6 100644 --- a/apps/accelerate/forward_forward/forward_forward/utils/modules.py +++ b/apps/accelerate/forward_forward/forward_forward/utils/modules.py @@ -829,3 +829,52 @@ def positive_eval(self, input_tensor: torch.Tensor, theta: float): ) cumulated_goodness /= self.predicted_tokens return prediction, cumulated_goodness + +class ConvBNReLU(torch.nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride, padding): + super().__init__() + self.conv = torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding) + self.bn = torch.nn.BatchNorm2d(out_channels) + self.relu = torch.nn.ReLU() + + def forward(self, x): + return self.relu(self.bn(self.conv(x))) + +class ConvFFLayer(BaseFFLayer): + def __init__( + self, + in_channels, + out_channels, + kernel_size, + stride, + padding, + optimizer_name, + optimizer_kwargs, + loss_fn_name, + ): + super().__init__() + self.layer = ConvBNReLU(in_channels, out_channels, kernel_size, stride, padding) + self.optimizer = getattr(torch.optim, optimizer_name)(self.layer.parameters(), **optimizer_kwargs) + self.loss_fn = eval(loss_fn_name) + + def forward(self, x): + return self.layer(x) + + def ff_train(self, x, signs, theta): + new_x = self(x.detach()) + y_pos = new_x[signs == 1] + y_neg = new_x[signs == -1] + loss_pos, goodness_pos = self.loss_fn(y_pos, theta, 1) + loss_neg, goodness_neg = self.loss_fn(y_neg, theta, -1) + loss = loss_pos + loss_neg + self.optimizer.zero_grad() + loss.backward() + self.optimizer.step() + return new_x, [goodness_pos, goodness_neg] + + @torch.no_grad() + def positive_eval(self, x, theta): + new_x = self(x) + goodness = new_x.pow(2).mean(dim=1) - theta + return new_x, goodness + From 40173cc97936d39bd546261f68bb594d0ff6ba2f Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Mon, 6 Feb 2023 21:15:05 +0530 Subject: [PATCH 07/23] Update build_models.py --- .../operations/build_models.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/build_models.py b/apps/accelerate/forward_forward/forward_forward/operations/build_models.py index 0ae3d9f5..9ad3a31e 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/build_models.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/build_models.py @@ -8,6 +8,7 @@ FCNetFFProgressive, RecurrentFCNetFF, LMFFNet, + ConvFFLayer, ) @@ -112,3 +113,30 @@ def execute( predicted_tokens=-1, ) self.model = model + +class CNNBuildOperation(BaseModelBuildOperation): + def __init__(self): + super().__init__() + + def execute( + self, + in_channels: int, + out_channels: int, + kernel_size: int, + stride: int, + padding: int, + optimizer_name: str, + optimizer_params: dict, + loss_fn_name: str, + ): + model = ConvFFLayer( + in_channels=in_channels, + out_channels=out_channels, + kernel_size=kernel_size, + stride=stride, + padding=padding, + optimizer_name=optimizer_name, + optimizer_kwargs=optimizer_params, + loss_fn_name=loss_fn_name, + ) + self.model = model From a17312a760e25eacb2c7854b7072c41734a66246 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Tue, 7 Feb 2023 00:19:11 +0530 Subject: [PATCH 08/23] Update trainers.py --- .../forward_forward/operations/trainers.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index f9163bb5..52791a8b 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -183,3 +183,53 @@ def _train( predictions, _ = model.positive_eval(test_data, theta) perplexity = compute_perplexity(predictions) self.logger.info(f"Perplexity: {perplexity}") + + +class CNNForwardForwardTrainer(BaseForwardForwardTrainer): + def _train(self, epochs: int, theta: float, device: str, **kwargs): + model = self.model.to(device) + for epoch in range(epochs): + accumulated_goodness = None + model.train() + # Preprocess the data + x_train = [data.flatten().numpy() for data, label in self.train_data] + x_test = [data.flatten().numpy() for data, label in self.test_data] + + # Perform clustering + kmeans = KMeans(n_clusters=10, random_state=0) + kmeans.fit(x_train) + + # Predict the cluster assignments for each data point + train_clusters = kmeans.predict(x_train) + test_clusters = kmeans.predict(x_test) + + for j, (data, target) in enumerate(self.train_data): + # TODO: THE IMAGE SHAPE SHOULD NOT BE DEFINED HERE + data = data.to(device).reshape(-1, 28 * 28) + target = torch.functional.F.one_hot( + torch.tensor([train_clusters[target]]), + num_classes=10, + ).to(device) + _, goodness = model.ff_train(data, target, theta) + if accumulated_goodness is None: + accumulated_goodness = goodness + else: + accumulated_goodness[0] += goodness[0] + accumulated_goodness[1] += goodness[1] + goodness_ratio = ( + accumulated_goodness[0] - accumulated_goodness[1] + ) / abs(max(accumulated_goodness)) + self.logger.info(f"Epoch {epoch + 1}") + self.logger.info(f"Accumulated goodness: {accumulated_goodness}") + self.logger.info(f"Goodness ratio: {goodness_ratio}") + model.eval() + correct = 0 + with torch.no_grad(): + for data, target in self.test_data: + data = data.to(device).reshape(-1, 28 * 28) + target = torch.tensor([test_clusters[target]]).to(device) + _, pred = model.positive_eval(data, theta) + correct += (pred.item() == test_clusters[target]).sum().item() + self.logger.info( + f"Test accuracy: {correct} / 10000 ({correct / 10000 * 100}%)" + ) From 5ad6249f0009e816b7d08a2ba53ab4e017a83948 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Tue, 7 Feb 2023 00:21:48 +0530 Subject: [PATCH 09/23] Update trainers.py --- .../forward_forward/forward_forward/operations/trainers.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index 52791a8b..52d3dd34 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -5,6 +5,11 @@ from nebullvm.operations.fetch_operations.local import FetchModelFromLocal from torch.utils.data import DataLoader from torchvision import datasets +import torch.optim as optim +from sklearn.cluster import KMeans +import torchvision +import torchvision.transforms as transforms + from forward_forward.operations.data import VOCABULARY from forward_forward.operations.fetch_operations import ( From 337cc4b45933350c4019978409e2d129f33064c2 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sat, 11 Feb 2023 22:50:57 +0530 Subject: [PATCH 10/23] Update trainers.py --- .../forward_forward/operations/trainers.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index 52d3dd34..bee25818 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -202,19 +202,15 @@ def _train(self, epochs: int, theta: float, device: str, **kwargs): # Perform clustering kmeans = KMeans(n_clusters=10, random_state=0) - kmeans.fit(x_train) + train_labels = kmeans.fit_predict(x_train) + train_dataset = torch.utils.data.TensorDataset(x_train, train_labels) + train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True) - # Predict the cluster assignments for each data point - train_clusters = kmeans.predict(x_train) - test_clusters = kmeans.predict(x_test) - - for j, (data, target) in enumerate(self.train_data): + for j, (data, target) in enumerate(train_dataloader): # TODO: THE IMAGE SHAPE SHOULD NOT BE DEFINED HERE - data = data.to(device).reshape(-1, 28 * 28) - target = torch.functional.F.one_hot( - torch.tensor([train_clusters[target]]), - num_classes=10, - ).to(device) + data = data.to(device) + target = torch.functional.F.one_hot(torch.tensor([target]), num_classes=10,).to(device) + _, goodness = model.ff_train(data, target, theta) if accumulated_goodness is None: accumulated_goodness = goodness From 298faed87546eb04ff4d7d3d21dd038e0f337a2e Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sat, 11 Feb 2023 22:51:34 +0530 Subject: [PATCH 11/23] Delete ffa.py --- .../forward_forward/forward_forward/api/ffa.py | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 apps/accelerate/forward_forward/forward_forward/api/ffa.py diff --git a/apps/accelerate/forward_forward/forward_forward/api/ffa.py b/apps/accelerate/forward_forward/forward_forward/api/ffa.py deleted file mode 100644 index 0812cad5..00000000 --- a/apps/accelerate/forward_forward/forward_forward/api/ffa.py +++ /dev/null @@ -1,14 +0,0 @@ -from forward_forward import train_with_forward_forward_algorithm -import os -os.environ["CUDA"]="-1" - -trained_model = train_with_forward_forward_algorithm( - model_type="progressive", - n_layers=3, - hidden_size=2000, - lr=0.03, - device="cpu", - epochs=100, - batch_size=5000, - theta=2., -) \ No newline at end of file From 8d27ab14dff13c761fff73d5680a88ef1a91561a Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sat, 11 Feb 2023 22:51:42 +0530 Subject: [PATCH 12/23] Delete ffa2.py --- .../forward_forward/forward_forward/api/ffa2.py | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 apps/accelerate/forward_forward/forward_forward/api/ffa2.py diff --git a/apps/accelerate/forward_forward/forward_forward/api/ffa2.py b/apps/accelerate/forward_forward/forward_forward/api/ffa2.py deleted file mode 100644 index a597cdb2..00000000 --- a/apps/accelerate/forward_forward/forward_forward/api/ffa2.py +++ /dev/null @@ -1,17 +0,0 @@ -from forward_forward import train_with_forward_forward_algorithm -import os -import torch - -device = "cuda" if torch.cuda.is_available() else "cpu" - - -trained_model = train_with_forward_forward_algorithm( - model_type="progressive", - n_layers=3, - hidden_size=2000, - lr=0.03, - device=device, - epochs=100, - batch_size=5000, - theta=2., -) \ No newline at end of file From a23967042f7eea42c873ae66b51ce89289ede1b9 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sat, 11 Feb 2023 22:55:12 +0530 Subject: [PATCH 13/23] Update functions.py --- .../accelerate/forward_forward/forward_forward/api/functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/accelerate/forward_forward/forward_forward/api/functions.py b/apps/accelerate/forward_forward/forward_forward/api/functions.py index 68d74a58..796384e6 100644 --- a/apps/accelerate/forward_forward/forward_forward/api/functions.py +++ b/apps/accelerate/forward_forward/forward_forward/api/functions.py @@ -28,7 +28,7 @@ def train_with_forward_forward_algorithm( input_size = 28 * 28 output_size = len(datasets.MNIST.classes) elif model_type is ForwardForwardModelType.CNN: - input_size = 28 * 28 * 1 + input_size = (28,28,1) output_size = len(datasets.MNIST.classes) else: # model_type is ForwardForwardModelType.NLP input_size = 10 # number of characters From 80d68fb4a17a8e3bd7818582f2810f64c2a87048 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sun, 12 Feb 2023 21:03:06 +0530 Subject: [PATCH 14/23] Update apps/accelerate/forward_forward/README.md Co-authored-by: Diego Fiori <38586138+diegofiori@users.noreply.github.com> --- apps/accelerate/forward_forward/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/accelerate/forward_forward/README.md b/apps/accelerate/forward_forward/README.md index 1bf30f24..684e3236 100644 --- a/apps/accelerate/forward_forward/README.md +++ b/apps/accelerate/forward_forward/README.md @@ -30,10 +30,12 @@ This process will just install the minimum requirements for running the module. At the current stage, this implementation supports the main architectures discussed by Hinton in his paper. Each architecture can be trained with the following command: ```python -from forward_forward import train_with_forward_forward_algorithm import os + import torch +from forward_forward import train_with_forward_forward_algorithm + device = "cuda" if torch.cuda.is_available() else "cpu" trained_model = train_with_forward_forward_algorithm( From d8293b5131cb71c7b8e6db6891fe693f2847b285 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sun, 12 Feb 2023 21:07:18 +0530 Subject: [PATCH 15/23] Update trainers.py --- .../forward_forward/operations/trainers.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index bee25818..dc3fa014 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -1,15 +1,13 @@ -from abc import ABC, abstractmethod - import torch -from nebullvm.operations.base import Operation -from nebullvm.operations.fetch_operations.local import FetchModelFromLocal -from torch.utils.data import DataLoader -from torchvision import datasets -import torch.optim as optim -from sklearn.cluster import KMeans import torchvision +import torch.optim as optim import torchvision.transforms as transforms - +from abc import ABC, abstractmethod +from sklearn.cluster import KMeans +from torch.utils.data import DataLoader +from torchvision import datasets +from nebulavm.operations.base import Operation +from nebulavm.operations.fetch_operations.local import FetchModelFromLocal from forward_forward.operations.data import VOCABULARY from forward_forward.operations.fetch_operations import ( From 77a8dd4ded434d3fa50407db5dd07612646f14f8 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sun, 12 Feb 2023 21:07:56 +0530 Subject: [PATCH 16/23] Update trainers.py --- .../forward_forward/forward_forward/operations/trainers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index dc3fa014..9ec46a21 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -188,7 +188,7 @@ def _train( self.logger.info(f"Perplexity: {perplexity}") -class CNNForwardForwardTrainer(BaseForwardForwardTrainer): +class UnsupervisedCNNForwardForwardTrainer(BaseForwardForwardTrainer): def _train(self, epochs: int, theta: float, device: str, **kwargs): model = self.model.to(device) for epoch in range(epochs): From 03d365da7cfd5ab6b9e4e2a64b3840b53cb01ef6 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sun, 12 Feb 2023 21:12:10 +0530 Subject: [PATCH 17/23] Update trainers.py --- .../forward_forward/forward_forward/operations/trainers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index 9ec46a21..16550522 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -195,8 +195,8 @@ def _train(self, epochs: int, theta: float, device: str, **kwargs): accumulated_goodness = None model.train() # Preprocess the data - x_train = [data.flatten().numpy() for data, label in self.train_data] - x_test = [data.flatten().numpy() for data, label in self.test_data] + x_train = [data.numpy() for data, label in self.train_data] + x_test = [data.numpy() for data, label in self.test_data] # Perform clustering kmeans = KMeans(n_clusters=10, random_state=0) @@ -225,7 +225,7 @@ def _train(self, epochs: int, theta: float, device: str, **kwargs): correct = 0 with torch.no_grad(): for data, target in self.test_data: - data = data.to(device).reshape(-1, 28 * 28) + data = data.to(device) target = torch.tensor([test_clusters[target]]).to(device) _, pred = model.positive_eval(data, theta) correct += (pred.item() == test_clusters[target]).sum().item() From 8291c7552651104c57888fc9735e14e9063ebcc8 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sun, 12 Feb 2023 23:25:47 +0530 Subject: [PATCH 18/23] Update trainers.py --- .../forward_forward/forward_forward/operations/trainers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index 16550522..957369f7 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -1,8 +1,9 @@ +from abc import ABC, abstractmethod + import torch import torchvision import torch.optim as optim import torchvision.transforms as transforms -from abc import ABC, abstractmethod from sklearn.cluster import KMeans from torch.utils.data import DataLoader from torchvision import datasets From 1b3d8df5011150ea0a95cbbd976bc19d301e6fb6 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sat, 18 Feb 2023 17:53:00 +0530 Subject: [PATCH 19/23] Update trainers.py --- .../forward_forward/operations/trainers.py | 53 +++++++++++++------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index 957369f7..d07aac7d 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -192,23 +192,17 @@ def _train( class UnsupervisedCNNForwardForwardTrainer(BaseForwardForwardTrainer): def _train(self, epochs: int, theta: float, device: str, **kwargs): model = self.model.to(device) + + # Get unsupervised labels using KMeans + unsupervised_loader, kmeans = self.get_unsupervised_label(device) + for epoch in range(epochs): accumulated_goodness = None model.train() - # Preprocess the data - x_train = [data.numpy() for data, label in self.train_data] - x_test = [data.numpy() for data, label in self.test_data] - # Perform clustering - kmeans = KMeans(n_clusters=10, random_state=0) - train_labels = kmeans.fit_predict(x_train) - train_dataset = torch.utils.data.TensorDataset(x_train, train_labels) - train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True) - - for j, (data, target) in enumerate(train_dataloader): - # TODO: THE IMAGE SHAPE SHOULD NOT BE DEFINED HERE + for j, (data, target) in enumerate(unsupervised_loader): data = data.to(device) - target = torch.functional.F.one_hot(torch.tensor([target]), num_classes=10,).to(device) + target = target.to(device) _, goodness = model.ff_train(data, target, theta) if accumulated_goodness is None: @@ -223,13 +217,40 @@ def _train(self, epochs: int, theta: float, device: str, **kwargs): self.logger.info(f"Accumulated goodness: {accumulated_goodness}") self.logger.info(f"Goodness ratio: {goodness_ratio}") model.eval() + + # Compute validation accuracy correct = 0 with torch.no_grad(): for data, target in self.test_data: data = data.to(device) - target = torch.tensor([test_clusters[target]]).to(device) - _, pred = model.positive_eval(data, theta) - correct += (pred.item() == test_clusters[target]).sum().item() + numpy_data = data.flatten().cpu().numpy() + target = torch.from_numpy(kmeans.predict(numpy_data)).to(device) + pred, _ = model.positive_eval(data.unsqueeze(1), theta) + correct += pred.eq(target.view_as(pred)).sum().item() self.logger.info( f"Test accuracy: {correct} / 10000 ({correct / 10000 * 100}%)" - ) + ) + + def get_unsupervised_label(self, device): + x_train = np.concatenate( + [data.detach().cpu().numpy() for data, label in self.train_data], axis=0) + + # Perform clustering + kmeans = KMeans(n_clusters=10, random_state=0) + train_labels = kmeans.fit_predict(x_train) + train_labels = torch.from_numpy(train_labels).to(device) + label_injector = LabelsInjector([f"cluster_{i}" for i in range(10)]) + + train_bs = self.train_data.batch_size + progressive_train_dataset = ProgressiveTrainingDataset( + (label_injector.inject_train( + x.unsqueeze(1), + train_labels[i*train_bs: (i+1)*train_bs] + ) for i, (x, y) in enumerate(self.train_data)) + ) + progressive_train_dataloader = torch.utils.data.DataLoader( + progressive_train_dataset, + batch_size=2 * train_bs, shuffle=False + ) + return progressive_train_dataloader, kmeans + From e739f3a399ceeec3710ffd72f72fb59dc7123473 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sat, 18 Feb 2023 17:53:32 +0530 Subject: [PATCH 20/23] Update trainers.py --- .../forward_forward/forward_forward/operations/trainers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index d07aac7d..ab7948d0 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -253,4 +253,3 @@ def get_unsupervised_label(self, device): batch_size=2 * train_bs, shuffle=False ) return progressive_train_dataloader, kmeans - From e8e463c180059cd1e4312400ac445016782386bd Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Sat, 18 Feb 2023 18:49:24 +0530 Subject: [PATCH 21/23] Update trainers.py --- .../forward_forward/forward_forward/operations/trainers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index ab7948d0..fdac65f2 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -193,7 +193,7 @@ class UnsupervisedCNNForwardForwardTrainer(BaseForwardForwardTrainer): def _train(self, epochs: int, theta: float, device: str, **kwargs): model = self.model.to(device) - # Get unsupervised labels using KMeans + unsupervised_loader, kmeans = self.get_unsupervised_label(device) for epoch in range(epochs): @@ -218,7 +218,7 @@ def _train(self, epochs: int, theta: float, device: str, **kwargs): self.logger.info(f"Goodness ratio: {goodness_ratio}") model.eval() - # Compute validation accuracy + correct = 0 with torch.no_grad(): for data, target in self.test_data: @@ -235,7 +235,7 @@ def get_unsupervised_label(self, device): x_train = np.concatenate( [data.detach().cpu().numpy() for data, label in self.train_data], axis=0) - # Perform clustering + kmeans = KMeans(n_clusters=10, random_state=0) train_labels = kmeans.fit_predict(x_train) train_labels = torch.from_numpy(train_labels).to(device) From 89766d4582e96d7797895fd591df006bfac7d47f Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Fri, 24 Feb 2023 11:27:28 +0530 Subject: [PATCH 22/23] Update apps/accelerate/forward_forward/forward_forward/operations/trainers.py Co-authored-by: Diego Fiori <38586138+diegofiori@users.noreply.github.com> --- .../forward_forward/forward_forward/operations/trainers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py index fdac65f2..fdab5e67 100644 --- a/apps/accelerate/forward_forward/forward_forward/operations/trainers.py +++ b/apps/accelerate/forward_forward/forward_forward/operations/trainers.py @@ -7,8 +7,8 @@ from sklearn.cluster import KMeans from torch.utils.data import DataLoader from torchvision import datasets -from nebulavm.operations.base import Operation -from nebulavm.operations.fetch_operations.local import FetchModelFromLocal +from nebullvm.operations.base import Operation +from nebullvm.operations.fetch_operations.local import FetchModelFromLocal from forward_forward.operations.data import VOCABULARY from forward_forward.operations.fetch_operations import ( From 385996da92580fbbff23cd5c9d55444278634383 Mon Sep 17 00:00:00 2001 From: Additi Pandey <49843878+cyclotomicextension@users.noreply.github.com> Date: Fri, 24 Feb 2023 20:37:17 +0530 Subject: [PATCH 23/23] Update benchmark.py --- nebullvm/tools/benchmark.py | 46 ++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/nebullvm/tools/benchmark.py b/nebullvm/tools/benchmark.py index bf170dee..377adafb 100644 --- a/nebullvm/tools/benchmark.py +++ b/nebullvm/tools/benchmark.py @@ -1,5 +1,6 @@ import time from abc import abstractmethod, ABC +from transformers import AutoModelForSequenceClassification, AutoTokenizer from typing import Any, Dict, Type import numpy as np @@ -19,7 +20,6 @@ is_data_subscriptable, ) - def _get_dl_framework(model: Any): if isinstance(model, torch.nn.Module) or str(model).startswith("Pytorch"): return DeepLearningFramework.PYTORCH @@ -53,6 +53,50 @@ def _create_model_inputs( return input_data +class HuggingFaceBenchmark(BaseBenchmark): + def __init__(self, model_name, input_texts, device, n_warmup=50, n_runs=1000): + self.tokenizer = AutoTokenizer.from_pretrained(model_name) + self.model = AutoModelForSequenceClassification.from_pretrained(model_name).to(device) + self.input_texts = input_texts + self.device = device + self.n_warmup = n_warmup + self.n_runs = n_runs + + def benchmark(self): + input_tensors = [] + for input_text in self.input_texts: + encoded = self.tokenizer(input_text, padding='max_length', truncation=True, max_length=512, return_tensors='pt') + input_tensors.append(encoded.to(self.device)) + + batch_size = input_tensors[0].shape[0] + + with torch.no_grad(): + for i in tqdm( + range(self.n_warmup), + desc=f"Performing warm up on {self.n_warmup} iterations", + ): + self.model(**input_tensors[i % min(self.n_warmup, len(input_tensors))]) + + if self.device.type is DeviceType.GPU: + torch.cuda.synchronize() + timings = [] + with torch.no_grad(): + for i in tqdm( + range(1, self.n_runs + 1), + desc=f"Performing benchmark on {self.n_runs} iterations", + ): + start_time = time.time() + self.model(**input_tensors[i % min(self.n_runs, len(input_tensors))]) + if self.device.type is DeviceType.GPU: + torch.cuda.synchronize() + end_time = time.time() + timings.append(end_time - start_time) + + throughput = batch_size / np.mean(timings) + latency = np.mean(timings) / batch_size + + return throughput, latency + class BaseBenchmark(ABC): def __init__(self, model, input_tensors, n_warmup=50, n_runs=1000):