0
import numpy as np
import pyswarms as ps
import tensorflow as tf
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# Load Iris dataset
iris = load_iris()
X = iris.data
y = iris.target

# Normalize input data
X = X.astype('float32') / np.max(X)

# One-hot encode target labels
y = tf.keras.utils.to_categorical(y)

# Split the dataset into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.80, random_state=11)

# Define bounds for the particles in PSO
param_bounds = ([-1] * 56, [1] * 56)  # 56 parameters for the weights

# Define a function to optimize (minimize)
def optimize_nn(params):
    model = Sequential()
    model.add(Dense(8, input_shape=(4,), activation='relu'))
    model.add(Dense(3, activation='sigmoid'))

    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    
    # Set the weights for each layer separately
    first_layer_weights = params[:32].reshape((4, 8))
    second_layer_weights = params[32:].reshape((8, 3))
    
    model.layers[0].set_weights([first_layer_weights, np.zeros(8)])
    model.layers[1].set_weights([second_layer_weights, np.zeros(3)])
    
    _, accuracy = model.evaluate(X_train, y_train, verbose=0)
    return 1 - accuracy  # We want to minimize the error, so return (1 - accuracy)

# Create a PSO optimizer
optimizer = ps.single.GlobalBestPSO(n_particles=10, dimensions=56, options={'c1': 0.5, 'c2': 0.3, 'w': 0.9})

# Perform optimization
best_cost, best_params = optimizer.optimize(optimize_nn, iters=50)

# Create a new neural network model
best_model = Sequential()
best_model.add(Dense(8, input_shape=(4,), activation='relu'))
best_model.add(Dense(3, activation='sigmoid'))

# Set the best weights found by PSO
first_layer_weights = best_params[:32].reshape((4, 8))
second_layer_weights = best_params[32:].reshape((8, 3))
best_model.layers[0].set_weights([first_layer_weights, np.zeros(8)])
best_model.layers[1].set_weights([second_layer_weights, np.zeros(3)])

# Compile the best model
best_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Evaluate the best model on the test set
loss, accuracy = best_model.evaluate(X_test, y_test, verbose=0)

print("Test set accuracy: {:.2f}%".format(accuracy * 100))

I have been trying to figure out what the problem is for some time now, I keep getting this error

ValueError: cannot reshape array of size 560 into shape (4,8) Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...

I changed the Dimensions but I couldn't reshape the weights, I couldn't figure out where the 560 is comming from.

I even tried to run the code from https://pyswarms.readthedocs.io/en/latest/examples/usecases/train_neural_network.html but it also had the same problem.

1 Answers1

0

You need to modify your optimize_nn function to handle the entire swarm. You see the code here

import numpy as np
import pyswarms as ps
import tensorflow as tf
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense

# Load Iris dataset
iris = load_iris()
X = iris.data
y = iris.target

# Normalize input data
X = X.astype('float32') / np.max(X)

# One-hot encode target labels
y = tf.keras.utils.to_categorical(y)

# Split the dataset into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.80, random_state=11)

# Define bounds for the particles in PSO
param_bounds = ([-1] * 56, [1] * 56)  # 56 parameters for the weights

# Define a function to optimize (minimize)
def optimize_nn(params):
    losses = []
    for particle in params:
        model = Sequential()
        model.add(Dense(8, input_shape=(4,), activation='relu'))
        model.add(Dense(3, activation='sigmoid'))

        model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
        
        # Set the weights for each layer separately
        first_layer_weights = particle[:32].reshape((4, 8))
        second_layer_weights = particle[32:].reshape((8, 3))
        
        model.layers[0].set_weights([first_layer_weights, np.zeros(8)])
        model.layers[1].set_weights([second_layer_weights, np.zeros(3)])
        
        _, accuracy = model.evaluate(X_train, y_train, verbose=0)
        losses.append(1 - accuracy)  # We want to minimize the error, so return (1 - accuracy)

    return np.mean(losses)

# Create a PSO optimizer
optimizer = ps.single.GlobalBestPSO(n_particles=10, dimensions=56, options={'c1': 0.5, 'c2': 0.3, 'w': 0.9})

# Perform optimization
best_cost, best_params = optimizer.optimize(optimize_nn, iters=50)

# Create a new neural network model
best_model = Sequential()
best_model.add(Dense(8, input_shape=(4,), activation='relu'))
best_model.add(Dense(3, activation='sigmoid'))

# Set the best weights found by PSO
first_layer_weights = best_params[:32].reshape((4, 8))
second_layer_weights = best_params[32:].reshape((8, 3))
best_model.layers[0].set_weights([first_layer_weights, np.zeros(8)])
best_model.layers[1].set_weights([second_layer_weights, np.zeros(3)])

# Compile the best model
best_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Evaluate the best model on the test set
loss, accuracy = best_model.evaluate(X_test, y_test, verbose=0)

print("Test set accuracy: {:.2f}%".format(accuracy * 100))
desertnaut
  • 57,590
  • 26
  • 140
  • 166
I_Al-thamary
  • 3,385
  • 2
  • 24
  • 37