[PYTHON] [Pytorch] MaxPool2d Ceil_Mode

Was ist Ceil_Mode?

Wenn Sie das von Pytorch trainierte Modell torchvision.models.googlenet nach Keras portieren möchten, sind Sie möglicherweise neugierig.

Was ist der Ceil_Mode von MaxPool2d?

In der Dokumentation heißt es: "Wenn True, verwenden Sie Ceil (Aufrunden) anstelle von Floor (Aufrunden), um die Ausgabeform zu berechnen."

torch.nn — PyTorch master documentation

ceil_mode – when True, will use ceil instead of floor to compute the output shape

Unten ist MaxPool2D, das zuerst auf ** torchvision.models.googlenet ** erscheint.

#Eingabe ist(112, 112, 64)
MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)

Wenn ich die Ausgabegröße berechne, ** 55,5 **

output\_shape = \frac{input\_shape + 2 \times padding - kernel\_size}{stride} + 1 \\
= \frac{112 + 2 \times 0 - 3}{2} + 1 = 55.5

Betrachtet man die tatsächliche Ausgabegröße mit Fackelzusammenfassung, so ist sie ** (ch = 64, 56, 56) **, so dass sie nach dem Dezimalpunkt sicherlich aufgerundet (Ceil) zu sein scheint.

MaxPool2d-4           [-1, 64, 56, 56]

Überprüfen Sie das Ergebnis von PyTorch

Fügen Sie die folgenden Beispieldaten der Größe (10,10) in MaxPool2d von Kernel = (3,3), Schritt = (2,2) ein und sehen Sie das Ergebnis.

Beispieldaten

import torch
import torch.nn as nn

>>> x = torch.arange(1, 101).view(1, 10, 10).float()
>>> x
tensor([[[  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.]]])
>>> x.shape
torch.Size([1, 10, 10])

ceil_mode = False padding = 1

>>> nn.MaxPool2d((3,3), stride=2, padding=1, ceil_mode=False)(x)               

#Ausgabegröße(5, 5)
tensor([[[ 12.,  14.,  16.,  18.,  20.],
         [ 32.,  34.,  36.,  38.,  40.],
         [ 52.,  54.,  56.,  58.,  60.],
         [ 72.,  74.,  76.,  78.,  80.],
         [ 92.,  94.,  96.,  98., 100.]]])
output\_shape = \frac{input\_shape + 2 \times padding - kernel\_size}{stride} + 1 \\
= \frac{10 + 2 \times 1 - 3}{2} + 1 = 5.5

Nach dem Dezimalpunkt abschneiden, 5.5 → 5

padding = 0

>>> nn.MaxPool2d((3,3), stride=2, padding=0, ceil_mode=False)(x) 

#Ausgabegröße(4, 4)
tensor([[[23., 25., 27., 29.],
         [43., 45., 47., 49.],
         [63., 65., 67., 69.],
         [83., 85., 87., 89.]]])
output\_shape = \frac{input\_shape + 2 \times padding - kernel\_size}{stride} + 1 \\
= \frac{10 + 2 \times 0 - 3}{2} + 1 = 4.5

Nach dem Dezimalpunkt abschneiden, 4.5 → 4

ceil_mode = True padding = 1

>>> nn.MaxPool2d((3,3), stride=2, padding=1, ceil_mode=True)(x) 

#Ausgabegröße(6, 6)
tensor([[[ 12.,  14.,  16.,  18.,  20.,  20.],
         [ 32.,  34.,  36.,  38.,  40.,  40.],
         [ 52.,  54.,  56.,  58.,  60.,  60.],
         [ 72.,  74.,  76.,  78.,  80.,  80.],
         [ 92.,  94.,  96.,  98., 100., 100.],
         [ 92.,  94.,  96.,  98., 100., 100.]]])
output\_shape = \frac{input\_shape + 2 \times padding - kernel\_size}{stride} + 1 \\
= \frac{10 + 2 \times 1 - 3}{2} + 1 = 5.5

Nach dem Dezimalpunkt aufrunden, 5.5 → 6

padding = 0

>>> nn.MaxPool2d((3,3), stride=2, padding=0, ceil_mode=True)(x)  

#Ausgabegröße(5, 5)
tensor([[[ 23.,  25.,  27.,  29.,  30.],
         [ 43.,  45.,  47.,  49.,  50.],
         [ 63.,  65.,  67.,  69.,  70.],
         [ 83.,  85.,  87.,  89.,  90.],
         [ 93.,  95.,  97.,  99., 100.]]])
