def pca_weights_init(self, data): """Initializes the weights of the competitive layers using Principal Component Analysis technique. Parameters ---------- data : 2D numpy array, shape (n_samples, n_features) Data vectors, where n_samples is the number of samples and n_features is the number of features. Returns ------- self : object Returns self. """ self._competitive_layer_weights = zeros( (self._n_subclass, data.shape[1])) pca_number_of_components = None coord = None if self._n_cols_subclass == 1 or self._n_rows_subclass == 1 or data.shape[ 1] == 1: pca_number_of_components = 1 if self._n_cols_subclass == self._n_rows_subclass: coord = array([[1], [0]]) print(coord) print(coord[0][0]) else: coord = zeros((self._n_subclass, 1)) for i in range(self._n_subclass): coord[i][0] = i else: pca_number_of_components = 2 coord = zeros((self._n_subclass, 2)) for i in range(self._n_subclass): coord[i][0] = i // self._n_cols_subclass coord[i][1] = i % self._n_cols_subclass mx = amax(coord, axis=0) mn = amin(coord, axis=0) coord = (coord - mn) / (mx - mn) coord = (coord - 0.5) * 2 pca = PCA(n_components=pca_number_of_components) pca.fit(data) eigvec = pca.components_ print(eigvec) for i in range(self._n_subclass): for j in range(eigvec.shape[0]): self._competitive_layer_weights[ i] = self._competitive_layer_weights[ i] + coord[i][j] * eigvec[j] if fast_norm(self._competitive_layer_weights[i]) == 0: self._competitive_layer_weights[i] = 0.01 * eigvec[0] # Normalizing the weights if self._weights_normalization == "length": norm = fast_norm(self._competitive_layer_weights[i]) self._competitive_layer_weights[ i] = self._competitive_layer_weights[i] / norm return self
def sample_weights_init(self, data): """ Initializes the weights of the competitive layer, picking random samples from data. Parameters ---------- data : 2D numpy array, shape (n_samples, n_features) Data vectors, where n_samples is the number of samples and n_features is the number of features. Returns ------- self : object Returns self. """ if self._competitive_layer_weights is None: self._competitive_layer_weights = zeros( (self._n_subclass, data.shape[1])) for i in range(self._n_subclass): # Initializing the weights, picking random sample from data rand_idx = random.random_integers(0, len(data) - 1) self._competitive_layer_weights[i] = data[rand_idx] # Normalizing the weights if self._weights_normalization == "length": norm = fast_norm(self._competitive_layer_weights[i]) self._competitive_layer_weights[ i] = self._competitive_layer_weights[i] / norm return self
def update(self, x, epoch, y=None): """Updates the weights of competitive layer and biasees value. Parameters ---------- x : 1D numpy array shape (n_features,) Input vector where n_features is the number of features. y : int Class to which input vector is relative. If y is not given, weights of competitive layer will be updated unsupervised. epoch : int Sequence number of epoch iterations, after each iterations, learning rate and sigma will be recalculated. Returns ------- self : object Returns self. """ win = self.winner(x) win_idx = argmax(win) self._biases = self._bias_function(self._biases, win_idx) self._winner_count[win_idx] += 1 alpha = self._learning_rate_decay_function(self._learning_rate, epoch, self._decay_rate) beta = alpha / 3 radius = self._radius_decay_function(self._radius, epoch, self._radius_decay_rate) correlation = self.neighborhood(win_idx, radius) is_class = None if y is not None: is_class = self.is_class(y) else: is_class = ones(self._n_subclass) for i in range(self._n_subclass): if is_class[i] == 1: self._competitive_layer_weights[ i] = self._competitive_layer_weights[ i] + is_class[i] * alpha * correlation[i] * ( x - self._competitive_layer_weights[i]) elif is_class[i] == -1: self._competitive_layer_weights[ i] = self._competitive_layer_weights[ i] + is_class[i] * beta * correlation[i] * ( x - self._competitive_layer_weights[i]) # Limiting the weights # if self._weights_init == 'random': # self._competitive_layer_weights[i] = limit_range(self._competitive_layer_weights[i]) # else: # self._competitive_layer_weights[i] = limit_range(self._competitive_layer_weights[i], feature_range = feature_range) # Normalizing the weights if self._weights_normalization == "length": norm = fast_norm(self._competitive_layer_weights[i]) self._competitive_layer_weights[ i] = self._competitive_layer_weights[i] / norm return self
def update(self, x, y, epoch): """ Updates the weights of competitive layer and the biases. Parameters ---------- x : 1D numpy array shape (n_features,) Input vector where n_features is the number of features. y : int Class to which input vector is relative. epoch : int Sequence number of epoch iterations, after each iterations, learning rate and sigma will be recalculated. Returns ------- self : object Returns self. """ win = self.winner(x) win_idx = argmax(win) self._biases = self._bias_function(self._biases, win_idx) self._winner_count[win_idx] += 1 y_hat = self.classify(win) alpha = self._learning_rate_decay_function(self._learning_rate, epoch, self._decay_rate) beta = alpha / 3 if y_hat == y: self._competitive_layer_weights[ win_idx] = self._competitive_layer_weights[win_idx] + alpha * ( x - self._competitive_layer_weights[win_idx]) else: self._competitive_layer_weights[ win_idx] = self._competitive_layer_weights[win_idx] - beta * ( x - self._competitive_layer_weights[win_idx]) # Limiting range of weights # if self._weights_init == 'random': # self._competitive_layer_weights[win_idx] = limit_range(self._competitive_layer_weights[win_idx]) # else: # self._competitive_layer_weights[win_idx] = limit_range(self._competitive_layer_weights[win_idx], feature_range = feature_range) # Normalizing the weights if self._weights_normalization == "length": norm = fast_norm(self._competitive_layer_weights[win_idx]) self._competitive_layer_weights[ win_idx] = self._competitive_layer_weights[win_idx] / norm return self
def fit(self, X, y, first_num_iteration, first_epoch_size, second_num_iteration, second_epoch_size): """Training the network using vectors in data sequentially. Parameters ---------- X : 2D numpy array, shape (n_samples, n_features) Training vectors, where n_samples is the number of samples and n_features is the number of features. y : 1D numpy array, shape (n_samples,) Target vector relative to X. first_num_iteration : int Number of iterations of the first phase of training. first_epoch_size : int Size of chunk of data for the first phase of training. second_num_iteration : int Number of iterations of the second phase of training. second_epoch_size : int Size of chunk of data for the second phase of training. Returns ------- self : object Returns self. """ if len(X.shape) <= 1: raise Exception("Data is expected to be 2D array") self._n_feature = X.shape[1] y = y.astype(np.int8) self._n_class = len(unique(y)) if self._n_subclass < self._n_class: raise Exception( "The number of subclasses must be more than or equal to the number of classes" ) # Initializing competitive layer weights if self._competitive_layer_weights is None: self._competitive_layer_weights = random.RandomState().rand( self._n_subclass, self._n_feature) if self._weights_init == 'sample': self.sample_weights_init(X) elif self._weights_init == 'pca': self.pca_weights_init(X) # Normalizing competitive layer weights for i in range(self._n_subclass): if self._weights_normalization == "length": norm = fast_norm(self._competitive_layer_weights[i]) self._competitive_layer_weights[ i] = self._competitive_layer_weights[i] / norm # Initializing linear layer weights if self._linear_layer_weights is None: self._linear_layer_weights = zeros( (self._n_class, self._n_subclass)) # Phase 1: Training using SOM concept self.train_competitive(X, first_num_iteration, first_epoch_size) self.label_neurons(X, y) # Phase 2: Training using LVQ concept self.train_batch(X, y, second_num_iteration, second_epoch_size) return self
def fit(self, X, y, num_iteration, epoch_size): """Fit the model according to the given training data. Parameters ---------- X : 2D numpy array, shape (n_samples, n_features) Training vectors, where n_samples is the number of samples and n_features is the number of features. y : 1D numpy array, shape (n_samples,) Target vector relative to X. num_iteration : int Number of iterations. epoch_size : int Size of chunk of data, after each chunk of data, parameter such as learning rate and sigma will be recalculated. Returns ------- self : object Returns self. """ if len(X.shape) <= 1: raise Exception("Data is expected to be 2D array") self._n_feature = X.shape[1] y = y.astype(np.int8) self._n_class = len(unique(y)) if self._n_subclass < self._n_class: raise Exception( "The number of subclasses must be more than or equal to the number of classes" ) # Initializing competitive layer weights if self._competitive_layer_weights is None: self._competitive_layer_weights = random.RandomState().rand( self._n_subclass, self._n_feature) # Normalizing competitive layer weights for i in range(self._n_subclass): if self._weights_normalization == "length": norm = fast_norm(self._competitive_layer_weights[i]) self._competitive_layer_weights[ i] = self._competitive_layer_weights[i] / norm if self._weights_init == 'sample': self.sample_weights_init(X) elif self._weights_init == 'pca': self.pca_weights_init(X) # Initializing linear layer weights if self._linear_layer_weights is None: self._linear_layer_weights = zeros( (self._n_class, self._n_subclass)) n_subclass_per_class = self._n_subclass // self._n_class for i in range(self._n_class): if i != self._n_class - 1: for j in range(i * n_subclass_per_class, (i + 1) * n_subclass_per_class): self._linear_layer_weights[i][j] = 1 else: for j in range(i * n_subclass_per_class, self._n_subclass): self._linear_layer_weights[i][j] = 1 self.train_batch(X, y, num_iteration, epoch_size) return self