[PYTHON] Gefaltete Schritte und durchschnittliches Pooling

Einführung

AveragePooling2D und MaxPooling2D werden häufig verwendet, um die Bildgröße bei Deep-Learning-Faltungsoperationen zu halbieren. Durch Halbieren der Bildgröße wird die Kerngröße des Filters in der nachfolgenden Faltungsschicht wesentlich größer. Andererseits werden gelegentlich auch Schritte in Conv2D verwendet, um die Bildgröße zu halbieren. Betrachten wir, wie sich dieser Unterschied auf die Filterbreite der Faltungsoperation auswirken kann.

※Hinweis Faltung Wenn jede Schicht ein Aktivierungsfunktionsrelu enthält, ist es nicht möglich, es in eine einfache Faltung umzuwandeln, wie unten erläutert. Daher ist die folgende Diskussion auf die Bedingung beschränkt, dass sie nur gilt, wenn die Aktivierungsfunktion nicht vorhanden ist.

1. Faltungsberechnung von scipy.signal

Stellen Sie zunächst sicher, dass die zweidimensionale Faltung mit scipy.signal.correlate2d () und scipy.signal.convolve2d () berechnet werden kann. Wenn A1 und B1 entsprechend definiert sind, kann das bekannte Ergebnis der Faltung von A1 zu B1 durch korrelate2d () erhalten werden. Beachten Sie auch, dass bei Verwendung von convolve2d () die Reihenfolge der Matrix umgekehrt werden muss.

python


import numpy as np
import scipy.signal as sp

A1 = np.random.randint(0,2,(3,3))
B1 = np.random.randint(-4,5,(7,7))
C1 = sp.correlate2d(B1, A1, mode='valid')
C2 = sp.convolve2d(B1, A1[::-1,::-1], mode='valid')

print('A1=\n', A1)
print('B1=\n', B1)
print('C1=\n', C1)
print('C2=\n', C2)
-----------------------------------------------
A1=
 [[0 1 0]
 [0 0 0]
 [1 0 1]]
B1=
 [[-1 -3  4 -3  1 -2 -2]
 [-3 -4 -2 -2  1  3  2]
 [-1 -4  2  3  3  3 -3]
 [ 3 -3 -2  1  3 -1  0]
 [ 2 -4  0  2  4  0  2]
 [ 4  0 -3  4  4  3  0]
 [ 0 -4 -2  4  3 -3  1]]
C1=
 [[-2  3  2  7 -2]
 [-3 -4 -1  1  6]
 [-2  0  7  5  9]
 [-2  2  2 10  3]
 [-6  0  3  5  4]]
C2=
 [[-2  3  2  7 -2]
 [-3 -4 -1  1  6]
 [-2  0  7  5  9]
 [-2  2  2 10  3]
 [-6  0  3  5  4]]

2. Wenn 3x3 zweimal gefaltet wird

Welche Art von Faltungsoperation entspricht in Keras 'Beschreibung, wenn die 3x3-Faltung zweimal angewendet wird, wie unten gezeigt? Dies entspricht, wie viele wissen, einer 5x5-Faltung. (* Unter der Bedingung, dass während der Faltung keine Aktivierungsfunktion vorhanden ist)

python



x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

Es kann gezeigt werden, dass C1 das Ergebnis der Faltung von A1 => A2 in B1 ist und E1 das Ergebnis der Faltung mit D1 als Ergebnis der Suche nach der Faltung von A1 und A2, wie unten gezeigt. Daher sind zwei 3x3-Falten gleich einer 5x5-Faltung. Das 5x5-Faltungsfilter kann mit "D1 = sp.convolve2d (A1, A2, mode =" full ")" berechnet werden.

python


import numpy as np
import scipy.signal as sp

A1 = np.random.randint(0,2,(3,3))
A2 = np.random.randint(0,2,(3,3))
B1 = np.random.randint(-4,5,(7,7))
C1 = sp.correlate2d(B1, A1, mode='valid')
C2 = sp.correlate2d(C1, A2, mode='valid')
D1 = sp.convolve2d(A1, A2, mode='full')
E1 = sp.correlate2d(B1, D1, mode='valid')

