Tensorflow/Keras 带有 padding='SAME' 的 Conv2D 层表现异常
Tensorflow/Keras Conv2D layers with padding='SAME' behave strangely
我的问题:
我进行的一个简单的实验表明,在 Keras/TF 的 conv2d 层中使用 padding='SAME'
与在前面的零填充层中使用 padding='VALID'
不同。
- 这怎么可能?
- Keras/TF 是否在张量周围对称地补零?
实验说明 - 如果您有兴趣进一步阅读:
我使用 onnx2keras
包将我的 Pytorch 模型转换为 keras/TF。
当 onnx2keras
在 ONNX 模型中遇到具有 padding > 0
的卷积层时,它将其转换为 Keras 的 Conv2D
并具有 valid
填充(即无填充! ),前面是 Keras 的 ZeroPadding2D
层。这非常有效,returns 输出与 Pytorch 网络产生的输出相同。
我还认为它不简单地使用 padding='SAME'
很奇怪,因为大多数参考文献都说 Keras/TF 使用零填充,就像 Pytorch 一样。
尽管如此,我修补了 onnx2keras
并使其生成 Conv2D
层 padding='SAME'
而不是现有的 'VALID'
填充解决方案和前面的零填充层.这使得生成的模型 return 与具有零填充层的模型输出不同,当然也不同于我的 Pytorch 模型,后者在补丁之前是相同的。
Keras 中的 padding='Same'
意味着当输入大小和内核大小不完全适合时,会根据需要添加填充以弥补重叠。
填充示例='Same':
# Importing dependency
import keras
from keras.models import Sequential
from keras.layers import Conv2D
# Create a sequential model
model = Sequential()
# Convolutional Layer
model.add(Conv2D(filters=24, input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2) ,padding='Same'))
# Model Summary
model.summary()
代码的输出-
Model: "sequential_20"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_28 (Conv2D) (None, 3, 3, 24) 120
=================================================================
Total params: 120
Trainable params: 120
Non-trainable params: 0
_________________________________________________________________
图示:
下图显示了当 padding=[=69 时输入的填充 (input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2)) =].
-------------------------------------------- ---------------------------------------------- ------------------
padding='Valid'
在 Keras 中表示不添加填充。
padding='Valid': 对 Conv2D 使用了与我们上面用于 padding = 'Same' 相同的输入。即(input_shape=(5,5,1), kernel_size=(2,2), 步幅 =(2,2))
# Importing dependency
import keras
from keras.models import Sequential
from keras.layers import Conv2D
# Create a sequential model
model = Sequential()
# Convolutional Layer
model.add(Conv2D(filters=24, input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2) ,padding='Valid'))
# Model Summary
model.summary()
代码的输出-
Model: "sequential_21"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_29 (Conv2D) (None, 2, 2, 24) 120
=================================================================
Total params: 120
Trainable params: 120
Non-trainable params: 0
_________________________________________________________________
图示:
下图显示没有为输入添加填充 (input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2)) 当 padding='Valid'。
-------------------------------------------- ---------------------------------------------- ------------------
现在让我们尝试使用用于 padding='Valid'
的相同代码作为输入 (input_shape=(6,6,1), kernel_size=(2,2), strides =(2,2))。 此处 padding='Valid'
的行为应与 padding='Same'
相同。
代码-
# Importing dependency
import keras
from keras.models import Sequential
from keras.layers import Conv2D
# Create a sequential model
model = Sequential()
# Convolutional Layer
model.add(Conv2D(filters=24, input_shape=(6,6,1), kernel_size=(2,2), strides =(2,2) ,padding='Valid'))
# Model Summary
model.summary()
代码的输出-
Model: "sequential_22"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_30 (Conv2D) (None, 3, 3, 24) 120
=================================================================
Total params: 120
Trainable params: 120
Non-trainable params: 0
_________________________________________________________________
我的问题:
我进行的一个简单的实验表明,在 Keras/TF 的 conv2d 层中使用 padding='SAME'
与在前面的零填充层中使用 padding='VALID'
不同。
- 这怎么可能?
- Keras/TF 是否在张量周围对称地补零?
实验说明 - 如果您有兴趣进一步阅读:
我使用 onnx2keras
包将我的 Pytorch 模型转换为 keras/TF。
当 onnx2keras
在 ONNX 模型中遇到具有 padding > 0
的卷积层时,它将其转换为 Keras 的 Conv2D
并具有 valid
填充(即无填充! ),前面是 Keras 的 ZeroPadding2D
层。这非常有效,returns 输出与 Pytorch 网络产生的输出相同。
我还认为它不简单地使用 padding='SAME'
很奇怪,因为大多数参考文献都说 Keras/TF 使用零填充,就像 Pytorch 一样。
尽管如此,我修补了 onnx2keras
并使其生成 Conv2D
层 padding='SAME'
而不是现有的 'VALID'
填充解决方案和前面的零填充层.这使得生成的模型 return 与具有零填充层的模型输出不同,当然也不同于我的 Pytorch 模型,后者在补丁之前是相同的。
padding='Same'
意味着当输入大小和内核大小不完全适合时,会根据需要添加填充以弥补重叠。
填充示例='Same':
# Importing dependency
import keras
from keras.models import Sequential
from keras.layers import Conv2D
# Create a sequential model
model = Sequential()
# Convolutional Layer
model.add(Conv2D(filters=24, input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2) ,padding='Same'))
# Model Summary
model.summary()
代码的输出-
Model: "sequential_20"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_28 (Conv2D) (None, 3, 3, 24) 120
=================================================================
Total params: 120
Trainable params: 120
Non-trainable params: 0
_________________________________________________________________
图示: 下图显示了当 padding=[=69 时输入的填充 (input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2)) =].
-------------------------------------------- ---------------------------------------------- ------------------
padding='Valid'
在 Keras 中表示不添加填充。
padding='Valid': 对 Conv2D 使用了与我们上面用于 padding = 'Same' 相同的输入。即(input_shape=(5,5,1), kernel_size=(2,2), 步幅 =(2,2))
# Importing dependency
import keras
from keras.models import Sequential
from keras.layers import Conv2D
# Create a sequential model
model = Sequential()
# Convolutional Layer
model.add(Conv2D(filters=24, input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2) ,padding='Valid'))
# Model Summary
model.summary()
代码的输出-
Model: "sequential_21"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_29 (Conv2D) (None, 2, 2, 24) 120
=================================================================
Total params: 120
Trainable params: 120
Non-trainable params: 0
_________________________________________________________________
图示:
下图显示没有为输入添加填充 (input_shape=(5,5,1), kernel_size=(2,2), strides =(2,2)) 当 padding='Valid'。
-------------------------------------------- ---------------------------------------------- ------------------
现在让我们尝试使用用于 padding='Valid'
的相同代码作为输入 (input_shape=(6,6,1), kernel_size=(2,2), strides =(2,2))。 此处 padding='Valid'
的行为应与 padding='Same'
相同。
代码-
# Importing dependency
import keras
from keras.models import Sequential
from keras.layers import Conv2D
# Create a sequential model
model = Sequential()
# Convolutional Layer
model.add(Conv2D(filters=24, input_shape=(6,6,1), kernel_size=(2,2), strides =(2,2) ,padding='Valid'))
# Model Summary
model.summary()
代码的输出-
Model: "sequential_22"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_30 (Conv2D) (None, 3, 3, 24) 120
=================================================================
Total params: 120
Trainable params: 120
Non-trainable params: 0
_________________________________________________________________