2015-07-30 10 views
5

Ich versuche eine Scan-Schleife in theano zu implementieren, die bei einem Tensor eine "bewegliche Scheibe" der Eingabe verwendet. Es muss nicht wirklich ein sich bewegendes Stück sein, es kann ein vorverarbeiteter Tensor zu einem anderen Tensor sein, der das sich bewegende Stück darstellt.Überlappende Iteration über den Tensor

wesentlichen in Betracht:

[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) 

wo |-------| der Eingang für jede Iteration ist.

Ich versuche herauszufinden, die effizienteste Möglichkeit, es zu tun, vielleicht mit einer Form der Referenzierung oder Manipulation von Schritten, aber ich habe es nicht geschafft, etwas zu arbeiten, auch für reine numpy.

Eine mögliche Lösung, die ich gefunden habe, kann here gefunden werden, aber ich kann nicht herausfinden, wie man schreitet, und ich sehe keinen Weg, das mit theano zu verwenden.

+1

[ 'theano.sandbox.neighbours.images2neibs'] (http://deeplearning.net/software/theano/library/tensor/nnet/neighbours.html#module-sandbox .neighbours) liegt in der Nähe zu dem, was Sie suchen. Soweit ich weiß, funktioniert es nur mit einem 4D Tensor, aber Sie könnten versuchen, Ihren 1D Vektor in (1, 1, 1, N) umzuformen. –

+1

Hm, das erfordert tatsächlich einige spezifischere Informationen, z. B. ob die Funktion, die auf das Segment angewendet werden soll, die vergangenen Ergebnisse sehen muss oder nicht. Die allgemeinste Lösung wird mit 'theano.scan', wie in der Antwort unten, aber mit einigen zusätzlichen Informationen, diese reduzieren können z.B. eine Faltung mit einem geeigneten Kern durch eine andere Funktion gefolgt. – eickenberg

+0

Der Grund, warum ich diese bewegliche Scheibe möchte, ist, weil ich versuche, eine 1d Faltung auf jede Scheibe anzuwenden. Ich denke, was ich will ist bereits [hier] (https://github.com/Lasagne/Lasagne/blob/master/lasagne/theano_extensions/conv.py#L97) implementiert, aber ich möchte, dass ich die Ergebnisse im Tandem mit anderen Operationen möchte während eines Scans, und ich gehe davon aus, dass es effizienter wäre, jedes Faltungsergebnis für jede Scheibe zu erhalten, und nachdem ich damit fertig bin, gehe zur nächsten über. Ich denke, @carriepl hat genau das beantwortet, was ich meine Theorie testen wollte. Wenn Sie weitere Beispiele dafür haben, teilen Sie uns bitte mit! Danke –

Antwort

3

Sie können an jedem Zeitschritt einen Vektor enthält den Startindex für die Scheibe bauen und rufen Scan mit diesem Vektor als eine Sequenz und Ihre ursprünglichen Vektor als Nicht-Sequenz. Innerhalb von Scan können Sie dann bei jeder Iteration das gewünschte Segment erhalten.

enthalten ich ein Beispiel, in dem ich die Größe der Scheiben auch ein symbolischer Eingang, die Sie wollen, es ändern von einem Aufruf Ihrer Theano Funktion zum nächsten Fall gemacht:

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) 

Ausführen der Funktion mit Ihren Parametern erzeugt die Ausgabe:

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

Genau das habe ich gebraucht. Elegant und einfach! Vielen Dank! –

1

könnten Sie this rolling_window recipe verwenden:

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)) 

die druckt

[[ 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]] 

Beachten Sie, dass es auch ausgefallenere Erweiterungen dafür sind, wie Joe Kington's rolling_window, die älter als mehrdimensionale Fenster rollen kann, und Sebastian Berg's implementation die Darüber hinaus kann durch Schritte springen.

+0

Ich schaffte es, das rollende Fenster mit 'np.lib.tride_tricks.as_strided' für bestimmte Schritte und Formen arbeiten zu lassen, aber dieses Rezept war genau das, was ich brauchte, um mein Leben einfacher zu machen. Du hast mich gerettet viel mit numpy und Debuggen Hantieren.Ich werde etwas warten, für den Fall, dass irgendjemand etwas in theanos Berechnungsgraphen vorschlägt, und wenn nichts kommt, werde ich Ihre Antwort akzeptieren. Vielen Dank! –

+0

Dies ist von Anfang an in 'sklearn.feature_extraction.image.extract_patches' zugänglich. – eickenberg

+0

Die Frage stellte jedoch eine Operation über den Tensor vor. – tdihp