Topic: Algoritmo genetico su rete neurale  (Letto 93 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Francesco G

  • python unicellularis
  • *
  • Post: 3
  • Punti reputazione: 0
    • Mostra profilo
Algoritmo genetico su rete neurale
« il: Maggio 14, 2020, 15:17 »
Buongiorno a tutti, sono nuovo sul forum e anche nell'ambiente machine learning, per cui mi scuso per eventuali imprecisioni.
Attualmente dovrei creare un programma in python che faccia le seguenti cose:

1 - Generazione di una rete neurale che simuli il comportamento di una certa funzione (che conosco);
2 - GA che vada a cercare il minimo di questa rete.

Il punto è che mi è stato detto che ad ogni epoch del genetico il minimo trovato debba essere aggiunto al set di train della rete, cosi da generarne una più "precisa" (non so se è il termine più corretto) che a sua volta verrà poi ottimizzata e via così...
Premetto che è la prima volta che scrivo qualcosa di machine learning, al momento sono riuscito a scrivere la rete ma non riesco ad innestare la cose all'interno del ciclo del genetico.

PS. So che l'uso di una rete neurale su una funzione nota non ha senso, ma mi serve solo per validare l'algoritmo per usi futuri dove la funzione non sarà nota a priori.

Grazie a chiunque spenderà del tempo per darmi qualche dritta!

Offline caronte

  • python erectus
  • ***
  • Post: 233
  • Punti reputazione: 0
    • Mostra profilo
Re:Algoritmo genetico su rete neurale
« Risposta #1 il: Maggio 14, 2020, 22:25 »
ciao
come prima cosa ticonviene postare quello che hai scritto, perche' a 'parole' soprattutto se non conosci bene la 'cosa'.., non ci capiamo poi tanto;
quindi come stai scrivendo l'algoritmo? in python? in tensorflow? Pytorch, keras?...

secondo: ovvero l'upgrade dei --parametri-- del network conviene farlo  ad ogni step/iterazione e quasi mai ad ogni epoca, a meno che tu non abbia 'numero di istanze' relativamente piccolo o un botto di memoria..
e si, il GA come SGD  e suoi derivati, ottimizzano i pesi in backprop ad ogni "step / batch size" basandosi sull'output della loss function che hai scelto per il tuo mdoello, portandoli, -- si spera-- vero il minimum..
capirai che dire una cosa del genere: " ad ogni epoch del genetico il minimo trovato debba essere aggiunto al set di train della rete.." nn ha alcun senso...

Offline Francesco G

  • python unicellularis
  • *
  • Post: 3
  • Punti reputazione: 0
    • Mostra profilo
Re:Algoritmo genetico su rete neurale
« Risposta #2 il: Maggio 15, 2020, 12:41 »
Ciao, grazie della rapida risposta!  :)
Di seguito posto quanto scritto fino ad ora, tutta la prima parte di codice sono dati passati dal tutor e anche la funzione su cui si allena la rete è data dal tutor, fino al fit della rete in teoria tutto bene sembra che essa si comporti bene (ho provato anche a plottare per punti funzione e rete e son molto simili, mse < 0.5 una volta sistemato set di train e test adeguatamente)

from sys import exit
import pathlib

import pandas as pd
import numpy as np
from scipy.optimize import minimize

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.metrics import mean_squared_error

import MatFunc as mf

#il DoE è generato con una distribuzione latin hypercube 2d
def GenerateLHS(nd, ns, opt='smt'):

    if opt == 'smt':
        from smt.sampling_methods import LHS

        xl = np.zeros((nd,2))
        xl[:,1] = 1.0
        # option are 'center', 'maximin', 'centermaximin', 'correlation', 'ese'
        smp = LHS(criterion='ese', xlimits = xl)
        data = smp(ns)

    elif opt == 'pyDOE':
        from pyDOE2 import lhs

        data = lhs(nd, samples=ns, criterion='center', iterations = 1000)
        #data = lhs(nd, samples=ns, criterion='maximin', iterations = 1000)
        #data = lhs(nd, samples=ns, criterion='centermaximin', iterations = 1000)
        #data = lhs(nd, samples=ns, criterion='correlation', iterations = 1000)
   
    elif opt == 'pyKriging':
        from pyKriging.samplingplan import samplingplan

        sp = samplingplan(nd) 
        data = sp.optimallhc(ns, iterations=10)

    else:
        print('GenerateLHS, wrong option', opt)
        exit()

    return data
