diff --git a/examples/cbc_circle.py b/examples/cbc_circle.py deleted file mode 100644 index 1ed88a8..0000000 --- a/examples/cbc_circle.py +++ /dev/null @@ -1,112 +0,0 @@ -"""CBC example using the Iris dataset.""" - -import numpy as np -import pytorch_lightning as pl -import torch -from matplotlib import pyplot as plt -from prototorch.components import initializers as cinit -from prototorch.datasets.abstract import NumpyDataset -from sklearn.datasets import make_circles -from torch.utils.data import DataLoader - -from prototorch.models.cbc import CBC, euclidean_similarity - - -class VisualizationCallback(pl.Callback): - def __init__( - self, - x_train, - y_train, - prototype_model=True, - title="Prototype Visualization", - cmap="viridis", - ): - super().__init__() - self.x_train = x_train - self.y_train = y_train - self.title = title - self.fig = plt.figure(self.title) - self.cmap = cmap - self.prototype_model = prototype_model - - def on_epoch_end(self, trainer, pl_module): - if self.prototype_model: - protos = pl_module.components - color = pl_module.prototype_labels - else: - protos = pl_module.components - color = "k" - ax = self.fig.gca() - ax.cla() - ax.set_title(self.title) - ax.set_xlabel("Data dimension 1") - ax.set_ylabel("Data dimension 2") - ax.scatter(x_train[:, 0], x_train[:, 1], c=y_train, edgecolor="k") - ax.scatter( - protos[:, 0], - protos[:, 1], - c=color, - cmap=self.cmap, - edgecolor="k", - marker="D", - s=50, - ) - x = np.vstack((x_train, protos)) - x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1 - y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1 - xx, yy = np.meshgrid(np.arange(x_min, x_max, 1 / 50), - np.arange(y_min, y_max, 1 / 50)) - mesh_input = np.c_[xx.ravel(), yy.ravel()] - y_pred = pl_module.predict(torch.Tensor(mesh_input)) - y_pred = y_pred.reshape(xx.shape) - - ax.contourf(xx, yy, y_pred, cmap=self.cmap, alpha=0.35) - ax.set_xlim(left=x_min + 0, right=x_max - 0) - ax.set_ylim(bottom=y_min + 0, top=y_max - 0) - plt.pause(0.1) - - -if __name__ == "__main__": - # Dataset - x_train, y_train = make_circles(n_samples=300, - shuffle=True, - noise=0.05, - random_state=None, - factor=0.5) - train_ds = NumpyDataset(x_train, y_train) - - # Dataloaders - train_loader = DataLoader(train_ds, num_workers=0, batch_size=150) - - # Hyperparameters - hparams = dict( - input_dim=x_train.shape[1], - nclasses=len(np.unique(y_train)), - num_components=5, - component_initializer=cinit.RandomInitializer(x_train.shape[1]), - lr=0.01, - ) - - # Initialize the model - model = CBC( - hparams, - data=[x_train, y_train], - similarity=euclidean_similarity, - ) - - # Callbacks - dvis = VisualizationCallback(x_train, - y_train, - prototype_model=False, - title="CBC Circle Example") - - # Setup trainer - trainer = pl.Trainer( - max_epochs=50, - callbacks=[ - dvis, - ], - ) - - # Training loop - trainer.fit(model, train_loader) diff --git a/examples/cbc_mnist.py b/examples/cbc_mnist.py deleted file mode 100644 index 8546025..0000000 --- a/examples/cbc_mnist.py +++ /dev/null @@ -1,128 +0,0 @@ -"""CBC example using the MNIST dataset. - -This script also shows how to use Tensorboard for visualizing the prototypes. -""" - -import argparse - -import pytorch_lightning as pl -import torchvision -from torch.utils.data import DataLoader -from torchvision import transforms -from torchvision.datasets import MNIST - -from prototorch.models.cbc import CBC, ImageCBC, euclidean_similarity - - -class VisualizationCallback(pl.Callback): - def __init__(self, to_shape=(-1, 1, 28, 28), nrow=2): - super().__init__() - self.to_shape = to_shape - self.nrow = nrow - - def on_epoch_end(self, trainer, pl_module: ImageCBC): - tb = pl_module.logger.experiment - - # components - components = pl_module.components - components_img = components.reshape(self.to_shape) - grid = torchvision.utils.make_grid(components_img, nrow=self.nrow) - tb.add_image( - tag="MNIST Components", - img_tensor=grid, - global_step=trainer.current_epoch, - dataformats="CHW", - ) - # Reasonings - reasonings = pl_module.reasonings - tb.add_images( - tag="MNIST Reasoning", - img_tensor=reasonings, - global_step=trainer.current_epoch, - dataformats="NCHW", - ) - - -if __name__ == "__main__": - # Arguments - parser = argparse.ArgumentParser() - parser.add_argument("--epochs", - type=int, - default=10, - help="Epochs to train.") - parser.add_argument("--lr", - type=float, - default=0.001, - help="Learning rate.") - parser.add_argument("--batch_size", - type=int, - default=256, - help="Batch size.") - parser.add_argument("--gpus", - type=int, - default=0, - help="Number of GPUs to use.") - parser.add_argument("--ppc", - type=int, - default=1, - help="Prototypes-Per-Class.") - args = parser.parse_args() - - # Dataset - mnist_train = MNIST( - "./datasets", - train=True, - download=True, - transform=transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize((0.1307, ), (0.3081, )) - ]), - ) - mnist_test = MNIST( - "./datasets", - train=False, - download=True, - transform=transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize((0.1307, ), (0.3081, )) - ]), - ) - - # Dataloaders - train_loader = DataLoader(mnist_train, batch_size=32) - test_loader = DataLoader(mnist_test, batch_size=32) - - # Grab the full dataset to warm-start prototypes - x, y = next(iter(DataLoader(mnist_train, batch_size=len(mnist_train)))) - x = x.view(len(mnist_train), -1) - - # Hyperparameters - hparams = dict( - input_dim=28 * 28, - nclasses=10, - prototypes_per_class=args.ppc, - prototype_initializer="randn", - lr=0.01, - similarity=euclidean_similarity, - ) - - # Initialize the model - model = CBC(hparams, data=[x, y]) - # Model summary - print(model) - - # Callbacks - vis = VisualizationCallback(to_shape=(-1, 1, 28, 28), nrow=args.ppc) - - # Setup trainer - trainer = pl.Trainer( - gpus=args.gpus, # change to use GPUs for training - max_epochs=args.epochs, - callbacks=[vis], - track_grad_norm=2, - # accelerator="ddp_cpu", # DEBUG-ONLY - # num_processes=2, # DEBUG-ONLY - ) - - # Training loop - trainer.fit(model, train_loader, test_loader) diff --git a/examples/cbc_spiral.py b/examples/cbc_spiral.py deleted file mode 100644 index ec13138..0000000 --- a/examples/cbc_spiral.py +++ /dev/null @@ -1,135 +0,0 @@ -"""CBC example using the Iris dataset.""" - -import numpy as np -import pytorch_lightning as pl -import torch -from matplotlib import pyplot as plt -from prototorch.datasets.abstract import NumpyDataset -from torch.utils.data import DataLoader - -from prototorch.models.cbc import CBC - - -class VisualizationCallback(pl.Callback): - def __init__( - self, - x_train, - y_train, - prototype_model=True, - title="Prototype Visualization", - cmap="viridis", - ): - super().__init__() - self.x_train = x_train - self.y_train = y_train - self.title = title - self.fig = plt.figure(self.title) - self.cmap = cmap - self.prototype_model = prototype_model - - def on_epoch_end(self, trainer, pl_module): - if self.prototype_model: - protos = pl_module.prototypes - color = pl_module.prototype_labels - else: - protos = pl_module.components - color = "k" - ax = self.fig.gca() - ax.cla() - ax.set_title(self.title) - ax.set_xlabel("Data dimension 1") - ax.set_ylabel("Data dimension 2") - ax.scatter(x_train[:, 0], x_train[:, 1], c=y_train, edgecolor="k") - ax.scatter( - protos[:, 0], - protos[:, 1], - c=color, - cmap=self.cmap, - edgecolor="k", - marker="D", - s=50, - ) - x = np.vstack((x_train, protos)) - x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1 - y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1 - xx, yy = np.meshgrid(np.arange(x_min, x_max, 1 / 50), - np.arange(y_min, y_max, 1 / 50)) - mesh_input = np.c_[xx.ravel(), yy.ravel()] - y_pred = pl_module.predict(torch.Tensor(mesh_input)) - y_pred = y_pred.reshape(xx.shape) - - ax.contourf(xx, yy, y_pred, cmap=self.cmap, alpha=0.35) - ax.set_xlim(left=x_min + 0, right=x_max - 0) - ax.set_ylim(bottom=y_min + 0, top=y_max - 0) - plt.pause(0.1) - - -def make_spirals(n_samples=500, noise=0.3): - def get_samples(n, delta_t): - points = [] - for i in range(n): - r = i / n_samples * 5 - t = 1.75 * i / n * 2 * np.pi + delta_t - x = r * np.sin(t) + np.random.rand(1) * noise - y = r * np.cos(t) + np.random.rand(1) * noise - points.append([x, y]) - return points - - n = n_samples // 2 - positive = get_samples(n=n, delta_t=0) - negative = get_samples(n=n, delta_t=np.pi) - x = np.concatenate( - [np.array(positive).reshape(n, -1), - np.array(negative).reshape(n, -1)], - axis=0) - y = np.concatenate([np.zeros(n), np.ones(n)]) - return x, y - - -if __name__ == "__main__": - # Dataset - x_train, y_train = make_spirals(n_samples=1000, noise=0.3) - train_ds = NumpyDataset(x_train, y_train) - - # Dataloaders - train_loader = DataLoader(train_ds, num_workers=0, batch_size=150) - - # Hyperparameters - hparams = dict( - input_dim=x_train.shape[1], - nclasses=2, - prototypes_per_class=40, - prototype_initializer="stratified_random", - lr=0.05, - ) - - # Initialize the model - model_class = CBC - model = model_class(hparams, data=[x_train, y_train]) - - # Pure-positive reasonings - new_reasoning = torch.zeros_like( - model.reasoning_layer.reasoning_probabilities) - for i, label in enumerate(model.component_layer.prototype_labels): - new_reasoning[0][0][i][int(label)] = 1.0 - - model.reasoning_layer.reasoning_probabilities.data = new_reasoning - - # Model summary - print(model) - - # Callbacks - vis = VisualizationCallback(x_train, - y_train, - prototype_model=hasattr(model, "prototypes")) - - # Setup trainer - trainer = pl.Trainer( - max_epochs=500, - callbacks=[ - vis, - ], - ) - - # Training loop - trainer.fit(model, train_loader) diff --git a/examples/cbc_spiral_with_glvq_start.py b/examples/cbc_spiral_with_glvq_start.py deleted file mode 100644 index bfc62c4..0000000 --- a/examples/cbc_spiral_with_glvq_start.py +++ /dev/null @@ -1,147 +0,0 @@ -"""CBC example using the spirals dataset. - -This example shows how to jump start a model by transferring weights from -another more stable model. -""" - -import numpy as np -import pytorch_lightning as pl -import torch -from matplotlib import pyplot as plt -from prototorch.datasets.abstract import NumpyDataset -from torch.utils.data import DataLoader - -from prototorch.models.cbc import CBC -from prototorch.models.glvq import GLVQ - - -class VisualizationCallback(pl.Callback): - def __init__( - self, - x_train, - y_train, - prototype_model=True, - title="Prototype Visualization", - cmap="viridis", - ): - super().__init__() - self.x_train = x_train - self.y_train = y_train - self.title = title - self.fig = plt.figure(self.title) - self.cmap = cmap - self.prototype_model = prototype_model - - def on_epoch_end(self, trainer, pl_module): - if self.prototype_model: - protos = pl_module.prototypes - color = pl_module.prototype_labels - else: - protos = pl_module.components - color = "k" - ax = self.fig.gca() - ax.cla() - ax.set_title(self.title) - ax.set_xlabel("Data dimension 1") - ax.set_ylabel("Data dimension 2") - ax.scatter(x_train[:, 0], x_train[:, 1], c=y_train, edgecolor="k") - ax.scatter( - protos[:, 0], - protos[:, 1], - c=color, - cmap=self.cmap, - edgecolor="k", - marker="D", - s=50, - ) - x = np.vstack((x_train, protos)) - x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1 - y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1 - xx, yy = np.meshgrid(np.arange(x_min, x_max, 1 / 50), - np.arange(y_min, y_max, 1 / 50)) - mesh_input = np.c_[xx.ravel(), yy.ravel()] - y_pred = pl_module.predict(torch.Tensor(mesh_input)) - y_pred = y_pred.reshape(xx.shape) - - ax.contourf(xx, yy, y_pred, cmap=self.cmap, alpha=0.35) - ax.set_xlim(left=x_min + 0, right=x_max - 0) - ax.set_ylim(bottom=y_min + 0, top=y_max - 0) - plt.pause(0.1) - - -def make_spirals(n_samples=500, noise=0.3): - def get_samples(n, delta_t): - points = [] - for i in range(n): - r = i / n_samples * 5 - t = 1.75 * i / n * 2 * np.pi + delta_t - x = r * np.sin(t) + np.random.rand(1) * noise - y = r * np.cos(t) + np.random.rand(1) * noise - points.append([x, y]) - return points - - n = n_samples // 2 - positive = get_samples(n=n, delta_t=0) - negative = get_samples(n=n, delta_t=np.pi) - x = np.concatenate( - [np.array(positive).reshape(n, -1), - np.array(negative).reshape(n, -1)], - axis=0) - y = np.concatenate([np.zeros(n), np.ones(n)]) - return x, y - - -def train(model, x_train, y_train, train_loader, epochs=100): - # Callbacks - vis = VisualizationCallback(x_train, - y_train, - prototype_model=hasattr(model, "prototypes")) - # Setup trainer - trainer = pl.Trainer( - max_epochs=epochs, - callbacks=[ - vis, - ], - ) - # Training loop - trainer.fit(model, train_loader) - - -if __name__ == "__main__": - # Dataset - x_train, y_train = make_spirals(n_samples=1000, noise=0.3) - train_ds = NumpyDataset(x_train, y_train) - - # Dataloaders - train_loader = DataLoader(train_ds, num_workers=0, batch_size=150) - - # Hyperparameters - hparams = dict( - input_dim=x_train.shape[1], - nclasses=2, - prototypes_per_class=40, - prototype_initializer="stratified_random", - lr=0.05, - ) - - # Initialize the model - glvq_model = GLVQ(hparams, data=[x_train, y_train]) - cbc_model = CBC(hparams, data=[x_train, y_train]) - - # Train GLVQ - train(glvq_model, x_train, y_train, train_loader, epochs=10) - - # Transfer Prototypes - cbc_model.component_layer.load_state_dict( - glvq_model.proto_layer.state_dict()) - # Pure-positive reasonings - new_reasoning = torch.zeros_like( - cbc_model.reasoning_layer.reasoning_probabilities) - for i, label in enumerate(cbc_model.component_layer.prototype_labels): - new_reasoning[0][0][i][int(label)] = 1.0 - new_reasoning[1][0][i][1 - int(label)] = 1.0 - - cbc_model.reasoning_layer.reasoning_probabilities.data = new_reasoning - - # Train CBC - train(cbc_model, x_train, y_train, train_loader, epochs=50) diff --git a/examples/glvq_mnist.py b/examples/glvq_mnist.py deleted file mode 100644 index fd96d3f..0000000 --- a/examples/glvq_mnist.py +++ /dev/null @@ -1,119 +0,0 @@ -"""GLVQ example using the MNIST dataset. - -This script also shows how to use Tensorboard for visualizing the prototypes. -""" - -import argparse - -import pytorch_lightning as pl -import torchvision -from prototorch.components import initializers as cinit -from torch.utils.data import DataLoader -from torchvision import transforms -from torchvision.datasets import MNIST - -from prototorch.models.glvq import ImageGLVQ - - -class VisualizationCallback(pl.Callback): - def __init__(self, to_shape=(-1, 1, 28, 28), nrow=2): - super().__init__() - self.to_shape = to_shape - self.nrow = nrow - - def on_epoch_end(self, trainer, pl_module): - protos = pl_module.proto_layer.prototypes.detach().cpu() - protos_img = protos.reshape(self.to_shape) - grid = torchvision.utils.make_grid(protos_img, nrow=self.nrow) - # grid = grid.permute((1, 2, 0)) - tb = pl_module.logger.experiment - tb.add_image( - tag="MNIST Prototypes", - img_tensor=grid, - global_step=trainer.current_epoch, - dataformats="CHW", - ) - - -if __name__ == "__main__": - # Arguments - parser = argparse.ArgumentParser() - parser.add_argument("--epochs", - type=int, - default=10, - help="Epochs to train.") - parser.add_argument("--lr", - type=float, - default=0.001, - help="Learning rate.") - parser.add_argument("--batch_size", - type=int, - default=256, - help="Batch size.") - parser.add_argument("--gpus", - type=int, - default=0, - help="Number of GPUs to use.") - parser.add_argument("--ppc", - type=int, - default=1, - help="Prototypes-Per-Class.") - args = parser.parse_args() - - # Dataset - mnist_train = MNIST( - "./datasets", - train=True, - download=True, - transform=transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize((0.1307, ), (0.3081, )) - ]), - ) - mnist_test = MNIST( - "./datasets", - train=False, - download=True, - transform=transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize((0.1307, ), (0.3081, )) - ]), - ) - - # Dataloaders - train_loader = DataLoader(mnist_train, batch_size=1024) - test_loader = DataLoader(mnist_test, batch_size=1024) - - # Grab the full dataset to warm-start prototypes - x, y = next(iter(DataLoader(mnist_train, batch_size=len(mnist_train)))) - x = x.view(len(mnist_train), -1) - - # Hyperparameters - hparams = dict( - input_dim=28 * 28, - nclasses=10, - prototypes_per_class=1, - prototype_initializer=cinit.StratifiedMeanInitializer(x, y), - lr=args.lr, - ) - - # Initialize the model - model = ImageGLVQ(hparams) - - # Model summary - print(model) - - # Callbacks - vis = VisualizationCallback(to_shape=(-1, 1, 28, 28), nrow=args.ppc) - - # Setup trainer - trainer = pl.Trainer( - gpus=args.gpus, # change to use GPUs for training - max_epochs=args.epochs, - callbacks=[vis], - # accelerator="ddp_cpu", # DEBUG-ONLY - # num_processes=2, # DEBUG-ONLY - ) - - # Training loop - trainer.fit(model, train_loader, test_loader) diff --git a/examples/grlvq_iris.py b/examples/grlvq_iris.py deleted file mode 100644 index 01c31cb..0000000 --- a/examples/grlvq_iris.py +++ /dev/null @@ -1,62 +0,0 @@ -"""GMLVQ example using all four dimensions of the Iris dataset.""" - -import pytorch_lightning as pl -import torch -from prototorch.components import initializers as cinit -from prototorch.datasets.abstract import NumpyDataset -from sklearn.datasets import load_iris -from torch.utils.data import DataLoader - -from prototorch.models.callbacks.visualization import VisSiameseGLVQ2D -from prototorch.models.glvq import GRLVQ - -from sklearn.preprocessing import StandardScaler - - -class PrintRelevanceCallback(pl.Callback): - def on_epoch_end(self, trainer, pl_module: GRLVQ): - print(pl_module.relevance_profile) - - -if __name__ == "__main__": - # Dataset - x_train, y_train = load_iris(return_X_y=True) - x_train = x_train[:, [0, 2]] - scaler = StandardScaler() - scaler.fit(x_train) - x_train = scaler.transform(x_train) - train_ds = NumpyDataset(x_train, y_train) - - # Dataloaders - train_loader = DataLoader(train_ds, - num_workers=0, - batch_size=50, - shuffle=True) - - # Hyperparameters - hparams = dict( - nclasses=3, - prototypes_per_class=1, - #prototype_initializer=cinit.SMI(torch.Tensor(x_train), - # torch.Tensor(y_train)), - prototype_initializer=cinit.UniformInitializer(2), - input_dim=x_train.shape[1], - lr=0.1, - #transfer_function="sigmoid_beta", - ) - - # Initialize the model - model = GRLVQ(hparams) - - # Model summary - print(model) - - # Callbacks - vis = VisSiameseGLVQ2D(x_train, y_train) - debug = PrintRelevanceCallback() - - # Setup trainer - trainer = pl.Trainer(max_epochs=200, callbacks=[vis, debug]) - - # Training loop - trainer.fit(model, train_loader) diff --git a/examples/grlvq_spiral.py b/examples/grlvq_spiral.py deleted file mode 100644 index 61d754c..0000000 --- a/examples/grlvq_spiral.py +++ /dev/null @@ -1,57 +0,0 @@ -"""GMLVQ example using all four dimensions of the Iris dataset.""" - -import pytorch_lightning as pl -import torch -from prototorch.components import initializers as cinit -from prototorch.datasets.abstract import NumpyDataset -from sklearn.datasets import load_iris -from torch.utils.data import DataLoader - -from prototorch.models.callbacks.visualization import VisSiameseGLVQ2D -from prototorch.models.glvq import GRLVQ - -from sklearn.preprocessing import StandardScaler - -from prototorch.datasets.spiral import make_spiral - - -class PrintRelevanceCallback(pl.Callback): - def on_epoch_end(self, trainer, pl_module: GRLVQ): - print(pl_module.relevance_profile) - - -if __name__ == "__main__": - # Dataset - x_train, y_train = make_spiral(n_samples=1000, noise=0.3) - train_ds = NumpyDataset(x_train, y_train) - - # Dataloaders - train_loader = DataLoader(train_ds, num_workers=0, batch_size=150) - - # Hyperparameters - hparams = dict( - nclasses=2, - prototypes_per_class=20, - prototype_initializer=cinit.SSI(torch.Tensor(x_train), - torch.Tensor(y_train)), - #prototype_initializer=cinit.UniformInitializer(2), - input_dim=x_train.shape[1], - lr=0.1, - #transfer_function="sigmoid_beta", - ) - - # Initialize the model - model = GRLVQ(hparams) - - # Model summary - print(model) - - # Callbacks - vis = VisSiameseGLVQ2D(x_train, y_train) - debug = PrintRelevanceCallback() - - # Setup trainer - trainer = pl.Trainer(max_epochs=200, callbacks=[vis, debug]) - - # Training loop - trainer.fit(model, train_loader)