output\_shape = \frac{input\_shape + 2 \times padding - kernel\_size}{stride} + 1 \\
= \frac{10 + 2 \times 0 - 3}{2} + 1 = 4.5

Nach dem Dezimalpunkt aufrunden, 4.5 → 5

Unterschied zwischen True / False von Ceil_Mode

Die folgenden Ausgabegrößen sind alle (5, 5), aber was ist der Unterschied?

padding=1, ceil_mode=False

Zustand von Max Pooling

image.png

Ausgabe

image.png

padding=0, ceil_mode=True

Zustand von Max Pooling

Da keine Polsterung vorhanden ist, wird das Pooling von oben links durchgeführt. Durch Aufrunden der Ausgabeform entspricht das Ergebnis dem Auffüllen nur der rechten und unteren Form.

image.png

Ausgabe

image.png

Lassen Sie uns das Ergebnis von Keras überprüfen

Fügen Sie die folgenden Beispieldaten der Größe (10,10) in MaxPool2d von Kernel = (3,3), Schritt = (2,2) ein und sehen Sie das Ergebnis. Keras 'MaxPooling2D hat keine Ceil_Mode-ähnlichen Parameter.

Es scheint, dass Keras das Berechnungsergebnis der Ausgabeform immer nach dem Dezimalpunkt abschneidet (** lid_mode = False ** in Pytorch).

Beispieldaten

Generieren Sie wie bei Pytorch 10x10 Daten.

from tensorflow.keras.layers import MaxPooling2D
import numpy as np

x = np.arange(1, 101).reshape(1, 10, 10, 1).astype(np.float)

padding=1 Gleiche Ausgabe wie ** padding = 1, lid_mode = False ** auf Pytorch.

>>> out = MaxPooling2D((3,3), strides=(2,2))(ZeroPadding2D((1,1))(x))
>>> out = tf.transpose(out, perm=[0,3,1,2])
>>> with tf.Session() as sess:  
>>>     out_value = sess.run(out)
>>>     print(out_value)

#Ausgabegröße(5, 5)
[[[[ 12.  14.  16.  18.  20.]
   [ 32.  34.  36.  38.  40.]
   [ 52.  54.  56.  58.  60.]
   [ 72.  74.  76.  78.  80.]
   [ 92.  94.  96.  98. 100.]]]]

padding=0 Gleiche Ausgabe wie ** padding = 0, lid_mode = False ** auf Pytorch.

>>> out = MaxPooling2D((3,3), strides=(2,2))(x)
>>> out = tf.transpose(out, perm=[0,3,1,2])
>>> with tf.Session() as sess:  
>>>     out_value = sess.run(out)
>>>     print(out_value)

#Ausgabegröße(4, 4)
[[[[23. 25. 27. 29.]
   [43. 45. 47. 49.]
   [63. 65. 67. 69.]
   [83. 85. 87. 89.]]]]

Wie erhalte ich mit Keras die gleiche Ausgabe wie Ceil_Mode = True?

Wenn ZeroPadding2D wie folgt eingestellt ist, wird das Null-Auffüllen vertikal und horizontal durchgeführt.

ZeroPadding2D((1,1))(x)

image.png

Es ist auch möglich, die Polstereinstellungen für oben und unten, links und rechts zu ändern, wie unten gezeigt. (Nullpolsterung wird nur unten und rechts angewendet.)

ZeroPadding2D(((0,1), (0,1)))(x)

image.png

Durch Anwenden der Null-Auffüllung nur unten und rechts konnten wir die gleiche Ausgabe wie Ceil_Mode = True erzielen.

>>> out = MaxPooling2D((3,3), strides=(2,2))(ZeroPadding2D(((0,1), (0,1)))(x))
>>> out = tf.transpose(out, perm=[0,3,1,2])
>>> with tf.Session() as sess:  
>>>     out_value = sess.run(out)
>>>     print(out_value)

#Ausgabegröße(5, 5)
[[[[ 23.  25.  27.  29.  30.]
   [ 43.  45.  47.  49.  50.]
   [ 63.  65.  67.  69.  70.]
   [ 83.  85.  87.  89.  90.]
   [ 93.  95.  97.  99. 100.]]]]

Recommended Posts

[Pytorch] MaxPool2d Ceil_Mode
Installieren Sie die Pytorch
PyTorch-Links
Übe Pytorch
Installieren Sie PyTorch