NNgen / nngen

NNgen: A Fully-Customizable Hardware Synthesis Compiler for Deep Neural Network
Apache License 2.0
340 stars 46 forks source link

ValueError: shape contains '0': (0,) at fasterrcnn_resnet50_fpn #13

Open Kocha opened 4 years ago

Kocha commented 4 years ago

I tried Faster-RCNN(ResNet50) model.

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)

# Pytorch to ONNX
onnx_filename = 'fasterrcnn_resnet50_fpn_imagenet.onnx'
dummy_input = torch.randn(1, 3, 224, 224)
input_names = ['act']
output_names = ['out']
model.eval()
torch.onnx.export(model, dummy_input, onnx_filename,
                  verbose=True,
                  export_params=True,
                  opset_version=11,
                  do_constant_folding=True,
                  input_names=input_names, output_names=output_names)

# data types
dtypes = {}
act_dtype = ng.int16
weight_dtype = ng.int16
bias_dtype = ng.int16
scale_dtype = ng.int16

disable_fusion=False

# ONNX to NNgen
(outputs, placeholders, variables,
 constants, operators) = ng.from_onnx(onnx_filename,
                                      value_dtypes=dtypes,
                                      default_placeholder_dtype=act_dtype,
                                      default_variable_dtype=weight_dtype,
                                      default_constant_dtype=weight_dtype,
                                      default_operator_dtype=act_dtype,
                                      default_scale_dtype=scale_dtype,
                                      default_bias_dtype=bias_dtype,
                                      disable_fusion=disable_fusion)

But, ValueError: shape contains '0': (0,) error message was displayed at ng.from_onnx.

Traceback (most recent call last):
  File "fasterrcnn_resnet50.py", line 47, in <module>
    disable_fusion=disable_fusion)
  File "/nngen/onnx/__init__.py", line 290, in from_onnx
    default_operator_dtype)
  File "/nngen/onnx/__init__.py", line 401, in _to_constants
    dtype=dtype, shape=shape, name=name)
  File "/nngen/storage.py", line 30, in __init__
    dtype=dtype, shape=shape, name=name)
  File "/nngen/basic_types.py", line 359, in __init__
    _Storage.__init__(self, dtype=dtype, shape=shape, name=name, is_input=False)
  File "/nngen/basic_types.py", line 335, in __init__
    _Numeric.__init__(self, dtype=dtype, shape=shape, name=name)
  File "/nngen/basic_types.py", line 57, in __init__
    raise ValueError("shape contains '0': %s" % str(shape))
ValueError: shape contains '0': (0,)

Do you know the cause of the error?

nagakei05 commented 4 years ago

Hi

I stumbled upon the same error when I tried to create a nngen model from onnx, and I think I have figured out the cause of this error, so would like to share my conclusion here.

My nngen version: 1.3.0

TL;DR

This error is caused by a lack of supporting onnx operators in nngen. In my case I need the Reszie operator. In @Kocha 's case, it needs Reszie and Split. To resolve this issue, an additional implementation for the operators is needed. If you would like to use Faster-RCNN(ResNet50) model in your project, I recommend opening a issue for a support for these operators.

My analysis of this error

The model I tried was a PyTorch implementation of Fast-SCNN; I first converted the weights provided by the repository to onnx, and using that onnx file I tried to convert it to a nngen model, which gave me this error

Traceback (most recent call last):
  File "onnx_to_nngen.py", line 28, in <module>
    default_bias_dtype=bias_dtype,)
  File "C:\Users\nagak\Anaconda3\envs\nngen\lib\site-packages\nngen\onnx\__init__.py", line 296, in from_onnx
    default_operator_dtype)
  File "C:\Users\nagak\Anaconda3\envs\nngen\lib\site-packages\nngen\onnx\__init__.py", line 407, in _to_constants
    dtype=dtype, shape=shape, name=name)
  File "C:\Users\nagak\Anaconda3\envs\nngen\lib\site-packages\nngen\storage.py", line 30, in __init__
    dtype=dtype, shape=shape, name=name)
  File "C:\Users\nagak\Anaconda3\envs\nngen\lib\site-packages\nngen\basic_types.py", line 359, in __init__
    _Storage.__init__(self, dtype=dtype, shape=shape, name=name, is_input=False)
  File "C:\Users\nagak\Anaconda3\envs\nngen\lib\site-packages\nngen\basic_types.py", line 335, in __init__
    _Numeric.__init__(self, dtype=dtype, shape=shape, name=name)
  File "C:\Users\nagak\Anaconda3\envs\nngen\lib\site-packages\nngen\basic_types.py", line 57, in __init__
    raise ValueError("shape contains '0': %s" % str(shape))
ValueError: shape contains '0': (0,)

After some digging around in the code, I found out that this value error pointed to an constant operator which contained no value, and was also an input for the scale parameter for Resize. I assume that when PyTorch tries to convert the model to onnx, the default parameters of F.inerpolate layers are automatically converted to onnx constant operators, despite the default parameter is set to None, hence causing this issue.