Ottimizzazione dello sciame di particelle (PSO) da zero.  Spiegazione più semplice in Python |  di Aleksei Rozanov |  Febbraio 2024

 | Intelligenza-Artificiale

Prima di tutto definiamo i nostri ipoparametri. Come in molti altri algoritmi metaeuristici, queste variabili dovrebbero essere aggiustate strada facendo e non esiste un insieme versatile di valori. Ma restiamo a questi:

POP_SIZE = 10 #population size 
MAX_ITER = 30 #the amount of optimization iterations
w = 0.2 #inertia weight
c1 = 1 #personal acceleration factor
c2 = 2 #social acceleration factor

Ora creiamo una funzione che generi una popolazione casuale:

def populate(size):
x1,x2 = -10, 3 #x1, x2 = right and left boundaries of our X axis
pop = rnd.uniform(x1,x2, size) # size = amount of particles in population
return pop

Se lo visualizziamo, otterremo qualcosa del genere:

x1=populate(50) 
y1=function(x1)

plt.plot(x,y, lw=3, label='Func to optimize')
plt.plot(x1,y1,marker='o', ls='', label='Particles')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True)
plt.show()

Immagine di autore.

Qui puoi vedere che ho inizializzato casualmente una popolazione di 50 particelle, alcune delle quali sono già vicine alla soluzione.

Ora implementiamo l'algoritmo PSO stesso. Ho commentato ogni riga del codice, ma se hai domande, non esitare a chiedere nei commenti qui sotto.

"""Particle Swarm Optimization (PSO)"""
particles = populate(POP_SIZE) #generating a set of particles
velocities = np.zeros(np.shape(particles)) #velocities of the particles
gains = -np.array(function(particles)) #calculating function values for the population

best_positions = np.copy(particles) #it's our first iteration, so all positions are the best
swarm_best_position = particles(np.argmax(gains)) #x with with the highest gain
swarm_best_gain = np.max(gains) #highest gain

l = np.empty((MAX_ITER, POP_SIZE)) #array to collect all pops to visualize afterwards

for i in range(MAX_ITER):

l(i) = np.array(np.copy(particles)) #collecting a pop to visualize

r1 = rnd.uniform(0, 1, POP_SIZE) #defining a random coefficient for personal behavior
r2 = rnd.uniform(0, 1, POP_SIZE) #defining a random coefficient for social behavior

velocities = np.array(w * velocities + c1 * r1 * (best_positions - particles) + c2 * r2 * (swarm_best_position - particles)) #calculating velocities

particles+=velocities #updating position by adding the velocity

new_gains = -np.array(function(particles)) #calculating new gains

idx = np.where(new_gains > gains) #getting index of Xs, which have a greater gain now
best_positions(idx) = particles(idx) #updating the best positions with the new particles
gains(idx) = new_gains(idx) #updating gains

if np.max(new_gains) > swarm_best_gain: #if current maxima is greateer than across all previous iters, than assign
swarm_best_position = particles(np.argmax(new_gains)) #assigning the best candidate solution
swarm_best_gain = np.max(new_gains) #assigning the best gain

print(f'Iteration {i+1} \tGain: {swarm_best_gain}')

Dopo 30 iterazioni abbiamo questo:

PSO (w=0,2, c1=1, c2=2). Immagine di autore.

Come puoi vedere, l'algoritmo è caduto nel minimo locale, che non è quello che volevamo. Ecco perché dobbiamo mettere a punto i nostri ipoparametri e ripartire. Questa volta ho deciso di impostare il peso d'inerzia w=0,8quindi, ora la velocità precedente ha un impatto maggiore sullo stato attuale.

PSO (w=0,9, c1=1, c2=2). Immagine di autore.

E voilà, abbiamo raggiunto il minimo globale della funzione. Ti incoraggio vivamente a giocare con POP_SIZE, c₁ e c₂. Ti consentirà di comprendere meglio il codice e l'idea alla base di PSO. Se sei interessato puoi complicare il compito e ottimizzare alcune funzioni 3D e realizzare una bella visualizzazione.

===========================================

(1) Shi Y. Ottimizzazione dello sciame di particelle // Connessioni IEEE. — 2004. — Т. 2. — №. 1. — С. 8–13.

===========================================

Tutti i miei articoli su Medium sono gratuiti e ad accesso aperto, ecco perché apprezzerei davvero se mi seguissi qui!

Ps Sono estremamente appassionato di (Geo)Data Science, ML/AI e cambiamento climatico. Quindi, se vuoi lavorare insieme su qualche progetto, contattami LinkedIn.

🛰️Segui per saperne di più🛰️

Fonte: towardsdatascience.com

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *