Pytorch 如何将pad2d层复制到coremltools转换器中作为火炬

Pytorch 如何将pad2d层复制到coremltools转换器中作为火炬,pytorch,coreml,coremltools,Pytorch,Coreml,Coremltools,我一直在尝试将pytorch模型转换为coreML格式,但是其中一个层目前不受支持。因此,我试图使用寄存器操作符装饰器@register\u torch\u op来实现它,以重新实现coremltools.converters的层,但是我很难理解当前能够实现该功能的输入类型。我得到了这个,这是一个从pytorch大致翻译过来的实现,但它不起作用 from coremltools.converters.mil import Builder as mb from coremltools.conver

我一直在尝试将pytorch模型转换为coreML格式,但是其中一个层目前不受支持。因此,我试图使用寄存器操作符装饰器
@register\u torch\u op
来实现它,以重新实现coremltools.converters的层,但是我很难理解当前能够实现该功能的输入类型。我得到了这个,这是一个从pytorch大致翻译过来的实现,但它不起作用

from coremltools.converters.mil import Builder as mb
from coremltools.converters.mil import register_torch_op
from coremltools.converters.mil.frontend.torch.ops import _get_inputs

@register_torch_op
def replication_pad2d(context, node):
  inputs = _get_inputs(context, node)
  x = inputs[0]
  a = len(x)
  L_list, R_list = [], []
  U_list, D_list = [], []
  for i in range(a):#i:0, 1
    l = x[:, :, :, (a-i):(a-i+1)]
    L_list.append(l)
    r = x[:, :, :, (i-a-1):(i-a)]
    R_list.append(r)
  L_list.append(x)
  x = mb.concat(L_list+R_list[::-1], axis=3, name=node.name)
  for i in range(a):
    u = x[:, :, (a-i):(a-i+1), :]
    U_list.append(u)
    d = x[:, :, (i-a-1):(i-a), :]
    D_list.append(d)
  U_list.append(x)
  x = mb.concat(U_list+D_list[::-1], axis=3, name=node.name)
  context.add(x)
但是得到以下错误

<ipython-input-12-cf14ed84cb93> in replication_pad2d(context, node)
     59   inputs = _get_inputs(context, node)
     60   x = inputs[0]
---> 61   a = len(x)
     62   L_list, R_list = [], []
     63   U_list, D_list = [], []

TypeError: object of type 'Var' has no len()

复制中的
_pad2d(上下文,节点)
59输入=_获取_输入(上下文,节点)
60 x=输入[0]
--->61 a=len(x)
62 L_列表,R_列表=[],[]
63 U_列表,D_列表=[],[]
TypeError:类型为“Var”的对象没有len()

如果有人能帮助我更好地理解这一点就太好了,尤其是输入类型节点和上下文

我认为您可以将现有的填充层用作:

from coremltools.converters.mil import Builder as mb
from coremltools.converters.mil import register_torch_op
from coremltools.converters.mil.frontend.torch.ops import _get_inputs

@register_torch_op(torch_alias=["replication_pad2d"])
def HackedReplication_pad2d(context, node):
    inputs = _get_inputs(context, node)
    x = inputs[0]
    pad = inputs[1].val
    x_pad = mb.pad(x=x, pad=[pad[2], pad[3], pad[0], pad[1]], mode='replicate')
    context.add(x_pad, node.name)

填充操作的文档不是很好,因此填充参数的排序是一个猜测游戏。

这些内容基本上没有文档记录,我担心您必须仔细阅读coremltools源代码才能理解这一点。然而,我担心您当前的方法无论如何都不会起作用:据我所知,所有操作都需要使用
mb
表示。但是您正在构建一个Python列表来捕获中间结果。
Builder
对象将永远看不到这一点。你不必写像
l=x[:,:,:,(a-i):(a-i+1)]
这样的东西,你必须使用像
mb.split()
这样的东西。(我自己还没有详细使用过这个,所以我可能会弄错一些。)然而,Core ML在其现有的填充层中确实有一个
PaddingReplication
模式。也许更简单的解决方案是“破解”coremltools以支持这种模式。