################################################################################
# INPUT VARIABLES ##############################################################
################################################################################

currentPath = pathlib.Path.cwd()

# Set Variable bound file
xBoundFile = 'Levy.csv'

# Set number of initial Database
nsol = 50

################################################################################
################################################################################
################################################################################

xBound = pd.read_csv(currentPath/xBoundFile, header = 0, sep='\t')

# Evaluate the variable ranges
xBound.loc[2] = xBound.loc[1] -xBound.loc[0]

# Print DataFrame Statistics
print(xBound.head())
print(xBound['X1'].values)
print(xBound.info(verbose=True))

# Evaluate the Number of Design variables
ndv = len(xBound.columns)

# Define Initial Database reduced matrix
xr = pd.DataFrame(data = GenerateLHS(ndv, nsol, opt='smt'), columns=xBound.columns)

# update NON-reduced matrix
x = pd.DataFrame(data = xBound.loc[0] +xr*xBound.loc[2], columns=xBound.columns)


################################################################################
################################################################################
################################################################################
# Eval all initial solutions: valuto le varie coppie x1,x2 nella funzione in esame: funzione di Ackley (2 variabili)

y = []
for i in range(nsol):
    y.append(mf.Ackley(x.loc[i]))

y = pd.DataFrame(data = y, columns=['Y'])
df = pd.concat([x, y], axis=1)
x1 = df['X1'].to_numpy()
x2= df['X2'].to_numpy()

#creo una lista di liste per accoppiare le coordinate [X1(i),X2(i)]
x = [[x1[i],x2[i]] for i in range(len(x))]

# porto tutto in ndarray
y_array = np.array(y, dtype=float)
x_array = np.array(x, dtype=float)

#Suddivido i dati in set di train e set di test
x_train, x_test, y_train, y_test = train_test_split(x_array, y_array, test_size=0.9, random_state=42)

#rete neurale
ANN = MLPRegressor(
    hidden_layer_sizes=(1000,),  activation='relu', solver='adam', alpha=0.001, batch_size='auto',
    learning_rate='constant', learning_rate_init=0.01, power_t=0.5, max_iter=1000, shuffle=True,
    random_state=0, tol=0.0001, verbose=False, warm_start=False, momentum=0.9, nesterovs_momentum=True,
    early_stopping=False, validation_fraction=0.1, beta_1=0.9, beta_2=0.999, epsilon=1e-08)

#fit
ANN.fit(x_train, y_train)

y_pred = ANN.predict(x_test)
print("Root mean squared error: {0:.2f}".format(mean_squared_error(y_test, y_pred)))



A questo punto mi trovo con una rete allenata (devo sistemare la suddivisione tra train e test ma su questo no problema), quello che dovrei fare ora è generare una popolazione iniziale di (x1, x2), valutarli con la rete neurale e attraverso un algoritmo genetico trovarne il minimo.
Il mio problema è che devo fare una cosa ricorsiva e non ho idea di come fare, in pratica mano a mano che il genetico trova dei punti migliori dovrebbe aggiungerli al set di train, riallenare la rete che poi va nuovamente nel genetico e così via fino ad un certo criterio di stop.
Ho guardato degli esempi su come settare un genetico seguendo questo esempio: https://hackernoon.com/genetic-algorithms-explained-a-python-implementation-sd4w374i ma sto fallendo nel tentativo di implementarlo sul mio problema appunto perchè non so come fare questo processo ciclico tra rete e genetico.

Offline caronte

  • python erectus
  • ***
  • Post: 233
  • Punti reputazione: 0
    • Mostra profilo
