2015-07-30 29 views
5

Sto provando a implementare un ciclo di scansione in theano, che dato un tensore userà una "porzione mobile" dell'input. Non deve essere effettivamente una fetta mobile, può essere un tensore preelaborato a un altro tensore che rappresenta la porzione mobile.Sovrapposizione iterazione sul tensore teano

Essenzialmente:

[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] 
|-------|         (first iteration) 
    |-------|        (second iteration) 
    |-------|        (third iteration) 
       ... 
        ... 
         ... 
           |-------| (last iteration) 

dove |-------| è l'ingresso per ogni iterazione.

Sto cercando di capire il modo più efficiente per farlo, magari usando una qualche forma di referenziazione o manipolazione delle falcate, ma non sono riuscito a far funzionare qualcosa anche per puro numpy.

Una possibile soluzione trovata è here, ma non riesco a capire come utilizzare le falcate e non vedo un modo per usarlo con theano.

+1

[ 'theano.sandbox.neighbours.images2neibs'] (http://deeplearning.net/software/theano/library/tensor/nnet/neighbours.html#module-sandbox .neighbours) è vicino a quello che stai cercando. Per quanto ne so, funziona solo con un tensore 4D, ma potresti provare a rimodellare il tuo vettore 1D in (1, 1, 1, N). –

+1

Hm, questo in realtà richiede alcune informazioni più specifiche, ad esempio se la funzione da applicare al segmento deve visualizzare i risultati passati o meno. La soluzione più generale sta usando 'theano.scan', come nella risposta sotto, ma con alcune informazioni extra, questo può ridursi ad es. una convoluzione con un kernel appropriato seguito da un'altra funzione. – eickenberg

+0

Il motivo per cui desidero questa porzione mobile è perché sto cercando di applicare una convoluzione 1d a ogni sezione. Penso che quello che voglio sia già implementato [qui] (https://github.com/Lasagne/Lasagne/blob/master/lasagne/theano_extensions/conv.py#L97) ma voglio che io desideri i risultati in tandem con altre operazioni durante una scansione, e presumo che sarebbe più efficiente ottenere ogni risultato di convoluzione per ogni fetta, e dopo averlo fatto passare alla successiva. Penso che @carriepl abbia risposto esattamente con ciò che volevo testare la mia teoria. Se avete altri esempi di questo usando theano per favore condividi! Grazie –

risposta

3

È possibile creare un vettore contenente l'indice iniziale per la sezione a ogni timestep e chiamare Scan con quel vettore come sequenza e il vettore originale come non sequenza. Quindi, all'interno di Scansione, è possibile ottenere la fetta desiderata ad ogni iterazione.

ho incluso un esempio in cui ho fatto anche la dimensione delle fette un ingresso simbolico, nel caso in cui si desidera cambiare da una chiamata della funzione Theano a quella successiva:

import theano 
import theano.tensor as T 

# Input variables 
x = T.vector("x") 
slice_size = T.iscalar("slice_size") 


def step(idx, vect, length): 

    # From the idx of the start of the slice, the vector and the length of 
    # the slice, obtain the desired slice. 
    my_slice = vect[idx:idx + length] 

    # Do something with the slice here. I don't know what you want to do 
    # to I'll just return the slice itself. 
    output = my_slice 

    return output 

# Make a vector containing the start idx of every slice 
slice_start_indices = T.arange(x.shape[0] - slice_size + 1) 

out, updates = theano.scan(fn=step, 
         sequences=[slice_start_indices], 
         non_sequences=[x, slice_size]) 

fct = theano.function([x, slice_size], out) 

esecuzione della funzione con i parametri produce l'uscita:

print fct(range(17), 5) 

[[ 0. 1. 2. 3. 4.] 
[ 1. 2. 3. 4. 5.] 
[ 2. 3. 4. 5. 6.] 
[ 3. 4. 5. 6. 7.] 
[ 4. 5. 6. 7. 8.] 
[ 5. 6. 7. 8. 9.] 
[ 6. 7. 8. 9. 10.] 
[ 7. 8. 9. 10. 11.] 
[ 8. 9. 10. 11. 12.] 
[ 9. 10. 11. 12. 13.] 
[ 10. 11. 12. 13. 14.] 
[ 11. 12. 13. 14. 15.] 
[ 12. 13. 14. 15. 16.]] 
+0

Questo è esattamente ciò di cui avevo bisogno. Elegante e semplice! Grazie mille! –

1

Si potrebbe utilizzare this rolling_window recipe:

import numpy as np 

def rolling_window_lastaxis(arr, winshape): 
    """ 
    Directly taken from Erik Rigtorp's post to numpy-discussion. 
    http://www.mail-archive.com/[email protected]/msg29450.html 
    (Erik Rigtorp, 2010-12-31) 

    See also: 
    http://mentat.za.net/numpy/numpy_advanced_slides/ (Stéfan van der Walt, 2008-08) 
    https://stackoverflow.com/a/21059308/190597 (Warren Weckesser, 2011-01-11) 
    https://stackoverflow.com/a/4924433/190597 (Joe Kington, 2011-02-07) 
    https://stackoverflow.com/a/4947453/190597 (Joe Kington, 2011-02-09) 
    """ 
    if winshape < 1: 
     raise ValueError("winshape must be at least 1.") 
    if winshape > arr.shape[-1]: 
     print(winshape, arr.shape) 
     raise ValueError("winshape is too long.") 
    shape = arr.shape[:-1] + (arr.shape[-1] - winshape + 1, winshape) 
    strides = arr.strides + (arr.strides[-1],) 
    return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides) 

x = np.arange(17) 
print(rolling_window_lastaxis(x, 5)) 

che stampa

[[ 0 1 2 3 4] 
[ 1 2 3 4 5] 
[ 2 3 4 5 6] 
[ 3 4 5 6 7] 
[ 4 5 6 7 8] 
[ 5 6 7 8 9] 
[ 6 7 8 9 10] 
[ 7 8 9 10 11] 
[ 8 9 10 11 12] 
[ 9 10 11 12 13] 
[10 11 12 13 14] 
[11 12 13 14 15] 
[12 13 14 15 16]] 

noti che ci sono estensioni ancora più elaborate di questo, come ad esempio Joe Kington's rolling_window che può rotolare sopra le finestre multi-dimensionali, e Sebastian Berg's implementation che , inoltre, può saltare a passi.

+0

Sono riuscito a far funzionare la finestra mobile con 'np.lib.stride_tricks.as_strided' per specifiche falcate e forme, ma questa ricetta era esattamente ciò di cui avevo bisogno per semplificarmi la vita. Mi hai risparmiato un sacco di giocherellando con numpy e debugging.Aspetterò un po 'nel caso qualcuno abbia qualcosa da suggerire per farlo nel grafico computazionale di theano e se non accadrà nulla accetterò la tua risposta. Grazie mille! –

+0

Questo è accessibile btw fuori dalla scatola in 'sklearn.feature_extraction.image.extract_patches'. – eickenberg

+0

La domanda ha richiesto un'operazione su theano tensor però. – tdihp