print('A1=\n', A1)
print('A2=\n', A2)
print('B1=\n', B1)
print('C1=\n', C1)
print('C2=\n', C2)
print('D1=\n', D1)
print('E1=\n', E1)
----------------------------------------------
A1=
 [[1 0 1]
 [1 1 1]
 [0 0 0]]
A2=
 [[0 0 1]
 [0 1 0]
 [0 0 0]]
B1=
 [[-3 -4  4 -4  0 -2  3]
 [ 2  0 -3  3  4  2 -4]
 [ 0  4 -4  0  1  1  2]
 [-4 -3  0 -1 -3  0 -2]
 [ 4  1  2 -2 -3 -1  1]
 [ 3 -1 -1 -4 -1  3 -2]
 [ 4  0 -1 -3 -4 -4 -3]]
C1=
 [[  0  -8   8   3   5]
 [ -1   3  -2   7   4]
 [-11   0  -7  -3  -2]
 [  3  -3  -6  -7  -8]
 [  7  -7  -7  -5  -2]]
C2=
 [[ 11   1  12]
 [ -2   0   1]
 [-10  -9  -9]]
D1=
 [[0 0 1 0 1]
 [0 1 1 2 1]
 [0 1 1 1 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]
E1=
 [[ 11   1  12]
 [ -2   0   1]
 [-10  -9  -9]]

3. Wenn 5x5 einmal gefaltet wird

Betrachten Sie das Gegenteil von 2. Wenn eine 5x5-Faltung einmal vorhanden ist, ist es möglich, sie in zwei 3x3-Faltungen aufzuteilen? Wenn theoretisch ein Faltungsfilter mit 5 × 5-Faltung 1 und 3 × 3-Faltung 1 offensichtlich ist, kann das Gewicht der anderen 3 × 3-Faltung als umgekehrte Faltung berechnet werden. Wenn "D1 = convolve2d (A1, A2)", dann ist "A2 = deconvolve2d (D1, A1)".

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (5, 5), padding="valid")(x)

Die ** zweidimensionale Umkehrfaltungsfunktion ** existiert jedoch nicht in scipy, so dass ich sie in scipy nicht bestätigen konnte. Unter Verwendung der Umkehrfaltungsfunktion für Bilder erhielten wir ungefähre Werte der Rückwärtsfaltung in F1 und F2, wie unten gezeigt. Erstens beträgt die Anzahl der Parameter für eine 5x5-Faltung 25, während die Anzahl der Parameter für 2 3x3-Faltungen 18 beträgt, so dass es unmöglich ist, alle 5x5-Faltungen mit 2 3x3-Faltungen in Bezug auf die Anzahl der Parameter anzuzeigen.

python


import numpy as np
import scipy.signal as sp
from skimage import restoration

A1 = np.random.randint(0,2,(3,3))
A2 = np.random.randint(0,2,(3,3))
D1 = sp.convolve2d(A1, A2, mode='full')
F1, _ = restoration.unsupervised_wiener(D1, A2)
F2, _ = restoration.unsupervised_wiener(D1, A1)

print('A1=\n', A1)
print('A2=\n', A2)
print('D1=\n', D1)
print('F1=\n', F1[1:-1,1:-1])
print('F2=\n', F2[1:-1,1:-1])
---------------------------------
A1=
 [[1 1 0]
 [1 0 0]
 [0 1 1]]
A2=
 [[0 0 0]
 [1 1 1]
 [0 0 0]]
D1=
 [[0 0 0 0 0]
 [1 2 2 1 0]
 [1 1 1 0 0]
 [0 1 2 2 1]
 [0 0 0 0 0]]
F1=
 [[ 0.96529897  0.89627574  0.13951081]
 [ 0.7975316   0.15137364 -0.02074955]
 [ 0.0798071   0.92025068  0.92801951]]
F2=
 [[ 0.00971747  0.0117676   0.00229734]
 [ 0.96429178  0.99937217  0.97182209]
 [-0.00158553  0.03361686 -0.00815724]]

