| import numpy as np
|
| from pyswarm import pso # Install using `pip install pyswarm`
|
| import matplotlib.pyplot as plt
|
|
|
| # Define the neural network
|
| def neural_network(weights, biases, X):
|
| layer_1 = np.dot(X, weights[0]) + biases[0]
|
| activation_1 = np.tanh(layer_1) # Example activation function
|
| output = np.dot(activation_1, weights[1]) + biases[1]
|
| return output
|
|
|
| # Define the loss function
|
| def loss_function(params, X, y):
|
| num_weights = [(X.shape[1], 4), (4, 1)] # Example architecture: input-4-1
|
| weights = [
|
| params[:np.prod(num_weights[0])].reshape(num_weights[0]),
|
| params[np.prod(num_weights[0]):np.prod(num_weights[0]) + np.prod(num_weights[1])].reshape(num_weights[1]),
|
| ]
|
| biases = [params[-5:-4], params[-4:]] # Adjust indexing based on architecture
|
| predictions = neural_network(weights, biases, X)
|
| return np.mean((predictions - y) ** 2)
|
|
|
| # Generate some example data
|
| np.random.seed(42)
|
| X = np.random.rand(100, 3)
|
| y = np.random.rand(100, 1)
|
|
|
| # PSO optimization
|
| losses = [] # To store losses over iterations
|
|
|
| def objective_function(params):
|
| loss = loss_function(params, X, y)
|
| losses.append(loss) # Log the loss during each iteration
|
| return loss
|
|
|
| # Define bounds for weights and biases
|
| num_weights = [(3, 4), (4, 1)] # Example architecture: 3 inputs -> 4 hidden -> 1 output
|
| total_params = sum(np.prod(w) for w in num_weights) + 5 # + biases
|
| lb = -1 * np.ones(total_params) # Lower bounds
|
| ub = 1 * np.ones(total_params) # Upper bounds
|
|
|
| # Run PSO
|
| best_params, _ = pso(objective_function, lb, ub, swarmsize=50, maxiter=100)
|
|
|
| # Brute-force search around PSO result
|
| def brute_force_search(best_params, step_size=0.01, radius=0.1):
|
| param_range = np.arange(-radius, radius + step_size, step_size)
|
| brute_losses = [] # To store losses in brute-force refinement
|
| best_loss = float('inf')
|
| best_solution = None
|
|
|
| for delta in param_range:
|
| candidate_params = best_params + delta
|
| current_loss = loss_function(candidate_params, X, y)
|
| brute_losses.append(current_loss) # Log loss
|
| if current_loss < best_loss:
|
| best_loss = current_loss
|
| best_solution = candidate_params
|
|
|
| return best_solution, best_loss, brute_losses
|
|
|
| # Perform brute-force refinement
|
| refined_params, refined_loss, brute_losses = brute_force_search(best_params)
|
| print("Refined loss:", refined_loss)
|
|
|
| # Plot accuracy over iterations
|
| plt.figure(figsize=(10, 6))
|
| plt.plot(range(len(losses)), 1 - np.array(losses), label="PSO Accuracy", marker='o')
|
| plt.plot(
|
| range(len(losses), len(losses) + len(brute_losses)),
|
| 1 - np.array(brute_losses),
|
| label="Brute-Force Accuracy",
|
| marker='x',
|
| )
|
| plt.axhline(1 - refined_loss, color="r", linestyle="--", label="Final Accuracy")
|
| plt.xlabel("Iteration")
|
| plt.ylabel("Accuracy")
|
| plt.title("Accuracy Over Iterations")
|
| plt.legend()
|
| plt.grid(True)
|
| plt.show()
|