【发布时间】:2021-01-13 21:11:06
【问题描述】:
因此,作为研究的一部分,我正在使用不同的深度学习框架,并观察到一些奇怪的事情(至少我无法解释其原因)。
我在 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 中使用一些随机值初始化模型,对单个批次进行前向传递。然后使用导出的参数在 Pytorch 中执行相同的操作。祝你好运!
-
@TarasSereda 绝妙的建议,我不知道为什么我没想过这样做。我尝试比较原始输出,它们几乎相同(由于四舍五入,第 7 位或第 8 位小数差异很小)。我观察到的差异在于准确性,我认为我使用的指标在两个框架中都不同。无论如何,我的问题现在已经解决了。谢谢!
标签: tensorflow neural-network pytorch