tensorflow - 相同的神经网络权重不应该产生相同的结果吗?
问题描述
因此,作为研究的一部分,我正在使用不同的深度学习框架,并观察到一些奇怪的事情(至少我无法解释其原因)。
我在 Tensorflow 中训练了一个相当简单的 MLP 模型(在 mnist 数据集上),提取了训练的权重,在 PyTorch 中创建了相同的模型架构,并将训练的权重应用于 PyTorch 模型。现在我的期望是从 Tensorflow 和 PyTorch 模型中获得相同的测试准确性,但事实并非如此。我得到不同的结果。
所以我的问题是:如果一个模型被训练到某个最佳值,那么每次在同一个数据集上进行测试时训练的权重是否应该产生相同的结果(不管使用的框架如何)?
PyTorch 模型:
class Net(nn.Module):
def __init__(self) -> None:
super(Net, self).__init__()
self.fc1 = nn.Linear(784, 24)
self.fc2 = nn.Linear(24, 10)
def forward(self, x: Tensor) -> Tensor:
x = torch.flatten(x, 1)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
张量流模型:
def build_model() -> tf.keras.Model:
# Build model layers
model = models.Sequential()
# Flatten Layer
model.add(layers.Flatten(input_shape=(28,28)))
# Fully connected layer
model.add(layers.Dense(24, activation='relu'))
model.add(layers.Dense(10))
# compile the model
model.compile(
optimizer='sgd',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy']
)
# return newly built model
return model
为了从 Tensorflow 模型中提取权重并将它们应用于 Pytorch 模型,我使用以下函数:
提取权重:
def get_weights(model):
# fetch latest weights
weights = model.get_weights()
# transpose weights
t_weights = []
for w in weights:
t_weights.append(np.transpose(w))
# return
return t_weights
应用权重:
def set_weights(model, weights):
"""Set model weights from a list of NumPy ndarrays."""
state_dict = OrderedDict(
{k: torch.Tensor(v) for k, v in zip(model.state_dict().keys(), weights)}
)
self.load_state_dict(state_dict, strict=True)
解决方案
在回答部分提供解决方案,以造福社区。来自评论
如果您以相同的方式使用相同的权重,则结果应该相同,但也应考虑浮点舍入误差。同样,模型是否经过训练也没关系。您可以将模型架构视为矩阵乘法链,其间具有元素非线性。差别有多大?您是否在比较模型输出,我们在数据集上计算的指标?作为建议,在 Keras 中使用一些随机值初始化模型,对单个批次进行前向传递(从 jdehesa 和 Taras Sereda 转述)