Ejemplo n.º 1
0
    def remove_hidden_node(self, n):
        if self.w_res_type in ['tetragonal', 'hexagonal', 'triangular']:
            nodes = list(self.G.nodes)
            self.G.remove_node(nodes[n])

            A = nx.to_numpy_matrix(self.G)
            self.hidden_nodes = len(A)

            w_res = torch.FloatTensor(A)
            cur_sr = _spectral_radius(w_res)
            self.org_spectral_radius = cur_sr
            if cur_sr != 0:
                w_res *= self.spectral_radius / cur_sr

            self.w_in = torch.cat([self.w_in[0:n], self.w_in[n + 1:]])
            self.w_res = w_res
            self.w_out = torch.cat([self.w_out[0:n], self.w_out[n + 1:]])
        elif self.w_res_type is None:
            self.w_in = np.delete(self.w_in, n)
            self.w_out = np.delete(self.w_out, n)
            self.w_res = np.delete(self.w_res, n, axis=1)
            self.w_res = np.delete(self.w_res, n, axis=0)
            self.hidden_nodes = len(self.w_in)
        else:
            raise ESNException(
                f'Cannot remove hidden node for w_res_type={self.w_res_type}')
Ejemplo n.º 2
0
    def make_edge_undirected(self, edge):
        if self.w_res_type in ['tetragonal', 'hexagonal', 'triangular']:
            u, v = edge[0], edge[1]
            self.G.add_edge(v, u)

            A = nx.to_numpy_matrix(self.G)
            self.hidden_nodes = len(A)

            self.w_res = torch.FloatTensor(A)
            cur_sr = _spectral_radius(self.w_res)
            self.org_spectral_radius = cur_sr
            if cur_sr != 0:
                self.w_res *= self.spectral_radius / cur_sr
        else:
            raise ESNException(
                f'Cannot remove edge for w_res_type={self.w_res_type}')
Ejemplo n.º 3
0
    def set_G(self, G):
        if self.w_res_type in ['tetragonal', 'hexagonal', 'triangular']:
            A = nx.to_numpy_matrix(G)
            self.hidden_nodes = len(A)
            self.G = G

            self.w_res = torch.FloatTensor(A)
            cur_sr = _spectral_radius(self.w_res)
            if cur_sr != 0:
                self.w_res *= self.spectral_radius / cur_sr
            else:
                # print('[WARN]: Original spectral radius was 0')
                pass

            self.w_in = torch.ones(self.hidden_nodes)
            self.w_in *= self.input_scaling
            self.w_out = torch.zeros(self.hidden_nodes)
        else:
            raise ESNException(
                f'Cannot set G for w_res_type={self.w_res_type}')
