Fammi pesare qui con alcune parole di cautela, precedute da una storia. Molto tempo fa, ho lavorato con un collega quando avevo appena iniziato. Aveva un problema di ottimizzazione da risolvere, con un obiettivo piuttosto disordinato. La sua soluzione era quella di generare i derivati analitici per un'ottimizzazione.
Il problema che ho visto era che questi derivati erano cattivi. Generati usando Macsyma, convertiti in codice fortran, erano ciascuno dozzine di dichiarazioni di continuazione lunghe. In effetti, il compilatore Fortran si è arrabbiato per questo, poiché ha superato il numero massimo di dichiarazioni di continuazione. Mentre abbiamo trovato una bandiera che ci ha permesso di aggirare quel problema, c'erano altri problemi.
Nelle espressioni lunghe, come sono comunemente generate dai sistemi CA, esiste il rischio di un'enorme cancellazione sottrattiva. Calcola un sacco di numeri grandi, solo per scoprire che tutti si annullano a vicenda per produrre un piccolo numero.
Spesso i derivati generati analiticamente sono in realtà più costosi da valutare rispetto ai derivati generati numericamente usando differenze finite. Un gradiente per n variabili può richiedere più di n volte il costo della valutazione della funzione obiettivo. (Potresti essere in grado di risparmiare un po 'di tempo perché molti dei termini possono essere riutilizzati tra le varie derivate, ma ciò ti costringerà anche a fare un'attenta codifica manuale, invece di utilizzare espressioni generate dal computer. E ogni volta che scrivi un codice matematico espressioni, la probabilità di un errore non è banale. Assicurati di verificare la precisione di questi derivati.)
Il punto della mia storia è che queste espressioni generate dalla CA hanno problemi propri. La cosa divertente è che il mio collega era davvero orgoglioso della complessità del problema, che stava chiaramente risolvendo un problema davvero difficile perché l'algebra era così brutta. Quello che non penso che considerasse era se quell'algebra stava effettivamente calcolando la cosa corretta, se lo stava facendo in modo accurato e lo stava facendo in modo così efficiente.
Se fossi stata la persona più anziana al momento in questo progetto, avrei letto l'atto antisommossa. Il suo orgoglio lo indusse a utilizzare una soluzione probabilmente inutilmente complessa, senza nemmeno verificare che un gradiente basato sulla differenza finita fosse adeguato. Scommetto che abbiamo trascorso forse una settimana uomo per far funzionare questa ottimizzazione. Per lo meno, l'avrei consigliato di testare attentamente il gradiente prodotto. È stato preciso? Quanto è stato accurato rispetto ai derivati a differenza finita? In effetti, ci sono strumenti in giro oggi che restituiranno anche una stima dell'errore nella loro previsione derivata. Questo è certamente vero per il codice di differenziazione adattativa, (derivato) che ho scritto in MATLAB.
Prova il codice. Verifica i derivati.
Ma prima di fare QUALUNQUE di questo, considera se altri, migliori schemi di ottimizzazione sono un'opzione. Ad esempio, se stai eseguendo un adattamento esponenziale, allora c'è un'ottima possibilità che tu possa usare un minimo quadrato non lineare partizionato (a volte chiamato minimo quadrato separabile. Penso che fosse il termine usato da Seber e Wild nel loro libro.) L'idea consiste nel suddividere l'insieme di parametri in insiemi intrinsecamente lineari e intrinsecamente non lineari. Utilizzare un'ottimizzazione che funziona solo con i parametri non lineari. Dato che questi parametri sono "conosciuti", i parametri intrinsecamente lineari possono essere stimati usando minimi quadrati lineari semplici. Questo schema ridurrà lo spazio dei parametri nell'ottimizzazione. Rende il problema più solido, poiché non è necessario trovare valori iniziali per i parametri lineari. Riduce la dimensionalità del tuo spazio di ricerca, rendendo il problema più rapido. Ancora una volta ho fornitouno strumento per questo scopo , ma solo in MATLAB.
Se si utilizzano i derivati analitici, codificarli per riutilizzare i termini. Questo può essere un serio risparmio di tempo e può effettivamente ridurre i bug, risparmiando tempo. Ma poi controlla quei numeri!
codegen
pacchetto in esso in quanto può generare codice C o Fortran compatto ed efficiente per ciascuna o tutte le espressioni automaticamente.