PyTorch 和 Keras 之间不同的 2D 卷积结果

问题描述 投票:0回答:1

我正在尝试找到以下 PyTorch 行的等效 Keras 表示:

conv1 = nn.Conv2d(int(filters*s), filters, kernel_size=(3, 1), stride=int(1/s), padding=(1, 0))

代码:

import torch
from torch import nn

import torch
import tensorflow as tf
import numpy as np

from keras import initializers
from tensorflow.keras import layers

# constants between both libraries
filters = 2
s = 1

# Set the seed for reproducible set of numbers between keras and pytorch
torch.manual_seed(0)
np.random.seed(0)
tf.random.set_seed(0)

# Create a tensor in PyTorch of shape (128, 2, 1024, 1)
pytorch_tensor = torch.rand((128, 2, 1024, 1))

# Convert the PyTorch tensor to a NumPy array
numpy_array = pytorch_tensor.numpy()

# Reshape the NumPy array to the desired shape for Keras (128, 1024, 1, 2)
numpy_array = np.transpose(numpy_array, (0, 2, 3, 1))

# Create a tensor in Keras (TensorFlow) from the NumPy array
keras_tensor = tf.constant(numpy_array)

# PyTorch zeropad and convolution 
pytorch_conv1 = nn.Conv2d(int(filters*s), filters, kernel_size=(3, 1), stride=int(1/s), padding=(1, 0))(pytorch_tensor)

print(f"Pytorch values: {pytorch_conv1}")

# Keras zeropad and convolution 
keras_zeropad = layers.ZeroPadding2D(padding=((0,0),(1,0)))(keras_tensor)
keras_conv1 = layers.Conv2D(filters, kernel_size=(3, 1), strides=int(1/s), padding='valid', data_format='channels_last')(keras_zeropad)

print(f"Keras tensor values: {keras_conv1}")

我认为这个问题是填充问题,因为 PyTorch 和 Keras 处理它的方式不同。也就是说,在 Keras 的 Conv2D 层内,填充只能设置为

valid
same
。相反,我在 Conv2D 之前使用 ZeroPadding2D 层,因此可以在 Keras 中完成非对称填充。然而,尽管如此,我仍然无法获得匹配的输出数据。

我编写了以下代码,为 PyTorch 和 Keras 生成相同的输入张量,因此我知道数据是相同的。我也尝试过以相同的方式初始化权重和偏差,但数据仍然不匹配。

我看过有关在 Keras 中使用 PyTorch 权重来实现相同结果的帖子,但我想在我的应用程序中避免这种情况。

tensorflow machine-learning keras pytorch convolution
1个回答
0
投票

如果您的水平内核大小为

3
并且想要与
padding='same'
相同的行为,则手动设置的填充必须对称且两端都等于
1

pad = layers.ZeroPadding2D(padding=(1,0))

conv = layers.Conv2D(filters, 
                     kernel_size=(3, 1), 
                     strides=int(1/s), 
                     padding='valid', 
                     data_format='channels_last')

然后

conv(pad(keras_tensor))
将具有
(128, 1024, 1, 2)
的形状。

© www.soinside.com 2019 - 2024. All rights reserved.