Selezione del risolutore: NonlinearBlockGS vs NewtonSolver
Ho due gruppi openmdao con dipendenza ciclica tra i gruppi. Calcolo le derivate usando Complex step. Ho un risolutore non lineare per la dipendenza e uso SLSQP per ottimizzare la mia funzione obiettivo. Il problema è con la scelta del risolutore non lineare. Quando utilizzo NonlinearBlockGS
l'ottimizzazione ha successo in 12 iterazioni. Ma quando uso NewtonSolver
con Directsolver
o ScipyKrylov
l'ottimizzazione fallisce (limite di iterazione superato), anche con maxiter=2000
. Le connessioni cicliche convergono, ma è solo che le variabili di progetto non raggiungono i valori ottimali. La differenza tra le variabili di progetto in iterazioni consecutive è nell'ordine 1e-5. E questo aumenta le iterazioni necessarie. Anche quando cambio l'ipotesi iniziale su un valore più vicino al valore ottimale, funziona.
Per verificare ulteriormente, ho convertito il modello in IDF (creando copie di variabili di accoppiamento e vincoli di coerenza) eliminando così la necessità di un risolutore. Ora l'ottimizzazione ha successo in 5 iterazioni e i risultati sono simili ai risultati quando NonlinearBlockGS
viene utilizzato.
Perché succede? Mi sto perdendo qualcosa? Quando dovrei usare NewtonSolver
rispetto ad altri? So che è difficile rispondere senza vedere il codice. Ma è solo che il mio codice è lungo con più componenti e non sono riuscito a ricreare il problema con un modello giocattolo. Quindi qualsiasi intuizione generale è molto apprezzata.
Risposte
Senza vedere il codice, hai ragione che è difficile fornire dettagli specifici.
In termini molto generali, Newton a volte può avere molti più problemi a convergere rispetto a NLBGS (Nota: questo non è assolutamente vero, ma è una buona regola empirica). Quindi quello che immagino stia accadendo è che alla tua prima o seconda iterazione, il risolutore newton non stia effettivamente convergendo. Puoi verificarlo impostando newton.options['iprint']=2
e osservando la cronologia delle iterazioni mentre l'ottimizzatore esegue le iterazioni.
Quando hai un risolutore nella tua ottimizzazione, è fondamentale che tu ti assicuri anche di impostarlo per generare un errore in caso di non convergenza. Alcuni ottimizzatori possono gestire questo errore e torneranno indietro sulla ricerca della riga. Altri moriranno e basta. Ad ogni modo, è importante. Altrimenti, finisci per dare all'ottimizzatore un caso non convergente che non sa essere non convergente.
Questo è un male per due motivi. In primo luogo, i valori dell'obiettivo e dei vincoli che ottiene saranno sbagliati! Secondo, e forse più importante, le derivate che calcola saranno sbagliate! Puoi leggere i dettagli [nel manuale di teoria,] ma in sintesi i metodi di derivazione analitica utilizzati da OpenMDAO presuppongono che i residui siano andati a 0. In caso contrario, la matematica si interrompe. Anche se stavi facendo la differenza finita del modello completo, i modelli non convergenti sono un problema. Otterrai solo spazzatura rumorosa quando proverai a FD. 2
Quindi, supponendo che tu abbia impostato correttamente il tuo modello e che i risolutori lineari abbiano impostato i problemi (sembra che tu lo faccia dato che funziona con NLBGS), è molto probabile che il risolutore newton non stia convergendo. Usa iprint, possibilmente combinato con la stampa di debug del driver , per verificarlo tu stesso. Se è così, devi capire come far comportare meglio newton.
Ci sono alcuni suggerimenti qui che sono piuttosto generali. Puoi anche provare a utilizzare la ricerca della linea armijo , che spesso può stabilizzare una risoluzione di newton a scapito di una certa velocità.
Infine... Newton non è la risposta migliore in tutte le situazioni. Se NLBGS è più stabile e computazionalmente più economico, dovresti usarlo. Applaudo il tuo desiderio di farlo funzionare con Newton. Dovresti assolutamente rintracciare il motivo per cui non lo è, ma se si scopre che Newton non è in grado di risolvere il tuo problema accoppiato in modo affidabile, va bene lo stesso!