├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── README.md ├── THU_Thesis-final.pdf ├── datasets ├── generated-data │ └── fake_data_generator.py ├── imagenet-32x32 │ └── .gitignore ├── imagenet-64x64-reduced │ ├── reduce-dataset-deprecated.py │ └── reduce-dataset.py ├── imagenet-64x64 │ └── .gitignore └── imagenet-reduced │ └── .gitignore ├── examples ├── ModelUtils.py ├── imagenet-224x224.py └── imagenet-64x64.py ├── experiments ├── ImageNet_1000_classes_224x224 │ ├── .gitkeep │ ├── experiment_1.py │ └── run.bash └── ImageNet_50_classes_224x224 │ ├── ImageNet-50-classes.txt │ ├── run.bash │ ├── vary_depth │ ├── experiment_1.py │ ├── experiment_10.py │ ├── experiment_11.py │ ├── experiment_12.py │ ├── experiment_2.py │ ├── experiment_3.py │ ├── experiment_4.py │ ├── experiment_5.py │ ├── experiment_6.py │ ├── experiment_7.py │ ├── experiment_8.py │ └── experiment_9.py │ ├── vary_fc_neurons │ ├── experiment_1.py │ ├── experiment_10.py │ ├── experiment_2.py │ ├── experiment_3.py │ ├── experiment_4.py │ ├── experiment_5.py │ ├── experiment_6.py │ ├── experiment_7.py │ ├── experiment_8.py │ └── experiment_9.py │ ├── vary_lr │ ├── experiment_1.py │ ├── experiment_2.py │ ├── experiment_3.py │ ├── experiment_4.py │ ├── experiment_5.py │ ├── experiment_6.py │ └── experiment_7.py │ └── vary_optimizer_activation │ ├── experiment_1.py │ ├── experiment_2.py │ ├── experiment_3.py │ └── experiment_4.py ├── feature-extractor ├── extractor-imagenet.py └── extractor-mnist.py ├── old-experiments ├── backprop-imagenet.py ├── backprop-mnist.py ├── features-imagenet.py ├── features-pc-imagenet.py ├── features-pc-mnist.py ├── fen-generated-data.py ├── fen-inference.py ├── pc-imagenet.py └── pc-mnist.py ├── results ├── ImageNet_1000_classes_224x224 │ ├── .gitignore │ └── scripts │ │ └── benchmark.m ├── ImageNet_50_classes_224x224 │ ├── .gitignore │ └── scripts │ │ ├── outputs │ │ ├── vary_depth.png │ │ ├── vary_lr.png │ │ ├── vary_optimizer.png │ │ └── vary_width.png │ │ ├── vary_depth.m │ │ ├── vary_lr.m │ │ ├── vary_optimizer.m │ │ └── vary_width.m └── old │ ├── data │ ├── MNIST-feat100-1 │ ├── MNIST-feat20-1 │ ├── MNIST-raw100-1 │ └── MNIST-raw20-1 │ └── scripts │ ├── old_graphs_imagenet.m │ └── old_graphs_mnist.m └── snn ├── Dataset.py ├── FreeEnergyNetwork.py ├── PcTorch.py ├── __init__.py ├── torch-verify-gpu.py └── util.py /.gitignore: -------------------------------------------------------------------------------- 1 | snn/__pycache__/ 2 | *.csv 3 | *.p 4 | results/graphs/* 5 | datasets/*.npz 6 | *.pyc 7 | *.npz -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Fit Generated", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/old-experiments/torch-generated-data.py", 12 | "cwd": "${workspaceFolder}/old-experiments", 13 | "console": "integratedTerminal" 14 | }, 15 | { 16 | "name": "Fit MNIST", 17 | "type": "python", 18 | "request": "launch", 19 | "program": "${workspaceFolder}/old-experiments/torch-mnist.py", 20 | "cwd": "${workspaceFolder}/old-experiments", 21 | "console": "integratedTerminal" 22 | }, 23 | { 24 | "name": "Feature Extractor", 25 | "type": "python", 26 | "request": "launch", 27 | "program": "${workspaceFolder}/feature-extractor/extractor.py", 28 | "cwd": "${workspaceFolder}/old-experiments", 29 | "console": "integratedTerminal" 30 | }, 31 | { 32 | "name": "Backprop Imagenet", 33 | "type": "python", 34 | "request": "launch", 35 | "program": "${workspaceFolder}/old-experiments/backprop-imagenet.py", 36 | "cwd": "${workspaceFolder}/old-experiments", 37 | "console": "integratedTerminal" 38 | }, 39 | 40 | { 41 | "name": "Backprop MNIST", 42 | "type": "python", 43 | "request": "launch", 44 | "program": "${workspaceFolder}/old-experiments/backprop-mnist.py", 45 | "cwd": "${workspaceFolder}/old-experiments", 46 | "console": "integratedTerminal" 47 | }, 48 | 49 | { 50 | "name": "PC Imagenet", 51 | "type": "python", 52 | "request": "launch", 53 | "program": "${workspaceFolder}/old-experiments/pc-imagenet.py", 54 | "cwd": "${workspaceFolder}/old-experiments", 55 | "console": "integratedTerminal" 56 | }, 57 | 58 | { 59 | "name": "Reduce 64x64 Imagenet", 60 | "type": "python", 61 | "request": "launch", 62 | "program": "${workspaceFolder}/datasets/imagenet-64x64-reduced/reduce-dataset.py", 63 | "cwd": "${workspaceFolder}", 64 | "console": "integratedTerminal" 65 | }, 66 | 67 | { 68 | "name": "64x64 Imagenet", 69 | "type": "python", 70 | "request": "launch", 71 | "program": "${workspaceFolder}/examples/imagenet-64x64.py", 72 | "cwd": "${workspaceFolder}", 73 | "console": "integratedTerminal" 74 | }, 75 | 76 | { 77 | "name": "224x224 Imagenet", 78 | "type": "python", 79 | "request": "launch", 80 | "program": "${workspaceFolder}/examples/imagenet-224x224.py", 81 | "cwd": "${workspaceFolder}", 82 | "console": "integratedTerminal" 83 | }, 84 | { 85 | "name": "Debug File", 86 | "type": "python", 87 | "request": "launch", 88 | "program": "${workspaceFolder}/experiments/ImageNet_50_classes_224x224/vary_depth/experiment_10.py", 89 | "cwd": "${workspaceFolder}", 90 | "console": "integratedTerminal" 91 | } 92 | 93 | ] 94 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Predictive Coding Model 2 | 3 | ## Bachelor Thesis 4 | 5 | This project was the base of my Bachelor's Thesis, mentored by [Professor Reinhold von Schwerin](https://studium.hs-ulm.de/de/users/142412) and Professor [Ronald Blechschmidt](https://studium.hs-ulm.de/de/users/617327), during my stay at the Technische Hochschule Ulm. 6 | 7 | [Download Final Thesis file](THU_Thesis-final.pdf) 8 | 9 | ## Overview 10 | 11 | This repository contrains an implementation of the paper *An Approximation of the Error Backpropagation Algorithm in a Predictive Coding Network with Local Hebbian Synaptic Plasticity, Whittington, James CR and Bogacz, Rafal [2017]* - [link](https://www.mitpressjournals.org/doi/full/10.1162/NECO_a_00949). 12 | 13 | Predictive Coding is an alternative approach to artificial neural networks, inspired by theories of brain function. The network is structured in a hierarchical fashion with multiple layers (similar to deep learning), in which bottom-most layers receive *sensory input*, while the higher layers are responsible for representing the underlying *hidden causes* of such inputs (i.e. the inferred structure of the real world which gave rise to such input, i.e. explain the input). 14 | 15 | Meanwhile, top-bottom (feedback) connections generate the predicted input given the hidden causes encoded in the higher layers, which are then compared with the actual input. Finally, their difference (the prediction error) is transmitted through bottom-up (forward) connections, adjusting the actual valued of the hidden causes such that they better explain the sensory information. 16 | 17 | There are many flavors of the Predictive Coding framework, and one in particular is a simple classifier for a static input network (that is, the input data does not contain a temporal dimension). 18 | 19 | ## Run Latest Model 20 | 21 | We compare the performance of a typical Backprop network againt the Predictive Coding implementation, on the Imagenet dataset. 22 | 23 | **Run all the commands below from the root folder** 24 | 25 | ### Reduced (64x64) ImageNet 26 | 27 | 1. Download the `Train(64x64) part1`, `Train(64x64) part2` and `Val(64x64)` (select `npz format`) from the [imagenet website](https://image-net.org/download-images). Extract inside `datasets/imagenet-64x64/`. 28 | 29 | 2. (optional) Create subsampled dataset (select desired class indices modifying `DESIRED_CLASSES` in the file `reduce-dataset.py`) and then 30 | 31 | ```bash 32 | python datasets/imagenet-64x64-reduced/reduce-dataset.py 33 | ``` 34 | 35 | 3. Update the variable `NUM_CLASSES` in `examples/imagenet-64x64.py` to match the number of classes selected on previous step 36 | 37 | 4. Train the backpropagation + predictive coding networks 38 | 39 | ```bash 40 | python -W ignore examples/imagenet-64x64.py 41 | ``` 42 | 43 | ### "Full" image size (224x224) ImageNet 44 | 45 | 1. Download the entire ImageNet dataset (from somewhere) and update the variable `FOLDER` in the file `examples/imagenet-224x224.py` to match the location of the dataset. 46 | 47 | 2. (optional) Select only some folders of some classes from the dataset, and put them inside the folder `datasets/imagenet-reduced/train/` and `datasets/imagenet-reduced/val/`. 48 | 49 | 4. Train the backpropagation + predictive coding networks 50 | 51 | ```bash 52 | python -W ignore examples/imagenet-224x224.py 53 | ``` 54 | 55 | ### Experiment Sequence 56 | 57 | 1. For 50 classes: 58 | 59 | ```bash 60 | ./experiments/ImageNet_50_classes_224x224/run.bash | tee -a results/ImageNet_50_classes_224x224/log.txt 61 | ``` 62 | 63 | - Or, using `tmux`: 64 | 65 | ```bash 66 | tmux 67 | ``` 68 | 69 | ```bash 70 | ./experiments/ImageNet_50_classes_224x224/run.bash | tee -a results/ImageNet_50_classes_224x224/log.txt 71 | ``` 72 | 73 | Detach from session with `Ctrl+B` and then `D` 74 | 75 | - To reattach after logging off: 76 | 77 | ```bash 78 | tmux attach 79 | ``` 80 | -------------------------------------------------------------------------------- /THU_Thesis-final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/THU_Thesis-final.pdf -------------------------------------------------------------------------------- /datasets/generated-data/fake_data_generator.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Generates fake data into CSV files 3 | ''' 4 | 5 | import numpy as np 6 | from mpl_toolkits.mplot3d import Axes3D 7 | # Axes3D import has side effects, it enables using projection='3d' in add_subplot 8 | import matplotlib.pyplot as plt 9 | 10 | # Functions to be sampled 11 | 12 | def f1(x,y): 13 | return x**3 + y**2*0.5 + x + y 14 | 15 | def f2(x,y): 16 | return x**2 + y**2 17 | 18 | def f3(x,y): 19 | return x**3*np.cos(y) 20 | 21 | # Select parameters 22 | FUNCTION = f1 23 | NOISE_LEVEL = 0.3 24 | VISUALIZE = True 25 | RANGE_MIN = -3 26 | RANGE_MAX = 3 27 | STEP = 0.3 28 | 29 | def create_csv(filename, data): 30 | separator = ',' 31 | with open(filename+'.csv', 'w') as f: 32 | keys = list(data) 33 | data_points = len(data[keys[0]]) 34 | 35 | for k in range(len(keys)): 36 | f.write(f'"{keys[k]}"') 37 | if k < len(keys)-1: 38 | f.write(separator) 39 | 40 | f.write('\n') 41 | 42 | for i in range(data_points): 43 | for k in range(len(keys)): 44 | f.write(f'{data[keys[k]][i]}') 45 | if k < len(keys)-1: 46 | f.write(separator) 47 | else: 48 | f.write(f'\n') 49 | 50 | f.close() 51 | 52 | def generate_data(generator_function, range_min, range_max, step, noise_level=0.2,visualize = False): 53 | # Generates data samples for dim_in = 2 and dim_out = 1 functions 54 | assert range_min < range_max 55 | assert step <= abs(range_max- range_min) 56 | 57 | x = y = np.arange(range_min, range_max, step) 58 | X, Y = np.meshgrid(x, y) 59 | xs = np.ravel(X) 60 | ys = np.ravel(Y) 61 | zs = np.array(generator_function(xs, ys)) 62 | 63 | if noise_level>0.0: 64 | noise = np.random.normal(0,noise_level,len(zs)) 65 | zs+=noise 66 | 67 | Z = zs.reshape(X.shape) 68 | 69 | if visualize: 70 | fig = plt.figure() 71 | ax = fig.add_subplot(111, projection='3d') 72 | ax.plot_surface(X, Y, Z) 73 | ax.set_xlabel('X Label') 74 | ax.set_ylabel('Y Label') 75 | ax.set_zlabel('Z Label') 76 | plt.show() 77 | 78 | return {'x': xs, 'y': ys, 'f': zs} 79 | 80 | filename = 'generated_'+FUNCTION.__name__ 81 | data = generate_data(FUNCTION, RANGE_MIN, RANGE_MAX, STEP, noise_level=NOISE_LEVEL, visualize=VISUALIZE) 82 | create_csv(filename, data) 83 | 84 | -------------------------------------------------------------------------------- /datasets/imagenet-32x32/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | */ 3 | !.gitignore -------------------------------------------------------------------------------- /datasets/imagenet-64x64-reduced/reduce-dataset-deprecated.py: -------------------------------------------------------------------------------- 1 | # Reduces the Imagenet 64x64 to a limited number of classes 2 | 3 | import numpy as np 4 | import datetime 5 | 6 | # Dataset 7 | DATASET_TRAIN_BATCH_COUNT = 10 8 | FOLDER = 'datasets/imagenet-64x64/' 9 | PREFIX = 'train_data_batch_' 10 | PREFIX_VALID = 'val_data' 11 | SUFFIX = '.npz' 12 | IMAGE_SIZE = 64 13 | CHANNELS = 3 14 | T = 100 15 | DESIRED_CLASSES=list(range(T,T+20)) 16 | 17 | # Process Dataset 18 | 19 | # Dataset train files 20 | file_paths_train = [] 21 | for i in range(1, DATASET_TRAIN_BATCH_COUNT+1): 22 | file = FOLDER+PREFIX+str(i)+SUFFIX 23 | file_paths_train.append(file) 24 | 25 | # Read train dataset 26 | labels = np.zeros((0,), dtype=np.int) 27 | data = np.zeros((0,IMAGE_SIZE*IMAGE_SIZE*CHANNELS), dtype=np.uint8) # using uint8 to fit dataset in memory 28 | 29 | t_start = datetime.datetime.now() 30 | t_last_batch = datetime.datetime.now() 31 | 32 | for dataset_index,path in enumerate(file_paths_train): 33 | dataset = np.load(path) 34 | x_batch = dataset['data'] 35 | y_batch = dataset['labels'] 36 | 37 | for i in range(x_batch.shape[0]): 38 | if y_batch[i] in DESIRED_CLASSES: 39 | labels = np.append(labels, y_batch[i]) 40 | data = np.concatenate((data, x_batch[i:i+1]), axis=0) 41 | 42 | t_now = datetime.datetime.now() 43 | batch_processing_time = (t_now - t_last_batch ) 44 | print("Batch [%d], processing time: %.2f (seconds)" % (dataset_index, batch_processing_time.total_seconds())) 45 | t_last_batch = t_now 46 | 47 | # Show total processing time 48 | t_end = datetime.datetime.now() 49 | total_time = (t_end - t_start ) 50 | print("Total time: %.2f (seconds)" % total_time.total_seconds()) 51 | 52 | 53 | # Save train dataset 54 | np.savez('datasets/dataset_training_reduced_1', labels=labels, data=data) 55 | 56 | 57 | # -------------------------------------------- 58 | # Dataset validation files 59 | file_paths_valid = [] 60 | file = FOLDER+PREFIX_VALID+SUFFIX 61 | file_paths_valid.append(file) 62 | 63 | # Read valid dataset 64 | labels = np.zeros((0,), dtype=np.int) 65 | data = np.zeros((0,IMAGE_SIZE*IMAGE_SIZE*CHANNELS), dtype=np.uint8) # using uint8 to fit dataset in memory 66 | 67 | for path in file_paths_valid: 68 | dataset = np.load(path) 69 | x_batch = dataset['data'] 70 | y_batch = dataset['labels'] 71 | 72 | for i in range(x_batch.shape[0]): 73 | if y_batch[i] in DESIRED_CLASSES: 74 | labels = np.append(labels, y_batch[i]) 75 | data = np.concatenate((data, x_batch[i:i+1]), axis=0) 76 | 77 | pass 78 | 79 | # Save valid dataset 80 | np.savez('datasets/dataset_valid_reduced', labels=labels, data=data) 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /datasets/imagenet-64x64-reduced/reduce-dataset.py: -------------------------------------------------------------------------------- 1 | # Reduces the Imagenet 64x64 to a limited number of classes 2 | # Using Linked List for performance 3 | 4 | import numpy as np 5 | import datetime 6 | from collections import deque 7 | 8 | # Dataset 9 | DATASET_TRAIN_BATCH_COUNT = 10 10 | FOLDER = 'datasets/imagenet-64x64/' 11 | PREFIX = 'train_data_batch_' 12 | PREFIX_VALID = 'val_data' 13 | SUFFIX = '.npz' 14 | IMAGE_SIZE = 64 15 | CHANNELS = 3 16 | LABEL_SHIFT = 100 17 | DESIRED_CLASSES=list(range(LABEL_SHIFT,LABEL_SHIFT+20)) # There are about 1280 images per class 18 | 19 | # Map labels to keep them sequential, starting from 1, e.g: [1, 2, 3, ...] 20 | label_map = {} 21 | for i in range(len(DESIRED_CLASSES)): 22 | label_map[DESIRED_CLASSES[i]] = i+1 23 | 24 | # Dataset train files 25 | file_paths_train = [] 26 | for i in range(1, DATASET_TRAIN_BATCH_COUNT+1): 27 | file = FOLDER+PREFIX+str(i)+SUFFIX 28 | file_paths_train.append(file) 29 | 30 | # Read train dataset 31 | llist_label_data = deque() 32 | 33 | t_start = datetime.datetime.now() 34 | t_last_batch = datetime.datetime.now() 35 | 36 | for dataset_index,path in enumerate(file_paths_train): 37 | 38 | with np.load(path) as dataset: 39 | x_batch = dataset['data'] 40 | y_batch = dataset['labels'] 41 | 42 | for i in range(x_batch.shape[0]): 43 | if y_batch[i] in DESIRED_CLASSES: 44 | llist_label_data.append((y_batch[i], np.copy(x_batch[i]))) 45 | 46 | del x_batch 47 | del y_batch 48 | 49 | t_now = datetime.datetime.now() 50 | batch_processing_time = (t_now - t_last_batch ) 51 | print("Batch [%d], processing time: %.2f (seconds)" % (dataset_index, batch_processing_time.total_seconds())) 52 | t_last_batch = t_now 53 | 54 | items = len(llist_label_data) 55 | labels = np.zeros((items,), dtype=np.int) 56 | data = np.zeros((items,IMAGE_SIZE*IMAGE_SIZE*CHANNELS), dtype=np.uint8) 57 | 58 | for i, (l, d) in enumerate(llist_label_data): 59 | labels[i] = label_map[l] 60 | data[i] = d 61 | 62 | # Show total processing time 63 | t_end = datetime.datetime.now() 64 | total_time = (t_end - t_start ) 65 | print("Total time: %.2f (seconds)" % total_time.total_seconds()) 66 | 67 | 68 | # Save train dataset 69 | np.savez('datasets/dataset_training_reduced_1', labels=labels, data=data) 70 | 71 | 72 | # -------------------------------------------- 73 | # Dataset validation files 74 | file_paths_valid = [] 75 | file = FOLDER+PREFIX_VALID+SUFFIX 76 | file_paths_valid.append(file) 77 | 78 | # Read valid dataset 79 | labels = np.zeros((0,), dtype=np.int) 80 | data = np.zeros((0,IMAGE_SIZE*IMAGE_SIZE*CHANNELS), dtype=np.uint8) # using uint8 to fit dataset in memory 81 | 82 | for path in file_paths_valid: 83 | dataset = np.load(path) 84 | x_batch = dataset['data'] 85 | y_batch = dataset['labels'] 86 | 87 | for i in range(x_batch.shape[0]): 88 | if y_batch[i] in DESIRED_CLASSES: 89 | labels = np.append(labels, label_map[y_batch[i]]) 90 | data = np.concatenate((data, x_batch[i:i+1]), axis=0) 91 | 92 | pass 93 | 94 | # Save valid dataset 95 | np.savez('datasets/dataset_valid_reduced', labels=labels, data=data) 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /datasets/imagenet-64x64/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | */ 3 | !.gitignore -------------------------------------------------------------------------------- /datasets/imagenet-reduced/.gitignore: -------------------------------------------------------------------------------- 1 | */ -------------------------------------------------------------------------------- /examples/imagenet-224x224.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 10 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model) 213 | 214 | # Print Metrics 215 | ModelUtils.printMetrics(metrics) 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /examples/imagenet-64x64.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (64x64) dataset 2 | # Extracted .npz files should go inside dataset/imagenet-64x64/ folder 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | sys.path.append('.') 17 | from snn.Dataset import Dataset 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 64 28 | NUM_CLASSES = 1000 29 | TRAIN_BATCH_SIZE = 32 30 | EPOCHS = 4 31 | USE_REDUCED_DATASET = True 32 | # VALID_PERC = 0.2 # Not used now, validation data is just one of the batches 33 | 34 | # Network Architecture 35 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 36 | PRINT_EVERY_N_BATCHES = 2000 37 | 38 | # Predictive Coding parameters 39 | INFERENCE_STEPS = 40 40 | 41 | # Dataset files 42 | FOLDER = 'datasets/imagenet-64x64/' 43 | SUFFIX = '.npz' 44 | FILE_PATHS_TRAIN = [ 45 | 'train_data_batch_1', 46 | 'train_data_batch_2', 47 | 'train_data_batch_3', 48 | 'train_data_batch_4', 49 | 'train_data_batch_5', 50 | 'train_data_batch_6', 51 | 'train_data_batch_7', 52 | 'train_data_batch_8', 53 | 'train_data_batch_9', 54 | 'train_data_batch_10' 55 | ] 56 | 57 | FILE_PATHS_VALID = [ 58 | 'val_data' 59 | ] 60 | 61 | if USE_REDUCED_DATASET: # Use reduced dataset? 62 | FOLDER = 'datasets/imagenet-64x64-reduced/' 63 | FILE_PATHS_TRAIN = ['dataset_training_reduced_1'] 64 | FILE_PATHS_VALID = ['dataset_valid_reduced'] 65 | NUM_CLASSES = 20 66 | FC_NEURONS = 512 67 | PRINT_EVERY_N_BATCHES = 100 68 | 69 | # Tunnable hyper-parameters 70 | parameters = { 71 | 72 | # Common parameters 73 | 'optimizer': 'sgd', 74 | 'activation': 'relu', 75 | 'hidden_layers': 2, 76 | 'fc_neurons': 512, 77 | 78 | # Backprop 79 | 'dropout_bp': False, 80 | 'lr_bp': 0.001, 81 | 'momentum_bp': 0.9, 82 | 83 | # PC 84 | 'lr_pc': 0.003, 85 | 'momentum_pc': 0.9 86 | } 87 | 88 | # Compose full data path 89 | FILE_PATHS_TRAIN = [FOLDER+file+SUFFIX for file in FILE_PATHS_TRAIN] 90 | FILE_PATHS_VALID = [FOLDER+file+SUFFIX for file in FILE_PATHS_VALID] 91 | 92 | # Datasets 93 | params = {'batch_size': TRAIN_BATCH_SIZE, 94 | 'shuffle': True, 95 | 'num_workers': 0, 96 | 'drop_last': True} 97 | 98 | # Data transformer 99 | # transform must contain transforms.ToTensor(), or be omitted 100 | mean = 0.5 101 | std = 0.5 102 | train_transform = transforms.Compose([ 103 | transforms.ToPILImage(), 104 | transforms.RandomHorizontalFlip(), 105 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 106 | transforms.ToTensor(), 107 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 108 | 109 | # Simpler transform 110 | valid_transform = transforms.Compose([ 111 | transforms.ToTensor(), 112 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 113 | 114 | # Data generators 115 | train_dataset = Dataset(FILE_PATHS_TRAIN, IMAGE_SIZE, transform=train_transform) 116 | train_generator = torch.utils.data.DataLoader(train_dataset, **params) 117 | 118 | valid_dataset=None 119 | valid_generator=None 120 | if len(FILE_PATHS_VALID) > 0: 121 | valid_dataset = Dataset(FILE_PATHS_VALID, IMAGE_SIZE, transform=valid_transform) 122 | valid_generator = torch.utils.data.DataLoader(valid_dataset, **params) 123 | 124 | # Show data example 125 | def imshow(img): 126 | img = img / 2 + 0.5 # unnormalize 127 | npimg = img.numpy() 128 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 129 | plt.show() 130 | 131 | train_it = train_generator.__iter__() 132 | data,labels = next(train_it) 133 | # imshow(torchvision.utils.make_grid(data)) 134 | 135 | # Resnet 136 | # Pre-trained model for Transfer Learning 137 | # resnet = models.resnet152(pretrained=True) 138 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 139 | # modules = list(resnet.children())[:-1] 140 | # resnet = nn.Sequential(*modules) 141 | # for p in resnet.parameters(): 142 | # p.requires_grad = False 143 | resnet = models.resnet152(pretrained=True) 144 | num_ftrs_resnet = resnet.fc.in_features 145 | for param in resnet.parameters(): 146 | param.requires_grad = False 147 | resnet.fc = nn.Flatten() 148 | 149 | # Vgg16 150 | vgg16 = models.vgg16(pretrained=True) 151 | vgg16 = vgg16.features 152 | for p in vgg16.parameters(): 153 | p.requires_grad = False 154 | num_ftrs_vgg16 = 512*2*2 155 | 156 | # Choose extractor 157 | feature_extractor = resnet 158 | num_ftrs = num_ftrs_resnet 159 | 160 | feature_extractor = feature_extractor.to(device) 161 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 162 | 163 | 164 | # Fully connected layer model 165 | model = ModelUtils.getFcModel( num_ftrs, 166 | NUM_CLASSES, 167 | parameters['hidden_layers'], 168 | parameters['fc_neurons'], 169 | parameters['activation'], 170 | parameters['dropout_bp'] ) 171 | 172 | model.to(device) # Move model to device 173 | summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 174 | 175 | # Predictive Coding model 176 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 177 | num_ftrs, 178 | NUM_CLASSES, 179 | parameters['hidden_layers'], 180 | parameters['fc_neurons'] 181 | ) 182 | 183 | pc_model = PcTorch(pc_model_architecture) 184 | pc_model.set_training_parameters( 185 | TRAIN_BATCH_SIZE, 186 | INFERENCE_STEPS, 187 | parameters['activation'], 188 | parameters['optimizer'], 189 | parameters['lr_pc'], 190 | parameters['momentum_pc'], 191 | normalize_input=True) 192 | 193 | # Loss and optmizer 194 | criterion = nn.CrossEntropyLoss() 195 | optimizer = 'None' 196 | 197 | if parameters['optimizer'] == 'sgd': 198 | optimizer = optim.SGD(model.parameters(), 199 | lr=parameters['lr_bp'], 200 | momentum=parameters['momentum_bp']) 201 | 202 | elif parameters['optimizer'] == 'adam': 203 | optimizer = optim.Adam(model.parameters(), 204 | lr=parameters['lr_bp'], 205 | betas=(parameters['momentum_bp'], 0.999)) 206 | 207 | 208 | # Train models 209 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 210 | EPOCHS, 211 | NUM_CLASSES, 212 | train_generator, 213 | valid_generator, 214 | model, 215 | feature_extractor, 216 | criterion, 217 | optimizer, 218 | device, 219 | PRINT_EVERY_N_BATCHES, 220 | pc_model=pc_model) 221 | 222 | # Print Metrics 223 | ModelUtils.printMetrics(metrics) 224 | 225 | 226 | # TODO Test accuracy 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | -------------------------------------------------------------------------------- /experiments/ImageNet_1000_classes_224x224/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/experiments/ImageNet_1000_classes_224x224/.gitkeep -------------------------------------------------------------------------------- /experiments/ImageNet_1000_classes_224x224/run.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "----------------------------------------" 3 | echo " 1000 classes experiment " 4 | echo "----------------------------------------" 5 | echo "Experiment 1" 6 | sleep 5 7 | python experiments/ImageNet_1000_classes_224x224/experiment_1.py 8 | echo "----------------------------------------" 9 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/run.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # echo "----------------------------------------" 3 | # echo " VARY DEPTH " 4 | # echo "----------------------------------------" 5 | # echo "Experiment 1" 6 | # sleep 5 7 | # # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_1.py <- too little layers, maybe a problem 8 | # echo "----------------------------------------" 9 | # echo "Experiment 2" 10 | # sleep 5 11 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_2.py 12 | # echo "----------------------------------------" 13 | # echo "Experiment 3" 14 | # sleep 5 15 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_3.py 16 | # echo "----------------------------------------" 17 | # echo "Experiment 4" 18 | # sleep 5 19 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_4.py 20 | # echo "Experiment 5" 21 | # sleep 5 22 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_5.py 23 | # echo "Experiment 6" 24 | # sleep 5 25 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_6.py 26 | # echo "Experiment 7" 27 | # sleep 5 28 | # # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_7.py <- too little layers, maybe a problem 29 | # echo "Experiment 8" 30 | # sleep 5 31 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_8.py 32 | # echo "Experiment 9" 33 | # sleep 5 34 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_9.py 35 | # echo "Experiment 10" 36 | # sleep 5 37 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_10.py 38 | # echo "Experiment 11" 39 | # sleep 5 40 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_11.py 41 | # echo "Experiment 12" 42 | # sleep 5 43 | # python experiments/ImageNet_50_classes_224x224/vary_depth/experiment_12.py 44 | 45 | # echo "----------------------------------------" 46 | # echo " VARY FC NEURONS " 47 | # echo "----------------------------------------" 48 | # echo "Experiment 1" 49 | # sleep 5 50 | # python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_1.py 51 | # echo "----------------------------------------" 52 | # echo "Experiment 2" 53 | # sleep 5 54 | # python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_2.py 55 | # echo "----------------------------------------" 56 | # echo "Experiment 3" 57 | # sleep 5 58 | # python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_3.py 59 | # echo "----------------------------------------" 60 | # echo "Experiment 4" 61 | # sleep 5 62 | # python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_4.py 63 | # echo "Experiment 5" 64 | # sleep 5 65 | # python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_5.py 66 | # echo "Experiment 6" 67 | # sleep 5 68 | # python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_6.py 69 | echo "Experiment 7" 70 | sleep 5 71 | python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_7.py 72 | echo "Experiment 8" 73 | sleep 5 74 | python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_8.py 75 | echo "Experiment 9" 76 | sleep 5 77 | python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_9.py 78 | echo "Experiment 10" 79 | sleep 5 80 | python experiments/ImageNet_50_classes_224x224/vary_fc_neurons/experiment_10.py 81 | 82 | 83 | echo "----------------------------------------" 84 | echo " VARY LR " 85 | echo "----------------------------------------" 86 | echo "Experiment 1" 87 | sleep 5 88 | python experiments/ImageNet_50_classes_224x224/vary_lr/experiment_1.py 89 | echo "----------------------------------------" 90 | echo "Experiment 2" 91 | sleep 5 92 | python experiments/ImageNet_50_classes_224x224/vary_lr/experiment_2.py 93 | echo "----------------------------------------" 94 | echo "Experiment 3" 95 | sleep 5 96 | python experiments/ImageNet_50_classes_224x224/vary_lr/experiment_3.py 97 | echo "----------------------------------------" 98 | echo "Experiment 4" 99 | sleep 5 100 | python experiments/ImageNet_50_classes_224x224/vary_lr/experiment_4.py 101 | echo "Experiment 5" 102 | sleep 5 103 | python experiments/ImageNet_50_classes_224x224/vary_lr/experiment_5.py 104 | echo "Experiment 6" 105 | sleep 5 106 | python experiments/ImageNet_50_classes_224x224/vary_lr/experiment_6.py 107 | echo "Experiment 7" 108 | sleep 5 109 | python experiments/ImageNet_50_classes_224x224/vary_lr/experiment_7.py 110 | 111 | echo "----------------------------------------" 112 | echo " VARY OPTIMIZER/ACTIVATION " 113 | echo "----------------------------------------" 114 | echo "Experiment 1" 115 | sleep 5 116 | python experiments/ImageNet_50_classes_224x224/vary_optimizer_activation/experiment_1.py 117 | echo "----------------------------------------" 118 | echo "Experiment 2" 119 | sleep 5 120 | python experiments/ImageNet_50_classes_224x224/vary_optimizer_activation/experiment_2.py 121 | echo "----------------------------------------" 122 | echo "Experiment 3" 123 | sleep 5 124 | python experiments/ImageNet_50_classes_224x224/vary_optimizer_activation/experiment_3.py 125 | echo "----------------------------------------" 126 | echo "Experiment 4" 127 | sleep 5 128 | python experiments/ImageNet_50_classes_224x224/vary_optimizer_activation/experiment_4.py 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_1.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 1, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_10.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 4, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': True, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_11.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 5, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': True, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_12.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 6, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': True, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_2.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_3.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 3, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_4.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 4, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_5.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 5, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_6.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 6, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_7.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 1, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': True, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_8.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': True, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_depth/experiment_9.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 3, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': True, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.003, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_lr/experiment_1.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.0002, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.0002, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_lr/experiment_2.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.0005, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.0005, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_lr/experiment_3.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.001, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.001, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_lr/experiment_4.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.002, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.002, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /experiments/ImageNet_50_classes_224x224/vary_lr/experiment_7.py: -------------------------------------------------------------------------------- 1 | # Transfer Learning on imagenet (full image sizes) dataset 2 | # Set flag FOLDER to where the dataset is. It should contain a `train` and `val` folders inside 3 | 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | from sklearn.utils import shuffle 7 | import torch 8 | import torch.nn as nn 9 | import torch.optim as optim 10 | import torchvision 11 | import torchvision.transforms as transforms 12 | import torchvision.models as models 13 | from torchinfo import summary 14 | 15 | import sys 16 | import os 17 | sys.path.append('.') 18 | from snn.PcTorch import PcTorch 19 | 20 | # Import util functions 21 | import examples.ModelUtils as ModelUtils 22 | 23 | # Set PyTorch device 24 | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 25 | 26 | # Dataset Parameters 27 | IMAGE_SIZE = 224 28 | TRAIN_BATCH_SIZE = 32 29 | EPOCHS = 20 30 | VALID_PERC = 0.2 31 | USE_REDUCED_DATASET = True 32 | 33 | # Network Architecture 34 | FC_NEURONS = 2048 # deprecated, set at the `parameters` dictionary 35 | PRINT_EVERY_N_BATCHES = 2000 36 | 37 | # Predictive Coding parameters 38 | INFERENCE_STEPS = 40 39 | 40 | # Dataset files 41 | FOLDER = '/data/datasets/imagenet/ILSVRC2012/train' 42 | SUFFIX = '.JPEG' 43 | 44 | if USE_REDUCED_DATASET: # Use reduced dataset? 45 | FOLDER = 'datasets/imagenet-reduced/train/' 46 | FC_NEURONS = 256 47 | PRINT_EVERY_N_BATCHES = 100 48 | 49 | # Tunnable hyper-parameters 50 | parameters = { 51 | 52 | # Common parameters 53 | 'optimizer': 'adam', 54 | 'activation': 'sigmoid', 55 | 'hidden_layers': 2, 56 | 'fc_neurons': 256, 57 | 58 | # Backprop 59 | 'dropout_bp': False, 60 | 'lr_bp': 0.01, 61 | 'momentum_bp': 0.9, 62 | 63 | # PC 64 | 'lr_pc': 0.01, 65 | 'momentum_pc': 0.9 66 | } 67 | 68 | # Count number of classes 69 | subfolders = [ f.path for f in os.scandir(FOLDER) if f.is_dir() ] 70 | NUM_CLASSES = len(subfolders) 71 | 72 | def load_split_train_test(datadir, valid_size = .2): 73 | # Data transformer 74 | # transform must contain transforms.ToTensor(), or be omitted 75 | mean = 0.5 76 | std = 0.5 77 | 78 | # TODO resize image to common NN input size (random crop, etc) 79 | train_transform = transforms.Compose([ 80 | transforms.RandomResizedCrop(IMAGE_SIZE, scale=(0.65, 1.0), ratio=(0.9, 1.1)), 81 | transforms.RandomHorizontalFlip(), 82 | transforms.ColorJitter(brightness=.3, hue=.05, contrast=0.2), 83 | transforms.ToTensor(), 84 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 85 | 86 | # Simpler transform 87 | valid_transform = transforms.Compose([ 88 | transforms.CenterCrop(IMAGE_SIZE), 89 | transforms.ToTensor(), 90 | transforms.Normalize([mean, mean, mean], [std, std, std])]) 91 | 92 | train_data = torchvision.datasets.ImageFolder(datadir, 93 | transform=train_transform) 94 | valid_data = torchvision.datasets.ImageFolder(datadir, 95 | transform=valid_transform) 96 | 97 | num_train = len(train_data) 98 | indices = list(range(num_train)) 99 | split = int(np.floor(valid_size * num_train)) 100 | np.random.shuffle(indices) 101 | from torch.utils.data.sampler import SubsetRandomSampler 102 | train_idx, valid_idx = indices[split:], indices[:split] 103 | 104 | train_sampler = SubsetRandomSampler(train_idx) 105 | valid_sampler = SubsetRandomSampler(valid_idx) 106 | train_generator = torch.utils.data.DataLoader(train_data, 107 | batch_size=TRAIN_BATCH_SIZE, sampler=train_sampler, drop_last=True) 108 | valid_generator = torch.utils.data.DataLoader(valid_data, 109 | batch_size=TRAIN_BATCH_SIZE, sampler=valid_sampler, drop_last=True) 110 | return train_generator, valid_generator 111 | 112 | # Data generators 113 | train_generator, valid_generator = load_split_train_test(FOLDER, VALID_PERC) 114 | 115 | # Show data example 116 | def imshow(img): 117 | img = img / 2 + 0.5 # unnormalize 118 | npimg = img.numpy() 119 | plt.imshow(np.transpose(npimg, (1, 2, 0))) 120 | plt.show() 121 | 122 | train_it = train_generator.__iter__() 123 | data,labels = next(train_it) 124 | #imshow(torchvision.utils.make_grid(data)) 125 | 126 | 127 | # Resnet 128 | # resnet = models.resnet152(pretrained=True) 129 | # num_ftrs_resnet = resnet.fc.in_features # Number of features before FC 130 | # modules = list(resnet.children())[:-1] 131 | # resnet = nn.Sequential(*modules) 132 | # for p in resnet.parameters(): 133 | # p.requires_grad = False 134 | 135 | resnet = models.resnet152(pretrained=True) 136 | num_ftrs_resnet = resnet.fc.in_features 137 | for param in resnet.parameters(): 138 | param.requires_grad = False 139 | resnet.fc = nn.Flatten() 140 | 141 | # Vgg16 142 | vgg16 = models.vgg16(pretrained=True) 143 | vgg16 = vgg16.features 144 | for p in vgg16.parameters(): 145 | p.requires_grad = False 146 | num_ftrs_vgg16 = 512*7*7 147 | 148 | # Choose extractor 149 | feature_extractor = resnet 150 | num_ftrs = num_ftrs_resnet 151 | 152 | feature_extractor = feature_extractor.to(device) 153 | # summary(feature_extractor, input_size=(TRAIN_BATCH_SIZE, 3, IMAGE_SIZE, IMAGE_SIZE)) 154 | 155 | 156 | # Fully connected layer model 157 | model = ModelUtils.getFcModel( num_ftrs, 158 | NUM_CLASSES, 159 | parameters['hidden_layers'], 160 | parameters['fc_neurons'], 161 | parameters['activation'], 162 | parameters['dropout_bp'] ) 163 | 164 | model.to(device) # Move model to device 165 | # summary(model,input_size=(TRAIN_BATCH_SIZE,num_ftrs)) 166 | 167 | # Predictive Coding model 168 | pc_model_architecture = ModelUtils.getPcModelArchitecture( 169 | num_ftrs, 170 | NUM_CLASSES, 171 | parameters['hidden_layers'], 172 | parameters['fc_neurons'] 173 | ) 174 | 175 | pc_model = PcTorch(pc_model_architecture) 176 | pc_model.set_training_parameters( 177 | TRAIN_BATCH_SIZE, 178 | INFERENCE_STEPS, 179 | parameters['activation'], 180 | parameters['optimizer'], 181 | parameters['lr_pc'], 182 | parameters['momentum_pc'], 183 | normalize_input=True) 184 | 185 | 186 | # Loss and optmizer 187 | criterion = nn.CrossEntropyLoss() 188 | optimizer = 'None' 189 | 190 | if parameters['optimizer'] == 'sgd': 191 | optimizer = optim.SGD(model.parameters(), 192 | lr=parameters['lr_bp'], 193 | momentum=parameters['momentum_bp']) 194 | 195 | elif parameters['optimizer'] == 'adam': 196 | optimizer = optim.Adam(model.parameters(), 197 | lr=parameters['lr_bp'], 198 | betas=(parameters['momentum_bp'], 0.999)) 199 | 200 | # Train models 201 | metrics = ModelUtils.train_TransferLearning_Simultaneous_Backprop_PC( 202 | EPOCHS, 203 | NUM_CLASSES, 204 | train_generator, 205 | valid_generator, 206 | model, 207 | feature_extractor, 208 | criterion, 209 | optimizer, 210 | device, 211 | PRINT_EVERY_N_BATCHES, 212 | pc_model=pc_model, 213 | verbose=False) 214 | 215 | # Print Metrics 216 | ModelUtils.printMetrics(metrics) 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | -------------------------------------------------------------------------------- /feature-extractor/extractor-imagenet.py: -------------------------------------------------------------------------------- 1 | # Trains backprop on imagenet dataset 2 | # Dataset link: http://www.image-net.org/download-images 3 | # Extracted .npz files should go inside dataset/ folder 4 | # RUN THIS FROM 'examples' folder 5 | 6 | import numpy as np 7 | from matplotlib import pyplot as plt 8 | from sklearn.utils import shuffle 9 | import pickle 10 | 11 | # tensorflow etc 12 | from tensorflow import keras 13 | from tensorflow.keras import layers 14 | from tensorflow.keras.models import Sequential 15 | from tensorflow.keras.applications import VGG16 16 | 17 | # Dataset Parameters 18 | CLASSES = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] 19 | DATASET_BATCH_COUNT = 10 20 | SUB_MEAN=False 21 | IMAGE_SIZE = 32 22 | VALID_PERC = 0.2 23 | 24 | def get_images(data, img_size, subtract_mean=False): 25 | # Returns the dataset with image format, instead of flat array 26 | # Useful for convolutional networks 27 | 28 | # Normalize 29 | data = data/np.float32(255) 30 | 31 | if subtract_mean: 32 | mean_image = np.mean(data, axis=0) 33 | data -= mean_image 34 | 35 | img_size2 = img_size * img_size 36 | 37 | data = np.dstack((data[:, :img_size2], data[:, img_size2:2*img_size2], data[:, 2*img_size2:])) 38 | data = data.reshape((data.shape[0], img_size, img_size, 3)).transpose(0, 1, 2, 3) 39 | 40 | return data 41 | 42 | def select_classes(x,y, CLASSES): 43 | # Returns the subset of the dataset containing only the desired classes 44 | 45 | indices = [] 46 | for label in CLASSES: 47 | rows = [i for i, x in enumerate(y) if x == label] 48 | indices.extend(rows) 49 | 50 | x = x[indices, :] 51 | y = y[indices] 52 | 53 | return x, y 54 | 55 | # ------- Load VGG16 ------- 56 | # might not work, manually download file to ~/.keras/models/ instead 57 | conv_base = VGG16(weights='imagenet', 58 | include_top=False, 59 | input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)) 60 | 61 | # ------- Preprocess data into an image array ------- 62 | 63 | # Load data 64 | dataset = None 65 | multiple_files = True 66 | y = np.zeros((0,)) 67 | x = np.zeros((0,IMAGE_SIZE*IMAGE_SIZE*3)) 68 | 69 | if multiple_files: 70 | count = DATASET_BATCH_COUNT # set to 10 when training on the full dataset 71 | prefix = 'train_data_batch_' 72 | for i in range(1, count+1): 73 | name = prefix + str(i) + '.npz' 74 | dataset = np.load('../datasets/'+name) 75 | x_batch = dataset['data'] 76 | y_batch = dataset['labels'] 77 | 78 | # Select only certain classes 79 | x_batch,y_batch = select_classes(x_batch,y_batch, CLASSES) 80 | 81 | y = np.concatenate([y, y_batch], axis=0) 82 | x = np.concatenate([x, x_batch], axis=0) 83 | 84 | else: 85 | dataset = np.load('../datasets/val_data.npz') 86 | x = dataset['data'] 87 | y = dataset['labels'] 88 | 89 | # Select only certain classes 90 | x,y = select_classes(x,y, CLASSES) 91 | 92 | # Subtract 1 from labels 93 | y = np.array([i-1 for i in y]) 94 | 95 | # Shuffle 96 | x, y = shuffle(x, y) 97 | 98 | # Convert x to images (optional, use for convolutions) 99 | x = get_images(x, IMAGE_SIZE, subtract_mean=SUB_MEAN) 100 | if not SUB_MEAN: 101 | # show image sample 102 | plt.imshow(x[0], interpolation='nearest') 103 | plt.show() 104 | 105 | # Separate train and validation data 106 | x_train = [] 107 | y_train = [] 108 | x_valid = [] 109 | y_valid = [] 110 | if VALID_PERC <= 1.0 and VALID_PERC>0: 111 | train_index = int(x.shape[0]*(1-VALID_PERC)) 112 | x_train = x[:train_index] 113 | y_train = y[:train_index] 114 | x_valid = x[train_index:] 115 | y_valid = y[train_index:] 116 | 117 | # One hot encode y 118 | num_classes = len(CLASSES) 119 | y_train = keras.utils.to_categorical(y_train, num_classes) 120 | y_valid = keras.utils.to_categorical(y_valid, num_classes) 121 | 122 | # ------- Extract features and save ------- 123 | 124 | features = conv_base.predict(x_train) 125 | x_train_features = features[:, 0,0, :] 126 | 127 | features = conv_base.predict(x_valid) 128 | x_valid_features = features[:, 0,0, :] 129 | 130 | dataset = { 131 | 'x_train_features': x_train_features, 132 | 'x_test_features': x_valid_features, 133 | 'y_train': y_train, 134 | 'y_test': y_valid 135 | } 136 | 137 | pickle.dump( dataset, open( "../feature-extractor/imagenet-features.p", "wb" ) ) 138 | 139 | pass -------------------------------------------------------------------------------- /feature-extractor/extractor-mnist.py: -------------------------------------------------------------------------------- 1 | # Extracts bottleneck features from MNIST dataset 2 | 3 | # https://www.kaggle.com/tolgahancepel/feature-extraction-and-fine-tuning-using-vgg16 4 | 5 | from tensorflow.keras.applications import VGG16 6 | from tensorflow.keras.datasets import mnist 7 | import numpy as np 8 | from skimage.transform import resize 9 | import pickle 10 | 11 | import sys 12 | sys.path.insert(0,'..') 13 | from snn import util 14 | 15 | # load model 16 | # might not work, manually download file to ~/.keras/models/ instead 17 | conv_base = VGG16(weights='imagenet', 18 | include_top=False, 19 | input_shape=(32, 32, 3)) 20 | 21 | # load dataset 22 | # might yield an error, manually download to ~/.keras/datasets/ instead 23 | (x_train, y_train),(x_test, y_test) = mnist.load_data() 24 | 25 | # One hot encode labels 26 | y_train = util.indices_to_one_hot(y_train, 10) 27 | y_test = util.indices_to_one_hot(y_test, 10) 28 | 29 | # Convert to feature vectors 30 | x_train_imgs = [] 31 | x_test_imgs = [] 32 | 33 | n = len(x_train) 34 | for i in range(n): 35 | img = x_train[i] 36 | img_rgb = np.asarray(np.dstack((img, img, img)), dtype=np.float64) 37 | img_rgb_risized = resize(img_rgb, (32, 32)) 38 | # img_rgb_risized = np.expand_dims(img_rgb_risized, axis=0) 39 | x_train_imgs.append(img_rgb_risized) 40 | # feature = conv_base.predict(img_rgb_risized).flatten() 41 | # x_train_features.append(feature) 42 | print(f'train: {i+1}/{n}') 43 | 44 | x_train_imgs = np.stack(x_train_imgs, axis=0) 45 | features = conv_base.predict(x_train_imgs) 46 | x_train_features = features[:, 0,0, :] 47 | 48 | n = len(x_test) 49 | for i in range(n): 50 | img = x_test[i] 51 | img_rgb = np.asarray(np.dstack((img, img, img)), dtype=np.float64) 52 | img_rgb_risized = resize(img_rgb, (32, 32)) 53 | # img_rgb_risized = np.expand_dims(img_rgb_risized, axis=0) 54 | x_test_imgs.append(img_rgb_risized) 55 | # feature = conv_base.predict(img_rgb_risized).flatten() 56 | # x_test_features.append(feature) 57 | print(f'test: {i+1}/{n}') 58 | 59 | x_test_imgs = np.stack(x_test_imgs, axis=0) 60 | features = conv_base.predict(x_test_imgs) 61 | x_test_features = features[:, 0,0, :] 62 | 63 | dataset = { 64 | 'x_train_features': x_train_features, 65 | 'x_test_features': x_test_features, 66 | 'y_train': y_train, 67 | 'y_test': y_test 68 | } 69 | 70 | pickle.dump( dataset, open( "mnist-features.p", "wb" ) ) 71 | 72 | pass 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /old-experiments/backprop-imagenet.py: -------------------------------------------------------------------------------- 1 | # Trains backprop on imagenet dataset 2 | # Dataset link: http://www.image-net.org/download-images 3 | # Extracted .npz files should go inside dataset/ folder 4 | # RUN THIS FROM 'examples' folder 5 | 6 | import numpy as np 7 | from matplotlib import pyplot as plt 8 | from sklearn.utils import shuffle 9 | import datetime 10 | 11 | # tensorflow etc 12 | from tensorflow import keras 13 | from tensorflow.keras import layers 14 | from tensorflow.keras.models import Sequential 15 | 16 | import sys 17 | sys.path.insert(0,'..') 18 | from snn import util 19 | 20 | # Dataset Parameters 21 | CLASSES = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] 22 | DATASET_BATCH_COUNT = 10 23 | SUB_MEAN=True 24 | IMAGE_SIZE = 32 25 | VALID_PERC = 0.2 26 | 27 | # Train parameters 28 | BATCH_SIZE = 16 29 | EPOCHS=15 30 | DATA_PERC = 0.2 31 | LR = 0.001 32 | 33 | def get_images(data, img_size, subtract_mean=False): 34 | # Returns the dataset with image format, instead of flat array 35 | # Useful for convolutional networks 36 | 37 | # Normalize 38 | data = data/np.float32(255) 39 | 40 | if subtract_mean: 41 | mean_image = np.mean(data, axis=0) 42 | data -= mean_image 43 | 44 | img_size2 = img_size * img_size 45 | 46 | data = np.dstack((data[:, :img_size2], data[:, img_size2:2*img_size2], data[:, 2*img_size2:])) 47 | data = data.reshape((x.shape[0], img_size, img_size, 3)).transpose(0, 1, 2, 3) 48 | 49 | return data 50 | 51 | def select_classes(x,y, CLASSES): 52 | indices = [] 53 | for label in CLASSES: 54 | rows = [i for i, x in enumerate(y) if x == label] 55 | indices.extend(rows) 56 | 57 | x = x[indices, :] 58 | y = y[indices] 59 | 60 | return x, y 61 | 62 | # Load data 63 | dataset = None 64 | multiple_files = True 65 | y =np.zeros((0,)) 66 | x = np.zeros((0,IMAGE_SIZE*IMAGE_SIZE*3)) 67 | 68 | if multiple_files: 69 | count = 6# set to 10 when training on the full dataset 70 | prefix = 'train_data_batch_' 71 | for i in range(1, count+1): 72 | name = prefix + str(i) + '.npz' 73 | dataset = np.load('../datasets/'+name) 74 | x_batch = dataset['data'] 75 | y_batch = dataset['labels'] 76 | 77 | # Select only certain classes 78 | x_batch,y_batch = select_classes(x_batch,y_batch, CLASSES) 79 | 80 | y = np.concatenate([y, y_batch], axis=0) 81 | x = np.concatenate([x, x_batch], axis=0) 82 | 83 | else: 84 | dataset = np.load('../datasets/val_data.npz') 85 | x = dataset['data'] 86 | y = dataset['labels'] 87 | 88 | # Select only certain classes 89 | x,y = select_classes(x,y, CLASSES) 90 | 91 | # Subtract 1 from labels 92 | y = np.array([i-1 for i in y]) 93 | 94 | # Shuffle 95 | x, y = shuffle(x, y) 96 | 97 | # Convert x to images (optional, use for convolutions) 98 | x = get_images(x, IMAGE_SIZE, subtract_mean=SUB_MEAN) 99 | if not SUB_MEAN: 100 | # show image sample 101 | plt.imshow(x[0], interpolation='nearest') 102 | plt.show() 103 | 104 | # Separate train and validation data 105 | x_train = [] 106 | y_train = [] 107 | x_valid = [] 108 | y_valid = [] 109 | if VALID_PERC <= 1.0 and VALID_PERC>0: 110 | train_index = int(x.shape[0]*(1-VALID_PERC)) 111 | x_train = x[:int(train_index*DATA_PERC)] 112 | y_train = y[:int(train_index*DATA_PERC)] 113 | x_valid = x[train_index:] 114 | y_valid = y[train_index:] 115 | 116 | # One hot encode y 117 | num_classes = len(CLASSES) 118 | y_train = keras.utils.to_categorical(y_train, num_classes) 119 | y_valid = keras.utils.to_categorical(y_valid, num_classes) 120 | 121 | # Define model 122 | model = Sequential([ 123 | layers.Input(shape=(IMAGE_SIZE,IMAGE_SIZE,3)), 124 | layers.Conv2D(64, 3, padding='same', activation='relu'), 125 | layers.MaxPooling2D(), 126 | layers.Conv2D(128, 3, padding='same', activation='relu'), 127 | layers.MaxPooling2D(), 128 | layers.Conv2D(256, 3, padding='same', activation='relu'), 129 | layers.Conv2D(256, 3, padding='same', activation='relu'), 130 | layers.MaxPooling2D(), 131 | layers.Conv2D(512, 3, padding='same', activation='relu'), 132 | layers.MaxPooling2D(), 133 | layers.Flatten(), 134 | layers.Dense(1024, activation='relu'), 135 | layers.Dropout(0.3), 136 | # layers.Dense(500, activation='relu'), 137 | # layers.Dropout(0.3), 138 | layers.Dense(num_classes, activation='softmax') 139 | ]) 140 | 141 | opt = keras.optimizers.Adam(learning_rate=LR) 142 | model.compile(optimizer=opt, 143 | loss=keras.losses.CategoricalCrossentropy(from_logits=False), 144 | metrics=['accuracy', keras.metrics.RootMeanSquaredError()]) 145 | 146 | model.summary() 147 | 148 | # Get time before training 149 | t_start = datetime.datetime.now() 150 | print("Starting timer") 151 | 152 | result = model.fit( 153 | x=x_train, 154 | y=y_train, 155 | batch_size=BATCH_SIZE, 156 | validation_data=(x_valid,y_valid), 157 | epochs=EPOCHS 158 | ) 159 | accuracy_txt = 'accuracy' 160 | print("Train_loss=", end="", flush=True) 161 | print(result.history['root_mean_squared_error']) 162 | # print(result.history['loss']) 163 | 164 | print("Train_accuracy=", end="", flush=True) 165 | print(result.history[accuracy_txt]) 166 | 167 | print("Valid_loss=", end="", flush=True) 168 | print(result.history['val_root_mean_squared_error']) 169 | # print(result.history['val_loss']) 170 | 171 | print("Valid_accuracy=", end="", flush=True) 172 | print(result.history['val_'+accuracy_txt]) 173 | 174 | # Get time after training 175 | t_end = datetime.datetime.now() 176 | elapsedTime = (t_end - t_start ) 177 | dt_sec = elapsedTime.total_seconds() 178 | 179 | print(f"Training time per epoch: {dt_sec/EPOCHS}") 180 | -------------------------------------------------------------------------------- /old-experiments/backprop-mnist.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from tensorflow import keras 3 | import tensorflow.keras.backend as K 4 | from tensorflow.keras import layers 5 | from tensorflow.keras.callbacks import CSVLogger 6 | import datetime 7 | 8 | # Dataset Parameters 9 | NUM_CLASSES = 10 10 | IMAGE_SIZE = 28 11 | 12 | # Train parameters 13 | BATCH_SIZE = 16 14 | EPOCHS = 1 15 | DATA_PERC = 1.0 16 | 17 | 18 | def root_mean_squared_error(y_true, y_pred): 19 | return K.sqrt(K.mean(K.square(y_pred - y_true))) 20 | 21 | 22 | # the data, split between train and test sets 23 | (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data() 24 | 25 | # Scale images to the [0, 1] range 26 | x_train = x_train.astype("float32") / 255 27 | x_test = x_test.astype("float32") / 255 28 | # Make sure images have shape (28, 28, 1) 29 | x_train = np.expand_dims(x_train, -1) 30 | x_test = np.expand_dims(x_test, -1) 31 | print("x_train shape:", x_train.shape) 32 | print(x_train.shape[0], "train samples") 33 | print(x_test.shape[0], "test samples") 34 | 35 | # Train only fraction of data 36 | train_samples = x_train.shape[0] 37 | max_index = int(np.floor(train_samples*DATA_PERC)) 38 | x_train = x_train[0:max_index, ...] 39 | y_train = y_train[0:max_index, ...] 40 | 41 | # convert class vectors to binary class matrices 42 | y_train = keras.utils.to_categorical(y_train, NUM_CLASSES) 43 | y_test = keras.utils.to_categorical(y_test, NUM_CLASSES) 44 | 45 | model = keras.Sequential( 46 | [ 47 | keras.Input(shape=(IMAGE_SIZE,IMAGE_SIZE,1)), 48 | layers.Flatten(), 49 | layers.Dense(500), 50 | layers.Dense(500), 51 | layers.Dense(NUM_CLASSES, activation="softmax") 52 | ] 53 | ) 54 | 55 | model.summary() 56 | 57 | model.compile(loss = "categorical_crossentropy", 58 | optimizer="adam", 59 | metrics=["accuracy", keras.metrics.RootMeanSquaredError()]) 60 | 61 | # Get time before training 62 | t_start = datetime.datetime.now() 63 | print("Starting timer") 64 | 65 | result = model.fit(x_train, 66 | y_train, 67 | batch_size=BATCH_SIZE, 68 | epochs=EPOCHS, 69 | validation_data=(x_test, y_test)) 70 | 71 | print("Train_loss=", end="", flush=True) 72 | print(result.history['loss']) 73 | 74 | print("Train_accuracy=", end="", flush=True) 75 | print(result.history['accuracy']) 76 | 77 | print("Valid_loss=", end="", flush=True) 78 | print(result.history['val_loss']) 79 | 80 | print("Valid_accuracy=", end="", flush=True) 81 | print(result.history['val_accuracy']) 82 | 83 | # Get time after training 84 | t_end = datetime.datetime.now() 85 | elapsedTime = (t_end - t_start ) 86 | dt_sec = elapsedTime.total_seconds() 87 | 88 | print(f"Training time per epoch: {dt_sec/EPOCHS}") 89 | -------------------------------------------------------------------------------- /old-experiments/features-imagenet.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/old-experiments/features-imagenet.py -------------------------------------------------------------------------------- /old-experiments/features-pc-imagenet.py: -------------------------------------------------------------------------------- 1 | import tensorflow 2 | import numpy as np 3 | import pickle 4 | import datetime 5 | 6 | import sys 7 | sys.path.insert(0,'..') 8 | from snn.PcTorch import PcTorch 9 | from snn import util 10 | 11 | # Dataset Parameters 12 | NUM_CLASSES = 20 13 | FEATURES_PATH = '../feature-extractor/imagenet-features.p' 14 | 15 | # Train parameters 16 | NETWORK_ARCHITECTURE = [512,1024,NUM_CLASSES] 17 | BATCH_SIZE = 16 18 | EPOCHS = 15 19 | DATA_PERC = 0.2 20 | INFERENCE_STEPS = 40 21 | OPTIMIZER = 'adam' 22 | ACTIVATION='sigmoid' 23 | LR = 0.001 24 | 25 | # Load features 26 | file = open(FEATURES_PATH,'rb') 27 | features = pickle.load(file) 28 | x_train = features['x_train_features'] 29 | x_test = features['x_test_features'] 30 | y_train = features['y_train'] 31 | y_test = features['y_test'] 32 | 33 | # One hot encode labels 34 | # (features already one hot encoded) 35 | 36 | # turn labels into list 37 | y_train_list = [] 38 | y_test_list = [] 39 | for i in range(len(y_train)): 40 | y_train_list.append(y_train[i].flatten()) 41 | 42 | for i in range(len(y_test)): 43 | y_test_list.append(y_test[i].flatten()) 44 | 45 | # turn features into list 46 | x_train_list = [] 47 | x_test_list = [] 48 | for i in range(len(x_train)): 49 | x_train_list.append(x_train[i].flatten().astype(np.float)) 50 | 51 | for i in range(len(x_test)): 52 | x_test_list.append(x_test[i].flatten().astype(np.float)) 53 | 54 | # normalize dataset 55 | x_train_list, mi, ma = util.normalize_dataset(x_train_list) 56 | x_test_list, mi, ma = util.normalize_dataset(x_test_list) 57 | 58 | # Get time before training 59 | t_start = datetime.datetime.now() 60 | print("Starting timer") 61 | 62 | # Initialize network and train 63 | model_torch = PcTorch(NETWORK_ARCHITECTURE) 64 | model_torch.train( 65 | x_train_list, 66 | y_train_list, 67 | x_test_list, 68 | y_test_list, 69 | batch_size=BATCH_SIZE, 70 | epochs=EPOCHS, 71 | max_it=INFERENCE_STEPS, 72 | optmizer=OPTIMIZER, 73 | activation=ACTIVATION, 74 | dataset_perc = DATA_PERC, 75 | learning_rate=LR 76 | ) 77 | 78 | # Get time after training 79 | t_end = datetime.datetime.now() 80 | elapsedTime = (t_end - t_start ) 81 | dt_sec = elapsedTime.total_seconds() 82 | 83 | print(f"Training time per epoch: {dt_sec/EPOCHS}") 84 | 85 | -------------------------------------------------------------------------------- /old-experiments/features-pc-mnist.py: -------------------------------------------------------------------------------- 1 | import tensorflow 2 | import numpy as np 3 | import pickle 4 | import datetime 5 | 6 | import sys 7 | sys.path.insert(0,'..') 8 | from snn.PcTorch import PcTorch 9 | from snn import util 10 | 11 | NETWORK_ARCHITECTURE = [512,500,500,10] 12 | BATCH_SIZE = 16 13 | EPOCHS = 1 14 | INFERENCE_STEPS = 40 15 | DATA_PERC = 1.0 16 | OPTIMIZER = 'none' 17 | OPTIMIZER = 'adam' 18 | ACTIVATION='linear' 19 | ACTIVATION='sigmoid' 20 | FEATURES_PATH = '../feature-extractor/mnist-features.p' 21 | 22 | # Load features 23 | file = open(FEATURES_PATH,'rb') 24 | features = pickle.load(file) 25 | 26 | 27 | # load dataset 28 | # might yield an error, manually download to ~/.keras/datasets/ instead 29 | 30 | x_train = features['x_train_features'] 31 | x_test = features['x_test_features'] 32 | y_train = features['y_train'] 33 | y_test = features['y_test'] 34 | 35 | # One hot encode labels 36 | # (features already one hot encoded) 37 | 38 | # turn labels into list 39 | y_train_list = [] 40 | y_test_list = [] 41 | for i in range(len(y_train)): 42 | y_train_list.append(y_train[i].flatten()) 43 | 44 | for i in range(len(y_test)): 45 | y_test_list.append(y_test[i].flatten()) 46 | 47 | # turn features into list 48 | x_train_list = [] 49 | x_test_list = [] 50 | for i in range(len(x_train)): 51 | x_train_list.append(x_train[i].flatten().astype(np.float)) 52 | 53 | for i in range(len(x_test)): 54 | x_test_list.append(x_test[i].flatten().astype(np.float)) 55 | 56 | # normalize dataset 57 | x_train_list, mi, ma = util.normalize_dataset(x_train_list) 58 | x_test_list, mi, ma = util.normalize_dataset(x_test_list) 59 | 60 | # Get time before training 61 | t_start = datetime.datetime.now() 62 | print("Starting timer") 63 | 64 | # Initialize network and train 65 | model_torch = PcTorch(NETWORK_ARCHITECTURE) 66 | model_torch.train( 67 | x_train_list, 68 | y_train_list, 69 | x_test_list, 70 | y_test_list, 71 | batch_size=BATCH_SIZE, 72 | epochs=EPOCHS, 73 | max_it=INFERENCE_STEPS, 74 | optmizer=OPTIMIZER, 75 | activation=ACTIVATION, 76 | dataset_perc = DATA_PERC 77 | ) 78 | 79 | # Get time after training 80 | t_end = datetime.datetime.now() 81 | elapsedTime = (t_end - t_start ) 82 | dt_sec = elapsedTime.total_seconds() 83 | 84 | print(f"Training time per epoch: {dt_sec/EPOCHS}") 85 | -------------------------------------------------------------------------------- /old-experiments/fen-generated-data.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | import csv 4 | import sys 5 | sys.path.insert(0,'..') 6 | 7 | from snn.FreeEnergyNetwork import FreeEnergyNetwork 8 | 9 | DATASET_FILE = '../datasets/generated_f1.csv' 10 | VALID_PERCENTAGE = 0.2 11 | NETWORK_ARCHITECTURE = [1,4,4,2] 12 | INFERENCE_STEPS = 30 13 | EPOCHS = 60 14 | 15 | # Reads csv, first 2 columns are X, last column is Y 16 | def read_csv(file): 17 | x_data, y_data= [],[] 18 | with open(file, newline='') as csvfile: 19 | reader = csv.reader(csvfile, delimiter=',', quotechar='"') 20 | next(reader) # skip first line 21 | for row in reader: 22 | x_data.append( 23 | np.array([ float(row[0]), float(row[1]) ]) 24 | ) 25 | 26 | y_data.append( 27 | np.array([ float(row[2]) ]) 28 | ) 29 | 30 | return x_data, y_data 31 | 32 | # Read data 33 | x, y = read_csv(DATASET_FILE) 34 | 35 | # Shuffle 36 | data = list(zip(x, y)) 37 | random.shuffle(data) 38 | x,y = zip(*data) 39 | 40 | # Train and validation data 41 | train_perc = (1-VALID_PERCENTAGE) 42 | x_train = x[0:int(train_perc*len(x))] 43 | y_train = y[0:int(train_perc*len(y))] 44 | x_valid = x[int(train_perc*len(x)):-1] 45 | y_valid = y[int(train_perc*len(y)):-1] 46 | 47 | # Initialize network 48 | model = FreeEnergyNetwork(NETWORK_ARCHITECTURE) 49 | model.compute_normalization(x,y) 50 | model.train(x_train,y_train,INFERENCE_STEPS, EPOCHS, x_valid=x_valid, y_valid=y_valid) 51 | 52 | model.unlock_output() 53 | index = 2 54 | input = x_valid[index] 55 | output = y_valid[index] 56 | model.setInput(x_valid[index]) 57 | model.inference_loop(INFERENCE_STEPS) 58 | y_hat = model.getOutput() 59 | print(f"Input: {input}, output: {y_hat}, desired: {output}") 60 | 61 | index = 5 62 | input = x_valid[index] 63 | output = y_valid[index] 64 | model.setInput(input) 65 | model.inference_loop(INFERENCE_STEPS) 66 | y_hat = model.getOutput() 67 | print(f"Input: {input}, output: {y_hat}, desired: {output}") -------------------------------------------------------------------------------- /old-experiments/fen-inference.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sys 3 | sys.path.insert(0,'..') 4 | 5 | from snn.FreeEnergyNetwork import FreeEnergyNetwork 6 | 7 | ''' 8 | Shows how to train the network and test it using the inference_loop() function for a very limited dataset. 9 | 10 | ''' 11 | 12 | # Network architecture and parameters 13 | neurons_per_layer = [2, 3, 2] 14 | inference_steps = 70 15 | update_weights_steps = 5 16 | epochs = 12 17 | 18 | # Training data 19 | inputs = [ 20 | np.array([1.0,2.0]), 21 | np.array([0.2,1.1]), 22 | np.array([0.8,-1.5]), 23 | np.array([0.7,-1.2]) 24 | ] 25 | outputs = [ 26 | np.array([1.8,4.0]), 27 | np.array([0.4,2.2]), 28 | np.array([1.6,-3.0]), 29 | np.array([1.4,-2.4]) 30 | ] 31 | 32 | # Visualization 33 | record_neurons_x = [(0,1), (0,2), (2,1), (2,2)] # neurons to be recorded 34 | record_neurons_e = [] 35 | 36 | # Define model 37 | model = FreeEnergyNetwork(neurons_per_layer) 38 | model.record_neurons(record_neurons_x, record_neurons_e) 39 | model.compute_normalization(inputs, outputs) 40 | 41 | ''' 42 | Training loop is: 43 | 44 | for all EPOCHS: 45 | for all DATA: 46 | set input 47 | set output 48 | 49 | inference loop 50 | update weights 51 | 52 | ''' 53 | 54 | # Initial relaxation 55 | model.setInput(inputs[0]) 56 | model.inference_loop(inference_steps) 57 | 58 | for e in range(epochs): 59 | for i in range(len(inputs)): 60 | model.setInput(inputs[i]) 61 | model.setOutput(outputs[i]) 62 | model.inference_loop(inference_steps) 63 | model.updateWeights() 64 | 65 | # Plot results 66 | model.plot_recording() 67 | 68 | # Test output 69 | index = 0 70 | model.setInput(inputs[index]) 71 | model.unlock_output() 72 | model.inference_loop(inference_steps) 73 | model.unlock_output() 74 | model.inference_loop(inference_steps) 75 | print(f"Input: {inputs[index]}, output: {model.getOutput()}") 76 | 77 | index = 1 78 | model.setInput(inputs[index]) 79 | model.unlock_output() 80 | model.inference_loop(inference_steps) 81 | model.unlock_output() 82 | model.inference_loop(inference_steps) 83 | print(f"Input: {inputs[index]}, output: {model.getOutput()}") 84 | 85 | # Plot results 86 | model.plot_recording() 87 | 88 | -------------------------------------------------------------------------------- /old-experiments/pc-imagenet.py: -------------------------------------------------------------------------------- 1 | # Trains backprop on imagenet dataset 2 | # Dataset link: http://www.image-net.org/download-images 3 | # Extracted .npz files should go inside dataset/ folder 4 | # RUN THIS FROM 'examples' folder 5 | 6 | import numpy as np 7 | from matplotlib import pyplot as plt 8 | from sklearn.utils import shuffle 9 | import datetime 10 | 11 | # tensorflow etc 12 | from tensorflow import keras 13 | from tensorflow.keras import layers 14 | from tensorflow.keras.models import Sequential 15 | 16 | import sys 17 | sys.path.insert(0,'..') 18 | from snn.PcTorch import PcTorch 19 | from snn import util 20 | 21 | # Dataset Parameters 22 | CLASSES = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] 23 | NUM_CLASSES = len(CLASSES) 24 | DATASET_BATCH_COUNT = 10 25 | SUB_MEAN=False # sigmoid doesn't work if subtract mean 26 | IMAGE_SIZE = 32 27 | VALID_PERC = 0.2 28 | 29 | # Train parameters 30 | NETWORK_ARCHITECTURE = [3072, 500, 500, NUM_CLASSES] 31 | BATCH_SIZE = 16 32 | EPOCHS=15 33 | DATA_PERC = 0.2 34 | INFERENCE_STEPS = 40 35 | OPTIMIZER = 'adam' 36 | ACTIVATION='sigmoid' 37 | LR = 0.001 38 | 39 | def select_classes(x,y, CLASSES): 40 | indices = [] 41 | for label in CLASSES: 42 | rows = [i for i, x in enumerate(y) if x == label] 43 | indices.extend(rows) 44 | 45 | x = x[indices, :] 46 | y = y[indices] 47 | 48 | return x, y 49 | 50 | # Load data 51 | dataset = None 52 | multiple_files = True 53 | y =np.zeros((0,)) 54 | x = np.zeros((0,IMAGE_SIZE*IMAGE_SIZE*3)) 55 | 56 | if multiple_files: 57 | count = DATASET_BATCH_COUNT # set to 10 when training on the full dataset 58 | prefix = 'train_data_batch_' 59 | for i in range(1, count+1): 60 | name = prefix + str(i) + '.npz' 61 | dataset = np.load('../datasets/imagenet-32x32/'+name) 62 | x_batch = dataset['data'] 63 | y_batch = dataset['labels'] 64 | 65 | # Select only certain classes 66 | x_batch,y_batch = select_classes(x_batch,y_batch, CLASSES) 67 | 68 | y = np.concatenate([y, y_batch], axis=0) 69 | x = np.concatenate([x, x_batch], axis=0) 70 | 71 | else: 72 | dataset = np.load('../datasets/val_data.npz') 73 | x = dataset['data'] 74 | y = dataset['labels'] 75 | 76 | # Select only certain classes 77 | x,y = select_classes(x,y, CLASSES) 78 | 79 | # Subtract 1 from labels 80 | y = np.array([i-1 for i in y]) 81 | 82 | # Shuffle 83 | x, y = shuffle(x, y) 84 | 85 | # Subtract mean, normalize... 86 | x = x/np.float32(255) 87 | if SUB_MEAN: 88 | mean_image = np.mean(x, axis=0) 89 | x -= mean_image 90 | 91 | # Separate train and validation data 92 | x_train = [] 93 | y_train = [] 94 | x_valid = [] 95 | y_valid = [] 96 | if VALID_PERC <= 1.0 and VALID_PERC>0: 97 | train_index = int(x.shape[0]*(1-VALID_PERC)) 98 | x_train = x[:train_index] 99 | y_train = y[:train_index] 100 | x_valid = x[train_index:] 101 | y_valid = y[train_index:] 102 | 103 | # One hot encode y 104 | num_classes = len(CLASSES) 105 | y_train = keras.utils.to_categorical(y_train, num_classes) 106 | y_valid = keras.utils.to_categorical(y_valid, num_classes) 107 | 108 | # turn labels into list 109 | y_train_list = [] 110 | y_valid_list = [] 111 | for i in range(len(y_train)): 112 | y_train_list.append(y_train[i].flatten()) 113 | 114 | for i in range(len(y_valid)): 115 | y_valid_list.append(y_valid[i].flatten()) 116 | 117 | # Flatten images 118 | x_train_list = [] 119 | x_valid_list = [] 120 | for i in range(len(x_train)): 121 | x_train_list.append(x_train[i].flatten().astype(np.float)) 122 | 123 | for i in range(len(x_valid)): 124 | x_valid_list.append(x_valid[i].flatten().astype(np.float)) 125 | 126 | # Get time before training 127 | t_start = datetime.datetime.now() 128 | print("Starting timer") 129 | 130 | # Initialize network and train 131 | model_torch = PcTorch(NETWORK_ARCHITECTURE) 132 | model_torch.train( 133 | x_train_list, 134 | y_train_list, 135 | x_valid_list, 136 | y_valid_list, 137 | batch_size=BATCH_SIZE, 138 | epochs=EPOCHS, 139 | max_it=INFERENCE_STEPS, 140 | optimizer=OPTIMIZER, 141 | activation=ACTIVATION, 142 | dataset_perc = DATA_PERC 143 | ) 144 | 145 | # Get time after training 146 | t_end = datetime.datetime.now() 147 | elapsedTime = (t_end - t_start ) 148 | dt_sec = elapsedTime.total_seconds() 149 | 150 | print(f"Training time per epoch: {dt_sec/EPOCHS}") 151 | -------------------------------------------------------------------------------- /old-experiments/pc-mnist.py: -------------------------------------------------------------------------------- 1 | import tensorflow 2 | from tensorflow.keras.datasets import mnist 3 | import numpy as np 4 | import matplotlib.pyplot as plt # Visualization 5 | import datetime 6 | 7 | import sys 8 | sys.path.insert(0,'..') 9 | from snn.PcTorch import PcTorch 10 | from snn import util 11 | 12 | # Dataset Parameters 13 | NUM_CLASSES = 10 14 | 15 | # Train parameters 16 | NETWORK_ARCHITECTURE = [784,500,500,NUM_CLASSES] 17 | BATCH_SIZE = 16 18 | EPOCHS = 1 19 | DATA_PERC = 1.0 20 | INFERENCE_STEPS = 40 21 | OPTIMIZER = 'adam' 22 | ACTIVATION='sigmoid' 23 | LR = 0.001 24 | 25 | # load dataset 26 | # might yield an error, manually download to ~/.keras/datasets/ instead 27 | (x_train, y_train),(x_test, y_test) = mnist.load_data() 28 | 29 | # One hot encode labels 30 | y_train = util.indices_to_one_hot(y_train, 10) 31 | y_test = util.indices_to_one_hot(y_test, 10) 32 | 33 | # turn labels into list 34 | y_train_list = [] 35 | y_test_list = [] 36 | for i in range(len(y_train)): 37 | y_train_list.append(y_train[i].flatten()) 38 | 39 | for i in range(len(y_test)): 40 | y_test_list.append(y_test[i].flatten()) 41 | 42 | # Flatten images 43 | x_train_list = [] 44 | x_test_list = [] 45 | for i in range(len(x_train)): 46 | x_train_list.append(x_train[i].flatten().astype(np.float)) 47 | 48 | for i in range(len(x_test)): 49 | x_test_list.append(x_test[i].flatten().astype(np.float)) 50 | 51 | # normalize dataset 52 | x_train_list, mi, ma = util.normalize_dataset(x_train_list) 53 | x_test_list, mi, ma = util.normalize_dataset(x_test_list) 54 | 55 | # Get time before training 56 | t_start = datetime.datetime.now() 57 | print("Starting timer") 58 | 59 | # Initialize network and train 60 | model_torch = PcTorch(NETWORK_ARCHITECTURE) 61 | model_torch.train( 62 | x_train_list, 63 | y_train_list, 64 | x_test_list, 65 | y_test_list, 66 | batch_size=BATCH_SIZE, 67 | epochs=EPOCHS, 68 | max_it=INFERENCE_STEPS, 69 | optmizer=OPTIMIZER, 70 | activation=ACTIVATION, 71 | dataset_perc = DATA_PERC, 72 | learning_rate=LR 73 | ) 74 | 75 | # Get time after training 76 | t_end = datetime.datetime.now() 77 | elapsedTime = (t_end - t_start ) 78 | dt_sec = elapsedTime.total_seconds() 79 | 80 | print(f"Training time per epoch: {dt_sec/EPOCHS}") 81 | -------------------------------------------------------------------------------- /results/ImageNet_1000_classes_224x224/.gitignore: -------------------------------------------------------------------------------- 1 | *.txt -------------------------------------------------------------------------------- /results/ImageNet_1000_classes_224x224/scripts/benchmark.m: -------------------------------------------------------------------------------- 1 | graph_title_text = "Varying Network Depth"; 2 | 3 | 4 | backprop_train_acc = [0.776, 0.807, 0.809, 0.807, 0.806, 0.804, 0.803, 0.801, 0.8, 0.799, 0.799, 0.799, 0.798, 0.798, 0.798, 0.797, 0.798, 0.797, 0.797, 0.798] 5 | backprop_val_acc = [0.766, 0.767, 0.761, 0.762, 0.758, 0.755, 0.755, 0.754, 0.752, 0.749, 0.755, 0.748, 0.749, 0.755, 0.751, 0.748, 0.747, 0.747, 0.747, 0.748] 6 | pc_train_acc = [0.736, 0.821, 0.83, 0.834, 0.837, 0.839, 0.841, 0.843, 0.844, 0.845, 0.847, 0.847, 0.848, 0.849, 0.849, 0.851, 0.851, 0.852, 0.852, 0.853] 7 | pc_val_acc = [0.772, 0.777, 0.779, 0.78, 0.781, 0.782, 0.783, 0.783, 0.784, 0.783, 0.783, 0.781, 0.782, 0.782, 0.782, 0.782, 0.782, 0.784, 0.782, 0.782] 8 | 9 | 10 | % Backpropagation 11 | % Val accuracy 12 | plot(backprop_val_acc*100, 'LineWidth',2) 13 | hold on 14 | 15 | % Train accuracy 16 | plot(backprop_train_acc*100, ':','LineWidth',2); 17 | 18 | hold on 19 | 20 | % PC 21 | % Valid accuracy 22 | plot(pc_val_acc*100,'LineWidth',2); 23 | hold on 24 | 25 | % Train accuracy 26 | plot(pc_train_acc*100, ':','LineWidth',2); 27 | hold on 28 | 29 | hold off 30 | 31 | legend('legend1', 'legend2', 'legend3', 'legend4', 'FontSize', 12, 'Location','southeast') 32 | 33 | title('Predictive Coding Accuracy', 'FontSize', 13) 34 | xlabel('Epoch', 'FontSize', 13) 35 | ylabel('Loss', 'FontSize', 13) 36 | 37 | % Set plot 2 ranges 38 | set(gca,'XTick',1:2:20); 39 | axis([1 20 50 100]) 40 | 41 | 42 | % No scientific notation 43 | % h = plot(Valid_loss_feat, ':','LineWidth',2); 44 | % ax = ancestor(h, 'axes'); 45 | % ax.XAxis.Exponent = 0; 46 | xtickformat('%.0f'); 47 | 48 | % Padronize window size 49 | x0=100; 50 | y0=50; 51 | width=1200; 52 | height=600; 53 | set(gcf,'position',[x0,y0,width,height]) 54 | 55 | sgtitle(graph_title_text, 'FontSize', 15) 56 | 57 | 58 | -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/.gitignore: -------------------------------------------------------------------------------- 1 | *.txt -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/scripts/outputs/vary_depth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/results/ImageNet_50_classes_224x224/scripts/outputs/vary_depth.png -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/scripts/outputs/vary_lr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/results/ImageNet_50_classes_224x224/scripts/outputs/vary_lr.png -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/scripts/outputs/vary_optimizer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/results/ImageNet_50_classes_224x224/scripts/outputs/vary_optimizer.png -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/scripts/outputs/vary_width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/results/ImageNet_50_classes_224x224/scripts/outputs/vary_width.png -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/scripts/vary_depth.m: -------------------------------------------------------------------------------- 1 | graph_title_text = "Varying Network Depth"; 2 | 3 | backprop_train_acc_1 = [0.01] 4 | backprop_val_acc_1= [0.01] 5 | pc_train_acc_1= [0.01] 6 | pc_val_acc_1= [0.01] 7 | 8 | % exp _2 9 | backprop_train_acc_2 = [0.925, 0.948, 0.952, 0.954, 0.955, 0.955, 0.958, 0.956, 0.956, 0.957, 0.958, 0.957, 0.957, 0.958, 0.959, 0.959, 0.96, 0.959, 0.958, 0.959] 10 | backprop_val_acc_2 = [0.911, 0.918, 0.923, 0.919, 0.918, 0.92, 0.922, 0.919, 0.919, 0.922, 0.921, 0.924, 0.921, 0.92, 0.924, 0.922, 0.916, 0.921, 0.919, 0.92] 11 | pc_train_acc_2 = [0.925, 0.953, 0.956, 0.959, 0.96, 0.961, 0.963, 0.964, 0.963, 0.965, 0.966, 0.965, 0.966, 0.968, 0.967, 0.968, 0.969, 0.969, 0.969, 0.969] 12 | pc_val_acc_2 = [0.92, 0.926, 0.927, 0.924, 0.925, 0.925, 0.922, 0.926, 0.923, 0.924, 0.923, 0.923, 0.924, 0.923, 0.924, 0.925, 0.922, 0.923, 0.924, 0.922] 13 | 14 | % exp _3 15 | backprop_train_acc_3 = [0.893, 0.943, 0.948, 0.947, 0.95, 0.952, 0.951, 0.951, 0.951, 0.953, 0.953, 0.955, 0.955, 0.954, 0.953, 0.955, 0.955, 0.956, 0.956, 0.955] 16 | backprop_val_acc_3 = [0.905, 0.913, 0.911, 0.911, 0.909, 0.916, 0.908, 0.908, 0.912, 0.915, 0.913, 0.911, 0.911, 0.911, 0.916, 0.911, 0.911, 0.913, 0.909, 0.91] 17 | pc_train_acc_3 = [0.834, 0.955, 0.958, 0.959, 0.962, 0.964, 0.964, 0.964, 0.964, 0.967, 0.966, 0.966, 0.967, 0.967, 0.967, 0.966, 0.968, 0.968, 0.969, 0.967] 18 | pc_val_acc_3 = [0.921, 0.918, 0.916, 0.916, 0.919, 0.92, 0.916, 0.918, 0.92, 0.92, 0.919, 0.915, 0.918, 0.916, 0.917, 0.918, 0.916, 0.918, 0.919, 0.91] 19 | 20 | % exp _4 21 | backprop_train_acc_4 = [0.822, 0.922, 0.93, 0.934, 0.936, 0.94, 0.94, 0.942, 0.944, 0.944, 0.945, 0.946, 0.947, 0.948, 0.948, 0.948, 0.949, 0.949, 0.95, 0.95] 22 | backprop_val_acc_4 = [0.89, 0.898, 0.897, 0.907, 0.909, 0.902, 0.904, 0.91, 0.91, 0.906, 0.913, 0.908, 0.911, 0.906, 0.91, 0.913, 0.908, 0.909, 0.91, 0.905] 23 | pc_train_acc_4 = [0.237, 0.886, 0.943, 0.948, 0.952, 0.955, 0.955, 0.958, 0.958, 0.958, 0.958, 0.96, 0.961, 0.961, 0.962, 0.962, 0.964, 0.964, 0.963, 0.963] 24 | pc_val_acc_4 = [0.668, 0.904, 0.913, 0.915, 0.917, 0.912, 0.918, 0.914, 0.917, 0.918, 0.919, 0.919, 0.918, 0.916, 0.915, 0.919, 0.917, 0.917, 0.905, 0.913] 25 | 26 | % exp _5 27 | backprop_train_acc_5 = [0.705, 0.894, 0.91, 0.918, 0.924, 0.928, 0.931, 0.934, 0.935, 0.935, 0.937, 0.939, 0.94, 0.943, 0.941, 0.943, 0.942, 0.944, 0.944, 0.944] 28 | backprop_val_acc_5 = [0.849, 0.871, 0.886, 0.891, 0.897, 0.899, 0.892, 0.902, 0.902, 0.898, 0.9, 0.896, 0.901, 0.901, 0.902, 0.908, 0.905, 0.896, 0.903, 0.904] 29 | pc_train_acc_5 = [0.02, 0.02, 0.021, 0.021, 0.02, 0.021, 0.02, 0.02, 0.021, 0.019, 0.021, 0.021, 0.02, 0.021, 0.019, 0.021, 0.02, 0.019, 0.02, 0.02] 30 | pc_val_acc_5 = [0.021, 0.021, 0.019, 0.021, 0.019, 0.018, 0.021, 0.02, 0.02, 0.019, 0.022, 0.02, 0.019, 0.021, 0.019, 0.02, 0.02, 0.023, 0.021, 0.021] 31 | 32 | % exp _6 33 | backprop_train_acc_6 = [0.595, 0.859, 0.887, 0.903, 0.909, 0.917, 0.92, 0.925, 0.924, 0.929, 0.93, 0.932, 0.933, 0.935, 0.937, 0.938, 0.938, 0.938, 0.94, 0.941] 34 | backprop_val_acc_6 = [0.828, 0.862, 0.885, 0.882, 0.885, 0.882, 0.896, 0.892, 0.899, 0.901, 0.898, 0.903, 0.908, 0.905, 0.905, 0.907, 0.915, 0.905, 0.907, 0.911] 35 | pc_train_acc_6 = [0.02, 0.021, 0.02, 0.022, 0.019, 0.02, 0.02, 0.021, 0.021, 0.021, 0.021, 0.02, 0.02, 0.021, 0.019, 0.019, 0.02, 0.021, 0.019, 0.019] 36 | pc_val_acc_6 = [0.02, 0.021, 0.022, 0.02, 0.02, 0.021, 0.018, 0.02, 0.021, 0.019, 0.018, 0.02, 0.02, 0.022, 0.021, 0.02, 0.02, 0.02, 0.022, 0.02] 37 | 38 | 39 | 40 | subplot(1,2,1); 41 | 42 | % Backpropagation 43 | % Val accuracy 44 | plot(backprop_val_acc_2*100, 'LineWidth',2) 45 | hold on 46 | 47 | plot(backprop_val_acc_3*100, 'LineWidth',2); 48 | hold on 49 | 50 | plot(backprop_val_acc_4*100, 'LineWidth',2); 51 | hold on 52 | 53 | plot(backprop_val_acc_5*100, 'LineWidth',2); 54 | hold on 55 | 56 | plot(backprop_val_acc_6*100, 'LineWidth',2); 57 | hold on 58 | 59 | % Train accuracy 60 | plot(backprop_train_acc_2*100, ':','LineWidth',2); 61 | hold on 62 | 63 | plot(backprop_train_acc_3*100, ':','LineWidth',2); 64 | hold on 65 | 66 | plot(backprop_train_acc_4*100, ':','LineWidth',2); 67 | hold on 68 | 69 | plot(backprop_train_acc_5*100, ':','LineWidth',2) 70 | hold on 71 | 72 | plot(backprop_train_acc_6*100, ':','LineWidth',2) 73 | hold off 74 | 75 | 76 | title('Backpropagation Accuracy', 'FontSize', 13) 77 | xlabel('Epoch', 'FontSize', 13) 78 | ylabel('Accuracy (perc.)', 'FontSize', 13) 79 | 80 | % Set plot 1 ranges 81 | set(gca,'XTick',1:2:20); 82 | axis([1 20 50 100]) 83 | 84 | 85 | subplot(1,2,2); 86 | 87 | % PC 88 | % Valid accuracy 89 | plot(pc_val_acc_2*100,'LineWidth',2); 90 | hold on 91 | 92 | plot(pc_val_acc_3*100,'LineWidth',2); 93 | hold on 94 | 95 | plot(pc_val_acc_4*100,'LineWidth',2); 96 | hold on 97 | 98 | plot(pc_val_acc_5*100,'LineWidth',2) 99 | hold on 100 | 101 | plot(pc_val_acc_6*100,'LineWidth',2) 102 | hold on 103 | 104 | % Train accuracy 105 | plot(pc_train_acc_2*100, ':','LineWidth',2); 106 | hold on 107 | 108 | plot(pc_train_acc_3*100, ':','LineWidth',2); 109 | hold on 110 | 111 | plot(pc_train_acc_4*100, ':','LineWidth',2); 112 | hold on 113 | 114 | plot(pc_train_acc_5*100, ':','LineWidth',2) 115 | hold on 116 | 117 | plot(pc_train_acc_6*100, ':','LineWidth',2) 118 | hold off 119 | 120 | legend('2 layers (val)', '3 layers (val)','4 layers (val)','5 layers (val)', '6 layers (val)', '2 layers (train)', '3 layers (train)','4 layers (train)','5 layers (train)', '6 layers (train)', 'FontSize', 12, 'Location','southeast') 121 | 122 | title('Predictive Coding Accuracy', 'FontSize', 13) 123 | xlabel('Epoch', 'FontSize', 13) 124 | ylabel('Loss', 'FontSize', 13) 125 | 126 | % Set plot 2 ranges 127 | set(gca,'XTick',1:2:20); 128 | axis([1 20 50 100]) 129 | 130 | 131 | % No scientific notation 132 | % h = plot(Valid_loss_feat, ':','LineWidth',2); 133 | % ax = ancestor(h, 'axes'); 134 | % ax.XAxis.Exponent = 0; 135 | xtickformat('%.0f'); 136 | 137 | % Padronize window size 138 | x0=100; 139 | y0=50; 140 | width=1200; 141 | height=600; 142 | set(gcf,'position',[x0,y0,width,height]) 143 | 144 | sgtitle(graph_title_text, 'FontSize', 15) 145 | 146 | 147 | -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/scripts/vary_optimizer.m: -------------------------------------------------------------------------------- 1 | graph_title_text = "Varying Optimizer"; 2 | 3 | % exp _1 4 | backprop_train_acc_1 = [0.924, 0.948, 0.951, 0.953, 0.954, 0.954, 0.957, 0.957, 0.958, 0.958, 0.958, 0.959, 0.958, 0.958, 0.96, 0.959, 0.96, 0.959, 0.96, 0.958] 5 | backprop_val_acc_1 = [0.918, 0.919, 0.924, 0.924, 0.923, 0.921, 0.921, 0.923, 0.922, 0.922, 0.921, 0.917, 0.918, 0.918, 0.923, 0.921, 0.923, 0.919, 0.922, 0.921] 6 | pc_train_acc_1 = [0.921, 0.952, 0.955, 0.957, 0.959, 0.96, 0.962, 0.963, 0.964, 0.965, 0.965, 0.967, 0.967, 0.968, 0.967, 0.968, 0.969, 0.968, 0.969, 0.97] 7 | pc_val_acc_1 = [0.921, 0.925, 0.925, 0.923, 0.923, 0.924, 0.923, 0.924, 0.924, 0.923, 0.922, 0.922, 0.921, 0.922, 0.923, 0.919, 0.924, 0.923, 0.924, 0.922] 8 | 9 | % exp _2 10 | backprop_train_acc_2 = [0.907, 0.934, 0.94, 0.941, 0.945, 0.947, 0.948, 0.949, 0.95, 0.952, 0.954, 0.954, 0.954, 0.955, 0.955, 0.956, 0.957, 0.958, 0.959, 0.958] 11 | backprop_val_acc_2 = [0.898, 0.907, 0.908, 0.909, 0.914, 0.913, 0.916, 0.915, 0.916, 0.916, 0.913, 0.911, 0.915, 0.917, 0.912, 0.914, 0.907, 0.915, 0.915, 0.914] 12 | pc_train_acc_2 = [0.89, 0.922, 0.927, 0.931, 0.933, 0.934, 0.937, 0.938, 0.939, 0.94, 0.941, 0.942, 0.942, 0.943, 0.944, 0.944, 0.943, 0.945, 0.945, 0.945] 13 | pc_val_acc_2 = [0.894, 0.896, 0.894, 0.892, 0.897, 0.896, 0.896, 0.896, 0.897, 0.896, 0.892, 0.896, 0.893, 0.893, 0.895, 0.895, 0.895, 0.897, 0.896, 0.898] 14 | 15 | % exp _3 16 | backprop_train_acc_3 = [0.874, 0.946, 0.952, 0.955, 0.958, 0.959, 0.959, 0.96, 0.961, 0.963, 0.964, 0.964, 0.964, 0.966, 0.965, 0.966, 0.966, 0.966, 0.966, 0.967] 17 | backprop_val_acc_3 = [0.915, 0.919, 0.92, 0.925, 0.927, 0.924, 0.927, 0.928, 0.927, 0.926, 0.927, 0.926, 0.926, 0.927, 0.928, 0.926, 0.928, 0.927, 0.928, 0.927] 18 | pc_train_acc_3 = [0.826, 0.935, 0.942, 0.944, 0.948, 0.949, 0.95, 0.952, 0.951, 0.954, 0.956, 0.955, 0.956, 0.957, 0.957, 0.958, 0.958, 0.959, 0.96, 0.959] 19 | pc_val_acc_3 = [0.903, 0.909, 0.913, 0.918, 0.918, 0.918, 0.921, 0.922, 0.923, 0.924, 0.922, 0.922, 0.923, 0.924, 0.925, 0.923, 0.924, 0.924, 0.923, 0.923] 20 | 21 | % exp _4 22 | backprop_train_acc_4 = [0.742, 0.927, 0.937, 0.941, 0.945, 0.946, 0.95, 0.951, 0.951, 0.953, 0.954, 0.955, 0.954, 0.957, 0.957, 0.958, 0.957, 0.957, 0.958, 0.958] 23 | backprop_val_acc_4 = [0.892, 0.907, 0.911, 0.916, 0.917, 0.92, 0.921, 0.922, 0.923, 0.923, 0.923, 0.924, 0.926, 0.926, 0.926, 0.927, 0.928, 0.927, 0.927, 0.927] 24 | pc_train_acc_4 = [0.582, 0.889, 0.916, 0.927, 0.933, 0.935, 0.939, 0.939, 0.94, 0.942, 0.944, 0.944, 0.945, 0.943, 0.945, 0.947, 0.946, 0.946, 0.947, 0.946] 25 | pc_val_acc_4 = [0.839, 0.881, 0.897, 0.905, 0.909, 0.91, 0.912, 0.914, 0.917, 0.914, 0.913, 0.918, 0.915, 0.919, 0.918, 0.916, 0.92, 0.92, 0.918, 0.919] 26 | 27 | 28 | subplot(1,2,1); 29 | 30 | % Backpropagation 31 | % Val accuracy 32 | plot(backprop_val_acc_1*100, 'LineWidth',2) 33 | hold on 34 | 35 | plot(backprop_val_acc_2*100, 'LineWidth',2) 36 | hold on 37 | 38 | plot(backprop_val_acc_3*100, 'LineWidth',2); 39 | hold on 40 | 41 | plot(backprop_val_acc_4*100, 'LineWidth',2); 42 | hold on 43 | 44 | 45 | % Train accuracy 46 | plot(backprop_train_acc_1*100, ':','LineWidth',2); 47 | hold on 48 | 49 | plot(backprop_train_acc_2*100, ':','LineWidth',2); 50 | hold on 51 | 52 | plot(backprop_train_acc_3*100, ':','LineWidth',2); 53 | hold on 54 | 55 | plot(backprop_train_acc_4*100, ':','LineWidth',2); 56 | hold off 57 | 58 | 59 | title('Backpropagation Accuracy', 'FontSize', 13) 60 | xlabel('Epoch', 'FontSize', 13) 61 | ylabel('Accuracy (perc.)', 'FontSize', 13) 62 | 63 | % Set plot 1 ranges 64 | set(gca,'XTick',1:2:20); 65 | axis([1 20 82 100]) 66 | 67 | 68 | subplot(1,2,2); 69 | 70 | % PC 71 | % Valid accuracy 72 | plot(pc_val_acc_1*100,'LineWidth',2); 73 | hold on 74 | 75 | plot(pc_val_acc_2*100,'LineWidth',2); 76 | hold on 77 | 78 | plot(pc_val_acc_3*100,'LineWidth',2); 79 | hold on 80 | 81 | plot(pc_val_acc_4*100,'LineWidth',2); 82 | hold on 83 | 84 | 85 | % Train accuracy 86 | plot(pc_train_acc_1*100, ':','LineWidth',2); 87 | hold on 88 | 89 | plot(pc_train_acc_2*100, ':','LineWidth',2); 90 | hold on 91 | 92 | plot(pc_train_acc_3*100, ':','LineWidth',2); 93 | hold on 94 | 95 | plot(pc_train_acc_4*100, ':','LineWidth',2); 96 | hold off 97 | 98 | 99 | legend('Adam + Sigmoid (val)', 'Adam + Relu (val)','SGD + Relu (val)','SGD + Sigmoid (val)', 'Adam + Sigmoid (train)', 'Adam + Relu (train)','SGD + Relu (train)','SGD + Sigmoid (train)', 'FontSize', 12, 'Location','southeast') 100 | 101 | title('Predictive Coding Accuracy', 'FontSize', 13) 102 | xlabel('Epoch', 'FontSize', 13) 103 | ylabel('Loss', 'FontSize', 13) 104 | 105 | % Set plot 2 ranges 106 | set(gca,'XTick',1:2:20); 107 | axis([1 20 82 100]) 108 | 109 | 110 | % No scientific notation 111 | % h = plot(Valid_loss_feat, ':','LineWidth',2); 112 | % ax = ancestor(h, 'axes'); 113 | % ax.XAxis.Exponent = 0; 114 | xtickformat('%.0f'); 115 | 116 | % Padronize window size 117 | x0=100; 118 | y0=50; 119 | width=1200; 120 | height=600; 121 | set(gcf,'position',[x0,y0,width,height]) 122 | 123 | sgtitle(graph_title_text, 'FontSize', 15) 124 | 125 | 126 | -------------------------------------------------------------------------------- /results/ImageNet_50_classes_224x224/scripts/vary_width.m: -------------------------------------------------------------------------------- 1 | graph_title_text = "Varying Network Width"; 2 | 3 | % exp _1 4 | backprop_train_acc_1 = [0.901, 0.946, 0.948, 0.949, 0.95, 0.952, 0.954, 0.953, 0.955, 0.956, 0.956, 0.957, 0.956, 0.956, 0.956, 0.958, 0.958, 0.957, 0.957, 0.957] 5 | backprop_val_acc_1 = [0.922, 0.92, 0.92, 0.919, 0.923, 0.921, 0.923, 0.919, 0.923, 0.919, 0.924, 0.922, 0.922, 0.919, 0.921, 0.92, 0.918, 0.918, 0.923, 0.916] 6 | pc_train_acc_1 = [0.919, 0.95, 0.952, 0.952, 0.954, 0.955, 0.955, 0.956, 0.957, 0.958, 0.957, 0.958, 0.959, 0.959, 0.958, 0.96, 0.959, 0.96, 0.96, 0.96] 7 | pc_val_acc_1 = [0.924, 0.926, 0.926, 0.926, 0.928, 0.928, 0.927, 0.927, 0.926, 0.926, 0.924, 0.928, 0.928, 0.928, 0.928, 0.926, 0.927, 0.926, 0.925, 0.925] 8 | 9 | % exp _2 10 | backprop_train_acc_2 = [0.921, 0.949, 0.953, 0.954, 0.954, 0.955, 0.957, 0.957, 0.957, 0.957, 0.958, 0.959, 0.958, 0.96, 0.959, 0.958, 0.959, 0.96, 0.959, 0.961] 11 | backprop_val_acc_2 = [0.915, 0.922, 0.911, 0.921, 0.918, 0.923, 0.925, 0.92, 0.917, 0.919, 0.92, 0.914, 0.917, 0.917, 0.915, 0.92, 0.921, 0.917, 0.917, 0.918] 12 | pc_train_acc_2 = [0.922, 0.952, 0.955, 0.957, 0.958, 0.959, 0.961, 0.962, 0.961, 0.962, 0.964, 0.964, 0.964, 0.966, 0.965, 0.966, 0.965, 0.967, 0.966, 0.969] 13 | pc_val_acc_2 = [0.922, 0.923, 0.92, 0.923, 0.922, 0.92, 0.923, 0.923, 0.922, 0.921, 0.922, 0.919, 0.922, 0.92, 0.919, 0.921, 0.922, 0.922, 0.919, 0.924] 14 | 15 | % exp _3 16 | backprop_train_acc_3 = [0.925, 0.949, 0.953, 0.953, 0.955, 0.955, 0.955, 0.957, 0.957, 0.957, 0.958, 0.958, 0.958, 0.959, 0.957, 0.96, 0.959, 0.959, 0.96, 0.96] 17 | backprop_val_acc_3 = [0.915, 0.921, 0.924, 0.921, 0.918, 0.919, 0.927, 0.921, 0.922, 0.92, 0.92, 0.917, 0.923, 0.922, 0.922, 0.923, 0.92, 0.924, 0.923, 0.919] 18 | pc_train_acc_3 = [0.923, 0.953, 0.956, 0.958, 0.961, 0.961, 0.963, 0.963, 0.964, 0.965, 0.966, 0.966, 0.967, 0.968, 0.966, 0.969, 0.968, 0.968, 0.969, 0.97] 19 | pc_val_acc_3 = [0.923, 0.926, 0.924, 0.925, 0.925, 0.922, 0.926, 0.927, 0.926, 0.924, 0.926, 0.925, 0.926, 0.927, 0.922, 0.925, 0.924, 0.924, 0.921, 0.924] 20 | 21 | % exp _4 22 | backprop_train_acc_4 = [0.925, 0.946, 0.949, 0.951, 0.951, 0.952, 0.954, 0.955, 0.955, 0.955, 0.957, 0.956, 0.957, 0.956, 0.956, 0.957, 0.957, 0.958, 0.957, 0.959] 23 | backprop_val_acc_4 = [0.918, 0.911, 0.916, 0.917, 0.919, 0.92, 0.915, 0.918, 0.921, 0.916, 0.917, 0.921, 0.917, 0.917, 0.912, 0.918, 0.917, 0.915, 0.92, 0.922] 24 | pc_train_acc_4 = [0.915, 0.953, 0.955, 0.958, 0.96, 0.961, 0.962, 0.964, 0.964, 0.964, 0.965, 0.967, 0.968, 0.968, 0.967, 0.968, 0.969, 0.969, 0.969, 0.969] 25 | pc_val_acc_4 = [0.921, 0.92, 0.923, 0.923, 0.924, 0.925, 0.923, 0.924, 0.923, 0.919, 0.923, 0.923, 0.92, 0.922, 0.921, 0.92, 0.921, 0.923, 0.925, 0.922] 26 | 27 | % exp _5 28 | backprop_train_acc_5 = [0.919, 0.94, 0.943, 0.945, 0.949, 0.946, 0.949, 0.949, 0.95, 0.95, 0.951, 0.95, 0.952, 0.953, 0.951, 0.952, 0.952, 0.953, 0.953, 0.953] 29 | backprop_val_acc_5 = [0.915, 0.917, 0.915, 0.913, 0.916, 0.904, 0.916, 0.912, 0.912, 0.923, 0.92, 0.915, 0.922, 0.911, 0.91, 0.918, 0.917, 0.915, 0.914, 0.918] 30 | pc_train_acc_5 = [0.9, 0.951, 0.954, 0.957, 0.959, 0.96, 0.961, 0.962, 0.963, 0.964, 0.964, 0.965, 0.966, 0.968, 0.968, 0.969, 0.969, 0.969, 0.97, 0.97] 31 | pc_val_acc_5 = [0.924, 0.925, 0.923, 0.925, 0.927, 0.923, 0.925, 0.925, 0.923, 0.923, 0.925, 0.924, 0.924, 0.924, 0.921, 0.92, 0.923, 0.923, 0.921, 0.924] 32 | 33 | 34 | subplot(1,2,1); 35 | 36 | % Backpropagation 37 | % Val accuracy 38 | plot(backprop_val_acc_1*100, 'LineWidth',2) 39 | hold on 40 | 41 | plot(backprop_val_acc_2*100, 'LineWidth',2) 42 | hold on 43 | 44 | plot(backprop_val_acc_3*100, 'LineWidth',2); 45 | hold on 46 | 47 | plot(backprop_val_acc_4*100, 'LineWidth',2); 48 | hold on 49 | 50 | plot(backprop_val_acc_5*100, 'LineWidth',2); 51 | hold on 52 | 53 | % Train accuracy 54 | plot(backprop_train_acc_1*100, ':','LineWidth',2); 55 | hold on 56 | 57 | plot(backprop_train_acc_2*100, ':','LineWidth',2); 58 | hold on 59 | 60 | plot(backprop_train_acc_3*100, ':','LineWidth',2); 61 | hold on 62 | 63 | plot(backprop_train_acc_4*100, ':','LineWidth',2); 64 | hold on 65 | 66 | plot(backprop_train_acc_5*100, ':','LineWidth',2) 67 | hold off 68 | 69 | 70 | 71 | title('Backpropagation Accuracy', 'FontSize', 13) 72 | xlabel('Epoch', 'FontSize', 13) 73 | ylabel('Accuracy (perc.)', 'FontSize', 13) 74 | 75 | % Set plot 1 ranges 76 | set(gca,'XTick',1:2:20); 77 | axis([1 20 82 100]) 78 | 79 | 80 | subplot(1,2,2); 81 | 82 | % PC 83 | % Valid accuracy 84 | plot(pc_val_acc_1*100,'LineWidth',2); 85 | hold on 86 | 87 | plot(pc_val_acc_2*100,'LineWidth',2); 88 | hold on 89 | 90 | plot(pc_val_acc_3*100,'LineWidth',2); 91 | hold on 92 | 93 | plot(pc_val_acc_4*100,'LineWidth',2); 94 | hold on 95 | 96 | plot(pc_val_acc_5*100,'LineWidth',2) 97 | hold on 98 | 99 | % Train accuracy 100 | plot(pc_train_acc_1*100, ':','LineWidth',2); 101 | hold on 102 | 103 | plot(pc_train_acc_2*100, ':','LineWidth',2); 104 | hold on 105 | 106 | plot(pc_train_acc_3*100, ':','LineWidth',2); 107 | hold on 108 | 109 | plot(pc_train_acc_4*100, ':','LineWidth',2); 110 | hold on 111 | 112 | plot(pc_train_acc_5*100, ':','LineWidth',2) 113 | hold off 114 | 115 | legend('64 neurons (val)', '128 neurons (val)','256 neurons (val)','512 neurons (val)', '1024 neurons (val)', '64 neurons (train)','128 neurons (train)','256 neurons (train)', '512 neurons (train)', '1024 neurons (train)', 'FontSize', 12, 'Location','southeast') 116 | 117 | title('Predictive Coding Accuracy', 'FontSize', 13) 118 | xlabel('Epoch', 'FontSize', 13) 119 | ylabel('Loss', 'FontSize', 13) 120 | 121 | % Set plot 2 ranges 122 | set(gca,'XTick',1:2:20); 123 | axis([1 20 82 100]) 124 | 125 | 126 | % No scientific notation 127 | % h = plot(Valid_loss_feat, ':','LineWidth',2); 128 | % ax = ancestor(h, 'axes'); 129 | % ax.XAxis.Exponent = 0; 130 | xtickformat('%.0f'); 131 | 132 | % Padronize window size 133 | x0=100; 134 | y0=50; 135 | width=1200; 136 | height=600; 137 | set(gcf,'position',[x0,y0,width,height]) 138 | 139 | sgtitle(graph_title_text, 'FontSize', 15) 140 | 141 | 142 | -------------------------------------------------------------------------------- /results/old/data/MNIST-feat100-1: -------------------------------------------------------------------------------- 1 | Dataset: MNIST 2 | Data Type: Features 3 | Percentage of data: 100% 4 | Architecture: [784,500,500,10] 5 | Ativation: Sigmoid 6 | Optimizer: adam 7 | 8 | Train_loss=[0.02533634088086015, 0.018595247696627487, 0.015627765412435747, 0.013791629862278016, 0.01264401472975138, 0.011920916863483505, 0.011427630381597085, 0.010979362317752204, 0.01062525118214652, 0.01025960862125063, 0.009975654645667215, 0.009723138001495917, 0.009492068898402088, 0.009282414086413603, 0.0091583451163257] 9 | Train_accuracy=[87.685, 90.56833333333333, 92.01666666666667, 92.81833333333334, 93.31666666666666, 93.61, 93.83333333333333, 94.03833333333334, 94.22333333333334, 94.42166666666667, 94.53833333333334, 94.675, 94.81166666666667, 94.89166666666667, 95.02166666666668] 10 | Valid_loss=[0.02539761433614275, 0.017589043681223323, 0.015101464281869611, 0.013292477982219745, 0.012235061958027134, 0.011537550934974088, 0.011106268731327792, 0.010780540064734901, 0.010543022949671275, 0.010236460730039075, 0.010046285076479472, 0.009873794701150344, 0.009706055301120389, 0.009556784679067185, 0.009494440921944894] 11 | Valid_accuracy=[88.09, 91.36999999999999, 92.58, 93.24, 94.02000000000001, 94.28999999999999, 94.45, 94.58, 94.66, 94.71000000000001, 94.77, 94.88, 94.94, 94.99, 95.1] 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /results/old/data/MNIST-feat20-1: -------------------------------------------------------------------------------- 1 | Dataset: MNIST 2 | Data Type: Features 3 | Percentage of data: 20% 4 | Architecture: [784,500,500,10] 5 | Ativation: Sigmoid 6 | Optimizer: adam 7 | 8 | Train_loss= [0.04811954337277718, 0.03905975125680167, 0.03415916110449904, 0.02990436080694336, 0.02501367174137474, 0.02248602781850827, 0.02079614788691005, 0.019509411251905844, 0.018510659793052726, 0.01771066599907997, 0.01702871569318902, 0.01642770903604127, 0.01592878518926152, 0.015521637039843873, 0.015198743860136223] 9 | Train_accuracy= [72.16666666666667, 77.2, 81.11666666666667, 84.97166666666666, 88.12, 89.03666666666666, 89.63, 90.115, 90.49000000000001, 90.83666666666666, 91.17833333333333, 91.485, 91.71166666666667, 91.85333333333332, 91.975] 10 | Valid_loss= [0.0474562508132969, 0.038070567851489365, 0.03371544464295973, 0.03026735856619801, 0.0249721823425384, 0.022188707273810296, 0.020332208125882507, 0.018984774360053962, 0.01798308682077307, 0.017205876699101258, 0.01653412101851553, 0.015946624178665953, 0.015449838320010907, 0.015042737843393227, 0.014723514496820462] 11 | Valid_accuracy= [72.38, 78.78, 82.54, 85.83, 88.64999999999999, 89.89, 90.33, 90.86, 91.21000000000001, 91.67, 91.92, 92.07, 92.30000000000001, 92.41, 92.54] 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /results/old/data/MNIST-raw100-1: -------------------------------------------------------------------------------- 1 | Dataset: MNIST 2 | Data Type: Raw 3 | Percentage of data: 100% 4 | Architecture: [784,500,500,10] 5 | Ativation: Sigmoid 6 | Optimizer: adam 7 | 8 | Train_loss=[0.008832917410186767, 0.004518496031477724, 0.0031850113197128306, 0.0023707651973511527, 0.001742001177620836, 0.001351021953606554, 0.0010757665892788576, 0.0009610659502402181, 0.0007745536081790572, 0.0006024458257862261, 0.0005446291770354906, 0.003423635604168046, 0.00311656070798234, 0.001372659150710142, 0.0006909691060092005] 9 | Train_accuracy=[95.28833333333333, 97.39833333333333, 98.27666666666667, 98.78, 99.16, 99.40333333333334, 99.53999999999999, 99.59833333333333, 99.72999999999999, 99.78833333333334, 99.82833333333333, 98.75833333333334, 98.65, 99.46666666666667, 99.77000000000001] 10 | Valid_loss=[0.008980646508679753, 0.005090042920349676, 0.004143742140714181, 0.0036127023597782065, 0.003192150241271929, 0.0030159601546733113, 0.002913133600057493, 0.0029741263319949455, 0.002813968550380026, 0.0027737856869030817, 0.00277790223557955, 0.004690569033389889, 0.004772705191889265, 0.003311429348722569, 0.002916657471355432] 11 | Valid_accuracy=[95.12, 96.96000000000001, 97.49, 97.83, 97.92999999999999, 98.06, 98.15, 98.18, 98.26, 98.22999999999999, 98.25, 97.43, 97.26, 97.98, 98.26] 12 | 13 | 14 | -------------------------------------------------------------------------------- /results/old/data/MNIST-raw20-1: -------------------------------------------------------------------------------- 1 | Dataset: MNIST 2 | Data Type: Raw 3 | Percentage of data: 20% 4 | Architecture: [784,500,500,10] 5 | Ativation: Sigmoid 6 | Optimizer: adam 7 | 8 | Train_loss = [0.020453374641969994, 0.015370725833592084, 0.012185497629308128, 0.01009113577881716, 0.008487831040197534, 0.007477895833703164, 0.006697119162578446, 0.00610890602714745, 0.005664598875245947, 0.0053438196138773115, 0.005132944630909333, 0.004998643589461351, 0.004910888514378305, 0.0048573147389844185, 0.004882024128242934] 9 | Train_accuracy= [90.10000000000001, 92.16, 93.43166666666667, 94.34333333333333, 94.98833333333333, 95.46, 95.88166666666666, 96.24666666666667, 96.50333333333333, 96.68833333333333, 96.79666666666667, 96.85666666666667, 96.84833333333333, 96.82333333333332, 96.77833333333334] 10 | Valid_loss = [0.020376544405025974, 0.015404468315066778, 0.012352834022101212, 0.010382176719784088, 0.008867483838844899, 0.007948023051568946, 0.0072533019458708246, 0.006737254240031898, 0.006359610092461254, 0.006100639234881784, 0.005937007945839235, 0.005830488886348567, 0.0057610305565019, 0.005752406815580369, 0.005827648167210424] 11 | Valid_accuracy = [90.12, 92.11, 93.26, 94.11, 94.67, 95.06, 95.39999999999999, 95.67999999999999, 95.93, 96.09, 96.21, 96.37, 96.38, 96.39, 96.22] 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /snn/Dataset.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | import torchvision.transforms as transforms 4 | 5 | class Dataset(torch.utils.data.Dataset): 6 | 7 | def __init__(self, file_paths, image_size, transform=transforms.ToTensor()): 8 | 9 | # Variables to hold dataset data 10 | self.y = np.zeros((0,), dtype=np.int) 11 | self.x = np.zeros((0, image_size, image_size, 3), dtype=np.uint8) # using uint8 to fit dataset in memory 12 | self.image_size = image_size 13 | self.transform = transform 14 | 15 | # Read dataset 16 | for path in file_paths: 17 | dataset = np.load(path) 18 | x_batch = dataset['data'] 19 | y_batch = dataset['labels'] 20 | y_batch = y_batch-1 # indices 0 ... 999 21 | 22 | x_batch = self.get_images(x_batch, self.image_size) 23 | 24 | self.y = np.concatenate([self.y, y_batch], axis=0) 25 | self.x = np.concatenate([self.x, x_batch], axis=0) 26 | 27 | def __len__(self): 28 | 'Denotes the total number of samples' 29 | return self.y.shape[0] 30 | 31 | def __getitem__(self, index): 32 | 'Generates one sample of data' 33 | return self.transform(self.x[index]), self.y[index] 34 | 35 | def get_images(self, data, img_size): 36 | # Returns the dataset with image format, instead of flat array 37 | # Useful for convolutional networks 38 | 39 | # Normalize 40 | # data = data/np.float32(255) 41 | 42 | img_size2 = img_size * img_size 43 | 44 | data = np.dstack((data[:, :img_size2], data[:, img_size2:2*img_size2], data[:, 2*img_size2:])) 45 | 46 | # Tesnsorflow shape [batch_size, rows, cols, channels] 47 | data = data.reshape((data.shape[0], img_size, img_size, 3)).transpose(0, 1, 2, 3) 48 | 49 | # Pytorch shape [batch_size, channels, rows, cols] 50 | # Not necessary, image will be reshaped by transforms.ToTensor() 51 | # data = data.reshape((data.shape[0], img_size, img_size, 3)).transpose(0, 3, 1, 2).astype(np.uint8) 52 | 53 | return data -------------------------------------------------------------------------------- /snn/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbersan/Predictive-Coding-Implementation/03b87ed9bd2412e52c4c19ff7eee03dbb97f3441/snn/__init__.py -------------------------------------------------------------------------------- /snn/torch-verify-gpu.py: -------------------------------------------------------------------------------- 1 | # Verifies if torch has access to GPU 2 | # Source: https://stackoverflow.com/a/48152675/2076973 3 | 4 | import torch 5 | 6 | device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu") 7 | 8 | print(device) 9 | -------------------------------------------------------------------------------- /snn/util.py: -------------------------------------------------------------------------------- 1 | import torch.nn 2 | import torch 3 | import csv 4 | from os import system, name 5 | import numpy as np 6 | 7 | # Onehot encode a 1 dim array to 2 dim array 8 | def indices_to_one_hot(data, nb_classes): 9 | """Convert an iterable of indices to one-hot encoded labels.""" 10 | targets = np.array(data).reshape(-1) 11 | M = np.eye(nb_classes)[targets] 12 | M += 0.03 13 | return np.minimum(0.97, M) 14 | 15 | # define our clear function 16 | def clear(): 17 | 18 | # for windows 19 | if name == 'nt': 20 | _ = system('cls') 21 | 22 | # for mac and linux(here, os.name is 'posix') 23 | else: 24 | _ = system('clear') 25 | 26 | def dRelu(x): 27 | return torch.gt(x, torch.zeros(x.shape, device=x.device)).type(x.type()) 28 | 29 | def dLinear(x): 30 | return torch.ones(x.shape).type(x.type()) 31 | 32 | def dSigmoid(x): 33 | sig_x = torch.nn.Sigmoid()(x) 34 | return sig_x*(1 - sig_x) 35 | 36 | def Linear(x): 37 | return x 38 | 39 | # Pre processing functions to make algorithm stable 40 | def preLinear(x): 41 | return x 42 | 43 | def preRelu(x): 44 | return x 45 | 46 | def preSigmoid(x): 47 | return torch.log(x/(1 - x)) 48 | 49 | # Reads csv, first 2 columns are X, last column is Y 50 | def read_csv(file): 51 | x_data, y_data= [],[] 52 | with open(file, newline='') as csvfile: 53 | reader = csv.reader(csvfile, delimiter=',', quotechar='"') 54 | next(reader) # skip first line 55 | for row in reader: 56 | x_data.append( 57 | np.array([ float(row[0]), float(row[1]) ]) 58 | ) 59 | 60 | y_data.append( 61 | np.array([ float(row[2]) ]) 62 | ) 63 | 64 | return x_data, y_data 65 | 66 | def normalize_dataset(data): 67 | """Normalizes a list of numpy arrays to the interval [0,1] 68 | """ 69 | min_value = min([min(n) for n in data]) 70 | data = [array-min_value for array in data] 71 | max_value = max([max(n) for n in data]) 72 | return [array/max_value for array in data], min_value, max_value 73 | 74 | def denormalize_sample(sample, min_value, max_value): 75 | """Applies the inverse of normalization to a single sample 76 | """ 77 | return sample*max_value + min_value --------------------------------------------------------------------------------