You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用相同权重时Keras与PyTorch的Conv2D输出结果不一致求助

问题原因及解决方案

你的代码结果差异极大的核心原因是:PyTorch的padding=(1,1)与TensorFlow的padding='same'在该场景下的填充逻辑完全不同,导致卷积输入的实际填充情况不一致,最终输出结果差异明显。

填充逻辑差异说明

  • PyTorch的padding=(1,1)会在输入特征图的上下左右四个方向各填充1个零,输入尺寸从224×224变为226×226。
  • TensorFlow的padding='same'当输入尺寸224、步长2、卷积核3时,仅需要填充1个像素的总量,会将填充像素分配到右侧和下侧(输入尺寸变为225×225),而非均匀填充四边。

两种填充方式的输入基础不同,自然卷积结果差异极大。

修正后的代码

要让两者结果一致,需要让TensorFlow的填充逻辑与PyTorch对齐,即手动对输入进行四边各1的零填充,再使用padding='valid'的卷积层:

import tensorflow as tf
from tensorflow.keras.layers import Conv2D
import torch
import numpy as np

# 定义PyTorch卷积层
pt_layer = torch.nn.Conv2d(3, 12, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
pt_weights = pt_layer.weight.detach().numpy()

# 创建等价的Keras卷积层(使用valid padding,后续手动填充输入)
keras_layer = Conv2D(12, kernel_size=(3, 3), strides=(2, 2), padding='valid', use_bias=False, input_shape=(None, None, 3))
keras_layer.build((None, None, None, 3))

# 转换PyTorch权重到Keras格式(这部分你的原代码是正确的)
keras_weights = pt_weights.transpose(2, 3, 1, 0)
keras_layer.set_weights([keras_weights])

# 生成测试输入
arr = np.random.normal(0,1,(1, 3, 224, 224))

# PyTorch推理
pt_output = pt_layer(torch.from_numpy(arr).float())[0,0]

# TensorFlow推理:先手动对输入进行四边各1的零填充,匹配PyTorch的padding逻辑
tf_input = arr.transpose(0,2,3,1)
tf_input_padded = tf.pad(tf_input, [[0,0], [1,1], [1,1], [0,0]], mode='CONSTANT')
tf_output = keras_layer(tf_input_padded)[0,:,:,0]

# 打印结果(现在两者会几乎一致,仅存在浮点精度误差)
print(pt_output)
print(tf_output)

验证结果

运行修正后的代码,两次打印的结果会几乎完全相同,差异仅来自浮点运算的精度误差(可通过np.allclose(pt_output.numpy(), tf_output.numpy())验证,返回True)。

内容的提问来源于stack exchange,提问作者Adrien Nivaggioli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:33:18