[PYTHON] Theanos Faltung

Um ein CNN in Theano zu erstellen, habe ich einige Untersuchungen zur zweidimensionalen Faltungsfunktion von Theano "theano.tensor.nnet.conv ()" durchgeführt. Verglichen mit der N-dimensionalen Faltungsfunktion `scipy.signal.fftconvolve ()`, die wahrscheinlich häufig in der Signalverarbeitung verwendet wird.

Falten zwischen zweidimensionalen Arrays

Versuchen wir zunächst, einfache zweidimensionale Arrays zusammenzufalten.

import theano
import theano.tensor as T
import theano.tensor.signal as signal 
import scipy.signal as s

m = T.matrix()
w = T.matrix()

#Muss Rang 4 sein.
o_full = nnet.conv.conv2d(m[None,None,:,:], w[None, None,:,:],
                          border_mode='full')
o_valid = nnet.conv.conv2d(m[None,None,:,:], w[None, None,:,:],
                          border_mode='valid')

m_arr = arange(25.).reshape((5,5)).astype(float32)
w_arr = ones((3,3)).astype(float32)
print("m_arr =")
print(m_arr)
print("w_arr =")
print(w_arr)

print("Output for Theano.")
print("full:")
print(o_full.eval({m:m_arr, w:w_arr}).round().astype(int))
print("valid:")
print(o_valid.eval({m:m_arr, w:w_arr}).round().astype(int))

print("Output for scipy.")
print("full:")
print(s.fftconvolve(m_arr, w_arr, "full").round().astype(int))
print("valid:")
print(s.fftconvolve(m_arr, w_arr, "valid").round().astype(int))

