├── LICENSE
├── README.md
├── examples
├── datasets
│ ├── MG.mat
│ └── pianomidi.mat
├── main_MackeyGlass.py
└── main_MultivariatePolyphonic.py
├── pyproject.toml
├── setup.py
└── src
└── deepesn
├── __init__.py
├── configurations.py
├── deepesn.py
├── metrics.py
└── task.py
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2018, Luca Pedrelli
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deep Echo State Network Python library (DeepESNpy), 2018
2 |
3 | Deep Echo State Network (DeepESN) is an extension of the ESN model towards the deep learning paradigm (Deep Reservoir Computing). A DeepESN is a deep Recurrent Neural Network composed by a hierarchy of recurrent layers intrinsically able to develop hierarchical and distributed temporal features. Such characteristics make DeepESN suitable for time-series and sequences processing.
4 |
5 | All details about DeepESN model are described in the reference paper (**CITATION REQUEST**):
6 | C. Gallicchio, A. Micheli, L. Pedrelli,
7 | ["Deep Reservoir Computing: A Critical Experimental Analysis", Neurocomputing, 2017, vol. 268, pp. 87-99](https://www.sciencedirect.com/science/article/pii/S0925231217307567)
8 |
9 | The design of DeepESN model in multivariate time-series prediction tasks is described in the following paper:
10 | C. Gallicchio, A. Micheli, L. Pedrelli,
11 | ["Design of deep echo state networks", Neural Networks, 2018, vol. 108, pp. 33-47](https://www.sciencedirect.com/science/article/pii/S0893608018302223)
12 |
13 |
14 | **AUTHOR INFORMATION**
15 |
16 | Luca Pedrelli
17 | luca.pedrelli@di.unipi.it
18 | lucapedrelli@gmail.com
19 |
20 | Department of Computer Science - University of Pisa (Italy)
21 | Computational Intelligence & Machine Learning (CIML) Group
22 | http://www.di.unipi.it/groups/ciml/
23 |
24 | ## Installation
25 |
26 | To install DeepESN, run the following command:
27 |
28 | ```bash
29 | pip install DeepESN
30 |
--------------------------------------------------------------------------------
/examples/datasets/MG.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lucapedrelli/DeepESN/67ecfd7e1abf83db4853f47a307b639ac44b89de/examples/datasets/MG.mat
--------------------------------------------------------------------------------
/examples/datasets/pianomidi.mat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lucapedrelli/DeepESN/67ecfd7e1abf83db4853f47a307b639ac44b89de/examples/datasets/pianomidi.mat
--------------------------------------------------------------------------------
/examples/main_MackeyGlass.py:
--------------------------------------------------------------------------------
1 | '''
2 | This is an example of the application of DeepESN model for next-step prediction on Mackey Glass time-series.
3 |
4 | Reference paper for DeepESN model:
5 | C. Gallicchio, A. Micheli, L. Pedrelli, "Deep Reservoir Computing: A Critical Experimental Analysis",
6 | Neurocomputing, 2017, vol. 268, pp. 87-99
7 |
8 | Reference paper for the design of DeepESN model in multivariate time-series prediction tasks:
9 | C. Gallicchio, A. Micheli, L. Pedrelli, "Design of deep echo state networks",
10 | Neural Networks, 2018, vol. 108, pp. 33-47
11 |
12 | ----
13 |
14 | This file is a part of the DeepESN Python Library (DeepESNpy)
15 |
16 | Luca Pedrelli
17 | luca.pedrelli@di.unipi.it
18 | lucapedrelli@gmail.com
19 |
20 | Department of Computer Science - University of Pisa (Italy)
21 | Computational Intelligence & Machine Learning (CIML) Group
22 | http://www.di.unipi.it/groups/ciml/
23 |
24 | ----
25 | '''
26 |
27 | import numpy as np
28 | import random
29 | from deepesn import DeepESN
30 | from deepesn.metrics import MSE
31 | from deepesn.configurations import config_MG
32 | from deepesn.task import load_MG, select_indexes
33 | class Struct(object): pass
34 |
35 | # sistemare indici per IP in config_pianomidi, mettere da un'altra parte
36 | # sistema selezione indici con transiente messi all'interno della rete
37 | def main():
38 |
39 | # fix a seed for the reproducibility of results
40 | np.random.seed(7)
41 |
42 | # dataset path
43 | path = 'datasets'
44 | dataset, Nu, error_function, optimization_problem, TR_indexes, VL_indexes, TS_indexes = load_MG(path, MSE)
45 |
46 | # load configuration for pianomidi task
47 | configs = config_MG(list(TR_indexes) + list(VL_indexes))
48 |
49 | # Be careful with memory usage
50 | Nr = 100 # number of recurrent units
51 | Nl = 5 # number of recurrent layers
52 | reg = 0.0;
53 | transient = 100
54 |
55 | deepESN = DeepESN(Nu, Nr, Nl, configs)
56 | states = deepESN.computeState(dataset.inputs, deepESN.IPconf.DeepIP)
57 |
58 | train_states = select_indexes(states, list(TR_indexes) + list(VL_indexes), transient)
59 | train_targets = select_indexes(dataset.targets, list(TR_indexes) + list(VL_indexes), transient)
60 | test_states = select_indexes(states, TS_indexes)
61 | test_targets = select_indexes(dataset.targets, TS_indexes)
62 |
63 | deepESN.trainReadout(train_states, train_targets, reg)
64 |
65 | train_outputs = deepESN.computeOutput(train_states)
66 | train_error = error_function(train_outputs, train_targets)
67 | print('Training ACC: ', np.mean(train_error), '\n')
68 |
69 | test_outputs = deepESN.computeOutput(test_states)
70 | test_error = error_function(test_outputs, test_targets)
71 | print('Test ACC: ', np.mean(test_error), '\n')
72 |
73 |
74 | if __name__ == "__main__":
75 | main()
76 |
77 |
--------------------------------------------------------------------------------
/examples/main_MultivariatePolyphonic.py:
--------------------------------------------------------------------------------
1 | '''
2 | This is an example of the application of DeepESN model for multivariate time-series prediction task
3 | on Piano-midi.de (see http://www-etud.iro.umontreal.ca/~boulanni/icml2012) dataset.
4 | The dataset is a polyphonic music task characterized by 88-dimensional sequences representing musical compositions.
5 | Starting from played notes at time t, the aim is to predict the played notes at time t+1.
6 |
7 | Reference paper for DeepESN model:
8 | C. Gallicchio, A. Micheli, L. Pedrelli, "Deep Reservoir Computing: A Critical Experimental Analysis",
9 | Neurocomputing, 2017, vol. 268, pp. 87-99
10 |
11 | In this Example we consider the hyper-parameters designed in the following paper:
12 | C. Gallicchio, A. Micheli, L. Pedrelli, "Design of deep echo state networks",
13 | Neural Networks, 2018, vol. 108, pp. 33-47
14 |
15 | However, for the ease of calculation, in this example
16 | we consider only Nr = 100 units and Nl = 5 layers instead of Nr = 200 and Nl = 35.
17 |
18 | ----
19 |
20 | This file is a part of the DeepESN Python Library (DeepESNpy)
21 |
22 | Luca Pedrelli
23 | luca.pedrelli@di.unipi.it
24 | lucapedrelli@gmail.com
25 |
26 | Department of Computer Science - University of Pisa (Italy)
27 | Computational Intelligence & Machine Learning (CIML) Group
28 | http://www.di.unipi.it/groups/ciml/
29 |
30 | ----
31 | '''
32 |
33 | import numpy as np
34 | import random
35 | from DeepESN import DeepESN
36 | from deepesn.metrics import computeMusicAccuracy
37 | from deepesn.configurations import config_pianomidi
38 | from deepesn.task import load_pianomidi, select_indexes
39 | class Struct(object): pass
40 |
41 | # sistemare indici per IP in config_pianomidi, mettere da un'altra parte
42 | # sistema selezione indici con transiente messi all'interno della rete
43 | def main():
44 |
45 | # fix a seed for the reproducibility of results
46 | np.random.seed(7)
47 |
48 | # dataset path
49 | path = 'datasets'
50 | dataset, Nu, error_function, optimization_problem, TR_indexes, VL_indexes, TS_indexes = load_pianomidi(path, computeMusicAccuracy)
51 |
52 | # load configuration for pianomidi task
53 | configs = config_pianomidi(list(TR_indexes) + list(VL_indexes))
54 |
55 | # Be careful with memory usage
56 | Nr = 100 # number of recurrent units
57 | Nl = 5 # number of recurrent layers
58 | reg = 10.0**-2;
59 | transient = 5
60 |
61 | deepESN = DeepESN(Nu, Nr, Nl, configs)
62 | states = deepESN.computeState(dataset.inputs, deepESN.IPconf.DeepIP)
63 |
64 | train_states = select_indexes(states, list(TR_indexes) + list(VL_indexes), transient)
65 | train_targets = select_indexes(dataset.targets, list(TR_indexes) + list(VL_indexes), transient)
66 | test_states = select_indexes(states, TS_indexes)
67 | test_targets = select_indexes(dataset.targets, TS_indexes)
68 |
69 | deepESN.trainReadout(train_states, train_targets, reg)
70 |
71 | train_outputs = deepESN.computeOutput(train_states)
72 | train_error = error_function(train_outputs, train_targets)
73 | print('Training ACC: ', np.mean(train_error), '\n')
74 |
75 | test_outputs = deepESN.computeOutput(test_states)
76 | test_error = error_function(test_outputs, test_targets)
77 | print('Test ACC: ', np.mean(test_error), '\n')
78 |
79 |
80 | if __name__ == "__main__":
81 | main()
82 |
83 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools>=42",
4 | "wheel"
5 | ]
6 | build-backend = "setuptools.build_meta"
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 | setup(
4 | name='DeepESN',
5 | version='1.1.5',
6 | packages=find_packages(where='src'),
7 | package_dir={'': 'src'},
8 | install_requires=[
9 | 'scipy',
10 | 'numpy'
11 | ],
12 | description="Deep Echo State Network Python library (DeepESNpy), 2018",
13 | author='Luca Pedrelli',
14 | author_email='lucapedrelli@gmail.com',
15 | license='BSD 3-Clause',
16 | url="https://github.com/lucapedrelli/DeepESN"
17 | )
18 |
--------------------------------------------------------------------------------
/src/deepesn/__init__.py:
--------------------------------------------------------------------------------
1 | from .deepesn import DeepESN
2 |
--------------------------------------------------------------------------------
/src/deepesn/configurations.py:
--------------------------------------------------------------------------------
1 | '''
2 | Model configuration file
3 |
4 | Reference paper for DeepESN model:
5 | C. Gallicchio, A. Micheli, L. Pedrelli, "Deep Reservoir Computing: A Critical Experimental Analysis",
6 | Neurocomputing, 2017, vol. 268, pp. 87-99
7 |
8 | Reference paper for the design of DeepESN model in multivariate time-series prediction tasks:
9 | C. Gallicchio, A. Micheli, L. Pedrelli, "Design of deep echo state networks",
10 | Neural Networks, 2018, vol. 108, pp. 33-47
11 |
12 | ----
13 |
14 | This file is a part of the DeepESN Python Library (DeepESNpy)
15 |
16 | Luca Pedrelli
17 | luca.pedrelli@di.unipi.it
18 | lucapedrelli@gmail.com
19 |
20 | Department of Computer Science - University of Pisa (Italy)
21 | Computational Intelligence & Machine Learning (CIML) Group
22 | http://www.di.unipi.it/groups/ciml/
23 |
24 | ----
25 | '''
26 |
27 | import numpy as np
28 |
29 | class Struct(object): pass
30 |
31 | def config_pianomidi(IP_indexes):
32 |
33 | configs = Struct()
34 |
35 | configs.rhos = 0.1 # set spectral radius 0.1 for all recurrent layers
36 | configs.lis = 0.7 # set li 0.7 for all recurrent layers
37 | configs.iss = 0.1 # set insput scale 0.1 for all recurrent layers
38 |
39 | configs.IPconf = Struct()
40 | configs.IPconf.DeepIP = 1 # activate pre-train
41 | configs.IPconf.threshold = 0.1 # threshold for gradient descent in pre-train algorithm
42 | configs.IPconf.eta = 10**-5 # learning rate for IP rule
43 | configs.IPconf.mu = 0 # mean of target gaussian function
44 | configs.IPconf.sigma = 0.1 # std of target gaussian function
45 | configs.IPconf.Nepochs = 10 # maximum number of epochs
46 | configs.IPconf.indexes = IP_indexes # perform the pre-train on these indexes
47 |
48 | configs.reservoirConf = Struct()
49 | configs.reservoirConf.connectivity = 1 # connectivity of recurrent matrix
50 |
51 | configs.readout = Struct()
52 | configs.readout.trainMethod = 'NormalEquations' # train with normal equations (faster)
53 | configs.readout.regularizations = 10.0**np.array(range(-4,-1,1))
54 |
55 | return configs
56 |
57 |
58 | def config_MG(IP_indexes):
59 |
60 | configs = Struct()
61 |
62 | configs.rhos = 0.9 # set spectral radius 0.9 for all recurrent layers
63 | configs.lis = 1.0 # set li 1.0 for all recurrent layers
64 | configs.iss = 0.1 # set insput scale 0.1 for all recurrent layers
65 |
66 | configs.IPconf = Struct()
67 | configs.IPconf.DeepIP = 0 # deactivate pre-train
68 |
69 | configs.reservoirConf = Struct()
70 | configs.reservoirConf.connectivity = 1 # connectivity of recurrent matrix
71 |
72 | configs.readout = Struct()
73 | configs.readout.trainMethod = 'SVD' # train with singular value decomposition (more accurate)
74 | configs.readout.regularizations = 10.0**np.array(range(-16,-1,1))
75 |
76 | return configs
--------------------------------------------------------------------------------
/src/deepesn/deepesn.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import numpy.matlib as npm
3 | import scipy as sc
4 | import random
5 | import sys
6 |
7 | class DeepESN():
8 |
9 | '''
10 | Deep Echo State Network (DeepESN) class:
11 | this class implement the DeepESN model suitable for
12 | time-serie prediction and sequence classification.
13 |
14 | Reference paper for DeepESN model:
15 | C. Gallicchio, A. Micheli, L. Pedrelli, "Deep Reservoir Computing: A
16 | Critical Experimental Analysis", Neurocomputing, 2017, vol. 268, pp. 87-99
17 |
18 | Reference paper for the design of DeepESN model in multivariate time-series prediction tasks:
19 | C. Gallicchio, A. Micheli, L. Pedrelli, "Design of deep echo state networks",
20 | Neural Networks, 2018, vol. 108, pp. 33-47
21 |
22 | ----
23 |
24 | This file is a part of the DeepESN Python Library (DeepESNpy)
25 |
26 | Luca Pedrelli
27 | luca.pedrelli@di.unipi.it
28 | lucapedrelli@gmail.com
29 |
30 | Department of Computer Science - University of Pisa (Italy)
31 | Computational Intelligence & Machine Learning (CIML) Group
32 | http://www.di.unipi.it/groups/ciml/
33 |
34 | ----
35 | '''
36 |
37 | def __init__(self, Nu,Nr,Nl, configs, verbose=0):
38 | # initialize the DeepESN model
39 |
40 | if verbose:
41 | sys.stdout.write('init DeepESN...')
42 | sys.stdout.flush()
43 |
44 | rhos = np.array(configs.rhos) # spectral radius (maximum absolute eigenvalue)
45 | lis = np.array(configs.lis) # leaky rate
46 | iss = np.array(configs.iss) # input scale
47 | IPconf = configs.IPconf # configuration for Deep Intrinsic Plasticity
48 | reservoirConf = configs.reservoirConf # reservoir configurations
49 |
50 | if len(rhos.shape) == 0:
51 | rhos = npm.repmat(rhos, 1,Nl)[0]
52 |
53 | if len(lis.shape) == 0:
54 | lis = npm.repmat(lis, 1,Nl)[0]
55 |
56 | if len(iss.shape) == 0:
57 | iss = npm.repmat(iss, 1,Nl)[0]
58 |
59 | self.W = {} # recurrent weights
60 | self.Win = {} # recurrent weights
61 | self.Gain = {} # activation function gain
62 | self.Bias = {} # activation function bias
63 |
64 | self.Nu = Nu # number of inputs
65 | self.Nr = Nr # number of units per layer
66 | self.Nl = Nl # number of layers
67 | self.rhos = rhos.tolist() # list of spectral radius
68 | self.lis = lis # list of leaky rate
69 | self.iss = iss # list of input scale
70 |
71 | self.IPconf = IPconf
72 |
73 | self.readout = configs.readout
74 |
75 | # sparse recurrent weights init
76 | if reservoirConf.connectivity < 1:
77 | for layer in range(Nl):
78 | self.W[layer] = np.zeros((Nr,Nr))
79 | for row in range(Nr):
80 | number_row_elements = round(reservoirConf.connectivity * Nr)
81 | row_elements = random.sample(range(Nr), number_row_elements)
82 | self.W[layer][row,row_elements] = np.random.uniform(-1,+1, size = (1,number_row_elements))
83 |
84 | # full-connected recurrent weights init
85 | else:
86 | for layer in range(Nl):
87 | self.W[layer] = np.random.uniform(-1,+1, size = (Nr,Nr))
88 |
89 | # layers init
90 | for layer in range(Nl):
91 |
92 | target_li = lis[layer]
93 | target_rho = rhos[layer]
94 | input_scale = iss[layer]
95 |
96 | if layer==0:
97 | self.Win[layer] = np.random.uniform(-input_scale, input_scale, size=(Nr,Nu+1))
98 | else:
99 | self.Win[layer] = np.random.uniform(-input_scale, input_scale, size=(Nr,Nr+1))
100 |
101 | Ws = (1-target_li) * np.eye(self.W[layer].shape[0], self.W[layer].shape[1]) + target_li * self.W[layer]
102 | eig_value,eig_vector = np.linalg.eig(Ws)
103 | actual_rho = np.max(np.absolute(eig_value))
104 |
105 | Ws = (Ws *target_rho)/actual_rho
106 | self.W[layer] = (target_li**-1) * (Ws - (1.-target_li) * np.eye(self.W[layer].shape[0], self.W[layer].shape[1]))
107 |
108 | self.Gain[layer] = np.ones((Nr,1))
109 | self.Bias[layer] = np.zeros((Nr,1))
110 |
111 | if verbose:
112 | print('done.')
113 | sys.stdout.flush()
114 |
115 | def computeLayerState(self, input, layer, initialStatesLayer = None, DeepIP = 0):
116 | # compute the state of a layer with pre-training if DeepIP == 1
117 |
118 | state = np.zeros((self.Nr, input.shape[1]))
119 |
120 | if initialStatesLayer is None:
121 | initialStatesLayer = np.zeros(state[:,0:1].shape)
122 |
123 | input = self.Win[layer][:,0:-1].dot(input) + np.expand_dims(self.Win[layer][:,-1],1)
124 |
125 | if DeepIP:
126 | state_net = np.zeros((self.Nr, input.shape[1]))
127 | state_net[:,0:1] = input[:,0:1]
128 | state[:,0:1] = self.lis[layer] * np.tanh(np.multiply(self.Gain[layer], state_net[:,0:1]) + self.Bias[layer])
129 | else:
130 | #state[:,0:1] = self.lis[layer] * np.tanh(np.multiply(self.Gain[layer], input[:,0:1]) + self.Bias[layer])
131 | state[:,0:1] = (1-self.lis[layer]) * initialStatesLayer + self.lis[layer] * np.tanh( np.multiply(self.Gain[layer], self.W[layer].dot(initialStatesLayer) + input[:,0:1]) + self.Bias[layer])
132 |
133 | for t in range(1,state.shape[1]):
134 | if DeepIP:
135 | state_net[:,t:t+1] = self.W[layer].dot(state[:,t-1:t]) + input[:,t:t+1]
136 | state[:,t:t+1] = (1-self.lis[layer]) * state[:,t-1:t] + self.lis[layer] * np.tanh(np.multiply(self.Gain[layer], state_net[:,t:t+1]) + self.Bias[layer])
137 |
138 | eta = self.IPconf.eta
139 | mu = self.IPconf.mu
140 | sigma2 = self.IPconf.sigma**2
141 |
142 | # IP learning rule
143 | deltaBias = -eta*((-mu/sigma2)+ np.multiply(state[:,t:t+1], (2*sigma2+1-(state[:,t:t+1]**2)+mu*state[:,t:t+1])/sigma2))
144 | deltaGain = eta / npm.repmat(self.Gain[layer],1,state_net[:,t:t+1].shape[1]) + deltaBias * state_net[:,t:t+1]
145 |
146 | # update gain and bias of activation function
147 | self.Gain[layer] = self.Gain[layer] + deltaGain
148 | self.Bias[layer] = self.Bias[layer] + deltaBias
149 |
150 | else:
151 | state[:,t:t+1] = (1-self.lis[layer]) * state[:,t-1:t] + self.lis[layer] * np.tanh( np.multiply(self.Gain[layer], self.W[layer].dot(state[:,t-1:t]) + input[:,t:t+1]) + self.Bias[layer])
152 |
153 | return state
154 |
155 | def computeDeepIntrinsicPlasticity(self, inputs):
156 | # we incrementally perform the pre-training (deep intrinsic plasticity) over layers
157 |
158 | len_inputs = range(len(inputs))
159 | states = []
160 |
161 | for i in len_inputs:
162 | states.append(np.zeros((self.Nr*self.Nl, inputs[i].shape[1])))
163 |
164 | for layer in range(self.Nl):
165 |
166 | for epoch in range(self.IPconf.Nepochs):
167 | Gain_epoch = self.Gain[layer]
168 | Bias_epoch = self.Bias[layer]
169 |
170 |
171 | if len(inputs) == 1:
172 | self.computeLayerState(inputs[0][:,self.IPconf.indexes], layer, DeepIP = 1)
173 | else:
174 | for i in self.IPconf.indexes:
175 | self.computeLayerState(inputs[i], layer, DeepIP = 1)
176 |
177 |
178 | if (np.linalg.norm(self.Gain[layer]-Gain_epoch,2) < self.IPconf.threshold) and (np.linalg.norm(self.Bias[layer]-Bias_epoch,2)< self.IPconf.threshold):
179 | sys.stdout.write(str(epoch+1))
180 | sys.stdout.write('.')
181 | sys.stdout.flush()
182 | break
183 |
184 | if epoch+1 == self.IPconf.Nepochs:
185 | sys.stdout.write(str(epoch+1))
186 | sys.stdout.write('.')
187 | sys.stdout.flush()
188 |
189 | inputs2 = []
190 | for i in range(len(inputs)):
191 | inputs2.append(self.computeLayerState(inputs[i], layer))
192 |
193 | for i in range(len(inputs)):
194 | states[i][(layer)*self.Nr: (layer+1)*self.Nr,:] = inputs2[i]
195 |
196 | inputs = inputs2
197 |
198 | return states
199 |
200 | def computeState(self,inputs, DeepIP = 0, initialStates = None, verbose=0):
201 | # compute the global state of DeepESN with pre-training if DeepIP == 1
202 |
203 | if self.IPconf.DeepIP and DeepIP:
204 | if verbose:
205 | sys.stdout.write('compute state with DeepIP...')
206 | sys.stdout.flush()
207 | states = self.computeDeepIntrinsicPlasticity(inputs)
208 | else:
209 | if verbose:
210 | sys.stdout.write('compute state...')
211 | sys.stdout.flush()
212 | states = []
213 |
214 | for i_seq in range(len(inputs)):
215 | states.append(self.computeGlobalState(inputs[i_seq], initialStates))
216 |
217 | if verbose:
218 | print('done.')
219 | sys.stdout.flush()
220 |
221 | return states
222 |
223 | def computeGlobalState(self,input, initialStates):
224 | # compute the global state of DeepESN
225 |
226 | state = np.zeros((self.Nl*self.Nr,input.shape[1]))
227 |
228 | initialStatesLayer = None
229 |
230 |
231 | for layer in range(self.Nl):
232 | if initialStates is not None:
233 | initialStatesLayer = initialStates[(layer)*self.Nr: (layer+1)*self.Nr,:]
234 | state[(layer)*self.Nr: (layer+1)*self.Nr,:] = self.computeLayerState(input, layer, initialStatesLayer, 0)
235 | input = state[(layer)*self.Nr: (layer+1)*self.Nr,:]
236 |
237 | return state
238 |
239 | def trainReadout(self,trainStates,trainTargets,lb, verbose=0):
240 | # train the readout of DeepESN
241 |
242 | trainStates = np.concatenate(trainStates,1)
243 | trainTargets = np.concatenate(trainTargets,1)
244 |
245 | # add bias
246 | X = np.ones((trainStates.shape[0]+1, trainStates.shape[1]))
247 | X[:-1,:] = trainStates
248 | trainStates = X
249 |
250 | if verbose:
251 | sys.stdout.write('train readout...')
252 | sys.stdout.flush()
253 |
254 | if self.readout.trainMethod == 'SVD': # SVD, accurate method
255 | U, s, V = np.linalg.svd(trainStates, full_matrices=False);
256 | s = s/(s**2 + lb)
257 |
258 | self.Wout = trainTargets.dot(np.multiply(V.T, np.expand_dims(s,0)).dot(U.T));
259 |
260 | else: # NormalEquation, fast method
261 | B = trainTargets.dot(trainStates.T)
262 | A = trainStates.dot(trainStates.T)
263 |
264 | self.Wout = np.linalg.solve((A + np.eye(A.shape[0], A.shape[1]) * lb), B.T).T
265 |
266 | if verbose:
267 | print('done.')
268 | sys.stdout.flush()
269 |
270 | def computeOutput(self,state):
271 | # compute a linear combination between the global state and the output weights
272 | state = np.concatenate(state,1)
273 | return self.Wout[:,0:-1].dot(state) + np.expand_dims(self.Wout[:,-1],1) # Wout product + add bias
274 |
--------------------------------------------------------------------------------
/src/deepesn/metrics.py:
--------------------------------------------------------------------------------
1 | '''
2 | Metrics functions
3 |
4 | ----
5 |
6 | This file is a part of the DeepESN Python Library (DeepESNpy)
7 |
8 | Luca Pedrelli
9 | luca.pedrelli@di.unipi.it
10 | lucapedrelli@gmail.com
11 |
12 | Department of Computer Science - University of Pisa (Italy)
13 | Computational Intelligence & Machine Learning (CIML) Group
14 | http://www.di.unipi.it/groups/ciml/
15 |
16 | ----
17 | '''
18 |
19 | import numpy as np
20 |
21 | # Accuracy function used to evaluate the prediction in polyphonic music tasks: true positive/(true positive + false positive + false negative)
22 | def computeMusicAccuracy(threshold,X,Y):
23 | Y = np.concatenate(Y,1)
24 | Nsys = np.sum(X>threshold, axis=0)
25 | Nref = np.sum(Y>threshold, axis=0)
26 | Ncorr = np.sum((X>threshold) * (Y>threshold), axis=0)
27 |
28 | TP = np.sum(Ncorr)
29 | FP = np.sum(Nsys-Ncorr)
30 | FN = np.sum(Nref-Ncorr)
31 | ACCURACY = TP/float(TP + FP + FN)
32 | return ACCURACY
33 |
34 | # Mean Absolute Percentage Error
35 | def MAPE(X, Y):
36 | return np.mean(np.abs((Y - X) / Y))
37 |
38 | # Mean Squared Error
39 | def MSE(X,Y):
40 | return np.mean((X-Y)**2)
41 |
42 | # Normalized Mean Squared Error
43 | def NRMSE(X,Y):
44 | return (np.mean((X-Y)**2) / (np.std(Y)**2))**0.5
45 |
46 | # Mean Absolute Error
47 | def MAE(X,Y):
48 | return np.mean(np.abs(X-Y))
49 |
--------------------------------------------------------------------------------
/src/deepesn/task.py:
--------------------------------------------------------------------------------
1 | '''
2 | Task configuration file
3 |
4 | ----
5 |
6 | This file is a part of the DeepESN Python Library (DeepESNpy)
7 |
8 | Luca Pedrelli
9 | luca.pedrelli@di.unipi.it
10 | lucapedrelli@gmail.com
11 |
12 | Department of Computer Science - University of Pisa (Italy)
13 | Computational Intelligence & Machine Learning (CIML) Group
14 | http://www.di.unipi.it/groups/ciml/
15 |
16 | ----
17 | '''
18 |
19 | import functools
20 | import os
21 | from scipy.io import loadmat
22 | import numpy as np
23 |
24 | class Struct(object): pass
25 |
26 | def select_indexes(data, indexes, transient=0):
27 |
28 | if len(data) == 1:
29 | return [data[0][:,indexes][:,transient:]]
30 |
31 | return [data[i][:,transient:] for i in indexes]
32 |
33 | def load_pianomidi(path, metric_function):
34 |
35 | data = loadmat(os.path.join(path, 'pianomidi.mat')) # load dataset
36 |
37 | dataset = Struct()
38 | dataset.name = data['dataset'][0][0][0][0]
39 | dataset.inputs = data['dataset'][0][0][1][0].tolist()
40 | dataset.targets = data['dataset'][0][0][2][0].tolist()
41 |
42 | # input dimension
43 | Nu = dataset.inputs[0].shape[0]
44 |
45 | # function used for model evaluation
46 | error_function = functools.partial(metric_function, 0.5)
47 |
48 | # select the model that achieves the maximum accuracy on validation set
49 | optimization_problem = np.argmax
50 |
51 |
52 | TR_indexes = range(87) # indexes for training, validation and test set in Piano-midi.de task
53 | VL_indexes = range(87,99)
54 | TS_indexes = range(99,124)
55 |
56 | return dataset, Nu, error_function, optimization_problem, TR_indexes, VL_indexes, TS_indexes
57 |
58 | def load_MG(path, metric_function):
59 |
60 | data = loadmat(os.path.join(path, 'MG.mat')) # load dataset
61 |
62 | dataset = Struct()
63 | dataset.name = data['dataset'][0][0][0][0]
64 | dataset.inputs = data['dataset'][0][0][1][0]
65 | dataset.targets = data['dataset'][0][0][2][0]
66 |
67 | # input dimension
68 | Nu = dataset.inputs[0].shape[0]
69 |
70 | # function used for model evaluation
71 | error_function = metric_function
72 |
73 | # select the model that achieves the maximum accuracy on validation set
74 | optimization_problem = np.argmin
75 |
76 |
77 | TR_indexes = range(4000) # indexes for training, validation and test set in Piano-midi.de task
78 | VL_indexes = range(4000,5000)
79 | TS_indexes = range(5000,9999)
80 |
81 | return dataset, Nu, error_function, optimization_problem, TR_indexes, VL_indexes, TS_indexes
82 |
--------------------------------------------------------------------------------