Im CNN-Modell wird der Pooling-Prozess häufig getrennt vom Faltungsprozess (Conv2D) erläutert. Wenn Sie damit vertraut sind, entspricht die Größe (2,2) ** AveragePooling2D () ** dem Faltungsfilter ((0,25,0,25), (0,25,0,25)), der mit Strecken = 2 gefaltet ist. Du hast es schon bemerkt. Andererseits erscheint es auf den ersten Blick unmöglich, wenn Sie fragen, ob es möglich ist, ** MaxPooling2D ** nur durch den Faltungsprozess von Conv2D auszudrücken. Wenn Sie jedoch sorgfältig darüber nachdenken, war es tatsächlich möglich, Maxpooling2D nur mit Conv2D auszudrücken, daher werde ich darüber schreiben.
Ziehen Sie in Betracht, $ max (a, b) $ mit $ relu (x) $ auszudrücken.
max(a,b) = relu(a-b) + b
Zum obigen Zeitpunkt können Sie sehen, dass $ a> b $ $ max (a, b) = a $ und $ a \ leqq b $ $ max (a, b) = b $ ist. Mit anderen Worten, die $ max $ -Funktion kann mit der $ relu $ -Funktion ausgedrückt werden.
Wenn Sie nun ** MaxPooling2D ** betrachten, betrachten Sie die Arbeit des Extrahierens des Maximalwerts aus den vier Elementen als pool_size (2,2). Unter Berücksichtigung von $ max (a, b, c, d) $ kann dies mit der Funktion $ relu $ wie folgt beschrieben werden.
\begin{align}
max(a,b,c,d) &= max(max(a,b), max(c,d))\\
&=max(relu(a-b)+b,relu(c-d)+d)\\
&=relu((relu(a-b)+b)-(relu(c-d)+d))+relu(c-d)+d\\
&=relu(relu(a-b) - relu(c-d) + (b - d)) + relu(c-d) + d
\end{align}
Nehmen wir nun an, dass $ relu (a-b) $ gefaltet ist und der Filter ((1, -1), (0,0)) mit Schritten = 2 multipliziert und dann die Aktivierungsfunktion $ relu $ multipliziert. In ähnlicher Weise hat $ relu (c-d) $ die Aktivierungsfunktion $ relu $ im Faltungsfilter ((0,0), (1, -1)). $ b $ hat einen Faltungsfilter ((0,1), (0,0)) mit einer Gleichheitsfunktion als Aktivierungsfunktion. $ d $ wird vom Faltungsfilter als ((0,0), (0,1)) multipliziert mit der Aktivierungsfunktion und der Gleichheitsfunktion betrachtet. Maxpooling kann reproduziert werden, indem das Ergebnis der Multiplikation dieser Additionsergebnisse mit $ relu $ und der Gleichheitsfunktion addiert wird.
Ich definierte die aus der Formel erhaltenen Faltungsfiltergewichte wie unten gezeigt und setzte die Gewichte mit **. Set_weights **.
python
import numpy as np
from keras.layers import Input, Conv2D, Add, Concatenate
from keras.models import Model
inputs = Input(shape=(16,16,1))
x1 = Conv2D(1, (2, 2), strides=2, padding='same', activation='relu', use_bias=False)(inputs)
x2 = Conv2D(1, (2, 2), strides=2, padding='same', activation='relu', use_bias=False)(inputs)
x3 = Conv2D(1, (2, 2), strides=2, padding='same', activation='linear', use_bias=False)(inputs)
x4 = Conv2D(1, (2, 2), strides=2, padding='same', activation='linear', use_bias=False)(inputs)
x5 = Concatenate()([x1, x2, x3, x4])
x6 = Conv2D(1, (1, 1), activation='relu', use_bias=False)(x5)
x7 = Conv2D(1, (1, 1), activation='linear', use_bias=False)(x5)
outputs = Add()([x6, x7])
model = Model(inputs=inputs, outputs=outputs)
model.summary()
weight1 = np.array([[[[1]],[[-1]]],[[[0]],[[0]]]]) # relu(a-b)
weight2 = np.array([[[[0]],[[0]]],[[[1]],[[-1]]]]) # relu(c-d)
weight3 = np.array([[[[0]],[[1]]],[[[0]],[[0]]]]) # b
weight4 = np.array([[[[0]],[[0]]],[[[0]],[[1]]]]) # d
weight5 = np.array([[[[1],[-1],[1],[-1]]]]) # relu(a-b) - relu(c-d) + b - d
weight6 = np.array([[[[0],[1],[0],[1]]]]) # relu(c-d) + d
model.get_layer(name='conv2d_1').set_weights([weight1])
model.get_layer(name='conv2d_2').set_weights([weight2])
model.get_layer(name='conv2d_3').set_weights([weight3])
model.get_layer(name='conv2d_4').set_weights([weight4])
model.get_layer(name='conv2d_5').set_weights([weight5])
model.get_layer(name='conv2d_6').set_weights([weight6])
X = np.random.randint(-10,11,(1,16,16,1))
Y = model.predict(X)
print('X=\n',X[0,:,:,0])
print('Y=\n',Y[0,:,:,0])
Ich habe bestätigt, dass die Ausgabe ** Maxpooling2D () ** der Größe (2,2) entspricht, wenn die entsprechende Eingabe gegeben wird. Das Modell verwendet nur Conv2D (), Concatenate () und Add ().
python
X=
[[ -7 7 0 -8 8 -3 -1 7 -6 9 4 -10 8 7 -6 10]
[ -4 -5 -5 0 -10 7 1 8 1 -9 10 -3 5 -10 5 -9]
[ -7 9 6 -9 0 -7 3 0 4 9 -6 -1 9 1 0 0]
[ 1 -3 -7 -5 7 3 6 7 -4 -2 6 -8 7 -6 0 -2]
[ -2 -6 9 4 4 3 10 3 9 9 -5 2 0 2 9 -3]
[ 2 7 5 -3 9 -7 -1 -10 7 -5 -4 -6 0 7 8 -10]
[ 1 -3 -3 9 -5 -6 -7 -7 -4 9 -7 -9 -6 2 1 -9]
[ -1 -5 -3 1 -2 9 0 10 -10 5 -9 -8 -2 8 -4 3]
[ 1 -4 -2 -5 -2 3 5 4 -5 3 -6 9 0 2 -3 6]
[ 6 1 4 -8 -6 7 -8 4 -10 -10 -5 7 -8 -7 -1 5]
[ 8 -2 4 9 6 9 -10 -4 -3 -9 7 1 -7 4 7 0]
[ -6 5 6 -1 -8 -2 0 0 6 3 10 -3 3 9 1 -2]
[ 2 3 -6 6 -1 1 9 -2 -3 2 4 5 -10 -7 5 4]
[ -5 5 0 9 4 2 -10 -8 7 4 -7 2 -8 7 -3 3]
[ 5 0 3 2 -4 2 -3 10 1 -7 -7 2 7 5 -4 2]
[ 0 -9 6 2 1 -2 -4 3 -4 7 9 -9 7 -5 4 -1]]
Y=
[[ 7. 0. 8. 8. 9. 10. 8. 10.]
[ 9. 6. 7. 7. 9. 6. 9. 0.]
[ 7. 9. 9. 10. 9. 2. 7. 9.]
[ 1. 9. 9. 10. 9. -7. 8. 3.]
[ 6. 4. 7. 5. 3. 9. 2. 6.]
[ 8. 9. 9. 0. 6. 10. 9. 7.]
[ 5. 9. 4. 9. 7. 5. 7. 5.]
[ 5. 6. 2. 10. 7. 9. 7. 4.]]
Es ist möglich, ein äquivalentes Modell mit ** Maxpooling2D () ** und ** Conv2d () ** zu beschreiben. Der Maximalwert von a, b, c, d ist $ max (max (a, c), max (b, d)) anstelle von $ max (max (a, b), max (c, d)) $ )) $ Kann verwendet werden, so dass es möglich sein kann, ** Maxpooling2D () ** mit anderen Koeffizienten zu reproduzieren. Da es jedoch notwendig ist, eine gleiche Funktion als Aktivierungsfunktion zu wählen (was selten zu sehen ist), ist in einem normalen Modell nur ** Conv2d () ** eine Schicht, die ** Maxpooling2D () ** entspricht. Es scheint, dass es nicht viel zu machen gibt. (Ist es möglich, wenn es eine Kombination von Identitäten gibt?)