Gewundenes Arraym_arrFensterfunktion zum Falten(oder Kernel oder Filter)w_arrZutheano.tensor.nnet.conv.conv2d()Wannscipy.signal.fftconvolve()``` Es fließt zu jedem. Hier,

# Muss Rang 4 sein.
o_full = nnet.conv.conv2d(m[None,None,:,:], w[None, None,:,:],
                          border_mode='full')
o_valid = nnet.conv.conv2d(m[None,None,:,:], w[None, None,:,:],
                          border_mode='valid')

mögen,m[None,None,:,:], w[None, None,:,:]Das Format des Eingabe- und Kernel-Arrays ist[Anzahl der Bilder, Anzahl der Kanäle, Höhe, Breite]Denn es ist.m,wIst Rang 2T.matrix()Weil es definiert wurde als[None, None,:,:]Auf diese Weise haben wir den Spitzenplatz um zwei erhöht.Diese Sendung ist die gleiche wie die von NumpyEs ist also sehr einfach, es persönlich zu benutzen.

Die Ausgabe sieht folgendermaßen aus:

m_arr =
[[  0.   1.   2.   3.   4.]
 [  5.   6.   7.   8.   9.]
 [ 10.  11.  12.  13.  14.]
 [ 15.  16.  17.  18.  19.]
 [ 20.  21.  22.  23.  24.]]
w_arr =
[[ 1.  1.  1.]
 [ 1.  1.  1.]
 [ 1.  1.  1.]]
Output for Theano.
full:
[[[[  0   1   3   6   9   7   4]
   [  5  12  21  27  33  24  13]
   [ 15  33  54  63  72  51  27]
   [ 30  63  99 108 117  81  42]
   [ 45  93 144 153 162 111  57]
   [ 35  72 111 117 123  84  43]
   [ 20  41  63  66  69  47  24]]]]
valid:
[[[[ 54  63  72]
   [ 99 108 117]
   [144 153 162]]]]
Output for scipy.
full:
[[  0   1   3   6   9   7   4]
 [  5  12  21  27  33  24  13]
 [ 15  33  54  63  72  51  27]
 [ 30  63  99 108 117  81  42]
 [ 45  93 144 153 162 111  57]
 [ 35  72 111 117 123  84  43]
 [ 20  41  63  66  69  47  24]]
valid:
[[ 54  63  72]
 [ 99 108 117]
 [144 153 162]]

Die Ausgabe der Faltung wird zur einfachen Anzeige abgerundet und dann in int konvertiert.

theano.tensor.nnet.conv()Dann grenzen_Es gab ein Argument namens mode. Sie können dafür voll oder gültig auswählen. Die Faltung nimmt die Summe, indem sie das Bild multipliziert, während der Filter bewegt wird. Voll ist jedoch ein Modus, der das Ergebnis in dem Zustand enthält, in dem mindestens eines der Elemente das Bild überlappt, selbst wenn der Filter aus dem Bild herausragt. Gültig ist Dieser Modus gibt nur das Ergebnis aus, wenn der Filter nicht über das Bild hinausreicht. Bild einer bestimmten Achse bzw. Filtergröße$M,m$Zu diesem Zeitpunkt ist die Größe der Achse mit dem Ausgabearray voll$M+(m-1)$, Gültig$M-(m-1)$Wird sein. Höhe im obigen Beispiel(oder Breite)Aber$M=5,m=3$Daher ist es 7, wenn es voll ist, und 3, wenn es gültig ist.



Wenn Sie die Ausgabe überprüfen,```theano.tensor.nnet.conv()```Wann```scipy.signal.fftconvolve()```damit(Mit Ausnahme des Ranges des Arrays)等しいこWannが確認damitきます。

Die beiden Ausgänge haben jedoch unterschiedliche Bedeutungen.```scipy.signal.fftconvolve()```Gibt das Ergebnis einer reinen N-dimensionalen Faltung zurück, während```theano.tensor.nnet.conv()```Gibt das Ergebnis der Faltung für jede Anzahl von Bildern und jeden Filter zurück. Das Ausgabearray ist```[Anzahl der Bilder, Anzahl der Dateien, Höhe, Breite]```ist. Auch wie später beschrieben wird```theano.tensor.nnet.conv()```Muss die gleiche Anzahl von Kanälen für das Bild und den Filter haben.

#Faltung beim Hinzufügen der Abmessungen der Anzahl der Bilder und der Anzahl der Kanäle

Als nächstes führen wir eine Faltung durch, die die Dimensionen der Anzahl der Bilder und der Anzahl der Kanäle hinzufügt. Falten Sie einen 3x3-Filter mit 1 Bild und 3 Kanälen für ein 5x5-Bild mit 2 Bildern und 3 Kanälen. Das Programm sieht folgendermaßen aus:

```python
m = T.tensor4()
w = T.tensor4()

# Muss Rang 4 sein.
o_full = nnet.conv.conv2d(m, w,
                          border_mode='full')
o_valid = nnet.conv.conv2d(m, w,
                          border_mode='valid')

m_arr = arange(2*3*5*5).reshape((2, 3, 5, 5)).astype(float32)
w_arr = ones((1,3,3,3)).astype(float32)
print("m_arr =")
print(m_arr)
print("w_arr =")
print(w_arr)

print("Output for Theano.")
print("full:")
print(o_full.eval({m:m_arr, w:w_arr}).round().astype(int))
print("valid:")
print(o_valid.eval({m:m_arr, w:w_arr}).round().astype(int))

print("Output for scipy.")
print("full:")
print(s.fftconvolve(m_arr, w_arr, "full").round().astype(int))
print("valid:")
print(s.fftconvolve(m_arr, w_arr, "valid").round().astype(int))

Einen Tensor mit Rang 4 einstellenmWannwZuT.tensor4()Ist eingestellt.