Re:Algoritmo genetico su rete neurale
« Risposta #3 il: Maggio 15, 2020, 22:02 »
forse mi sfugge qualcosa ma non hoc apito il perche' vuoi usare il GA optimizer cosi..

cioe' e' la rete stessa che hai definito che ti deve approssimare al meglio la funzione in questione, qualunque essa sia;
e lo fa sfruttando appunto l'optimizer implementato nel modello, nel processo inverso di backpropagazione;
in questo caso l'optimizer e' l'--adam-- e a ragion veduta, cieo' tu stai gia' usando un optimizer che non e' GA, e a meno che non lo implementi manualmente in sklearn, mah...nn avrebbe gran senso

quindi se la funzione 'oggettiva' che hai definito nel tuo caso, che e' la RMSE, la rete non fara' altro che
minimizzare l'errore, quindi aggiornare i parametri in maniera da arrivare al minimo della loss definita, -- l'RMSE, appunto..
pertanto non capisco il resto del problema...a meno che tu non voglia fare due cose distinte...poi puo' essere che non ho centrato il punto io..

se vuoi usare GA come optimizer, dovresti implementarti la rete 'manualemnte' in python o sfruttare frameworks che ti consentano di scriverti, se non gia' definito, un GA come optimizer..se non sbaglio Tensorflow ha qualcoasa del genere:
https://www.tensorflow.org/probability/api_docs/python/tfp/optimizer/differential_evolution_minimize, che cmq devi implementare all'i nterno di un  mdoello scritto in TF...chiaramente;

ps. Ga non viene quasi mai usato come optimizert, probabilmente perche' risulterebbe abbastanza ingombrante e lento, quindi poco effciente da usare nella BP,  diversamente l'ho visto usare come tuning dei hyperparametri, ma sostanzialemnet solo in 'shallow algorithms', raramente avrebbe senso sulle reti  e nel deep learning in generale; poi....

Offline Francesco G

  • python unicellularis
  • *
  • Post: 3
  • Punti reputazione: 0
    • Mostra profilo
Re:Algoritmo genetico su rete neurale
« Risposta #4 il: Maggio 18, 2020, 12:14 »
Il mio obiettivo finale è quello di minimizzare una certa funzione di N variabili attraverso un algoritmo genetico. Nel fare questa cosa mi è stato consigliato dal tutor di usare un modello surrogato (in tal caso una rete neurale) e di ottimizzare quella invece della funzione originale.
Mi scuso per la mia poca pratica in questi argomenti (sono un ing. meccanico e non mastico troppo bene queste cose), da quello che ho capito la rete si dovrebbe allenare all'interno del GA in modo ricorsivo in modo che i minimi del GA vadano a far parte del set di train)
Non so veramente come muovermi a riguardo  :(

Offline caronte

  • python erectus
  • ***
  • Post: 233
  • Punti reputazione: 0
    • Mostra profilo
Re:Algoritmo genetico su rete neurale
« Risposta #5 il: Maggio 20, 2020, 21:07 »
ciao
non devi scusarti di nulla;
allora non capisco il senso di "far girare una rete neurale dentro un GA ""???
secondo me dovresti chiarirti bene col tuo tutor;
vero sarebbe il contrario, ovvero  istruire una rete tramite GA; cosa che come ti ho gia' detto non si fa quasi mai, perche' molto piu efficienti affidarsi a derivati della famiglia dei --stochastic gradient descent --(di cui fa parte appunto l'adam implementato in sklearn come nella maggior parte dei frameworks votati al DL;
detto questo, invece ha molto piu senso minimizzare/maximizzare una funzione solo tramite GA, questo si;

 fatti cmq un giro in rete..e' pieno di dimostarzioni in python, come ad es. una delle prime cose che esce fuori:

https://towardsdatascience.com/genetic-algorithm-implementation-in-python-5ab67bb124a6
https://wiki.fysik.dtu.dk/ase/tutorials/ga/ga_optimize.html
....