Zusammenfassung ・ Jede 2-fache 3x3-Faltung kann 1-mal in 5x5-Faltung umgewandelt werden => True ・ Jede 5x5-Faltung kann in 2 3x3-Faltungen umgewandelt werden => Falsch (ungefährer Wert ist möglich)

4. Im Fall von Average Pooling ((2,2))

Übrigens ist Average Pooling mit Poolgröße (2,2) Conv2D mit "x = Conv2D (1, (2, 2), Auffüllen =" gültig ", Schritte = 2) (x)" und Faltungsfiltergewichten ((0,25,0,25), (0,25,0,25)) Ich möchte zeigen, dass es einer Operation entspricht. Wenn der Glättungsfilter A1 wie folgt definiert ist, ist das Ergebnis D2, das durch Falten von A1 in B1 und Durchführen der Schrittverarbeitung erhalten wird, gleich dem Ergebnis C1 von Average Pooling.

A1: Glättungsfilter image.png

python


x = Input(shape=(28, 28, 1))
x = AveragePooling2D((2, 2))(x)

python


import numpy as np
import scipy.signal as sp
import skimage.measure

A1 = np.ones((2,2))/4
B1 = np.random.randint(-4,5,(8,8))*4
C1 = skimage.measure.block_reduce(B1, (2,2), np.average)
D1 = sp.correlate2d(B1, A1, mode='valid')
D2 = D1[::2,::2]

print('A1=\n', A1)
print('B1=\n', B1)
print('C1=\n', C1)
print('D1=\n', D1)
print('D2=\n', D2)
---------------------------------
A1=
 [[0.25 0.25]
 [0.25 0.25]]
B1=
 [[-12  -4   0   8  -4   4 -12  -8]
 [  4  -4   8 -12  -8 -16 -12  -8]
 [-16 -16 -16   8   8 -16 -12   0]
 [-12  -8  -4  16  -4  -8 -16  -4]
 [-12  -8 -12  16  -4   4  -4   0]
 [-12 -12   4  -8 -12   8   0  16]
 [ -8  16   8  16 -12 -12 -16   0]
 [ -8   4   4 -12  12  -4 -16   4]]
C1=
 [[ -4.   1.  -6. -10.]
 [-13.   1.  -5.  -8.]
 [-11.   0.  -1.   3.]
 [  1.   4.  -4.  -7.]]
D1=
 [[ -4.   0.   1.  -4.  -6.  -9. -10.]
 [ -8.  -7.  -3.  -1.  -8. -14.  -8.]
 [-13. -11.   1.   7.  -5. -13.  -8.]
 [-10.  -8.   4.   6.  -3.  -6.  -6.]
 [-11.  -7.   0.  -2.  -1.   2.   3.]
 [ -4.   4.   5.  -4.  -7.  -5.   0.]
 [  1.   8.   4.   1.  -4. -12.  -7.]]
D2=
 [[ -4.   1.  -6. -10.]
 [-13.   1.  -5.  -8.]
 [-11.   0.  -1.   3.]
 [  1.   4.  -4.  -7.]]

Daher ist das durchschnittliche Pooling gleich: Der Wert des Filters ist jedoch ein Glättungsfilter.

python


x = Input(shape=(28, 28, 1))
x = AveragePooling2D((2, 2))(x)
---------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)

5. Für Conv2D + AveragePooling ((2,2))

Wenn Sie Conv2D und Average Pooling wie unten haben, möchte ich dies auf eine einfache Faltung korrigieren.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

Wenn zu diesem Zeitpunkt die Filterverarbeitung mit 3 × 3-Faltung A2 nach dem durchschnittlichen Pooling ohne durchschnittliches Pooling betrachtet wird, ist ersichtlich, dass sie dem Ergebnis der Faltung des 6 × 6-Faltungsfilters A3 entspricht, das doppelt so groß ist wie der mit demselben Wert gefüllte, und ihn dann mit Schritten multipliziert. .. A2: image.png A3: image.png Nachfolgend kann bestätigt werden, dass C3 und E2 gleich sind.

python


import numpy as np
import scipy.signal as sp
import skimage.measure