m_arr =
[[[[   0.    1.    2.    3.    4.]
   [   5.    6.    7.    8.    9.]
   [  10.   11.   12.   13.   14.]
   [  15.   16.   17.   18.   19.]
   [  20.   21.   22.   23.   24.]]

  [[  25.   26.   27.   28.   29.]
   [  30.   31.   32.   33.   34.]
   [  35.   36.   37.   38.   39.]
   [  40.   41.   42.   43.   44.]
   [  45.   46.   47.   48.   49.]]

  [[  50.   51.   52.   53.   54.]
   [  55.   56.   57.   58.   59.]
   [  60.   61.   62.   63.   64.]
   [  65.   66.   67.   68.   69.]
   [  70.   71.   72.   73.   74.]]]


 [[[  75.   76.   77.   78.   79.]
   [  80.   81.   82.   83.   84.]
   [  85.   86.   87.   88.   89.]
   [  90.   91.   92.   93.   94.]
   [  95.   96.   97.   98.   99.]]

  [[ 100.  101.  102.  103.  104.]
   [ 105.  106.  107.  108.  109.]
   [ 110.  111.  112.  113.  114.]
   [ 115.  116.  117.  118.  119.]
   [ 120.  121.  122.  123.  124.]]

  [[ 125.  126.  127.  128.  129.]
   [ 130.  131.  132.  133.  134.]
   [ 135.  136.  137.  138.  139.]
   [ 140.  141.  142.  143.  144.]
   [ 145.  146.  147.  148.  149.]]]]
w_arr =
[[[[ 1.  1.  1.]
   [ 1.  1.  1.]
   [ 1.  1.  1.]]

  [[ 1.  1.  1.]
   [ 1.  1.  1.]
   [ 1.  1.  1.]]

  [[ 1.  1.  1.]
   [ 1.  1.  1.]
   [ 1.  1.  1.]]]]
Output for Theano.
full:
[[[[  75  153  234  243  252  171   87]
   [ 165  336  513  531  549  372  189]
   [ 270  549  837  864  891  603  306]
   [ 315  639  972  999 1026  693  351]
   [ 360  729 1107 1134 1161  783  396]
   [ 255  516  783  801  819  552  279]
   [ 135  273  414  423  432  291  147]]]


 [[[ 300  603  909  918  927  621  312]
   [ 615 1236 1863 1881 1899 1272  639]
   [ 945 1899 2862 2889 2916 1953  981]
   [ 990 1989 2997 3024 3051 2043 1026]
   [1035 2079 3132 3159 3186 2133 1071]
   [ 705 1416 2133 2151 2169 1452  729]
   [ 360  723 1089 1098 1107  741  372]]]]
valid:
[[[[ 837  864  891]
   [ 972  999 1026]
   [1107 1134 1161]]]


 [[[2862 2889 2916]
   [2997 3024 3051]
   [3132 3159 3186]]]]
