├── spike_response.m ├── Spike_code.m ├── generate_population.m ├── population_encoding.m ├── STDP_norm.m ├── setup_SNN.m ├── README.md ├── FiringTime.m ├── train_SNN.m ├── validate.m ├── Main.m ├── iris_test_1.csv ├── iris_train_1.csv └── MC_SEFRON.m /spike_response.m: -------------------------------------------------------------------------------- 1 | function [LIF_norm] = spike_response(s,tau) 2 | x=s./tau; 3 | LIF_norm = x.*exp(1-x); 4 | 5 | LIF_norm(LIF_norm<0)=0; 6 | end 7 | 8 | -------------------------------------------------------------------------------- /Spike_code.m: -------------------------------------------------------------------------------- 1 | function Sample = Spike_code(Spike_train,class,param) 2 | 3 | Sample.Spike_Time=Spike_train; 4 | Sample.Esto=spike_response(bsxfun(@minus, param.TID,Spike_train'),param.tau); 5 | Sample.U_TID=STDP_norm((param.TID-Spike_train),param.stdp)'; 6 | Sample.class=class; 7 | 8 | end 9 | 10 | -------------------------------------------------------------------------------- /generate_population.m: -------------------------------------------------------------------------------- 1 | function Encoding_neurons = generate_population(param) 2 | RF=param.RF; 3 | dim=param.dim; 4 | overlap=param.overlap; 5 | Imin = 0; 6 | Imax = 1; 7 | Encoding_neurons.centre(1:RF*dim) = repmat((Imin+(2*(1:RF)-3)/2*(Imax-Imin)/(RF-2)),1,dim); 8 | Encoding_neurons.width(1:RF*dim) = 1/overlap*(Imax-Imin)/(RF-2); 9 | Encoding_neurons.RF=RF; 10 | end 11 | 12 | -------------------------------------------------------------------------------- /population_encoding.m: -------------------------------------------------------------------------------- 1 | function spiketime = population_encoding(Data,Encorder,param) 2 | 3 | spiketime=zeros(size(Data,1),size(Data,2)*Encorder.RF); 4 | for j=1:size(Data,1) 5 | target = reshape(repmat(Data(j,:),Encorder.RF,1),[1,Encorder.RF*size(Data,2)]); 6 | Firing_Strength = exp(-((target - Encorder.centre).^2) ./ (2*(Encorder.width.^2))); 7 | spiketime(j,:) = round(param.T*(1-Firing_Strength))+1; 8 | end 9 | 10 | end 11 | 12 | -------------------------------------------------------------------------------- /STDP_norm.m: -------------------------------------------------------------------------------- 1 | function Ut=STDP_norm(r_time,tau) 2 | stdp= exp(-abs(r_time)/tau); 3 | g=r_time; 4 | g(g>0)=1; 5 | g(g<0)=0; 6 | g=g.*stdp; 7 | pos_weight=bsxfun(@rdivide,g,sum(g)); 8 | temp=isnan(pos_weight); 9 | pos_weight(temp)=0; 10 | g=r_time; 11 | g(g>0)=0; 12 | g(g<0)=1; 13 | g=g.*stdp; 14 | neg_weight=-1*bsxfun(@rdivide,g,sum(g)); 15 | temp=isnan(neg_weight); 16 | neg_weight(temp)=0; 17 | 18 | Ut=pos_weight+neg_weight; 19 | end 20 | -------------------------------------------------------------------------------- /setup_SNN.m: -------------------------------------------------------------------------------- 1 | function model= setup_SNN(opts) 2 | 3 | model.RF = opts.RF; 4 | model.sigma =opts.efficacy_update_range/opts.precision; 5 | model.l_rate=opts.learning_rate; 6 | model.T = opts.Pre/opts.precision; 7 | model.TOID = opts.Post/opts.precision; 8 | model.t_train=0:1:model.T; 9 | model.no_epoch=opts.epoch; 10 | model.fun=@(A,B) exp(-(A-B).^2/(2*model.sigma^2)); 11 | model.TID = opts.Desired /opts.precision; 12 | model.tau = opts.tau/opts.precision; 13 | model.overlap=0.7; 14 | model.stdp= opts.stdp/opts.precision; 15 | model.Tm = 0.05/opts.precision; 16 | model.Td = model.TID; 17 | end 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MC-SEFRON 2 | 3 | A Matlab toolbox for Spiking Neural Network. 4 | 5 | 6 | This toolbox uses time-varying functions as weights. If you are using time-varying weight models please cite [SEFRON](https://ieeexplore.ieee.org/document/8472924) and if you are using this toolbox please cite [MC-SEFRON](https://arxiv.org/abs/1904.11367). 7 | 8 | Regular updates on this project are posted at https://www.researchgate.net/project/Spiking-Neural-Networks-7 9 | 10 | Example: Iris train and test dataset are given in iris_train_1.csv and iris_test_1.csv respectively. Run the Main.m file to train the MC-SEFRON. 11 | 12 | Note: Change the hyperparamets for other problems. 13 | -------------------------------------------------------------------------------- /FiringTime.m: -------------------------------------------------------------------------------- 1 | function [tc,V] = FiringTime(Output_neuron,Sample,param) 2 | 3 | linearInd = sub2ind(size(Output_neuron.weight), repmat([1:param.dim*param.RF],1,param.no_class), repmat(Sample.Spike_Time,1,param.no_class),reshape(repmat([1:param.no_class],param.dim*param.RF,1),1,[])); 4 | W_sample=Output_neuron.weight(linearInd); 5 | wh=reshape(W_sample,param.dim*param.RF,param.no_class); 6 | V=wh'*spike_response(bsxfun(@minus, param.t,Sample.Spike_Time'),param.tau); 7 | firing=(V>Output_neuron.theta'); 8 | [~,firing_time]=max(firing'); 9 | firing_time(firing_time==1)=param.TOID; 10 | tc = firing_time; 11 | 12 | end 13 | 14 | -------------------------------------------------------------------------------- /train_SNN.m: -------------------------------------------------------------------------------- 1 | function Trained_model = train_SNN(model,Tr,Te) 2 | Train_class = Tr(:,end); 3 | Train = Tr(:,1:end-1); 4 | train_size=size(Train,1); 5 | 6 | Test_class = Te(:,end); 7 | Test = Te(:,1:end-1); 8 | test_size=size(Test,1); 9 | 10 | model.no_class = max(Train_class); 11 | model.dim = size(Train,2); 12 | model.t = ones(model.dim*model.RF,1)*(0:1:model.TOID); 13 | 14 | Encoding_neurons = generate_population(model); % Creating population encoding neurons 15 | Spike_Train=population_encoding(Train,Encoding_neurons,model); % converting real-valued Training dataset to spike times 16 | Spike_Test=population_encoding(Test,Encoding_neurons,model); % converting real-valued Testing dataset to spike times 17 | 18 | 19 | Trained_model=MC_SEFRON(model,Spike_Train,Train_class,train_size,Spike_Test,Test_class); 20 | 21 | end 22 | 23 | -------------------------------------------------------------------------------- /validate.m: -------------------------------------------------------------------------------- 1 | function accuracy = validate(Spike_data,Class,Trained_model) 2 | Output_class=zeros(size(Class)); 3 | 4 | for j=1:size(Spike_data,1) 5 | Sample=Spike_code(Spike_data(j,:),Class(j),Trained_model); 6 | [tc,Fire_vk] =FiringTime(Trained_model.Output_neuron,Sample,Trained_model); 7 | 8 | firing_index=find(tc~=Trained_model.TOID); 9 | val=find(min(tc)==tc); 10 | vd1=min(tc); 11 | if(vd1~=Trained_model.TOID && size(val,1)==1) 12 | [~,Output_class(j)] = min(tc); 13 | elseif(size(val,1)~=1 && vd1~=Trained_model.TOID) 14 | fire_precision=Fire_vk(val,vd1-1:vd1); 15 | ds=bsxfun(@minus,fire_precision,Trained_model.Output_neuron.theta(val)); 16 | temp_ds=(zeros(size(val))-ds(:,1))./(ds(:,2)-ds(:,1)); 17 | [~,f]=min(temp_ds); 18 | Output_class(j) = val(f); 19 | end 20 | 21 | end 22 | 23 | correct=find(Output_class==Class); 24 | accuracy= size(correct,1)/size(Spike_data,1)*100; 25 | end 26 | 27 | -------------------------------------------------------------------------------- /Main.m: -------------------------------------------------------------------------------- 1 | clear all 2 | %% Load training and testing data 3 | Tr= csvread('iris_train_1.csv'); 4 | Te = csvread('iris_test_1.csv'); 5 | 6 | %% Choose learning algorithm paramters 7 | 8 | opts.RF = 6; % Number of receptive feild neuron in population encoding scheme 9 | opts.Pre = 3; % Presynaptic spike interval in ms 10 | opts.Post = 4; % Postsynaptic spike interval in ms 11 | opts.Desired = 2; % Desired postsynaptic firing time in ms 12 | opts.precision = 0.01; % Precision of time-step 13 | opts.learning_rate = 0.5; % learning rate of weight update 14 | opts.efficacy_update_range = 0.55; % sigma of time-varying weight kernal in ms 15 | opts.tau = 3; % Time constant of spike response function in ms 16 | opts.epoch = 100; % number of maximum epochs 17 | opts.stdp = 1.6; % time-constant of STDP learning window 18 | 19 | 20 | %% Train MC-SEFRON 21 | 22 | model=setup_SNN(opts); 23 | 24 | Trained_model=train_SNN(model,Tr,Te); 25 | 26 | -------------------------------------------------------------------------------- /iris_test_1.csv: -------------------------------------------------------------------------------- 1 | 0.19444,0.625,0.050847,0.083333,1 2 | 0.083333,0.58333,0.067797,0.083333,1 3 | 0.11111,0.5,0.10169,0.041667,1 4 | 0.13889,0.41667,0.067797,0,1 5 | 0.19444,0.54167,0.067797,0.041667,1 6 | 0.16667,0.41667,0.067797,0.041667,1 7 | 0.19444,0.58333,0.084746,0.041667,1 8 | 0.027778,0.375,0.067797,0.041667,1 9 | 0.16667,0.45833,0.084746,0,1 10 | 0.30556,0.70833,0.084746,0.041667,1 11 | 0.13889,0.58333,0.10169,0.041667,1 12 | 0.38889,1,0.084746,0.125,1 13 | 0.30556,0.79167,0.050847,0.125,1 14 | 0.38889,0.75,0.11864,0.083333,1 15 | 0.083333,0.66667,0,0.041667,1 16 | 0.19444,0.41667,0.10169,0.041667,1 17 | 0.25,0.625,0.084746,0.041667,1 18 | 0.25,0.58333,0.067797,0.041667,1 19 | 0.30556,0.58333,0.084746,0.125,1 20 | 0.25,0.875,0.084746,0,1 21 | 0.33333,0.91667,0.067797,0.041667,1 22 | 0.16667,0.45833,0.084746,0,1 23 | 0.027778,0.41667,0.050847,0.041667,1 24 | 0.055556,0.125,0.050847,0.083333,1 25 | 0.19444,0.625,0.10169,0.20833,1 26 | 0.52778,0.375,0.55932,0.5,2 27 | 0.38889,0.41667,0.54237,0.45833,2 28 | 0.55556,0.20833,0.66102,0.58333,2 29 | 0.55556,0.54167,0.62712,0.625,2 30 | 0.41667,0.25,0.50847,0.45833,2 31 | 0.58333,0.5,0.59322,0.58333,2 32 | 0.72222,0.45833,0.66102,0.58333,2 33 | 0.33333,0.125,0.50847,0.5,2 34 | 0.38889,0.33333,0.59322,0.5,2 35 | 0.19444,0,0.42373,0.375,2 36 | 0.44444,0.41667,0.54237,0.58333,2 37 | 0.5,0.375,0.62712,0.54167,2 38 | 0.36111,0.41667,0.59322,0.58333,2 39 | 0.41667,0.29167,0.52542,0.375,2 40 | 0.36111,0.20833,0.49153,0.41667,2 41 | 0.44444,0.5,0.64407,0.70833,2 42 | 0.58333,0.375,0.55932,0.5,2 43 | 0.63889,0.41667,0.57627,0.54167,2 44 | 0.38889,0.25,0.42373,0.375,2 45 | 0.41667,0.29167,0.49153,0.45833,2 46 | 0.30556,0.41667,0.59322,0.58333,2 47 | 0.33333,0.25,0.57627,0.45833,2 48 | 0.19444,0.125,0.38983,0.375,2 49 | 0.22222,0.20833,0.33898,0.41667,2 50 | 0.38889,0.33333,0.52542,0.5,2 51 | 0.58333,0.33333,0.77966,0.875,3 52 | 0.41667,0.29167,0.69492,0.75,3 53 | 0.66667,0.45833,0.77966,0.95833,3 54 | 1,0.75,0.91525,0.79167,3 55 | 0.5,0.41667,0.66102,0.70833,3 56 | 0.55556,0.54167,0.84746,1,3 57 | 0.55556,0.375,0.77966,0.70833,3 58 | 0.16667,0.20833,0.59322,0.66667,3 59 | 0.66667,0.20833,0.81356,0.70833,3 60 | 0.80556,0.66667,0.86441,1,3 61 | 0.61111,0.5,0.69492,0.79167,3 62 | 0.69444,0.41667,0.76271,0.83333,3 63 | 0.94444,0.25,1,0.91667,3 64 | 0.94444,0.33333,0.9661,0.79167,3 65 | 0.55556,0.29167,0.66102,0.70833,3 66 | 0.66667,0.54167,0.79661,0.83333,3 67 | 0.80556,0.41667,0.81356,0.625,3 68 | 0.94444,0.41667,0.86441,0.91667,3 69 | 0.55556,0.58333,0.77966,0.95833,3 70 | 0.58333,0.45833,0.76271,0.70833,3 71 | 0.47222,0.41667,0.64407,0.70833,3 72 | 0.66667,0.54167,0.79661,1,3 73 | 0.55556,0.20833,0.67797,0.75,3 74 | 0.61111,0.41667,0.71186,0.79167,3 75 | 0.52778,0.58333,0.74576,0.91667,3 76 | -------------------------------------------------------------------------------- /iris_train_1.csv: -------------------------------------------------------------------------------- 1 | 0.22222,0.75,0.15254,0.125,1 2 | 0.5,0.33333,0.62712,0.45833,2 3 | 0.5,0.25,0.77966,0.54167,3 4 | 0.33333,0.625,0.050847,0.041667,1 5 | 0.33333,0.16667,0.47458,0.41667,2 6 | 0.69444,0.5,0.83051,0.91667,3 7 | 0.083333,0.5,0.067797,0.041667,1 8 | 0.36111,0.375,0.44068,0.5,2 9 | 0.94444,0.75,0.9661,0.875,3 10 | 0.16667,0.45833,0.084746,0,1 11 | 0.25,0.29167,0.49153,0.54167,2 12 | 0.52778,0.33333,0.64407,0.70833,3 13 | 0.22222,0.625,0.067797,0.041667,1 14 | 0.66667,0.45833,0.62712,0.58333,2 15 | 0.66667,0.41667,0.71186,0.91667,3 16 | 0.083333,0.45833,0.084746,0.041667,1 17 | 0.47222,0.083333,0.50847,0.375,2 18 | 0.86111,0.33333,0.86441,0.75,3 19 | 0.19444,0.58333,0.10169,0.125,1 20 | 0.75,0.5,0.62712,0.54167,2 21 | 0.80556,0.5,0.84746,0.70833,3 22 | 0.22222,0.70833,0.084746,0.125,1 23 | 0.69444,0.33333,0.64407,0.54167,2 24 | 0.41667,0.33333,0.69492,0.95833,3 25 | 0.30556,0.79167,0.11864,0.125,1 26 | 0.36111,0.41667,0.52542,0.5,2 27 | 0.83333,0.375,0.89831,0.70833,3 28 | 0.22222,0.625,0.067797,0.083333,1 29 | 0.33333,0.16667,0.45763,0.375,2 30 | 0.72222,0.45833,0.74576,0.83333,3 31 | 0.22222,0.75,0.084746,0.083333,1 32 | 0.63889,0.375,0.61017,0.5,2 33 | 0.44444,0.41667,0.69492,0.70833,3 34 | 0.13889,0.41667,0.067797,0.083333,1 35 | 0.61111,0.33333,0.61017,0.58333,2 36 | 0.91667,0.41667,0.94915,0.83333,3 37 | 0.13889,0.45833,0.10169,0.041667,1 38 | 0.55556,0.125,0.57627,0.5,2 39 | 0.72222,0.45833,0.69492,0.91667,3 40 | 0.11111,0.5,0.050847,0.041667,1 41 | 0.38889,0.375,0.54237,0.5,2 42 | 0.61111,0.41667,0.81356,0.875,3 43 | 0.22222,0.75,0.10169,0.041667,1 44 | 0.66667,0.41667,0.67797,0.66667,2 45 | 0.58333,0.5,0.72881,0.91667,3 46 | 0.27778,0.70833,0.084746,0.041667,1 47 | 0.66667,0.45833,0.57627,0.54167,2 48 | 0.58333,0.29167,0.72881,0.75,3 49 | 0.22222,0.54167,0.11864,0.16667,1 50 | 0.47222,0.29167,0.69492,0.625,2 51 | 0.58333,0.33333,0.77966,0.83333,3 52 | 0.19444,0.5,0.033898,0.041667,1 53 | 0.5,0.33333,0.50847,0.5,2 54 | 0.47222,0.083333,0.67797,0.58333,3 55 | 0.41667,0.83333,0.033898,0.041667,1 56 | 0.36111,0.29167,0.54237,0.5,2 57 | 0.55556,0.33333,0.69492,0.58333,3 58 | 0.027778,0.5,0.050847,0.041667,1 59 | 0.52778,0.083333,0.59322,0.58333,2 60 | 0.38889,0.20833,0.67797,0.79167,3 61 | 0.13889,0.58333,0.15254,0.041667,1 62 | 0.5,0.41667,0.61017,0.54167,2 63 | 0.41667,0.29167,0.69492,0.75,3 64 | 0.30556,0.58333,0.11864,0.041667,1 65 | 0.16667,0.16667,0.38983,0.375,2 66 | 0.72222,0.5,0.79661,0.91667,3 67 | 0.22222,0.58333,0.084746,0.041667,1 68 | 0.47222,0.58333,0.59322,0.625,2 69 | 0.77778,0.41667,0.83051,0.83333,3 70 | 0,0.41667,0.016949,0,1 71 | 0.47222,0.375,0.59322,0.58333,2 72 | 0.61111,0.41667,0.76271,0.70833,3 73 | 0.19444,0.66667,0.067797,0.041667,1 74 | 0.33333,0.20833,0.50847,0.5,2 75 | 0.36111,0.33333,0.66102,0.79167,3 76 | -------------------------------------------------------------------------------- /MC_SEFRON.m: -------------------------------------------------------------------------------- 1 | function Trained_model = MC_SEFRON(model,Spike_Train,Train_class,train_size,Spike_Test,Test_class) 2 | 3 | 4 | rng('shuffle') 5 | no_epoch=model.no_epoch; 6 | Output_size=0; 7 | model.theta=[]; 8 | Train_accu=zeros(1,no_epoch); 9 | Test_accu=zeros(1,no_epoch); 10 | Output_neuron.weight=zeros(model.dim*model.RF,model.T+1,model.no_class); 11 | Output_neuron.theta=zeros(1,model.no_class); 12 | % order=randperm(train_size); 13 | order=1:train_size; 14 | 15 | %Initialize weith and firing threshlod 16 | for j=1:train_size 17 | Sample=Spike_code(Spike_Train(order(j),:),Train_class(order(j)),model); 18 | if (Output_neuron.theta(Sample.class)==0) 19 | Output_size = Output_size+1; 20 | Output_neuron.weight(:,:,Sample.class)=bsxfun(@times,bsxfun(model.fun,model.t_train,Sample.Spike_Time'),Sample.U_TID); 21 | Output_neuron.theta(Sample.class)=Sample.U_TID'*Sample.Esto; 22 | end 23 | if(Output_size==model.no_class) 24 | break 25 | end 26 | end 27 | 28 | %% Training MC_SEFRON 29 | 30 | for epoch=1:no_epoch 31 | 32 | for j=1:train_size 33 | Sample=Spike_code(Spike_Train(order(j),:),Train_class(order(j)),model); 34 | 35 | tc=FiringTime(Output_neuron,Sample,model); %determine the firing time of all the output neurons 36 | Other_class = setdiff(1:model.no_class,Sample.class); 37 | tcc = tc(Sample.class); 38 | tmc = min(tc(Other_class)); 39 | reference_time=tc; 40 | 41 | if(tmcmodel.Td) 44 | reference_time(Sample.class)=model.Td; 45 | end 46 | trf_mc=min(model.TOID,tcc+model.Tm); 47 | Wrng_class=find(tc(Other_class)