Dans le modèle CNN, le processus de regroupement est souvent expliqué séparément du processus de convolution (Conv2D). Cependant, si vous le connaissez, la taille (2,2) ** AveragePooling2D () ** est équivalente au filtre de convolution ((0.25.0.25), (0.25.0.25)) alambiqué avec des étirements = 2. Vous l'avez déjà remarqué. En revanche, il semble impossible à première vue si vous vous demandez s'il est possible d'exprimer ** MaxPooling2D ** uniquement par le processus de convolution de Conv2D. Cependant, si vous y réfléchissez bien, il était en fait possible d'exprimer Max Covoiturage2D uniquement avec Conv2D, donc je vais écrire à ce sujet.
Pensez à exprimer $ max (a, b) $ en utilisant $ relu (x) $.
max(a,b) = relu(a-b) + b
Au moment ci-dessus, vous pouvez voir que $ a> b $ est $ max (a, b) = a $ et $ a \ leqq b $ est $ max (a, b) = b $. En d'autres termes, la fonction $ max $ peut être exprimée en utilisant la fonction $ relu $.
Maintenant, lorsque vous considérez ** MaxPooling2D **, considérez le travail d'extraction de la valeur maximale des quatre éléments comme pool_size (2,2). Considérant $ max (a, b, c, d) $, il peut être décrit comme suit en utilisant la fonction $ relu $.
\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}
Supposons maintenant que $ relu (a-b) $ soit plié et que le filtre multiplie ((1, -1), (0,0)) par coups = 2, puis multiplie la fonction d'activation $ relu $. De même, $ relu (c-d) $ a la fonction d'activation $ relu $ dans le filtre de convolution ((0,0), (1, -1)). $ b $ a un filtre de convolution ((0,1), (0,0)) avec une fonction d'égalité comme fonction d'activation. $ d $ est considéré par le filtre de convolution comme étant ((0,0), (0,1)) multiplié par la fonction d'activation et la fonction d'égalité. Maxpool peut être reproduit en ajoutant le résultat de la multiplication de ces résultats d'addition par $ relu $ et la fonction d'égalité.
J'ai défini les poids de filtre de convolution obtenus à partir de la formule comme indiqué ci-dessous et défini les poids avec **. 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])
J'ai confirmé que la sortie est équivalente à ** Maxpool2D () ** de taille (2,2) lorsque l'entrée appropriée est donnée. Le modèle utilise uniquement Conv2D (), Concatenate () et 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.]]
Il est possible de décrire un modèle équivalent en utilisant ** Maxpool2D () ** et ** Conv2d () **. La valeur maximale de a, b, c, d est $ max (max (a, c), max (b, d)) au lieu de $ max (max (a, b), max (c, d)) $ )) $ Peut être utilisé, il est donc possible de reproduire ** Maxpool2D () ** avec d'autres coefficients. Cependant, comme il est nécessaire de choisir une fonction égale comme fonction d'activation (ce qui est rarement vu), dans un modèle normal, seul ** Conv2d () ** se trouve être une couche équivalente à ** Maxpool2D () **. Il semble qu'il n'y ait pas grand chose à faire. (Est-ce possible s'il y a une combinaison d'identités?)