Output for scipy.
full:
[[[[   0    1    3    6    9    7    4]
   [   5   12   21   27   33   24   13]
   [  15   33   54   63   72   51   27]
   [  30   63   99  108  117   81   42]
   [  45   93  144  153  162  111   57]
   [  35   72  111  117  123   84   43]
   [  20   41   63   66   69   47   24]]

  [[  25   52   81   87   93   64   33]
   [  60  124  192  204  216  148   76]
   [ 105  216  333  351  369  252  129]
   [ 135  276  423  441  459  312  159]
   [ 165  336  513  531  549  372  189]
   [ 120  244  372  384  396  268  136]
   [  65  132  201  207  213  144   73]]

  [[  75  153  234  243  252  171   87]
   [ 165  336  513  531  549  372  189]
   [ 270  549  837  864  891  603  306]
   [ 315  639  972  999 1026  693  351]
   [ 360  729 1107 1134 1161  783  396]
   [ 255  516  783  801  819  552  279]
   [ 135  273  414  423  432  291  147]]

  [[  75  152  231  237  243  164   83]
   [ 160  324  492  504  516  348  176]
   [ 255  516  783  801  819  552  279]
   [ 285  576  873  891  909  612  309]
   [ 315  636  963  981  999  672  339]
   [ 220  444  672  684  696  468  236]
   [ 115  232  351  357  363  244  123]]

  [[  50  101  153  156  159  107   54]
   [ 105  212  321  327  333  224  113]
   [ 165  333  504  513  522  351  177]
   [ 180  363  549  558  567  381  192]
   [ 195  393  594  603  612  411  207]
   [ 135  272  411  417  423  284  143]
   [  70  141  213  216  219  147   74]]]


 [[[  75  151  228  231  234  157   79]
   [ 155  312  471  477  483  324  163]
   [ 240  483  729  738  747  501  252]
   [ 255  513  774  783  792  531  267]
   [ 270  543  819  828  837  561  282]
   [ 185  372  561  567  573  384  193]
   [  95  191  288  291  294  197   99]]

  [[ 175  352  531  537  543  364  183]
   [ 360  724 1092 1104 1116  748  376]
   [ 555 1116 1683 1701 1719 1152  579]
   [ 585 1176 1773 1791 1809 1212  609]
   [ 615 1236 1863 1881 1899 1272  639]
   [ 420  844 1272 1284 1296  868  436]
   [ 215  432  651  657  663  444  223]]

  [[ 300  603  909  918  927  621  312]
   [ 615 1236 1863 1881 1899 1272  639]
   [ 945 1899 2862 2889 2916 1953  981]
   [ 990 1989 2997 3024 3051 2043 1026]
   [1035 2079 3132 3159 3186 2133 1071]
   [ 705 1416 2133 2151 2169 1452  729]
   [ 360  723 1089 1098 1107  741  372]]

  [[ 225  452  681  687  693  464  233]
   [ 460  924 1392 1404 1416  948  476]
   [ 705 1416 2133 2151 2169 1452  729]
   [ 735 1476 2223 2241 2259 1512  759]
   [ 765 1536 2313 2331 2349 1572  789]
   [ 520 1044 1572 1584 1596 1068  536]
   [ 265  532  801  807  813  544  273]]

  [[ 125  251  378  381  384  257  129]
   [ 255  512  771  777  783  524  263]
   [ 390  783 1179 1188 1197  801  402]
   [ 405  813 1224 1233 1242  831  417]
   [ 420  843 1269 1278 1287  861  432]
   [ 285  572  861  867  873  584  293]
   [ 145  291  438  441  444  297  149]]]]
valid:
[[[[ 837  864  891]
   [ 972  999 1026]
   [1107 1134 1161]]]


 [[[2862 2889 2916]
   [2997 3024 3051]
   [3132 3159 3186]]]]

Es ist lang und schwer zu vergleichen,validIst das gleiche, aberfullDie Ergebnisse sind zwischen den beiden unterschiedlich. Schauen wir uns also die Form des Arrays nach der Ausgabe an.

print("Output for Theano.")
print("full:")
print(o_full.eval({m:m_arr, w:w_arr}).round().astype(int).shape)
print("valid:")
print(o_valid.eval({m:m_arr, w:w_arr}).round().astype(int).shape)

print("Output for scipy.")
print("full:")
print(s.fftconvolve(m_arr, w_arr, "full").round().astype(int).shape)
print("valid:")
print(s.fftconvolve(m_arr, w_arr, "valid").round().astype(int).shape)
Output for Theano.
full:
(2, 1, 7, 7)
valid:
(2, 1, 3, 3)
Output for scipy.
full:
(2, 5, 7, 7)
valid:
(2, 1, 3, 3)

das ist,scipy.signal.fftconvolve()Führt auch den Faltvorgang auf den Achsen der Anzahl der Bilder und der Anzahl der Kanäle durch.theano.tensor.nnet.conv()Dies liegt daran, dass nur die Abmessungen für Bildbreite und -höhe verwendet werden und die Anzahl der Bilder und die Anzahl der Kanäle unabhängig voneinander verarbeitet werden. Undtheano.tensor.nnet.conv()Die Ausgabe von[Anzahl der Bilder, Anzahl der Filter, Höhe, Breite]Die zweite Form ist also 1. Ebenfalls,theano.tensor.nnet.conv()Es ist notwendig, die Anzahl der Kanäle mit dem Bild und dem Filter wie oben beschrieben abzugleichen. Zum Beispiel

m_arr = arange(2*3*5*5).reshape((2, 3, 5, 5)).astype(float32)
w_arr = ones((1,1,3,3)).astype(float32)

Wenn die Anzahl der Kanäle des Bildes 3 und die Anzahl der Kanäle des Filters 1 ist, wie intheano.tensor.nnet.conv()Gibt den folgenden Fehler aus.