A1 = np.random.randint(0,2,(3,3))
A2 = np.random.randint(0,2,(3,3))
A3 = np.repeat(A2, 2, axis=0)
A3 = np.repeat(A3, 2, axis=1)
B1 = np.random.randint(-4,5,(12,12))
C1 = sp.correlate2d(B1, A1, mode='valid')
C2 = skimage.measure.block_reduce(C1, (2,2), np.average)
C3 = sp.correlate2d(C2, A2, mode='valid')
D1 = sp.convolve2d(A1, A3, mode='full')
E1 = sp.correlate2d(B1, D1, mode='valid')/4
E2 = E1[::2,::2]

print('A1=\n', A1)
print('A2=\n', A2)
print('A3=\n', A3)
print('B1=\n', B1)
print('C1=\n', C1)
print('C2=\n', C2)
print('C3=\n', C3)
print('D1=\n', D1)
print('E1=\n', E1)
print('E2=\n', E2)
------------------------------
A1=
 [[0 0 1]
 [1 0 0]
 [0 0 1]]
A2=
 [[1 1 1]
 [0 0 0]
 [0 0 1]]
A3=
 [[1 1 1 1 1 1]
 [1 1 1 1 1 1]
 [0 0 0 0 0 0]
 [0 0 0 0 0 0]
 [0 0 0 0 1 1]
 [0 0 0 0 1 1]]
B1=
 [[ 0 -2 -1 -3 -4  2 -3 -1 -3 -4 -2  1]
 [ 4 -1  2 -4 -4  4 -1 -1 -4 -2  2  2]
 [ 1 -4  3  3 -2  2  3 -2 -3  4 -1  2]
 [-3 -1 -4  4  0  3  1  0  0  0 -4  1]
 [ 3  1  4  1 -2 -2  2  1 -3  0  3 -3]
 [-4  0  3 -4  3  4  2  0  3  0  1 -4]
 [ 1 -3 -1 -1  3 -4 -2  3 -4  1  0 -3]
 [ 1 -4  0  4  4  3 -2 -4  3 -2  3  0]
 [ 0  2 -2  3  3  3  2 -2 -1  0  1 -1]
 [-4 -4  2 -2 -4 -1  4  4 -1  3 -1  4]
 [ 4  4 -2 -1 -1  0  4 -2  3  3 -4  4]
 [-4 -3  0 -1 -2  0 -2  3  3 -1 -2 -4]]
C1=
 [[  6  -1  -4   0  -4   1  -7  -1  -7   1]
 [ -1  -4  -1  10  -2   1  -1  -4  -5   7]
 [  4   3  -8   4   5   2  -5   4   2  -1]
 [  2   1   7   8   1  -2   5   1  -6  -3]
 [ -1   0   4 -10   3   8  -5   1   6  -6]
 [  4  -3   6   6   3  -8   4   1   0  -3]
 [ -2  -2   6   3   4   4  -7  -3   4  -6]
 [  2   4  -2   5   5   3   4  -1   1   4]
 [ -8  -2   4   1   2  -5   6   7  -4   6]
 [  6   1  -8  -2   1   7   6   0   0   3]]
C2=
 [[ 0.    1.25 -1.   -3.25 -1.  ]
 [ 2.5   2.75  1.5   1.25 -2.  ]
 [ 0.    1.5   1.5   0.25 -0.75]
 [ 0.5   3.    4.   -1.75  0.75]
 [-0.75 -1.25  1.25  4.75  1.25]]
C3=
 [[ 1.75 -2.75 -6.  ]
 [10.75  3.75  1.5 ]
 [ 4.25  8.    2.25]]
D1=
 [[0 0 1 1 1 1 1 1]
 [1 1 2 2 2 2 1 1]
 [1 1 2 2 2 2 1 1]
 [0 0 1 1 1 1 1 1]
 [0 0 0 0 0 0 1 1]
 [0 0 0 0 1 1 1 1]
 [0 0 0 0 1 1 1 1]
 [0 0 0 0 0 0 1 1]]