Ejemplo n.º 4
0
    def __init__(self,
                 hidden_nodes=200,
                 spectral_radius=0.9,
                 washout=200,
                 w_in_density=1.0,
                 w_res_density=1.0,
                 input_scaling=1.0,
                 w_in_distrib=Distribution.uniform,
                 w_res_distrib=Distribution.uniform,
                 readout='rr',
                 w_ridge=0.00,
                 w_res_type=None,
                 grow_neigh=0,
                 **kwargs):
        super().__init__()

        self.hidden_nodes = hidden_nodes
        self.spectral_radius = spectral_radius
        self.f = torch.tanh
        self.w_in_density = w_in_density
        self.w_res_density = w_res_density
        self.washout = washout
        self.input_scaling = input_scaling
        self.w_in_distrib = w_in_distrib
        self.w_res_distrib = w_res_distrib
        self.readout = readout
        self.w_ridge = w_ridge
        self.rr = Ridge(alpha=w_ridge, solver='svd')
        self.w_res_type = w_res_type
        self.grow_neigh = grow_neigh

        if self.w_res_type == 'waxman':
            G = matrix.waxman(n=self.hidden_nodes,
                              alpha=1.0,
                              beta=1.0,
                              connectivity='global',
                              **kwargs)
            self.G = G
            A = nx.to_numpy_matrix(G)

            w_res = torch.FloatTensor(A)
            cur_sr = _spectral_radius(w_res)
            self.org_w_res = w_res.clone()
            self.org_spectral_radius = cur_sr
            if self.spectral_radius is None:
                self.spectral_radius = self.org_spectral_radius
            if cur_sr != 0:
                w_res *= self.spectral_radius / cur_sr
        elif self.w_res_type in [
                'tetragonal', 'hexagonal', 'triangular', 'rectangular'
        ]:
            sqrt = np.sqrt(self.hidden_nodes)
            if sqrt - int(sqrt) != 0:
                raise ValueError(
                    "Non square number of nodes given for lattice")

            self.sign_frac = None
            if 'sign_frac' in kwargs:
                self.sign_frac = kwargs['sign_frac']
                del kwargs['sign_frac']

            self.dir_frac = None
            if 'dir_frac' in kwargs:
                self.dir_frac = kwargs['dir_frac']
                del kwargs['dir_frac']

            if self.w_res_type == 'tetragonal':
                G = matrix.tetragonal([int(sqrt), int(sqrt)], **kwargs)
            elif self.w_res_type == 'hexagonal':
                G = matrix.hexagonal(
                    int(sqrt) // 2, int(np.ceil(sqrt / 2) * 2), **kwargs)
            elif self.w_res_type == 'triangular':
                G = matrix.triangular(int(sqrt) + 3, int(sqrt) + 3, **kwargs)
            elif self.w_res_type == 'rectangular':
                G = matrix.rectangular(int(sqrt), int(sqrt), **kwargs)
            self.G = G

            if self.grow_neigh > 0:
                matrix.grow_neighborhoods(self.G, l=grow_neigh, **kwargs)

            if self.sign_frac is not None:
                matrix.make_weights_negative(self.G, self.sign_frac)

            if self.dir_frac is not None:
                self.G = matrix.make_graph_directed(self.G, self.dir_frac)

            A = nx.to_numpy_matrix(self.G)
            self.hidden_nodes = len(A)
            w_res = torch.FloatTensor(A)

            cur_sr = _spectral_radius(w_res)
            self.org_spectral_radius = cur_sr
            if cur_sr != 0:
                w_res *= self.spectral_radius / cur_sr
        else:
            if self.w_res_distrib == Distribution.gaussian:
                w_res = torch.empty(self.hidden_nodes,
                                    hidden_nodes).normal_(mean=0.0, std=1.0)
            elif self.w_res_distrib == Distribution.uniform:
                w_res = torch.rand(self.hidden_nodes, self.hidden_nodes) - 0.5
            elif self.w_res_distrib == Distribution.fixed:
                w_res = torch.ones(self.hidden_nodes, self.hidden_nodes)

            w_res[torch.rand(self.hidden_nodes, self.hidden_nodes) >
                  self.w_res_density] = 0.0
            if _spectral_radius(w_res) != 0:
                w_res *= self.spectral_radius / _spectral_radius(w_res)

        if self.w_in_distrib == Distribution.gaussian:
            w_in = torch.empty(self.hidden_nodes).normal_(mean=0.0, std=1.0)
        elif self.w_in_distrib == Distribution.uniform:
            w_in = torch.rand(self.hidden_nodes) - 0.5
        elif self.w_in_distrib == Distribution.fixed:
            w_in = torch.ones(self.hidden_nodes)

        w_in[torch.rand(self.hidden_nodes) > self.w_in_density] = 0.0
        w_in *= self.input_scaling

        w_out = torch.zeros(self.hidden_nodes)

        self.register_buffer('w_res', w_res)
        self.register_buffer('w_in', w_in)
        self.register_buffer('w_out', w_out)
Ejemplo n.º 5
0
 def scale_spectral_radius(self, new_sr):
     cur_sr = _spectral_radius(self.w_res)
     if cur_sr != 0:
         self.w_res *= new_sr / cur_sr
Ejemplo n.º 6
0
    def __init__(self,
                 hidden_nodes=200,
                 spectral_radius=0.9,
                 washout=200,
                 w_in_density=1.0,
                 w_out_density=1.0,
                 w_res_density=1.0,
                 input_scaling=1.0,
                 w_in_distrib=Distribution.uniform,
                 w_res_distrib=Distribution.uniform,
                 awgn_train_std=0.0,
                 awgn_test_std=0.0,
                 adc_quantization=None,
                 readout='pinv',
                 w_ridge=0.00):
        super(ESN, self).__init__()

        self.hidden_nodes = hidden_nodes
        self.spectral_radius = spectral_radius
        self.f = torch.tanh
        self.w_in_density = w_in_density
        self.w_out_density = w_out_density
        self.w_res_density = w_res_density
        self.washout = washout
        self.input_scaling = input_scaling
        self.w_in_distrib = w_in_distrib
        self.w_res_distrib = w_res_distrib
        self.awgn_train_std = awgn_train_std
        self.awgn_test_std = awgn_test_std
        self.adc_quantization = adc_quantization
        self.readout = readout
        self.rr = Ridge(alpha=w_ridge)

        # We can't just mask w_out with the density, as the masked out nodes
        # must be hidden during training as well.
        mask_size = int(self.hidden_nodes * self.w_out_density)
        self.w_out_mask = np.random.choice(self.hidden_nodes,
                                           mask_size,
                                           replace=False)
        self.w_out_mask = torch.from_numpy(self.w_out_mask)
        self.output_dim = self.w_out_mask.shape[0]

        if self.w_res_distrib == Distribution.gaussian:
            w_res = torch.empty(self.hidden_nodes,
                                hidden_nodes).normal_(mean=0.0, std=1.0)
        elif self.w_res_distrib == Distribution.uniform:
            w_res = torch.rand(self.hidden_nodes, self.hidden_nodes) - 0.5
        elif self.w_res_distrib == Distribution.fixed:
            w_res = torch.ones(self.hidden_nodes, self.hidden_nodes)

        w_res[torch.rand(self.hidden_nodes, self.hidden_nodes) >
              self.w_res_density] = 0.0
        w_res *= self.spectral_radius / _spectral_radius(w_res)

        if self.w_in_distrib == Distribution.gaussian:
            w_in = torch.empty(self.hidden_nodes).normal_(mean=0.0, std=1.0)
        elif self.w_in_distrib == Distribution.uniform:
            w_in = torch.rand(self.hidden_nodes) - 0.5
        elif self.w_in_distrib == Distribution.fixed:
            w_in = torch.ones(self.hidden_nodes)

        w_in[torch.rand(self.hidden_nodes) > self.w_in_density] = 0.0
        w_in *= self.input_scaling

        w_out = torch.ones(self.hidden_nodes)

        self.register_buffer('w_res', w_res)
        self.register_buffer('w_in', w_in)
        self.register_buffer('w_out', w_out)