diff --git a/neural_network/adaptive_resonance_theory_1.py b/neural_network/adaptive_resonance_theory_1.py new file mode 100644 index 000000000000..abff2cf7e294 --- /dev/null +++ b/neural_network/adaptive_resonance_theory_1.py @@ -0,0 +1,101 @@ +""" +- - - - - -- - - - - - - - - - - - - - - - - - - - - - - +Name - - ART1 - Adaptive Resonance Theory 1 +Goal - - Cluster Binary Data +Detail: Unsupervised clustering model using a vigilance parameter + to control cluster formation in binary datasets. + * Initialize with features and vigilance threshold + * Train to form clusters based on input patterns + * Predict for assigning new inputs to clusters +Author: Your Name +Github: your_email@example.com +Date: 2024.10.31 +- - - - - -- - - - - - - - - - - - - - - - - - - - - - - +""" + +import numpy as np + + +class ART1: + def __init__(self, num_features, vigilance=0.8): + """ + Initialize the ART1 model with the number of features and the vigilance parameter. + + Parameters: + num_features (int): Number of features in input binary data. + vigilance (float): Vigilance parameter to control cluster formation (0 < vigilance <= 1). + """ + self.num_features = num_features + self.vigilance = vigilance + self.weights = [] # Stores the weights for clusters + + def _similarity(self, x, w): + """ + Calculate similarity between input vector x and weight vector w. + + Parameters: + x (np.array): Input binary vector. + w (np.array): Cluster weight vector. + + Returns: + float: Similarity value based on the intersection over the input length. + """ + return np.sum(np.minimum(x, w)) / np.sum(x) + + def _weight_update(self, x, w): + """ + Update weights for a cluster based on input vector. + + Parameters: + x (np.array): Input binary vector. + w (np.array): Cluster weight vector. + + Returns: + np.array: Updated weight vector. + """ + return np.minimum(x, w) + + def train(self, data): + """ + Train the ART1 model to form clusters based on the vigilance parameter. + + Parameters: + data (np.array): Binary dataset with each row as a sample. + """ + for x in data: + assigned = False + for i, w in enumerate(self.weights): + # Check similarity and update weights if similarity exceeds vigilance + similarity = self._similarity(x, w) + if similarity >= self.vigilance: + self.weights[i] = self._weight_update(x, w) + assigned = True + break + if not assigned: + self.weights.append(x.copy()) + + def predict(self, x): + """ + Predict the cluster for a new input vector or classify it as a new cluster. + + Parameters: + x (np.array): Input binary vector. + + Returns: + int: Cluster index for the input or -1 if classified as a new cluster. + """ + for i, w in enumerate(self.weights): + # Check similarity for prediction + similarity = self._similarity(x, w) + if similarity >= self.vigilance: + return i + return -1 + + def get_weights(self): + """ + Retrieve the weight vectors of the clusters. + + Returns: + list: List of weight vectors for each cluster. + """ + return self.weights diff --git a/neural_network/radial_basis_function_neural_network.py b/neural_network/radial_basis_function_neural_network.py new file mode 100644 index 000000000000..68e3ecbd2aa3 --- /dev/null +++ b/neural_network/radial_basis_function_neural_network.py @@ -0,0 +1,94 @@ +""" + - - - - - -- - - - - - - - - - - - - - - - - - - - - - - +Name - - RBFNN - Radial Basis Function Neural Network +Goal - - Recognize Patterns in Data +Detail: Total 3 layers neural network + * Input layer + * Hidden layer with RBF activation + * Output layer +Author: Your Name +Github: your_email@example.com +Date: 2024.10.31 +- - - - - -- - - - - - - - - - - - - - - - - - - - - - - +""" + +import numpy as np # For numerical operations + + +class RBFNN: + def __init__(self, input_size, hidden_size, output_size): + """ + Initialize the RBFNN parameters. + + :param input_size: Number of input features + :param hidden_size: Number of hidden units in the RBF layer + :param output_size: Number of output classes + """ + self.input_size = input_size # Size of input layer + self.hidden_size = hidden_size # Size of hidden layer + self.output_size = output_size # Size of output layer + + rng = np.random.default_rng() # Create a random number generator + # Initialize centers and spread of the RBF neurons + self.centers = rng.random((hidden_size, input_size)) # Centers for RBF + self.spread = rng.random(hidden_size) # Spread for each RBF + + # Initialize weights for the output layer + self.weights = rng.random( + (hidden_size, output_size) + ) # Weights for output layer + + def rbf(self, x, center, spread): + """Radial Basis Function (Gaussian).""" + return np.exp(-(np.linalg.norm(x - center) ** 2) / (2 * spread**2)) + + def forward(self, x): + """Forward pass through the network.""" + hidden_outputs = np.zeros(self.hidden_size) # Outputs of hidden layer + for i in range(self.hidden_size): + hidden_outputs[i] = self.rbf( + x, self.centers[i], self.spread[i] + ) # Compute RBF outputs + + output = np.dot(hidden_outputs, self.weights) # Compute final output + return output + + def train(self, x_train, y_train, epochs, learning_rate): + """ + Train the RBFNN model. + + :param x_train: Input data + :param y_train: Target output + :param epochs: Number of training iterations + :param learning_rate: Learning rate for weight updates + """ + for _ in range(epochs): # Use underscore for unused loop variable + for i in range(len(x_train)): + x_i = x_train[i] + y_i = y_train[i] + + # Forward pass + hidden_outputs = np.zeros(self.hidden_size) + for j in range(self.hidden_size): + hidden_outputs[j] = self.rbf(x_i, self.centers[j], self.spread[j]) + + output = np.dot(hidden_outputs, self.weights) # Output layer + + # Calculate the error + error = y_i - output + + # Update weights + self.weights += learning_rate * hidden_outputs.reshape(-1, 1) * error + + def predict(self, x_test): + """ + Predict outputs for given input data. + + :param x_test: Input data + :return: Predicted outputs + """ + predictions = [] + for x in x_test: + output = self.forward(x) # Forward pass to get prediction + predictions.append(output) + return np.array(predictions)