I’m facing a weird error when trying to export my model to onnx: ValueError: Auto nesting doesn't know how to process an input object of type str. Accepted types: Tensors, or lists/tuples of them
The error says I’m using str
as input, which I’m not. My model is a M2Det detector and the implementation is quite tricky: there are for
loops, if
s and ModuleList
inside it. However, none of it seem to be the culprit for the error at hand.
The code is:
class M2Det(nn.Module):
def __init__(self, phase, size, config = None):
'''
M2Det: Multi-level Multi-scale single-shot object Detector
'''
super(M2Det,self).__init__()
self.phase = phase
self.size = size
self.init_params(config)
print_info('===> Constructing M2Det model', ['yellow','bold'])
self.construct_modules()
def init_params(self, config=None): # Directly read the config
assert config is not None, 'Error: no config'
for key,value in config.items():
if check_argu(key,value):
setattr(self, key, value)
def construct_modules(self,):
# construct tums
for i in range(self.num_levels):
if i == 0:
setattr(self,
'unet{}'.format(i+1),
TUM(first_level=True,
input_planes=self.planes//2,
is_smooth=self.smooth,
scales=self.num_scales,
side_channel=512)) #side channel isn't fixed.
else:
setattr(self,
'unet{}'.format(i+1),
TUM(first_level=False,
input_planes=self.planes//2,
is_smooth=self.smooth,
scales=self.num_scales,
side_channel=self.planes))
# construct base features
if 'vgg' in self.net_family:
self.base = nn.ModuleList(get_backbone(self.backbone))
shallow_in, shallow_out = 512,256
deep_in, deep_out = 1024,512
self.reduce= BasicConv(shallow_in, shallow_out, kernel_size=3, stride=1, padding=1)
self.up_reduce= BasicConv(deep_in, deep_out, kernel_size=1, stride=1)
# construct others
if self.phase == 'test':
self.softmax = nn.Softmax()
self.Norm = nn.BatchNorm2d(256*8)
self.leach = nn.ModuleList([BasicConv(
deep_out+shallow_out,
self.planes//2,
kernel_size=(1,1),stride=(1,1))]*self.num_levels)
# construct localization and recognition layers
loc_ = list()
conf_ = list()
for i in range(self.num_scales):
loc_.append(nn.Conv2d(self.planes*self.num_levels,
4 * 6, # 4 is coordinates, 6 is anchors for each pixels,
3, 1, 1))
conf_.append(nn.Conv2d(self.planes*self.num_levels,
self.num_classes * 6, #6 is anchors for each pixels,
3, 1, 1))
self.loc = nn.ModuleList(loc_)
self.conf = nn.ModuleList(conf_)
def forward(self,x):
loc,conf = list(),list()
base_feats = list()
if 'vgg' in self.net_family:
for k in range(len(self.base)):
x = self.base[k](x)
if k in self.base_out:
base_feats.append(x)
base_feature = torch.cat(
(self.reduce(base_feats[0]), F.interpolate(self.up_reduce(base_feats[1]),scale_factor=2,mode='nearest')),1
)
# tum_outs is the multi-level multi-scale feature
tum_outs = [getattr(self, 'unet{}'.format(1))(self.leach[0](base_feature), 'none')]
for i in range(1,self.num_levels,1):
tum_outs.append(
getattr(self, 'unet{}'.format(i+1))(
self.leach[i](base_feature), tum_outs[i-1][-1]
)
)
# concat with same scales
sources = [torch.cat([_fx[i-1] for _fx in tum_outs],1) for i in range(self.num_scales, 0, -1)]
sources[0] = self.Norm(sources[0])
for (x,l,c) in zip(sources, self.loc, self.conf):
loc.append(l(x).permute(0, 2, 3, 1).contiguous())
conf.append(c(x).permute(0, 2, 3, 1).contiguous())
loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1)
conf = torch.cat([o.view(o.size(0), -1) for o in conf], 1)
if self.phase == "test":
output = (
loc.view(loc.size(0), -1, 4), # loc preds
self.softmax(conf.view(-1, self.num_classes)), # conf preds
)
else:
output = (
loc.view(loc.size(0), -1, 4),
conf.view(conf.size(0), -1, self.num_classes),
)
return output
Thanks a lot