我是 pytorch 和 coreml 的新手。我从https://github.com/zhangboshen/A2J下载了一个预训练的pytorch模型(.pth文件),我想将其转换为coreml模型以用于ios应用程序。我加载模型如下。
import coremltools as ct
import torch
import torch.nn as nn
model = torch.load('/Users/sarojraut/Downloads/side.pth',map_location=torch.device('cpu'))
example_input = torch.rand(1, 3, 224, 224)
traced_model = torch.jit.trace(model, example_input)
但它给出了错误:
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
traced_model = torch.jit.trace(model, dummy_input)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site- packages/torch/jit/_trace.py", line 846, in trace
name = _qualified_name(func)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site- packages/torch/_jit_internal.py", line 1145, in _qualified_name
raise RuntimeError("Could not get name of python class object")
RuntimeError: Could not get name of python class object
您收到此错误的原因是因为您仅加载模型的权重或字典。 PyTorch 模型有两个主要部分:架构(模型的类)和权重/字典。他们通常是分开的。
要加载模型,请按照以下步骤操作:
使用其原始类( 建筑学)。 A2J_model 在您的情况下。
加载模型的状态字典(权重)。 HANDS2017.pth 用于此演示,但您可以使用 Github 存储库上提供的任何其他模型。
让我们利用 hands2017.py:
将其付诸实践import torch
import model as model
# This number provided by the original hands2017.py source code.
keypointsNumber = 21
model_dir = '/Desktop/A2J/HANDS2017.pth'
# Instance of the model.
net = model.A2J_model(num_classes = keypointsNumber)
# load the weights into the model.
net.load_state_dict(torch.load(model_dir, map_location=torch.device('cpu')))
# Put the model in eval mode before tracing.
net.eval()
example_input = torch.rand(1, 3, 224, 224)
# Trace your model..
traced_model = torch.jit.trace(net, example_input)
# Print the traced model to verify if the tracing was successful.
print(traced_model)
这会打印出我们的追踪模型(torchscript):
A2J_model(
original_name=A2J_model
(Backbone): ResNetBackBone(
original_name=ResNetBackBone
(model): ResNet(
original_name=ResNet
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
(maxpool): MaxPool2d(original_name=MaxPool2d)
(layer1): Sequential(
original_name=Sequential
(0): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
(downsample): Sequential(
original_name=Sequential
(0): Conv2d(original_name=Conv2d)
(1): BatchNorm2d(original_name=BatchNorm2d)
)
)
(1): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(2): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
)
(layer2): Sequential(
original_name=Sequential
(0): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
(downsample): Sequential(
original_name=Sequential
(0): Conv2d(original_name=Conv2d)
(1): BatchNorm2d(original_name=BatchNorm2d)
)
)
(1): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(2): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(3): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
)
(layer3): Sequential(
original_name=Sequential
(0): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
(downsample): Sequential(
original_name=Sequential
(0): Conv2d(original_name=Conv2d)
(1): BatchNorm2d(original_name=BatchNorm2d)
)
)
(1): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(2): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(3): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(4): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(5): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
)
(layer4): Sequential(
original_name=Sequential
(0): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
(downsample): Sequential(
original_name=Sequential
(0): Conv2d(original_name=Conv2d)
(1): BatchNorm2d(original_name=BatchNorm2d)
)
)
(1): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
(2): Bottleneck(
original_name=Bottleneck
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(relu): ReLU(original_name=ReLU)
)
)
(avgpool): AdaptiveAvgPool2d(original_name=AdaptiveAvgPool2d)
(fc): Linear(original_name=Linear)
)
)
(regressionModel): RegressionModel(
original_name=RegressionModel
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(act1): ReLU(original_name=ReLU)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(act2): ReLU(original_name=ReLU)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(act3): ReLU(original_name=ReLU)
(conv4): Conv2d(original_name=Conv2d)
(bn4): BatchNorm2d(original_name=BatchNorm2d)
(act4): ReLU(original_name=ReLU)
(output): Conv2d(original_name=Conv2d)
)
(classificationModel): ClassificationModel(
original_name=ClassificationModel
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(act1): ReLU(original_name=ReLU)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(act2): ReLU(original_name=ReLU)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(act3): ReLU(original_name=ReLU)
(conv4): Conv2d(original_name=Conv2d)
(bn4): BatchNorm2d(original_name=BatchNorm2d)
(act4): ReLU(original_name=ReLU)
(output): Conv2d(original_name=Conv2d)
)
(DepthRegressionModel): DepthRegressionModel(
original_name=DepthRegressionModel
(conv1): Conv2d(original_name=Conv2d)
(bn1): BatchNorm2d(original_name=BatchNorm2d)
(act1): ReLU(original_name=ReLU)
(conv2): Conv2d(original_name=Conv2d)
(bn2): BatchNorm2d(original_name=BatchNorm2d)
(act2): ReLU(original_name=ReLU)
(conv3): Conv2d(original_name=Conv2d)
(bn3): BatchNorm2d(original_name=BatchNorm2d)
(act3): ReLU(original_name=ReLU)
(conv4): Conv2d(original_name=Conv2d)
(bn4): BatchNorm2d(original_name=BatchNorm2d)
(act4): ReLU(original_name=ReLU)
(output): Conv2d(original_name=Conv2d)
)
)
这表明我们追踪成功了。 最后一点,查看这个旧的存储库,想与您分享,您通过利用 Apple 的本机 API 实现了手部和人体姿势估计(这些是基于视觉的模型,由 Apple 直接维护):
希望这有帮助。愉快地转换为 coreml 模型:)
@saroj 你解决这个问题了吗?