我正在尝试使用PyTorch website中的示例代码来转换python模型,以便在PyTorch c ++ api(LibTorch)中使用。
Converting to Torch Script via Tracing
To convert a PyTorch model to Torch Script via tracing, you must pass an instance of your model along with an example input to the torch.jit.trace function. This will produce a torch.jit.ScriptModule object with the trace of your model evaluation embedded in the module’s forward method:
import torch
import torchvision
# An instance of your model.
model = torchvision.models.resnet18()
# An example input you would normally provide to your model's forward() method.
example = torch.rand(1, 3, 224, 224)
# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save("model.pt")
此示例工作正常,并按预期保存了文件。 当我切换到该模型时:
model = models.segmentation.deeplabv3_resnet101(pretrained=True)
它给我以下错误:
File "convert.py", line 14, in <module>
traced_script_module = torch.jit.trace(model, example)
File "C:\Python37\lib\site-packages\torch\jit\__init__.py", line 636, in trace
raise ValueError('Expected more than 1 value per channel when training, got input size {}'.format(size))
ValueError: Expected more than 1 value per channel when training, got input size torch.Size([1, 256, 1, 1])
我认为这是因为example
格式错误,但是如何获得正确的格式呢?
根据下面的评论,我的新代码是:
import torch
import torchvision
from torchvision import models
model = models.segmentation.deeplabv3_resnet101(pretrained=True)
model.eval()
# An example input you would normally provide to your model's forward() method.
example = torch.rand(1, 3, 224, 224)
# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save("model.pt")
现在我得到了错误:
File "convert.py", line 15, in <module>
traced_script_module = torch.jit.trace(model, example)
File "C:\Python37\lib\site-packages\torch\jit\__init__.py", line 636, in trace
var_lookup_fn, _force_outplace)
RuntimeError: Only tensors and (possibly nested) tuples of tensors are supported as inputs or outputs of traced functions (toIValue at C:\a\w\1\s\windows\pytorch\torch/csrc/jit/pybind_utils.h:91)
(no backtrace available)
答案 0 :(得分:1)
您的问题出在BatchNorm层。如果每个通道需要个以上的值,则您的模型处于训练模式。您可以在模型上调用https://pytorch.org/cppdocs/api/classtorch_1_1nn_1_1_module.html#_CPPv4N5torch2nn6Module4evalEv并查看是否有改进吗?
否则,您也可以尝试生成一个批次中有多个实例的随机数据,即example = torch.rand(5, 3, 224, 224)
。
此外,您应该注意正确规范化数据,但是,这不会引起错误。
答案 1 :(得分:0)
(来自pytorch论坛)
trace仅支持将张量或张量元组作为输出的模块。 根据deeplabv3的实现,其输出为OrderedDict。那是个问题。 为了解决这个问题,制作一个包装模块
class wrapper(torch.nn.Module):
def __init__(self, model):
super(wrapper, self).__init__()
self.model = model
def forward(self, input):
results = []
output = self.model(input)
for k, v in output.items():
results.append(v)
return tuple(results)
model = wrapper(deeplap_model)
#trace...
是否保存了我的模型。