无论是tensorflow还是pytorch的卷积操作在一般情况的padding都是正常的及两边上下补,只有当两边补除不尽的时候才会有不同,
个人测试:
如果pading=1,一般为两边都补充0即:
torch:padding=1 == tf:paddings=[[0, 0], [1, 1], [1, 1], [0, 0]]
如果padding=1 步长为2除不尽时,他就会只在上左进行填充:
torch:padding=1 == tf:padding=[[0, 0], [1, 0], [1, 0], [0, 0]]
如果padding=1 步长为2除不尽时,
torch:padding=1 == tf:padding=[[0, 0], [2, 1], [2,1], [0, 0]]
下面有完整代码,大家可以试一下,如果我的结论片面,请大家及时评论
在这里插入代码片
# 测试tensorflow 与torch 卷积的不同
import torch
import torch.nn.functional as F
import torchvision.transforms as transforms
import tensorflow as tf
import numpy as np
from tensorflow.keras import initializers
def model_th(x, kernel_init):
print(x.shape)
print(kernel_init.shape)
x = F.conv2d(x, weight=kernel_init, stride=2, padding=1)
print(x.shape)
return x
def model_tf(k_init):
kernel_init = initializers.Constant(k_init)
x0 = tf.keras.layers.Input(shape=[6, 6, 1])
x = tf.pad(x0, paddings=[[0, 0], [1, 0], [1, 0], [0, 0]])
x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, strides=2, padding='valid', use_bias=False, kernel_initializer=kernel_init)(x)
out = tf.keras.models.Model(inputs=x0, outputs=x)
return out
def model_tf_nopad(k_init):
kernel_init = initializers.Constant(k_init)
x0 = tf.keras.layers.Input(shape=[6, 6, 1])
#x = tf.pad(x0, paddings=[[0, 0], [1, 0], [1, 0], [0, 0]])
x = tf.keras.layers.Conv2D(filters=32, kernel_size=3, strides=1, padding='same', use_bias=False,
kernel_initializer=kernel_init)(x0)
out = tf.keras.models.Model(inputs=x0, outputs=x)
return out
if __name__ == '__main__':
img = np.random.uniform(0, 255, [6, 6, 1])
kernel = np.random.uniform(-5, 5, [32, 1, 3, 3])
tf_kernel = kernel.transpose([2, 3, 1, 0])
th_kernel = torch.from_numpy(kernel).float()
totensor = transforms.ToTensor()
th_img = totensor(img).unsqueeze(0).float()
tf_img = tf.expand_dims(img, axis=0)
tf_img = tf.cast(tf_img, tf.float32)
th_out = model_th(th_img, th_kernel)
tf_out = model_tf(tf_kernel)(tf_img)
tf_out_nopad = model_tf_nopad(tf_kernel)(tf_img)
print('--------------out-------------------')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
tf_out = sess.run(tf_out)
tf_out_nopad = sess.run(tf_out_nopad)
print('tf_out', tf_out.shape, tf_out)
print('th_out.permute([0, 2, 3, 1])', th_out.permute([0, 2, 3, 1]).shape, th_out.permute([0, 2, 3, 1]))
#print('valu',tf_out - th_out.permute([0, 2, 3, 1]).numpy())
print('tf_out_nopad',tf_out_nopad.shape, tf_out_nopad)