将pytorch转换为torchscript后得到不同的结果?将NSnumber转换为Float是否会造成任何损失?

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

我将pytorch预训练模型(.pt)转换为torchscript模型(.pt),以便在Swift 5(ios-iphone6s,xcode 11)中使用它。在Swift中,模型的“预测”功能为我提供了其嵌入值(张量)。由于它作为预测结果返回了NSNumber数组,因此我将类型为[NSNumber]的类型强制转换为[Double]或[Float]以计算两个嵌入值之间的距离。 L2归一化,点积等。

但是,虽然pytorch版本获得了正确答案,但是torchscript模型得到了很多错误答案。不仅答案不同,而且torchscript中两个嵌入对的距离计算也与结果不同。 PC(CPU,Pycharm)上的pytorch模型。实际上,在使用类型转换进行距离计算之前,NSNumber(Swift)中的嵌入值与float32(pytorch)中的值是如此不同。我使用了相同的输入图像。

我试图找到原因。有一次,我从swift-torchscript复制了嵌入值([NSNumber])并计算了pytorch中两个嵌入之间的距离,以检查我的距离计算实现是否存在问题在Swift中。我使用了torch.FloatTensor来使用类型转换[NSNumber]-> [Float]。我也尝试过[Double]。结果,我发现了无穷多个。这是否与错误答案相关?

此“ inf”是什么意思?它是计算错误还是类型转换错误?从NSNumber转换为Float或Double时,我是否丢失了信息?如何迅速从Torchscript模型中获取正确的值? 我应该检查什么?

我使用以下代码进行转换。 pytorch->火炬脚本。

import torch

from models.inception_resnet_v1 import InceptionResnetV1

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)

example = torch.rand(1, 3, 160, 160)
traced_script_module = torch.jit.trace(resnet, example)
traced_script_module.save("mobile_model.pt")
swift deep-learning pytorch nsnumber torchscript
1个回答
0
投票

您是否正在从以下位置使用InceptionResnetV1:https://github.com/timesler/facenet-pytorch?当您在比较输出时引用pytorch模型时,是在pytorch中运行时还是在按原样使用resnet时参考torchscript模型?

如果是后者,您是否已经检查了以下类似内容?

运行以下命令会得到什么:

print('Original:')
orig_res = resnet(example)
print(orig_res.shape)
print(orig_res[0, 0:10])
print('min abs value:{}'.format(torch.min(torch.abs(orig_res))))
print('Torchscript:')
ts_res = traced_script_module(example)
print(ts_res.shape)
print(ts_res[0, 0:10])
print('min abs value:{}'.format(torch.min(torch.abs(ts_res))))
print('Dif sum:')
abs_diff = torch.abs(orig_res-ts_res)
print(torch.sum(abs_diff))
print('max dif:{}'.format(torch.max(abs_diff)))

在定义'traced_script_module'之后。我得到以下信息:

Original:
torch.Size([1, 512])
tensor([ 0.0347,  0.0145, -0.0124,  0.0723, -0.0102,  0.0653, -0.0574,  0.0004,
        -0.0686,  0.0695], device='cuda:0', grad_fn=<SliceBackward>)
min abs value:0.00034740756382234395
Torchscript:
torch.Size([1, 512])
tensor([ 0.0347,  0.0145, -0.0124,  0.0723, -0.0102,  0.0653, -0.0574,  0.0004,
        -0.0686,  0.0695], device='cuda:0', grad_fn=<SliceBackward>)
min abs value:0.0003474018594715744
Dif sum:
tensor(8.1539e-06, device='cuda:0', grad_fn=<SumBackward0>)
max dif:5.960464477539063e-08

这不是完美的,但考虑到输出至少为10 ^ -4,并且前一个数字是512个元素的绝对差之和,不是均值,对我来说似乎不太遥远。最大差异在10 ^ -8左右。

顺便说一下,您可能想更改为:

example = torch.rand(1, 3, 160, 160).to(device)

如果您在上述测试中得到类似的结果,那么从swift-torchscript中获得的前10个输出值作为NSNumber会得到什么样的值,然后将其转换为float时,将两者进行比较pytorch和torchscript-pytorch模型输出中的切片?

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