E1=
 [[ 1.75 -3.25 -2.75 -2.75 -6.  ]
 [ 4.   -0.75  0.    3.25 -0.5 ]
 [10.75  6.25  3.75  5.    1.5 ]
 [ 6.5   7.    9.25  3.25  2.5 ]
 [ 4.25  5.5   8.    3.    2.25]]
E2=
 [[ 1.75 -2.75 -6.  ]
 [10.75  3.75  1.5 ]
 [ 4.25  8.    2.25]]

Das heißt, das Modell, das aus Conv2D und Average Pooling besteht, kann wie folgt organisiert werden.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (8, 8), padding="valid", strides=2)(x)

6. Für Conv2D + AveragePooling ((2,2)) 2

Wenn Sie Conv2D und Average Pooling wie unten haben, möchte ich dies auf eine einfache Faltung korrigieren.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

Dies kann wie folgt berechnet werden: Sie können sehen, dass das Ergebnis der Multiplikation von Conv2D und AveragePooling C5 ist, was 6x6 ist und dem Ergebnis von E3 entspricht, das zweimal mit den Schritten2 multipliziert wird.

python


import numpy as np
import scipy.signal as sp
import skimage.measure

A1 = np.random.randint(0,2,(3,3))
A2 = np.random.randint(0,2,(3,3))
A3 = np.random.randint(0,2,(3,3))
A4 = np.repeat(A2, 2, axis=0)
A4 = np.repeat(A4, 2, axis=1)
A5 = np.repeat(A3, 2, axis=0)
A5 = np.repeat(A5, 2, axis=1)
B1 = np.random.randint(-4,5,(26,26))*4
C1 = sp.correlate2d(B1, A1, mode='valid')
C2 = skimage.measure.block_reduce(C1, (2,2), np.average)
C3 = sp.correlate2d(C2, A2, mode='valid')
C4 = skimage.measure.block_reduce(C3, (2,2), np.average)
C5 = sp.correlate2d(C4, A3, mode='valid')
D1 = sp.convolve2d(A1, A4, mode='full')
E1 = sp.correlate2d(B1, D1, mode='valid')/4
E2 = E1[::2,::2]
E3 = sp.correlate2d(E2, A5, mode='valid')/4
E3 = E3[::2,::2]

print('A1=\n', A1)
print('A2=\n', A2)
print('A3=\n', A3)
print('A4=\n', A4)
print('A5=\n', A5)
print('C5=\n', C5)
print('E3=\n', E3)
--------------------------
A1=
 [[1 1 0]
 [1 0 0]
 [0 0 0]]
A2=
 [[0 0 0]
 [0 0 0]
 [1 1 0]]
A3=
 [[1 0 1]
 [0 0 1]
 [1 0 1]]
A4=
 [[0 0 0 0 0 0]
 [0 0 0 0 0 0]
 [0 0 0 0 0 0]
 [0 0 0 0 0 0]
 [1 1 1 1 0 0]
 [1 1 1 1 0 0]]
A5=
 [[1 1 0 0 1 1]
 [1 1 0 0 1 1]
 [0 0 0 0 1 1]
 [0 0 0 0 1 1]
 [1 1 0 0 1 1]
 [1 1 0 0 1 1]]
C5=
 [[ -6.75 -15.5  -45.5 ]
 [-32.5    1.25   9.75]
 [-15.5    5.75 -28.  ]]
E3=
 [[ -6.75 -15.5  -45.5 ]
 [-32.5    1.25   9.75]
 [-15.5    5.75 -28.  ]]

Das heißt, das Modell, das aus Conv2D und Average Pooling besteht, kann wie folgt organisiert werden.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)