ValueError: GpuDnnConv images and kernel must have the same stack size

Jedoch,scipy.signal.fftconvolve()Dann ist die Form des Arrays

Output for scipy.
full:
(2, 3, 7, 7)
valid:
(2, 3, 3, 3)

Gibt das Ergebnis von zurück.fullDannM+(m-1)validDannM-(m-1)Es ist wie folgt.

Versuchen Sie es schließlich mit 2 Bildern, 3 Filtern und 1 Kanal. Wir haben auch die Anzahl der Elemente im Array reduziert.

m = T.tensor4()
w = T.tensor4()

# Muss Rang 4 sein.
o_full = nnet.conv.conv2d(m, w,
                          border_mode='full')
o_valid = nnet.conv.conv2d(m, w,
                          border_mode='valid')

m_arr = arange(2*1*3*3).reshape((2, 1, 3, 3)).astype(float32)
w_arr = ones((3,1,1,1)).astype(float32)
print("m_arr =")
print(m_arr)
print("w_arr =")
print(w_arr)

print("Output for Theano.")
print("full:")
print(o_full.eval({m:m_arr, w:w_arr}).round().astype(int))
print("valid:")
print(o_valid.eval({m:m_arr, w:w_arr}).round().astype(int))

print("Output for scipy.")
print("full:")
print(s.fftconvolve(m_arr, w_arr, "full").round().astype(int))
print("valid:")
print(s.fftconvolve(m_arr, w_arr, "valid").round().astype(int))
m_arr =
[[[[  0.   1.   2.]
   [  3.   4.   5.]
   [  6.   7.   8.]]]


 [[[  9.  10.  11.]
   [ 12.  13.  14.]
   [ 15.  16.  17.]]]]
w_arr =
[[[[ 1.]]]


 [[[ 1.]]]


 [[[ 1.]]]]
Output for Theano.
full:
[[[[ 0  1  2]
   [ 3  4  5]
   [ 6  7  8]]

  [[ 0  1  2]
   [ 3  4  5]
   [ 6  7  8]]

  [[ 0  1  2]
   [ 3  4  5]
   [ 6  7  8]]]


 [[[ 9 10 11]
   [12 13 14]
   [15 16 17]]

  [[ 9 10 11]
   [12 13 14]
   [15 16 17]]

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

  [[ 0  1  2]
   [ 3  4  5]
   [ 6  7  8]]

  [[ 0  1  2]
   [ 3  4  5]
   [ 6  7  8]]]


 [[[ 9 10 11]
   [12 13 14]
   [15 16 17]]

  [[ 9 10 11]
   [12 13 14]
   [15 16 17]]

  [[ 9 10 11]
   [12 13 14]
   [15 16 17]]]]
Output for scipy.
full:
[[[[ 0  1  2]
   [ 3  4  5]
   [ 6  7  8]]]


 [[[ 9 11 13]
   [15 17 19]
   [21 23 25]]]


 [[[ 9 11 13]
   [15 17 19]
   [21 23 25]]]


 [[[ 9 10 11]
   [12 13 14]
   [15 16 17]]]]
valid:
ValueError: For 'valid' mode, one must be at least as large as the other in every dimension

scipy.signal.fftconvolve()vonvalidHat zu einem Fehler geführt.validvon場合、画像とフィルタvonいずれかが片方よりもすべてvon次元で大きくないといけないようです。

Die Form des Arrays ist wie folgt.

Output for Theano.
full:
(2, 3, 3, 3)
valid:
(2, 3, 3, 3)
Output for scipy.
full:
(4, 1, 3, 3)
valid:

theano.tensor.nnet.conv()Ist 1 von Form,Die zweite ist die Anzahl der Bilder bzw. die Anzahl der Filter und der RestfullDannM+(m-1)validDannM-(m-1)Es ist gewordenscipy.signal.fftconvolve()Für alle AchsenfullDannM+(m-1)Sie können sehen, dass es ist.

#schreiten

Recommended Posts

Theanos Faltung
Theanos Grundnotizen