2013-12-09 15 views
6

Ho una funzione compare_images(k, a, b) che confronta due 2D-array a e bCome forzare passi più grandi sulle funzioni scipy.optimize?

All'interno del funcion, ho applicare un gaussian_filter con sigma=k-a La mia idea è quella di stimare quanto devo per lisciare immagine a in modo che esso per essere simile all'immagine b

il problema è la mia funzione compare_images restituirà solo valori diversi se k variazione è sopra 0.5, e se lo faccio fmin(compare_images, init_guess, (a, b) di solito rimane bloccata al valore init_guess.

Credo che il problema è fmin (e minimize) tende a iniziare con piccoli passi, che nel mio caso si riprodurre il valore esatto stesso rendimento per compare_images, e così il metodo pensa già trovato un minimo. Proverò solo un paio di volte.

C'è un modo per forzare fmin o qualsiasi altra funzione di riduzione da scipy per eseguire passi più grandi? O esiste un metodo più adatto alle mie esigenze?

MODIFICA: Ho trovato una soluzione temporanea. In primo luogo, come raccomandato, ho usato xtol=0.5 e superiore come argomento per fmin. Anche in questo caso, ho ancora avuto alcuni problemi e alcune volte fmin restituire init_guess. Ho quindi creato un ciclo semplice in modo che se fmin == init_guess, vorrei generare un altro, casuale init_guess e riprovare.

È piuttosto lento, naturalmente, ma ora ho avuto modo di correre. Ci vorranno 20 ore circa per eseguirlo per tutti i miei dati, ma non avrò bisogno di farlo di nuovo.

In ogni caso, per spiegare meglio il problema per coloro che sono ancora interessati a trovare una soluzione migliore:

  • Ho 2 immagini, A e B, contenente alcuni dati scientifici.
  • A sembra alcuni punti con valore variabile (è una matrice di in cui ciascun punto valutati rappresenta cui si è verificato un evento ed è intensità)
  • B sembra un heatmap livellato (è la densità osservata di occorrenze)
  • B sembra proprio come se si fosse applicato un filtro gaussiano a A con un po 'di rumore semi-casuale.
  • Siamo approssimati a B applicando un filtro gaussiano con costante sigma a A. Questo sigma è stato scelto visivamente, ma funziona solo per una determinata classe di immagini.
  • Sto cercando di ottenere un sigma ottimale per ogni immagine, quindi in seguito sono riuscito a trovare alcune relazioni di sigma e la classe di evento mostrata in ciascuna immagine.

In ogni caso, grazie per l'aiuto!

+1

Quindi stai cercando un minimo di diverso, allora? –

+2

Forse non è il modo migliore, ma certamente il più semplice è semplicemente applicare un ridimensionamento lineare alle variabili o il valore ridotto al minimo. Ci sono alcuni valori hardcoded nelle funzioni di ottimizzazione di scipy. Anche giocare con 'xtol' può essere d'aiuto. – Daniel

+0

Mi sembra che sia necessario smussare entrambe le immagini * a * e image * b * per renderle simili, a meno che * b * non sia già livellato. Se questo è il caso, potrebbe essere che (a seconda di come si misura la somiglianza tra le due immagini) qualsiasi livellamento applicato a * a * da solo lo renderà * meno * simile a * b * piuttosto che più simile. Oppure, potresti provare a utilizzare una misura di somiglianza diversa in 'compare_images()' in modo che restituisca valori diversi per similarità anche se la variazione in 'k' è inferiore a 0.5. Se mostri la tua funzione 'compare_images()', le persone potrebbero avere dei suggerimenti? – Simon

risposta

3

Controllo rapido: probabilmente intendevi davvero fmin(compare_images, init_guess, (a,b))?

Se gaussian_filter si comporta come dici tu, la tua funzione è costante a tratti, il che significa che gli ottimizzatori che fanno affidamento su derivati ​​(ad esempio la maggior parte di essi) sono fuori. Puoi provare un ottimizzatore globale come anneal o una ricerca di forza bruta su un intervallo ragionevole di k.

Tuttavia, come hai descritto il problema, in generale, ci sarà solo una chiara, minimo globale di compare_images se b è una versione livellata a. Il tuo approccio ha senso se vuoi determinare la quantità di smoothing di a che rende entrambe le immagini più simili.

Se la domanda è "quanto sono simili le immagini", allora penso che il confronto in pixel (magari con un po 'di livellamento) sia la strada da percorrere. A seconda delle immagini di cui stiamo parlando, potrebbe essere necessario allineare prima le immagini (ad esempio per confrontare le fotografie). Si prega di chiarire :-)

modificare: Un'altra idea che potrebbe aiutare: riscrivere compare_images in modo che calcola due versioni di smoothed- a - uno con sigma = floor(k) e uno con ceil(k) (cioè k intorno al di prossima inferiore/superiore int). Quindi calcolare a_smooth = a_floor*(1-kfrac)+a_ceil*kfrac, con kfrac come parte frazionaria di k. In questo modo la funzione di confronto diventa continua w.r.t k.

Buona fortuna!

+0

Hai ragione, non è 'k', è' compare_immagini' in 'fmin'. Cercherò di chiarire nel post originale – user2329994

1

Basin hopping può fare un po 'meglio, in quanto ha un'alta probabilità di continuare comunque quando rimane bloccato all'altopiano.

ho trovato su questa funzione di esempio che lo fa abbastanza bene con una bassa temperatura:

>>> opt.basinhopping(lambda (x,y): int(0.1*x**2 + 0.1*y**2), (5,-5), T=.1) 
    nfev: 409 
    fun: 0 
     x: array([ 1.73267813, -2.54527514]) 
message: ['requested number of basinhopping iterations completed successfully'] 
    njev: 102 
    nit: 100 
Problemi correlati