Übrigens ist das Obige die Grenze, um als äquivalenter Ausdruck zu organisieren. Die obige Gleichung kann jedoch etwas weiter angeordnet werden, wenn der ungefähre Wert zulässig ist und die Faltung durch die umgekehrte Faltung zerlegt wird, wie in 3 gezeigt. Wenn Sie den 5x5-Faltungsfilter durch die umgekehrte Faltung des 2x2-Glättungsfilters finden

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x) # AveragePooling2D((2,2))
x = Conv2D(1, (6, 6), padding="valid")(x)
x = Conv2D(1, (1, 1), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (12, 12), padding="valid", strides=2)(x)
x = Conv2D(1, (1, 1), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (4, 4), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = AveragePooling2D((4,4))(x)

Hier ist das 5 × 5-Faltungsfilter ein Faltungsfilter, das durch Rückfaltung eines 2 × 2-Glättungsfilters aus einem 6 × 6-Faltungsfilter erhalten wird, in dem ein 3 × 3-Faltungsfilter mit demselben Wert gefüllt ist. Das 9 × 9-Faltungsfilter ist ein Faltungsfilter, das durch Rückfaltung eines 4 × 4-Glättungsfilters aus einem 12 × 12-Faltungsfilter erhalten wird, in dem ein 3 × 3-Faltungsfilter viermal mit demselben Wert gefüllt ist. Das heißt, die Faltung wird wie folgt zusammengefasst.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (18, 18), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (15, 15), padding="valid")(x)
x = AveragePooling2D((4,4))(x)

7. Wenn Conv2D + Schritte = 2

Stellen Sie sich ein Modell vor, das den folgenden Schritt enthält. Dies ist in dem Sinne nahe, dass die 3 × 3-Faltung dreimal durchgeführt wird und die Bildgröße zweimal wie in 6 halbiert wird. Außerdem ist die Anzahl der in der Berechnung verwendeten Parameter in Bezug auf die Anzahl der Gewichte gleich, da drei 3x3-Filter vorhanden sind.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

Wenn Sie zulassen, dass die Faltung wie in 3 zerlegt wird.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (12, 12), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (4, 4), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(28, 28, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = AveragePooling2D((4,4))(x)

Es ist ersichtlich, dass die Größe des Faltungsfilters etwas kleiner als die von 6 ist. Wenn Sie die Größe des Faltungsfilters an die Größe von Average Pooling 2D anpassen möchten, ist es meiner Meinung nach erforderlich, die Filtergröße bei Verwendung von Schritten um 1 zu erhöhen.

python


x = Input(shape=(28, 28, 1))
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

8. Für mehrstufige Modelle

python


x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = AveragePooling2D((2,2))(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

Wenn die Entfaltung durch die umgekehrte Faltung des Glättungsfilters erlaubt ist,

python


x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid")(x)
x = Conv2D(1, (1, 1), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (10, 10), padding="valid", strides=2)(x)
x = Conv2D(1, (10, 10), padding="valid", strides=2)(x)
x = Conv2D(1, (12, 12), padding="valid", strides=2)(x)
x = Conv2D(1, (1, 1), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (12, 12), padding="valid")(x)
x = Conv2D(1, (1, 1), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (18, 18), padding="valid", strides=2)(x)
x = Conv2D(1, (24, 24), padding="valid", strides=2)(x)
x = Conv2D(1, (1, 1), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (17, 17), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (24, 24), padding="valid")(x)
x = Conv2D(1, (1, 1), padding="valid", strides=8)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (17, 17), padding="valid")(x)
x = Conv2D(1, (48, 48), padding="valid", strides=2)(x)
x = Conv2D(1, (1, 1), padding="valid", strides=8)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (17, 17), padding="valid")(x)
x = Conv2D(1, (33, 33), padding="valid")(x)
x = Conv2D(1, (16, 16), padding="valid", strides=16)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (63, 63), padding="valid")(x)
x = AveragePooling2D((16,16))(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (78, 78), padding="valid", strides=16)(x)

Es ist ersichtlich, dass die Größe der Faltung jeder Schicht jedes Mal, wenn sie das durchschnittliche Pooling 2D durchläuft, mit ** (3 → 5 → 9 → 17 → 33) ** zunimmt. Kurz gesagt, die Größe der Falten jeder Schicht verdoppelt sich.

--Wenn Conv2D + Schritte = 2

python


x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

Wenn die Entfaltung durch die umgekehrte Faltung des Glättungsfilters erlaubt ist,

python


x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid")(x)
x = Conv2D(1, (1, 1), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
x = Conv2D(1, (6, 6), padding="valid", strides=2)(x)
x = Conv2D(1, (12, 12), padding="valid", strides=2)(x)
x = Conv2D(1, (1, 1), padding="valid", strides=2)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (12, 12), padding="valid")(x)
x = Conv2D(1, (1, 1), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (10, 10), padding="valid", strides=2)(x)
x = Conv2D(1, (24, 24), padding="valid", strides=2)(x)
x = Conv2D(1, (1, 1), padding="valid", strides=4)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (2, 2), padding="valid", strides=2)(x)
x = Conv2D(1, (24, 24), padding="valid")(x)
x = Conv2D(1, (1, 1), padding="valid", strides=8)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (48, 48), padding="valid", strides=2)(x)
x = Conv2D(1, (1, 1), padding="valid", strides=8)(x)
-----------------------------------------
x = Input(shape=(224, 224, 1))
x = Conv2D(1, (2, 2), padding="valid")(x)
x = Conv2D(1, (3, 3), padding="valid")(x)
x = Conv2D(1, (5, 5), padding="valid")(x)
x = Conv2D(1, (9, 9), padding="valid")(x)
x = Conv2D(1, (33, 33), padding="valid")(x)
x = Conv2D(1, (16, 16), padding="valid", strides=16)(x)
-----------------------------------------

Es ist ersichtlich, dass die Größe der Faltung jeder Schicht mit jedem Schritt = 2 (** (2 → 3 → 5 → 9 → 33) ** zunimmt. Im Vergleich zu AveragePooling scheint nur die Faltgröße der letzten Schicht unausgeglichen zu sein.

python


x = Input(shape=(224, 224, 1))
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid", strides=2)(x)
x = Conv2D(1, (2, 2), padding="valid")(x)

Wenn die Größe der endgültigen Faltung 2x2 beträgt, beträgt die Größe der Faltung ** (2 → 3 → 5 → 9 → 17) **. Die 2x2-Faltung trägt jedoch nicht zur Beschleunigung bei, sodass es keinen Sinn macht, sie zu verwenden.

python


x = Input(shape=(224, 224, 1))
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (4, 4), padding="valid", strides=2)(x)
x = Conv2D(1, (3, 3), padding="valid")(x)

Wenn Sie die oben beschriebene 4x4-Faltung verwenden, können Sie ** (3 → 5 → 9 → 17 → 33) ** ähnlich wie beim durchschnittlichen Pooling reproduzieren. Dies legt nahe, dass die Größe des Filters bei Conv2D + -Schritten = 2 um 1 um den Betrag reduziert wird, um den der 2x2-Glättungsfilter von Average Pooling für die umgekehrte Faltung berechnet wird. In Anbetracht eines 4x4-Filters mit Conv2D + -Schritten = 2 besteht der Nachteil, dass die Anzahl der Parameter größer als das durchschnittliche Pooling ist. (Umgekehrt kann es ein Verdienst sein) Wenn wir darüber nachdenken, ob es möglich ist, einen Faltungsfilter zu erzeugen, der Merkmale beliebiger Größe mit Faltungsfiltern verschiedener Größen extrahiert, erinnert uns dies an das Problem der Messung kontinuierlicher Gewichte mit einer endlichen Anzahl von Gewichten.

Zusammenfassung:

Wir haben die Größe des Faltungsfilters bei der Verwendung von Conv2D-Schritten und Average Pooling berücksichtigt. Beides sind Prozesse, die die Bildgröße halbieren. Es wurde jedoch vorgeschlagen, dass die Größe des Faltungsfilters bei Verwendung von Conv2D-Schritten kleiner als das durchschnittliche Pooling ist. Es ist jedoch nur möglich, auf diese Weise zu organisieren, wenn keine Aktivierungsfunktion vorhanden ist und die Faltung durch umgekehrte Faltung in zwei Teile zerlegt werden kann. Daher ist zu beachten, dass eine solche Anordnung in allgemeinen Modellen nicht möglich ist. ist.

Recommended Posts

Gefaltete Schritte und durchschnittliches Pooling
Einführung in Deep Learning ~ Falten und Pooling ~
Grad-CAM und erweiterte Faltung
Kerzenbalkendiagramm und gleitender Durchschnittsliniendiagramm