Coder Social home page Coder Social logo

chainer / onnx-chainer Goto Github PK

View Code? Open in Web Editor NEW
85.0 17.0 24.0 1.21 MB

Add-on package for ONNX format support in Chainer

License: MIT License

Python 98.64% Shell 0.50% Dockerfile 0.68% Batchfile 0.18%
chainer onnx deep-learning onnx-chainer onnx-support caffe onnx-format

onnx-chainer's Introduction

Notice: As announced, Chainer is under the maintenance phase and further development will be limited to bug-fixes and maintenance only.


Chainer: A deep learning framework

pypi GitHub license travis coveralls Read the Docs Optuna

Website | Docs | Install Guide | Tutorials (ja) | Examples (Official, External) | Concepts | ChainerX

Forum (en, ja) | Slack invitation (en, ja) | Twitter (en, ja)

Chainer is a Python-based deep learning framework aiming at flexibility. It provides automatic differentiation APIs based on the define-by-run approach (a.k.a. dynamic computational graphs) as well as object-oriented high-level APIs to build and train neural networks. It also supports CUDA/cuDNN using CuPy for high performance training and inference. For more details about Chainer, see the documents and resources listed above and join the community in Forum, Slack, and Twitter.

Installation

For more details, see the installation guide.

To install Chainer, use pip.

$ pip install chainer

To enable CUDA support, CuPy is required. Refer to the CuPy installation guide.

Docker image

We are providing the official Docker image. This image supports nvidia-docker. Login to the environment with the following command, and run the Python interpreter to use Chainer with CUDA and cuDNN support.

$ nvidia-docker run -it chainer/chainer /bin/bash

Contribution

See the contribution guide.

ChainerX

See the ChainerX documentation.

License

MIT License (see LICENSE file).

More information

References

Tokui, Seiya, et al. "Chainer: A Deep Learning Framework for Accelerating the Research Cycle." Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. ACM, 2019. URL BibTex

Tokui, S., Oono, K., Hido, S. and Clayton, J., Chainer: a Next-Generation Open Source Framework for Deep Learning, Proceedings of Workshop on Machine Learning Systems(LearningSys) in The Twenty-ninth Annual Conference on Neural Information Processing Systems (NIPS), (2015) URL, BibTex

Akiba, T., Fukuda, K. and Suzuki, S., ChainerMN: Scalable Distributed Deep Learning Framework, Proceedings of Workshop on ML Systems in The Thirty-first Annual Conference on Neural Information Processing Systems (NIPS), (2017) URL, BibTex

onnx-chainer's People

Contributors

colspan avatar disktnk avatar durswd avatar hakuyume avatar mitaki28 avatar mitmul avatar msakai avatar notogawa avatar okdshin avatar rezoo avatar shinh avatar sonots avatar syoyo avatar take-cheeze avatar tsurumeso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

onnx-chainer's Issues

Cannot fetch intermediate variable

Tested with chainer==5.1.0 and onnx-chainer==1.3.0a1.

import numpy as np

import chainer
import chainer.links as L
import onnx_chainer


class Model(chainer.Chain):

    def __init__(self):
        super().__init__()
        with self.init_scope():
            self.l1 = L.Linear(4)
            self.l2 = L.Linear(5)

    def __call__(self, x):
        y = self.l1(x)
        z = self.l2(y)
        return y, z


model = Model()
x = np.empty((1, 3), dtype=np.float32)
onnx_chainer.export(model, (x,))
Traceback (most recent call last):
  File "***.py", line 24, in <module>
    onnx_chainer.export(model, (x,))
  File "***/lib/python3.7/site-packages/onnx_chainer/export.py", line 306, in export
    checker.check_model(model)
  File "***/lib/python3.7/site-packages/onnx/checker.py", line 82, in check_model
    C.check_model(model.SerializeToString())
onnx.onnx_cpp2py_export.checker.ValidationError: Nodes in a graph must be topologically sorted, however input 'Input_0' of node: 
input: "Input_0" input: "139839959553304" input: "139839959553528" output: "Gemm_0" op_type: "Gemm" attribute { name: "alpha" f: 1 type: FLOAT } attribute { name: "beta" f: 1 type: FLOAT } attribute { name: "transA" i: 0 type: INT } attribute { name: "transB" i: 1 type: INT }
 is not output of any previous nodes.

Note that all of the following conditions worked well.

  • Return z only.
    def __call__(self, x):
        y = self.l1(x)
        z = self.l2(y)
        return z
  • Return y only.
    def __call__(self, x):
        y = self.l1(x)
        z = self.l2(y)
        return y
  • y is not intermediate variable.
    def __call__(self, x):
        y = self.l1(x)
        z = self.l2(x)
        return y, z

Support chainer.links.Bias

chainer.links.Bias is not included in Supported Functions.
However, I can export onnx model including Bias function.

Is chainer.links.Bias officially supported?
If the answer is YES, can you update Supported Functions?

NNVM example fails with `NNVMError`

When I run NNVM example on TVM 0.5 (the latest release)/ChainerCV 0.12.0/Chainer 6.0.0rc1, it fails as follows:

Traceback (most recent call last):
  File "export.py", line 76, in <module>
    main()
  File "export.py", line 65, in main
    save_as_onnx_then_import_from_nnvm(model, 'vgg16.onnx')
  File "export.py", line 30, in save_as_onnx_then_import_from_nnvm
    sym, params = nnvm.frontend.from_onnx(model_onnx)
  File "/home/xxxxxxxx/anaconda3/envs/work/lib/python3.6/site-packages/nnvm/frontend/onnx.py", line 984, in from_onnx
    sym, params = g.from_onnx(graph, opset)
  File "/home/xxxxxxxx/anaconda3/envs/work/lib/python3.6/site-packages/nnvm/frontend/onnx.py", line 839, in from_onnx
    op = self._convert_operator(op_name, inputs, attr, opset)
  File "/home/xxxxxxxx/anaconda3/envs/work/lib/python3.6/site-packages/nnvm/frontend/onnx.py", line 940, in _convert_operator
    sym = convert_map[op_name](inputs, attrs, self._params)
  File "/home/xxxxxxxx/anaconda3/envs/work/lib/python3.6/site-packages/nnvm/frontend/onnx.py", line 102, in _impl_v1
    custom_check=dimension_constraint())(inputs, attr, params)
  File "/home/xxxxxxxx/anaconda3/envs/work/lib/python3.6/site-packages/nnvm/frontend/common.py", line 139, in __call__
    return get_nnvm_op(op_name)(*inputs, **new_attrs)
  File "/home/xxxxxxxx/anaconda3/envs/work/lib/python3.6/site-packages/nnvm/_ctypes/symbol.py", line 197, in creator
    ctypes.byref(sym_handle)))
  File "/home/xxxxxxxx/anaconda3/envs/work/lib/python3.6/site-packages/nnvm/_base.py", line 91, in check_call
    raise NNVMError(py_str(_LIB.NNGetLastError()))
nnvm._base.NNVMError: Cannot find argument 'storage_order', Possible Arguments:
----------------
pool_size : , required
    Size of the pooling windows..
strides : , optional, default=[1,1]
    Specifies the strides of the convolution.
padding : , optional, default=[0,0]
    If padding is non-zero, then the input is implicitly zero-paddedPadding support both symmetric and asymmetric asone int : same padding used on all sidestwo int : bottom, right will use same padding as top, leftfour int : padding width in the order of (top, left, bottom, right)
layout : string, optional, default='NCHW'
    Dimension ordering of data and weight. Can be 'NCHW', 'NHWC', etc.'N', 'C', 'H', 'W' stands for batch, channel, height, and widthdimensions respectively. Convolution is applied on the 'H' and'W' dimensions.
ceil_mode : boolean, optional, default=0
    When true, will use ceil instead of floor to compute the output shape.
, in operator max_pool2d(name="", ceil_mode="False", strides="(2, 2)", storage_order="0", padding="(0, 0)", pool_size="(2, 2)")

There seems to be several complicated causes for this:

  1. NNVM lacks support for Opset > 1:
    ONNX-Chainer generates storage_order attribute for MaxPool operator, which was introduced in Opset 8 and unknown to NNVM.
  2. Though opset_version=1 for onnx_chainer.export() can help the above, it makes arithmetic operators (e.g. Mul) to be non-broadcasting mode.
    ONNX-Chainer generates broadcasting-Mul for the last pooling of ResNet-50, which requires explicit broadcast=1 in Opset 1.
  3. NNVM's broadcasting arithmetic operators seem buggy:
    Even if Mul operator has broadcast=1, NNVM raises another exception for tensor-by-scalar operation.
    (I'm asking at the TVM community for this problem)

Buid docker errors

Hi, I have faced several build docker errors when using the command "bash build_docker.sh" on Ubuntu 16.04, with onnx 1.1.1, Chainer 3.5.0, and Python 2.7. The errors are attached as follows, can you please help me solve these errors as soon as possible? Many thanks for that!

[ 13%] Building CXX object CMakeFiles/tvm.dir/src/arithmetic/bound_deducer.cc.o
[ 14%] Building CXX object CMakeFiles/tvm.dir/src/arithmetic/canonical.cc.o
/root/tvm/src/api/dsl_api.cc: In member function 'virtual void tvm::runtime::DSLAPIImpl::NodeGetAttr(NodeHandle, const char*, TVMValue*, int*, int*) const':
/root/tvm/src/api/dsl_api.cc:123:19: error: cannot declare variable 'getter' to be of abstract type 'tvm::runtime::APIAttrGetter'
APIAttrGetter getter;
^
/root/tvm/src/api/dsl_api.cc:32:8: note: because the following virtual functions are pure within 'tvm::runtime::APIAttrGetter':
struct APIAttrGetter : public AttrVisitor {
^
In file included from /root/tvm/include/tvm/./base.h:11:0,
from /root/tvm/include/tvm/api_registry.h:10,
from /root/tvm/src/api/dsl_api.cc:9:
/root/tvm/HalideIR/src/tvm/node.h:43:16: note: virtual void tvm::AttrVisitor::Visit(const char*, tvm::runtime::NDArray*)
virtual void Visit(const char* key, runtime::NDArray* value) = 0;
^
/root/tvm/src/api/dsl_api.cc: In member function 'virtual void tvm::runtime::DSLAPIImpl::NodeListAttrNames(NodeHandle, int*, const char***) const':
/root/tvm/src/api/dsl_api.cc:151:16: error: cannot declare variable 'dir' to be of abstract type 'tvm::runtime::APIAttrDir'
APIAttrDir dir;
^
/root/tvm/src/api/dsl_api.cc:71:8: note: because the following virtual functions are pure within 'tvm::runtime::APIAttrDir':
struct APIAttrDir : public AttrVisitor {
^
In file included from /root/tvm/include/tvm/./base.h:11:0,
from /root/tvm/include/tvm/api_registry.h:10,
from /root/tvm/src/api/dsl_api.cc:9:
/root/tvm/HalideIR/src/tvm/node.h:43:16: note: virtual void tvm::AttrVisitor::Visit(const char*, tvm::runtime::NDArray*)
virtual void Visit(const char* key, runtime::NDArray* value) = 0;
^
CMakeFiles/tvm.dir/build.make:153: recipe for target 'CMakeFiles/tvm.dir/src/api/dsl_api.cc.o' failed
make[2]: *** [CMakeFiles/tvm.dir/src/api/dsl_api.cc.o] Error 1
make[2]: *** Waiting for unfinished jobs....
[ 15%] Linking CXX shared library libtvm_runtime.so
[ 15%] Built target tvm_runtime
make[1]: *** [CMakeFiles/tvm.dir/all] Error 2
CMakeFiles/Makefile2:141: recipe for target 'CMakeFiles/tvm.dir/all' failed
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2
The command '/bin/sh -c cd $HOME/tvm &amp;&amp; git checkout ${TVM_COMMIT_ID} && mkdir build && cd build && cmake -DUSE_LLVM=ON .. && make -j$(nproc) install' returned a non-zero code: 2
The push refers to repository [docker.io/mitmul/onnx-chainer]
An image does not exist locally with the tag: mitmul/onnx-chainer

constant_values in Pad node should be float, not int

Current implementation of convert_Pad requires that the attribute constant_values contains an int. On the other hand, Pad operator in ONNX requires that the attribute value should be a float. As a result, when I try to export a model containing F.Pad with constant_values keyword, some error like below is invoked.

Traceback (most recent call last):
  File "temp_gen.py", line 66, in <module>
    onnx_chainer.export_testcase(model, (x,), 'pad', output_grad=True)
  File "/home/mkusumoto/onnx-chainer/onnx_chainer/export_testcase.py", line 37, in export_testcase
    return_flat_inout=True)
  File "/home/mkusumoto/onnx-chainer/onnx_chainer/export.py", line 348, in export
    checker.check_model(model)
  File "/home/mkusumoto/py3.5/lib/python3.5/site-packages/onnx/checker.py", line 86, in check_model
    C.check_model(model.SerializeToString())
onnx.onnx_cpp2py_export.checker.ValidationError: Attribute 'value' is expected to have field 'f'

==> Context: Bad node spec: input: "Conv_0" output: "Pad_0" op_type: "Pad" attribute { name: "mode" s: "constant" type: STRING } attribute { name: "pads" ints: 2 ints: 2 ints: 2 ints: 2 ints: 2 ints: 2 ints: 2 ints: 2 type: INTS } attribute { name: "value" i: -1 type: INT }

I think this can be fixed simply by casting int values to float in convert_Pad.

Support Faster R-CNN

__call__ method of Faster R-CNN returns (Variable, Variable, array, array). src
This causes the following exception.

File "[path to]chainer/function_node.py", line 783, in grad
    v.node._check_old_style_gradient()
AttributeError: 'numpy.ndarray' object has no attribute 'node'

Is it possible for onnx-chainer to support Faster R-CNN ?

Cannot import ONNX models exported from Chainer models with Linear's nobias option

Hello.

I work on verification of DNN inference via ONNX models.
In the progress, I found the following problem.

When exporting a ONNX model from Chainer model with nobias=True of chainer.links.Linear,
Gemm's bias shape is as below.

2019-02-24 8 25 13

In this case, the following import error occurs on Menoh and Intel OpenVINO model optimizer.
libc++abi.dylib: terminating with uncaught exception of type menoh::error: menoh unsupported operator error: Gemm Abort trap: 6

When exporting a ONNX model from Chainer model with nobias=False of chainer.links.Linear,
Gemm's bias shape is as below.

2019-02-24 8 25 45

In this case, import and inference succeed on Menoh and Intel OpenVINO.

I tried the following modification and confirmed that import and inference run properly.

def convert_LinearFunction(func, onnx_op_name, opset_version, input_names, output_names, parameters):
    # When the func has bias
    if len(func.inputs) == 2:
        batchsize = func.inputs[0].shape[0]
        bias_dim = func.inputs[1].shape[0]
        if batch size == 1:
            bias = np.zeros((bias_dim), dtype=np.float32)
        else:
            bias = np.zeros((batchsize, bias_dim), dtype=np.float32)
        bias_param = chainer.Parameter(bias)
        parameters.append(bias_param)
        input_names.append(str(id(bias_param)))

BatchNormalization testing

export function forced forwarding to be chainer.config.train = False, this means BatchNormalization operator is always converted to FixedBatchNormalization.

  • add train = True mode on exporting
    • especially grad output, required to run with train = True (it's a bug)
  • add BatchNormalization test
  • deal with the pattern that number of outputs are different between Chainer and onnxruntime.

chainer->ONNX->Mxnet failed due to Input shape vs padding spec mismatch

hello,
any suggestion for this error? Thanks in advance.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "export.py", line 52, in
main()
File "export.py", line 45, in main
save_as_onnx_then_import_from_mxnet(model, 'vgg16.onnx')
File "export.py", line 29, in save_as_onnx_then_import_from_mxnet
label_shapes=None)
File "/miniconda/lib/python3.6/site-packages/mxnet/module/module.py", line 428, in bind
state_names=self._state_names)
File "/miniconda/lib/python3.6/site-packages/mxnet/module/executor_group.py", line 237, in init
self.bind_exec(data_shapes, label_shapes, shared_group)
File "/miniconda/lib/python3.6/site-packages/mxnet/module/executor_group.py", line 333, in bind_exec
shared_group))
File "/miniconda/lib/python3.6/site-packages/mxnet/module/executor_group.py", line 611, in _bind_ith_exec
shared_buffer=shared_data_arrays, **input_shapes)
File "/miniconda/lib/python3.6/site-packages/mxnet/symbol/symbol.py", line 1494, in simple_bind
raise RuntimeError(error_msg)
RuntimeError: simple_bind error. Arguments:
input_0: (1, 3, 224, 224)
Error in operator pad0: [18:08:15] src/operator/./pad-inl.h:211: Input shape vs padding spec mismatch.

A name can be used as both Input/Output

Probably a bug?

import numpy as np
import chainer
import chainer.functions as F

import onnx_chainer


class Model(chainer.Chain):
    def forward(self, x):
        return F.relu(x), x


model = Model()
x = model.xp.array([2,3], dtype=np.float32)
onnx_chainer.export(model, [x], 'o.onnx')

Output ONNX:

$ python3 -c 'import sys; import onnx; print(onnx.helper.printable_graph(onnx.load(sys.argv[1]).graph))' o.onnx
graph Graph (
  %Input_0[FLOAT, 2]
) {
  %Relu_0 = Relu(%Input_0)
  return %Relu_0, %Input_0
}

Export error on BatchNormarization with use_beta=False

add use_beta=False on BatchNormarization unit test, got

E           AssertionError: Parameterized test failed.
E
E           Base test method: TestBatchNormalization.test_output
E           Test parameters:
E             kwargs: {'use_beta': False}
E
E           ValidationError: Nodes in a graph must be topologically sorted, however input 'Input_1' of node:
E           input: "Input_0" input: "139828040779312" input: "Input_1" input: "139828040779928" input: "139828040954936" output: "BatchNormalization_0" op_type: "BatchNormalization" attribute { name: "epsilon" f: 2e-05 type: FLOAT } attribute { name: "momentum" f: 0 type: FLOAT }
E            is not output of any previous nodes.

pypi package does not include `functions` directory

$ git clone https://github.com/mitmul/onnx-chainer
$ python setup.py sdist
running sdist
running egg_info
creating onnx_chainer.egg-info
writing requirements to onnx_chainer.egg-info/requires.txt
writing onnx_chainer.egg-info/PKG-INFO
writing top-level names to onnx_chainer.egg-info/top_level.txt
writing dependency_links to onnx_chainer.egg-info/dependency_links.txt
writing manifest file 'onnx_chainer.egg-info/SOURCES.txt'
reading manifest file 'onnx_chainer.egg-info/SOURCES.txt'
writing manifest file 'onnx_chainer.egg-info/SOURCES.txt'
warning: sdist: standard file not found: should have one of README, README.rst, README.txt

running check
creating onnx-chainer-0.2.1b3
creating onnx-chainer-0.2.1b3/onnx_chainer
creating onnx-chainer-0.2.1b3/onnx_chainer.egg-info
copying files to onnx-chainer-0.2.1b3...
copying setup.cfg -> onnx-chainer-0.2.1b3
copying setup.py -> onnx-chainer-0.2.1b3
copying onnx_chainer/__init__.py -> onnx-chainer-0.2.1b3/onnx_chainer
copying onnx_chainer/export.py -> onnx-chainer-0.2.1b3/onnx_chainer
copying onnx_chainer/mapping.py -> onnx-chainer-0.2.1b3/onnx_chainer
copying onnx_chainer.egg-info/PKG-INFO -> onnx-chainer-0.2.1b3/onnx_chainer.egg-info
copying onnx_chainer.egg-info/SOURCES.txt -> onnx-chainer-0.2.1b3/onnx_chainer.egg-info
copying onnx_chainer.egg-info/dependency_links.txt -> onnx-chainer-0.2.1b3/onnx_chainer.egg-info
copying onnx_chainer.egg-info/requires.txt -> onnx-chainer-0.2.1b3/onnx_chainer.egg-info
copying onnx_chainer.egg-info/top_level.txt -> onnx-chainer-0.2.1b3/onnx_chainer.egg-info
Writing onnx-chainer-0.2.1b3/setup.cfg
creating dist
Creating tar archive
removing 'onnx-chainer-0.2.1b3' (and everything under it)

It does not include functions directory.

ONNX chainer raises an exception for unused parameters

This is probably a bug of the model, but I think we can make the error message more informative. I'm feeling a warning with parameters in question ignored is more appropriate than an error, since the exported model would work, but I'm not sure. What do you think?

import numpy as np
import chainer
import chainer.functions as F
import chainer.links as L
import onnx_chainer


class MLP(chainer.Chain):

    def __init__(self, n_units, n_out):
        super(MLP, self).__init__()
        with self.init_scope():
            # the size of the inputs to each layer will be inferred
            self.l1 = L.Linear(None, n_units)  # n_in -> n_units
            self.l2 = L.Linear(None, n_units)  # n_units -> n_units
            self.l3 = L.Linear(None, n_out)  # n_units -> n_out

    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        # Unused, for some reason.
        #h2 = F.relu(self.l2(h1))
        return self.l3(h1)


model = MLP(100, 10)
x = np.random.rand(1, 768).astype(np.float32)
onnx_chainer.export_testcase(model, [x], 'foo')

onnx-chainer generates multiple anonymous inputs for resnet50

Using the latest onnx-chainer release v1.1.1a2 , the converted onnx model for resnet contains numerous input parameters instead of one input ( ex . %140697098812368[FLOAT, 1x3x224x224] ).

Note : This issue doesn't happen in old version of onnx-chainer(v1.0.0a1 )
resnet50 model : took from release directory

You can also view the onnx model in netron viewer ( https://lutzroeder.github.io/Netron/ )

Below is the onnx graph preview :

graph Graph (                                           // anonymous inputs starts from here
  %140696804801872[FLOAT, 256]
  %140696823510544[FLOAT, 128]
  %140696804495568[FLOAT, 512]
  %140696804932240[FLOAT, 128]
  %140696823510864[FLOAT, 128]
  %140696804935440[FLOAT, 64]
  %140696804871632[FLOAT, 256]
  %140696804930192[FLOAT, 128]
  %140696804803152[FLOAT, 256]
  %140696804803856[FLOAT, 1024]
  %140696804871248[FLOAT, 512]
  %140696822800784[FLOAT, 64]
  %140696804840464[FLOAT, 512]
  %140696804848144[FLOAT, 128]
  %140696804870736[FLOAT, 256]
  %140696804819728[FLOAT, 256]
  %140696804498832[FLOAT, 512]
  %140696804871440[FLOAT, 512]
  %140696804842896[FLOAT, 512]
  %140696804802832[FLOAT, 1024]
  %140696804809616[FLOAT, 1024]
  %140696804923792[FLOAT, 256]
  %140696804933008[FLOAT, 512]
  %140696804922128[FLOAT, 64]
  %140696804809872[FLOAT, 256]
  %140696823510928[FLOAT, 128]
  %140696804924432[FLOAT, 128]
  %140696804923216[FLOAT, 64]
  %140696804924880[FLOAT, 128]
  %140696804496144[FLOAT, 512]
  %140696804841872[FLOAT, 512]
  %140696823411024[FLOAT, 64]
  %140696804497168[FLOAT, 2048]
  %140696804850448[FLOAT, 512]
  %140696804937680[FLOAT, 256]
  %140696804820944[FLOAT, 1024]
  %140696823512528[FLOAT, 128]
  %140696804821328[FLOAT, 1024]
  %140696804869648[FLOAT, 1024]
  %140696823413968[FLOAT, 64]
  %140696804849040[FLOAT, 128]
  %140696804805008[FLOAT, 256]
  %140696804805840[FLOAT, 1024]
  %140696804806352[FLOAT, 1024]
  %140696804808400[FLOAT, 256]
  %140696804841040[FLOAT, 2048]
  %140696823511696[FLOAT, 512]
  %140696804810640[FLOAT, 256]
  %140697098812368[FLOAT, 1x3x224x224]                  // actual input (nchw) 
  %140696823509968[FLOAT, 512]
  %140696804871120[FLOAT, 256]
  %140696804801808[FLOAT, 1024]
  %140696804851088[FLOAT, 512]
  %140696804496656[FLOAT, 512]
  %140696804843472[FLOAT, 2048]
  %140696804932560[FLOAT, 512]
  %140696823512144[FLOAT, 128]
  %140696804799312[FLOAT, 256]
  %140696823413584[FLOAT, 256]
  %140696804819216[FLOAT, 256]
  %140696822900176[FLOAT, 64]
  %140696804498448[FLOAT, 512]
  %140696804806032[FLOAT, 256]
  %140696804819856[FLOAT, 256]
  %140696804921936[FLOAT, 64]
  %140696804809488[FLOAT, 1024]
  %140696804822672[FLOAT, 256]
  %140696822899920[FLOAT, 64]
  %140696823509776[FLOAT, 512]
  %140696804934096[FLOAT, 64]
  %140696804822480[FLOAT, 1024]
  %140696804932432[FLOAT, 512]
  %140696804840336[FLOAT, 512]
  %140696804499216[FLOAT, 512]
  %140696804936528[FLOAT, 64]
  %140696822800848[FLOAT, 64]
  %140696804806992[FLOAT, 256]
  %140696804870352[FLOAT, 1024]
  %140696804800144[FLOAT, 256]
  %140696804537552[FLOAT, 2048]
  %140696804925200[FLOAT, 256]
  %140696804936336[FLOAT, 64]
  %140696823413264[FLOAT, 256]
  %140696804842192[FLOAT, 2048]
  %140696804937040[FLOAT, 256]
  %140696804497808[FLOAT, 2048]
  %140696804801104[FLOAT, 256]
  %140696804807888[FLOAT, 256]
  %140696804843344[FLOAT, 2048]
  %140696804804944[FLOAT, 256]
  %140696804921744[FLOAT, 64]
  %140696804802000[FLOAT, 1024]
  %140696804537488[FLOAT, 2048]
  %140696804847696[FLOAT, 512]
  %140696823512272[FLOAT, 128]
  %140696804850960[FLOAT, 256]
  %140696804933520[FLOAT, 512]
  %140696804804048[FLOAT, 256]
  %140696823411792[FLOAT, 256]
  %140696804820304[FLOAT, 1024]
  %140696804869968[FLOAT, 256]
  %140696804929616[FLOAT, 128]
  %140696804848336[FLOAT, 128]
  %140696823414480[FLOAT, 256]
  %140696804933200[FLOAT, 128]
  %140696804808528[FLOAT, 256]
  %140696804848080[FLOAT, 128]            //ends here
) initializers (
  %140696804798864[FLOAT, 1000]
  %140696804767696[FLOAT, 1000x2048]
  %140696822800592[FLOAT, 256]
  %140696822803280[FLOAT, 256]
  %140696822803216[FLOAT, 256x64x1x1]
  %140696822803856[FLOAT, 64]
  %140696822802704[FLOAT, 64]
  %140696822868112[FLOAT, 64x64x3x3]
  %140696822866064[FLOAT, 64]
  %140696822866320[FLOAT, 64]
  %140696822869264[FLOAT, 64x64x1x1]
  %140696822901520[FLOAT, 256]
  %140696822802576[FLOAT, 256]
  %140696822802064[FLOAT, 256x64x1x1]
  %140696823137424[FLOAT, 256]
  %140696823137104[FLOAT, 256]
  %140696823136656[FLOAT, 256x64x1x1]
  %140696822900752[FLOAT, 64]
  %140696822901264[FLOAT, 64]
  %140696822900240[FLOAT, 64x64x3x3]
  %140696822901904[FLOAT, 64]
  %140696822901776[FLOAT, 64]
  %140696822902544[FLOAT, 64x256x1x1]
  %140696823258512[FLOAT, 256]
  %140696823258192[FLOAT, 256]
  %140696822801808[FLOAT, 256x64x1x1]
  %140696823257552[FLOAT, 64]
  %140696823257232[FLOAT, 64]
  %140696823256784[FLOAT, 64x64x3x3]
  %140696823256400[FLOAT, 64]
  %140696823256080[FLOAT, 64]
  %140696823255632[FLOAT, 64x256x1x1]
  %140696823225104[FLOAT, 512]
  %140696823224784[FLOAT, 512]
  %140696823224336[FLOAT, 512x128x1x1]
  %140696823223952[FLOAT, 128]
  %140696823223632[FLOAT, 128]
  %140696823223184[FLOAT, 128x128x3x3]
  %140696823222800[FLOAT, 128]
  %140696823222480[FLOAT, 128]
  %140696823258960[FLOAT, 128x256x1x1]
  %140696823226128[FLOAT, 512]
  %140696823225808[FLOAT, 512]
  %140696823225488[FLOAT, 512x256x1x1]
  %140696823201104[FLOAT, 512]
  %140696823200784[FLOAT, 512]
  %140696823200336[FLOAT, 512x128x1x1]
  %140696823199952[FLOAT, 128]
  %140696823199632[FLOAT, 128]
  %140696823199184[FLOAT, 128x128x3x3]
  %140696823198800[FLOAT, 128]
  %140696823198480[FLOAT, 128]
  %140696823198032[FLOAT, 128x512x1x1]
  %140696823266192[FLOAT, 512]
  %140696823265808[FLOAT, 512]
  %140696823265360[FLOAT, 512x128x1x1]
  %140696823264976[FLOAT, 128]
  %140696823264656[FLOAT, 128]
  %140696823264208[FLOAT, 128x128x3x3]
  %140696823263824[FLOAT, 128]
  %140696823263504[FLOAT, 128]
  %140696823201552[FLOAT, 128x512x1x1]
  %140696804994192[FLOAT, 512]
  %140696804993808[FLOAT, 512]
  %140696804993296[FLOAT, 512x128x1x1]
  %140696804992784[FLOAT, 128]
  %140696804992400[FLOAT, 128]
  %140696804991888[FLOAT, 128x128x3x3]
  %140696804991376[FLOAT, 128]
  %140696823267280[FLOAT, 128]
  %140696823266768[FLOAT, 128x512x1x1]
  %140696805022992[FLOAT, 1024]
  %140696805022608[FLOAT, 1024]
  %140696805022096[FLOAT, 1024x256x1x1]
  %140696805021584[FLOAT, 256]
  %140696805021200[FLOAT, 256]
  %140696805020688[FLOAT, 256x256x3x3]
  %140696805020176[FLOAT, 256]
  %140696805019792[FLOAT, 256]
  %140696804994768[FLOAT, 256x512x1x1]
  %140696805053008[FLOAT, 1024]
  %140696805052624[FLOAT, 1024]
  %140696805023504[FLOAT, 1024x512x1x1]
  %140696805172880[FLOAT, 1024]
  %140696805172496[FLOAT, 1024]
  %140696805171984[FLOAT, 1024x256x1x1]
  %140696805171472[FLOAT, 256]
  %140696805138256[FLOAT, 256]
  %140696805137744[FLOAT, 256x256x3x3]
  %140696805137232[FLOAT, 256]
  %140696805136848[FLOAT, 256]
  %140696805136336[FLOAT, 256x1024x1x1]
  %140696805197712[FLOAT, 1024]
  %140696805197328[FLOAT, 1024]
  %140696805196816[FLOAT, 1024x256x1x1]
  %140696805196304[FLOAT, 256]
  %140696805195920[FLOAT, 256]
  %140696805174864[FLOAT, 256x256x3x3]
  %140696805174352[FLOAT, 256]
  %140696805173968[FLOAT, 256]
  %140696805173456[FLOAT, 256x1024x1x1]
  %140696805077904[FLOAT, 1024]
  %140696805077520[FLOAT, 1024]
  %140696805056464[FLOAT, 1024x256x1x1]
  %140696805055952[FLOAT, 256]
  %140696805055568[FLOAT, 256]
  %140696805055056[FLOAT, 256x256x3x3]
  %140696805054544[FLOAT, 256]
  %140696805054160[FLOAT, 256]
  %140696805053648[FLOAT, 256x1024x1x1]
  %140696805110928[FLOAT, 1024]
  %140696805110544[FLOAT, 1024]
  %140696805110032[FLOAT, 1024x256x1x1]
  %140696805080784[FLOAT, 256]
  %140696805080400[FLOAT, 256]
  %140696805079888[FLOAT, 256x256x3x3]
  %140696805079376[FLOAT, 256]
  %140696805078992[FLOAT, 256]
  %140696805078480[FLOAT, 256x1024x1x1]
  %140696805135760[FLOAT, 1024]
  %140696805135376[FLOAT, 1024]
  %140696805134864[FLOAT, 1024x256x1x1]
  %140696805113808[FLOAT, 256]
  %140696805113424[FLOAT, 256]
  %140696805112912[FLOAT, 256x256x3x3]
  %140696805112400[FLOAT, 256]
  %140696805112016[FLOAT, 256]
  %140696805111504[FLOAT, 256x1024x1x1]
  %140696804706320[FLOAT, 2048]
  %140696804705936[FLOAT, 2048]
  %140696804705424[FLOAT, 2048x512x1x1]
  %140696804704912[FLOAT, 512]
  %140696804704528[FLOAT, 512]
  %140696805199568[FLOAT, 512x512x3x3]
  %140696805199056[FLOAT, 512]
  %140696805198672[FLOAT, 512]
  %140696805198288[FLOAT, 512x1024x1x1]
  %140696804707600[FLOAT, 2048]
  %140696804707216[FLOAT, 2048]
  %140696804706832[FLOAT, 2048x1024x1x1]
  %140696804736592[FLOAT, 2048]
  %140696804736208[FLOAT, 2048]
  %140696804735696[FLOAT, 2048x512x1x1]
  %140696804735184[FLOAT, 512]
  %140696804734800[FLOAT, 512]
  %140696804734288[FLOAT, 512x512x3x3]
  %140696804733776[FLOAT, 512]
  %140696804733392[FLOAT, 512]
  %140696804708240[FLOAT, 512x2048x1x1]
  %140696804769616[FLOAT, 2048]
  %140696804769232[FLOAT, 2048]
  %140696804768720[FLOAT, 2048x512x1x1]
  %140696804768208[FLOAT, 512]
  %140696804767824[FLOAT, 512]
  %140696804767312[FLOAT, 512x512x3x3]
  %140696804766800[FLOAT, 512]
  %140696804766416[FLOAT, 512]
  %140696804765904[FLOAT, 512x2048x1x1]
  %140696823511248[FLOAT, 64]
  %140696823512784[FLOAT, 64]
  %140696823413456[FLOAT, 64]
  %140696823412176[FLOAT, 64x3x7x7]
  %140696804799056[FLOAT, 2048]
  %140696804538576[FLOAT, 2048]
  %140696804539856[FLOAT, 512]
  %140696804540240[FLOAT, 512]
  %140696804538768[FLOAT, 512]
  %140696803922384[FLOAT, 512]
  %140696804538384[FLOAT, 2048]
  %140696804767568[FLOAT, 2048]
  %140696804798544[FLOAT, 512]
  %140696803923920[FLOAT, 512]
  %140696804734608[FLOAT, 512]
  %140696803924688[FLOAT, 512]
  %140696803923728[FLOAT, 2048]
  %140696803924816[FLOAT, 2048]
  %140696804733968[FLOAT, 512]
  %140696803963152[FLOAT, 512]
  %140696804704336[FLOAT, 2048]
  %140696803963920[FLOAT, 2048]
  %140696804707856[FLOAT, 512]
  %140696803964112[FLOAT, 512]
  %140696805199248[FLOAT, 1024]
  %140696803963280[FLOAT, 1024]
  %140696804734992[FLOAT, 256]
  %140696803966224[FLOAT, 256]
  %140696805175120[FLOAT, 256]
  %140696803999824[FLOAT, 256]
  %140696804935632[FLOAT, 1024]
  %140696803966032[FLOAT, 1024]
  %140696805172240[FLOAT, 256]
  %140696804001360[FLOAT, 256]
  %140696805138000[FLOAT, 256]
  %140696804002128[FLOAT, 256]
  %140696805171664[FLOAT, 1024]
  %140696804002832[FLOAT, 1024]
  %140696804003728[FLOAT, 256]
  %140696805196112[FLOAT, 256]
  %140696805113552[FLOAT, 256]
  %140696804045456[FLOAT, 256]
  %140696805135952[FLOAT, 1024]
  %140696805136656[FLOAT, 1024]
  %140696805110288[FLOAT, 256]
  %140696804046992[FLOAT, 256]
  %140696805110736[FLOAT, 256]
  %140696804047760[FLOAT, 256]
  %140696804046800[FLOAT, 1024]
  %140696804047888[FLOAT, 1024]
  %140696804003664[FLOAT, 256]
  %140696804078032[FLOAT, 256]
  %140696805079184[FLOAT, 256]
  %140696804078800[FLOAT, 256]
  %140696805080528[FLOAT, 1024]
  %140696804079504[FLOAT, 1024]
  %140696804048464[FLOAT, 256]
  %140696804080336[FLOAT, 256]
  %140696804081168[FLOAT, 1024]
  %140696804081296[FLOAT, 1024]
  %140696804081104[FLOAT, 256]
  %140696805052816[FLOAT, 256]
  %140696805019984[FLOAT, 512]
  %140696805055696[FLOAT, 512]
  %140696805021008[FLOAT, 128]
  %140696804116240[FLOAT, 128]
  %140696804992208[FLOAT, 128]
  %140696804117008[FLOAT, 128]
  %140696823267088[FLOAT, 512]
  %140696804117712[FLOAT, 512]
  %140696804078992[FLOAT, 128]
  %140696804159568[FLOAT, 128]
  %140696804118352[FLOAT, 128]
  %140696804160336[FLOAT, 128]
  %140696804991184[FLOAT, 512]
  %140696804160528[FLOAT, 512]
  %140696823200528[FLOAT, 128]
  %140696804161872[FLOAT, 128]
  %140696823199440[FLOAT, 128]
  %140696804162640[FLOAT, 128]
  %140696804161680[FLOAT, 512]
  %140696804162768[FLOAT, 512]
  %140696823198928[FLOAT, 128]
  %140696803680912[FLOAT, 128]
  %140696823223440[FLOAT, 512]
  %140696803681680[FLOAT, 512]
  %140696823226320[FLOAT, 128]
  %140696803681872[FLOAT, 128]
  %140696804935376[FLOAT, 256]
  %140696803681040[FLOAT, 256]
  %140696803684048[FLOAT, 64]
  %140696803684176[FLOAT, 64]
  %140696803683984[FLOAT, 64]
  %140696803705296[FLOAT, 64]
  %140696823222992[FLOAT, 256]
  %140696823257040[FLOAT, 256]
  %140696823199824[FLOAT, 64]
  %140696803706832[FLOAT, 64]
  %140696823136464[FLOAT, 64]
  %140696803707600[FLOAT, 64]
  %140696803706640[FLOAT, 256]
  %140696803707728[FLOAT, 256]
  %140696823257360[FLOAT, 64]
  %140696803746064[FLOAT, 64]
  %140696822868560[FLOAT, 256]
  %140696803746832[FLOAT, 256]
  %140696822900624[FLOAT, 64]
  %140696803747024[FLOAT, 64]
  %140696844545104[FLOAT, 64]
  %140696803747600[FLOAT, 64]                   
) {
  %140696822900048 = Conv[dilations = [1, 1], kernel_shape = [7, 7], pads = [3, 3, 3, 3], strides = [2, 2]](%140697098812368, %140696823412176, %140696823413456)
  %140696822899664 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696822900048, %140696823512784, %140696823511248, %140696844545104, %140696803747600)
  %140696822899024 = Relu(%140696822899664)
  %140696822898896 = MaxPool[kernel_shape = [3, 3], pads = [0, 0, 0, 0], strides = [2, 2]](%140696822899024)
  %140696822801232 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696822898896, %140696822869264)
  %140696823412880 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696822898896, %140696822802064)
  %140696823410896 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696822801232, %140696822866320, %140696822866064, %140696822900624, %140696803747024)
  %140696804937552 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823412880, %140696822802576, %140696822901520, %140696822868560, %140696803746832)
  %140696823411984 = Relu(%140696823410896)
  %140696823414160 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696823411984, %140696822868112)
  %140696823412688 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823414160, %140696822802704, %140696822803856, %140696823257360, %140696803746064)
  %140696823413008 = Relu(%140696823412688)
  %140696823412624 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696823413008, %140696822803216)
  %140696823411856 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823412624, %140696822803280, %140696822800592, %140696803706640, %140696803707728)
  %140696823412816 = Add(%140696823411856, %140696804937552)
  %140696804936976 = Relu(%140696823412816)
  %140696804936208 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804936976, %140696822902544)
  %140696804933968 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804936208, %140696822901776, %140696822901904, %140696823136464, %140696803707600)
  %140696804934480 = Relu(%140696804933968)
  %140696804934160 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804934480, %140696822900240)
  %140696804937232 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804934160, %140696822901264, %140696822900752, %140696823199824, %140696803706832)
  %140696804936656 = Relu(%140696804937232)
  %140696804936784 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804936656, %140696823136656)
  %140696804923728 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804936784, %140696823137104, %140696823137424, %140696823222992, %140696823257040)
  %140696804937104 = Add(%140696804923728, %140696804936976)
  %140696804923408 = Relu(%140696804937104)
  %140696804923088 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804923408, %140696823255632)
  %140696804921680 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804923088, %140696823256080, %140696823256400, %140696803683984, %140696803705296)
  %140696804922704 = Relu(%140696804921680)
  %140696804922000 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804922704, %140696823256784)
  %140696804923984 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804922000, %140696823257232, %140696823257552, %140696803684048, %140696803684176)
  %140696804922896 = Relu(%140696804923984)
  %140696804923344 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804922896, %140696822801808)
  %140696804924816 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804923344, %140696823258192, %140696823258512, %140696804935376, %140696803681040)
  %140696804923856 = Add(%140696804924816, %140696804923408)
  %140696804924176 = Relu(%140696804923856)
  %140696804921808 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [2, 2]](%140696804924176, %140696823258960)
  %140696804931088 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [2, 2]](%140696804924176, %140696823225488)
  %140696804930640 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804921808, %140696823222480, %140696823222800, %140696823226320, %140696803681872)
  %140696804931664 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804931088, %140696823225808, %140696823226128, %140696823223440, %140696803681680)
  %140696804931280 = Relu(%140696804930640)
  %140696804930448 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804931280, %140696823223184)
  %140696804931216 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804930448, %140696823223632, %140696823223952, %140696823198928, %140696803680912)
  %140696804930128 = Relu(%140696804931216)
  %140696804933392 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804930128, %140696823224336)
  %140696804932688 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804933392, %140696823224784, %140696823225104, %140696804161680, %140696804162768)
  %140696804932048 = Add(%140696804932688, %140696804931664)
  %140696804931536 = Relu(%140696804932048)
  %140696804932112 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804931536, %140696823198032)
  %140696823510992 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804932112, %140696823198480, %140696823198800, %140696823199440, %140696804162640)
  %140696823512400 = Relu(%140696823510992)
  %140696823511440 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696823512400, %140696823199184)
  %140696823512208 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823511440, %140696823199632, %140696823199952, %140696823200528, %140696804161872)
  %140696823510736 = Relu(%140696823512208)
  %140696823509648 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696823510736, %140696823200336)
  %140696823510160 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823509648, %140696823200784, %140696823201104, %140696804991184, %140696804160528)
  %140696823513040 = Add(%140696823510160, %140696804931536)
  %140696823511568 = Relu(%140696823513040)
  %140696823512080 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696823511568, %140696823201552)
  %140696823511888 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823512080, %140696823263504, %140696823263824, %140696804118352, %140696804160336)
  %140696823509456 = Relu(%140696823511888)
  %140696823511824 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696823509456, %140696823264208)
  %140696823510416 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823511824, %140696823264656, %140696823264976, %140696804078992, %140696804159568)
  %140696823512848 = Relu(%140696823510416)
  %140696823509840 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696823512848, %140696823265360)
  %140696804850768 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696823509840, %140696823265808, %140696823266192, %140696823267088, %140696804117712)
  %140696823510352 = Add(%140696804850768, %140696823511568)
  %140696804850896 = Relu(%140696823510352)
  %140696804850064 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804850896, %140696823266768)
  %140696804848464 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804850064, %140696823267280, %140696804991376, %140696804992208, %140696804117008)
  %140696804849360 = Relu(%140696804848464)
  %140696804848592 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804849360, %140696804991888)
  %140696804850128 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804848592, %140696804992400, %140696804992784, %140696805021008, %140696804116240)
  %140696804849168 = Relu(%140696804850128)
  %140696804850256 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804849168, %140696804993296)
  %140696804850320 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804850256, %140696804993808, %140696804994192, %140696805019984, %140696805055696)
  %140696804849296 = Add(%140696804850320, %140696804850896)
  %140696804851216 = Relu(%140696804849296)
  %140696804848016 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [2, 2]](%140696804851216, %140696804994768)
  %140696804803280 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [2, 2]](%140696804851216, %140696805023504)
  %140696804804432 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804848016, %140696805019792, %140696805020176, %140696804081104, %140696805052816)
  %140696804805136 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804803280, %140696805052624, %140696805053008, %140696804081168, %140696804081296)
  %140696804804752 = Relu(%140696804804432)
  %140696804804304 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804804752, %140696805020688)
  %140696804803024 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804804304, %140696805021200, %140696805021584, %140696804048464, %140696804080336)
  %140696804802640 = Relu(%140696804803024)
  %140696804802704 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804802640, %140696805022096)
  %140696804806480 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804802704, %140696805022608, %140696805022992, %140696805080528, %140696804079504)
  %140696804805776 = Add(%140696804806480, %140696804805136)
  %140696804803664 = Relu(%140696804805776)
  %140696804805264 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804803664, %140696805053648)
  %140696804807440 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804805264, %140696805054160, %140696805054544, %140696805079184, %140696804078800)
  %140696804807568 = Relu(%140696804807440)
  %140696804806928 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804807568, %140696805055056)
  %140696804810000 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804806928, %140696805055568, %140696805055952, %140696804003664, %140696804078032)
  %140696804810512 = Relu(%140696804810000)
  %140696804809360 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804810512, %140696805056464)
  %140696804808272 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804809360, %140696805077520, %140696805077904, %140696804046800, %140696804047888)
  %140696804810256 = Add(%140696804808272, %140696804803664)
  %140696804807312 = Relu(%140696804810256)
  %140696804806800 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804807312, %140696805078480)
  %140696804809168 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804806800, %140696805078992, %140696805079376, %140696805110736, %140696804047760)
  %140696804808080 = Relu(%140696804809168)
  %140696804810192 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804808080, %140696805079888)
  %140696804821840 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804810192, %140696805080400, %140696805080784, %140696805110288, %140696804046992)
  %140696804821968 = Relu(%140696804821840)
  %140696804821584 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804821968, %140696805110032)
  %140696804820240 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804821584, %140696805110544, %140696805110928, %140696805135952, %140696805136656)
  %140696804820688 = Add(%140696804820240, %140696804807312)
  %140696804819920 = Relu(%140696804820688)
  %140696804819344 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804819920, %140696805111504)
  %140696804820496 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804819344, %140696805112016, %140696805112400, %140696805113552, %140696804045456)
  %140696804819408 = Relu(%140696804820496)
  %140696804821520 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804819408, %140696805112912)
  %140696804822544 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804821520, %140696805113424, %140696805113808, %140696804003728, %140696805196112)
  %140696804821200 = Relu(%140696804822544)
  %140696804822288 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804821200, %140696805134864)
  %140696804800848 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804822288, %140696805135376, %140696805135760, %140696805171664, %140696804002832)
  %140696804822800 = Add(%140696804800848, %140696804819920)
  %140696804800592 = Relu(%140696804822800)
  %140696804800272 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804800592, %140696805136336)
  %140696804799952 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804800272, %140696805136848, %140696805137232, %140696805138000, %140696804002128)
  %140696804799568 = Relu(%140696804799952)
  %140696804800976 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804799568, %140696805137744)
  %140696804801296 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804800976, %140696805138256, %140696805171472, %140696805172240, %140696804001360)
  %140696804802192 = Relu(%140696804801296)
  %140696804801552 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804802192, %140696805171984)
  %140696804868496 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804801552, %140696805172496, %140696805172880, %140696804935632, %140696803966032)
  %140696804801936 = Add(%140696804868496, %140696804800592)
  %140696804868560 = Relu(%140696804801936)
  %140696804868688 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804868560, %140696805173456)
  %140696804870480 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804868688, %140696805173968, %140696805174352, %140696805175120, %140696803999824)
  %140696804871504 = Relu(%140696804870480)
  %140696804869840 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804871504, %140696805174864)
  %140696804868432 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804869840, %140696805195920, %140696805196304, %140696804734992, %140696803966224)
  %140696804869456 = Relu(%140696804868432)
  %140696804869520 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804869456, %140696805196816)
  %140696804870288 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804869520, %140696805197328, %140696805197712, %140696805199248, %140696803963280)
  %140696804869136 = Add(%140696804870288, %140696804868560)
  %140696804871312 = Relu(%140696804869136)
  %140696804869584 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [2, 2]](%140696804871312, %140696805198288)
  %140696804839888 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [2, 2]](%140696804871312, %140696804706832)
  %140696804841104 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804869584, %140696805198672, %140696805199056, %140696804707856, %140696803964112)
  %140696804842064 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804839888, %140696804707216, %140696804707600, %140696804704336, %140696803963920)
  %140696804840784 = Relu(%140696804841104)
  %140696804840208 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804840784, %140696805199568)
  %140696804840016 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804840208, %140696804704528, %140696804704912, %140696804733968, %140696803963152)
  %140696804839760 = Relu(%140696804840016)
  %140696804840912 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804839760, %140696804705424)
  %140696804842768 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804840912, %140696804705936, %140696804706320, %140696803923728, %140696803924816)
  %140696804840720 = Add(%140696804842768, %140696804842064)
  %140696804839824 = Relu(%140696804840720)
  %140696804841488 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804839824, %140696804708240)
  %140696804496016 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804841488, %140696804733392, %140696804733776, %140696804734608, %140696803924688)
  %140696804842832 = Relu(%140696804496016)
  %140696804495504 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804842832, %140696804734288)
  %140696804497424 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804495504, %140696804734800, %140696804735184, %140696804798544, %140696803923920)
  %140696804497936 = Relu(%140696804497424)
  %140696804498064 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804497936, %140696804735696)
  %140696804496976 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804498064, %140696804736208, %140696804736592, %140696804538384, %140696804767568)
  %140696804498192 = Add(%140696804496976, %140696804839824)
  %140696804496720 = Relu(%140696804498192)
  %140696804496464 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804496720, %140696804765904)
  %140696804498768 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804496464, %140696804766416, %140696804766800, %140696804538768, %140696803922384)
  %140696804497744 = Relu(%140696804498768)
  %140696804498960 = Conv[dilations = [1, 1], kernel_shape = [3, 3], pads = [1, 1, 1, 1], strides = [1, 1]](%140696804497744, %140696804767312)
  %140696804537744 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804498960, %140696804767824, %140696804768208, %140696804539856, %140696804540240)
  %140696804499088 = Relu(%140696804537744)
  %140696804537808 = Conv[dilations = [1, 1], kernel_shape = [1, 1], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804499088, %140696804768720)
  %140696804536976 = BatchNormalization[consumed_inputs = [0, 0, 0, 1, 1], epsilon = 1.99999994947575e-05, is_test = 1, spatial = 1](%140696804537808, %140696804769232, %140696804769616, %140696804799056, %140696804538576)
  %140696804537680 = Add(%140696804536976, %140696804496720)
  %140696804536720 = Relu(%140696804537680)
  %140696804497488 = AveragePool[kernel_shape = [7, 7], pads = [0, 0, 0, 0], strides = [1, 1]](%140696804536720)
  %140696804536528 = Reshape[shape = [1, 2048]](%140696804497488)
  %140696804536656 = Gemm[alpha = 1, beta = 1, transA = 0, transB = 1](%140696804536528, %140696804767696, %140696804798864)
  %140696804538064 = Softmax[axis = 1](%140696804536656)
  return %140696804538064
}

About Installation

Hi, I installed onnx-chainer along with https://github.com/chainer/onnx-chainer/blob/master/README.md.
I use Ubuntu 16.04.3 LTS, pyenv, and anaconda3-4.1.1.
In my environment, I need to write CPATH as export CPATH="/home/[USERAME]/.pyenv/versions/anaconda3-4.1.1/pkgs/protobuf-3.5.1-py35_3/include/" to successfully perform pip install git+git://github.com/onnx/onnx.git@8d0fc40162e0df1d14a0eba9e9696568153e54fd command.
When I didn't write CPATH, this error occured as below:

    cc1plus: warning: command line option '-Wstrict-prototypes' is valid for C/ObjC but not for C++
    In file included from /tmp/pip-v6otrtle-build/onnx/onnx.pb.cc:4:0:
    /tmp/pip-v6otrtle-build/onnx/onnx.pb.h:9:42: fatal error: google/protobuf/stubs/common.h: No such file or directory
    compilation terminated.
    error: command 'gcc' failed with exit status 1

Perhaps if he or she uses conda with pyenv, CPATH may not be set.
If you write about this on README.md, he or she may be helped.

I finally could install, so I have no problem.
I hope this will help.

quick start example MemoryError

When I run the quick start example in the Readme, I get the following error:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    onnx_chainer.export(model, x, filename='vgg16.onnx')
  File "/home/ubuntu/anaconda3/envs/chainer_p36/lib/python3.6/site-packages/onnx_chainer/export.py", line 237, in export
    checker.check_graph(onnx_graph)
  File "/home/ubuntu/anaconda3/envs/chainer_p36/lib/python3.6/site-packages/onnx/checker.py", line 46, in checker
    proto.SerializeToString(), ctx)
MemoryError

This is happening on a c5d.large instance type on a Deep Learning AMI on AWS. It has 4GB of RAM.

Input data don't follow args order

Even if give input [a, b, c], ONNX graph generated by export could be set the input values in different order like [b, c, a].

input/output test has exist but input dataset (input_*.pb) is made by network_inputs dictionary, so can't catch this error.

From Python 3.6+, key order of dictionary is held, so this bug couldn't be exposed.

RNN support for ONNX-Chainer

I just raised it, as we intensively use RNN (LSTM) for attention-based end-to-end ASR https://github.com/espnet/espnet with chainer and pytorch as a backend, and want to unify these two backends with the ONNX framework to some extent. I really appreciate if you answer when and how it is supported.

Value None error when F.sum(x, axis=None)

chainer.functions.sum(x) cause error when exporting.

Chainer sets axis=None on default, but ONNX does not allow axes=None on ReduceSum operator, must not set axes attribute when axis=None. Other ReduceXX operators are same.

Fix to accept inputs out of parameter scope

By #65, current exporter cannot resolve the below network, because an input value is in variable node, does not come from outer network inputs.

class Model(chainer.Chain):

    def __init__(self):
        super(Model, self).__init__()
        self.frac = chainer.Variable(np.array(2, dtype=np.float32))

    def __call__(self, x):
        return x / self.frac

Cannot output values in middle of a network

If you apply the following patch, the input of F.sigmoid will be an implicit input, instead of the output of Tanh:

  node {
    input: "140018190894696"
    output: "Sigmoid_0"
    op_type: "Sigmoid"
  }

Patch (note the test actually passes, but the graph is not what you want.

diff --git a/tests/test_inout.py b/tests/test_inout.py
index c1571d1..24e0960 100644
--- a/tests/test_inout.py
+++ b/tests/test_inout.py
@@ -97,7 +97,7 @@ class TestMultipleOutput(unittest.TestCase):
                 if self._use_bn:
                     h = self.bn(h)
                 o1 = F.tanh(h)
-                o2 = F.sigmoid(h)
+                o2 = F.sigmoid(o1)
                 if self._out_type == 'dict':
                     return {
                         'Tanh_0': o1,

Different behavior of bilinear interpolation between resize_images and ONNX Upsample

I have implemented exporting resize_images to ONNX by lowering it into Upsample ONNX op as did in unpooling_2D.

https://github.com/syoyo/onnx-chainer/tree/resize_images

and wanted to submit PR, but found a unit test fails due to different behavior of bilinear interpolation in Chainer and onnxruntime(and also TensorFlow/OpenCV which is a reference).

I use resize_images for pyramid pooling, thus need to embed resizing op into a model file.
So, I've tracked down this problem and here is a summary:

Input and output

Input shape: (2x2). [[64, 32], [64, 32]]
Output shape: (4x4) (Scaling factor is 2x)
Result: [64, ***, ***, 32] (Just check the first row)

========================================================= FAILURES ==========================================================
_______________________________________________ TestResizeImages.test_output ________________________________________________

self = <tests.functions_tests.test_arrays.TestResizeImages testMethod=test_output>

    def test_output(self):
    
        # FIXME(syoyo): Currently the test will fail due to different behavior
        # of bilinear interpolation between Chainer and onnxruntime.
        #
        # Currently Chainer will give [64, 53.333336, 42.666668, 32]
        # (same result with tensorflow r1.13.1 with `align_corners=True`),
        # while onnxruntime gives [64, 48, 32, 32]
        # (same result with tensorflow r1.13.1 with `align_corners=False`)
        #
        # Even though, expected bevhavior will be [64, 54, 40, 32].
        # (cv2.resize and tensorflow master(r1.14 or r2.0) after this fix:
        #  https://github.com/tensorflow/tensorflow/issues/6720)
    
        # TODO(hamaji): onnxruntime does not support Upsample-9 yet.
        # https://github.com/chainer/onnx-chainer/issues/111
>       self.expect(self.model, self.x, name='resize_images', skip_opset_version=[9])

tests/functions_tests/test_arrays.py:240: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/helper.py:101: in expect
    self.check_out_values(test_path, input_names=graph_input_names)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

test_path = 'out/opset7/test_resize_images', input_names = ['Input_0']

    def check_model_expect(test_path, input_names=None):
        if not ONNXRUNTIME_AVAILABLE:
            raise ImportError('ONNX Runtime is not found on checking module.')
    
        model_path = os.path.join(test_path, 'model.onnx')
        with open(model_path, 'rb') as f:
            onnx_model = onnx.load_model(f)
        sess = rt.InferenceSession(onnx_model.SerializeToString())
        rt_input_names = [value.name for value in sess.get_inputs()]
        rt_output_names = [value.name for value in sess.get_outputs()]
    
        # To detect unexpected inputs created by exporter, check input names
        if input_names is not None:
            assert list(sorted(input_names)) == list(sorted(rt_input_names))
    
        test_data_sets = sorted([
            p for p in os.listdir(test_path) if p.startswith('test_data_set_')])
        for test_data in test_data_sets:
            test_data_path = os.path.join(test_path, test_data)
            assert os.path.isdir(test_data_path)
            inputs, outputs = load_test_data(
                test_data_path, rt_input_names, rt_output_names)
    
            rt_out = sess.run(list(outputs.keys()), inputs)
            for cy, my in zip(outputs.values(), rt_out):
>               np.testing.assert_allclose(cy, my, rtol=1e-5, atol=1e-5)
E               AssertionError: 
E               Not equal to tolerance rtol=1e-05, atol=1e-05
E               
E               Mismatch: 50%
E               Max absolute difference: 10.666668
E               Max relative difference: 0.33333337
E                x: array([[[[64.      , 53.333336, 42.666668, 32.      ],
E                        [64.      , 53.333336, 42.666668, 32.      ],
E                        [64.      , 53.333332, 42.666668, 32.      ],
E                        [64.      , 53.333336, 42.666668, 32.      ]]]], dtype=float32)
E                y: array([[[[64., 48., 32., 32.],
E                        [64., 48., 32., 32.],
E                        [64., 48., 32., 32.],
E                        [64., 48., 32., 32.]]]], dtype=float32)

onnx_chainer/testing/test_onnxruntime.py:62: AssertionError

Chainer(v5.4)

it results in [64, 53.333336, 42.666668, 32].
(can be reproducable by running tests/functions_tests/test_arrays.py)

onnxruntime(v0.3.0)

it results in [64, 48, 32, 32].
(can be reproducable by running tests/functions_tests/test_arrays.py)

TensorFlow

import tensorflow as tf
import numpy as np

print(tf.__version__)

# NCHW
img = np.array([[[[64, 32],
                  [64, 32]]]], np.float32)
print(img.shape)

# to NHWC
img = tf.transpose(img, [0, 2, 3, 1])
print(img.shape)

align_corners = False # or True
img = tf.image.resize_bilinear(img, size=[4, 4], align_corners=align_corners)

sess = tf.Session()
ret = sess.run(img)
print(ret)

cv2.resize(should be the ground truth)

import cv2
import numpy as np

width = 2
height = 2

img = np.array([[64.0, 64.0],
                [32.0, 32.0]], np.float32)

size = (4, 4)

resized_img = cv2.resize(img, size)

print(resized_img)
 
# => (64, 56, 40, 32). FYI interpolator is [0, 0.25, 0.75, 1.0]

Current Chainer's behavior is same with the result of TF r1.13.1 but there was a bug

tensorflow/tensorflow#6720

and recently there had a fix to TF's resize_images with this commit: tensorflow/tensorflow@371c96d

What I should do?

Correct behavior will be the one in cv2.resize and tf r2.0([64, 56, 40, 32]), so we are better to move towards this direction in the last(i.e. add a fix or implement new resize_images into Chainer), but for a while there will be some options:

  • Disable unit test for resize_images and send PR
  • Write custom ONNX op or compare with manually supplied exected values
  • Wait until onnx opset 10 support in onnx-chainer(Resize op. since Upsample will be deprecated in opset 10)

References

export error about BroadCastTo

I'm trying export OurModel via onnx-chainer 1.4.1 from pip3.
OurModel uses F.reshape and F.transpose instead of Darknet reorg layer function.
I got error message bellow,
---from here
Traceback (most recent call last):
onnx_chainer.export(ourmodel, x_data ,filename='ourmodel.onnx', opset_version=None)
File "$HOME/.local/lib/python3.5/site-packages/onnx_chainer/export.py", line 266, in export
outputs.backward()
File "$HOME/.local/lib/python3.5/site-packages/chainer/variable.py", line 963, in backward
self._backward_main(retain_grad, loss_scale)
File "$HOME/.local/lib/python3.5/site-packages/chainer/variable.py", line 1043, in _backward_main
hook.backward_postprocess(func, in_data, out_grad_array)
File "$HOME/.local/lib/python3.5/site-packages/onnx_chainer/export.py", line 128, in backward_postprocess
onnx_op_name, opset_versions = mapping.operators[func_name]
KeyError: 'BroadcastTo'
--- end of message

OurModel don't use 'BroadcastTo' layer, but onnx-chainer select it for OurModel. I don't know why.
And I don't understand why to use cuda modules even though i do not using GPU.
A part of OurModel corresponding to reorg layer bellow,

---from here code snipet
batch_size, input_channel, input_height, input_width = h.data.shape
output_height, output_width, output_channel = int(input_height/2), int(input_width/2), input_channel22
output = F.transpose(F.reshape(h, (batch_size, input_channel, output_height, 2, output_width, 2)), (0, 1, 2, 4, 3, 5))
output = F.transpose(F.reshape(output, (batch_size, input_channel, output_height, output_width, -1)), (0, 4, 1, 2, 3))
high_resolution_feature = F.reshape(output, (batch_size, output_channel, output_height, output_width))
--- end of a code snipet

onn-chainer opset_verson is latest(specified None), may be opset_version >= 7.
Please help me anyone.

cannot broadcast a non-scalar to a scalar array?

Hi, I have a problem in export model to ONNX, could you help me? as follow:
In program, it works,
image
however, when In ONNXExport(opset_version) context, it occur problems
image

could you tell how to fix it, thanks a lot

To merge with the mainstream Chainer

  • Add input_names and output_names options to the export function
  • Add force_export option to export function to make auto-renaming of nodes possible
  • Add custom_name_resolver option to export function for custom renaming by users
  • Fix all source files to pass flake8 + hacking checks

onnx_chainer.export_testcase does not like cupy.arrays

import numpy as np
import chainer
import chainer.functions as F

import onnx_chainer


class Model(chainer.Chain):
    def forward(self, x):
        return F.relu(x)


model = Model()
model.to_gpu()
x = model.xp.array([2,3], dtype=np.float32)
onnx_chainer.export_testcase(model, [x], 'o')

An exception will be thrown:

$ python3 bug2.py
Traceback (most recent call last):
  File "bug2.py", line 16, in <module>
    onnx_chainer.export_testcase(model, [x], 'o')
  File "/home/i/wrk/onnx-chainer/onnx_chainer/export_testcase.py", line 49, in export_testcase
    t = numpy_helper.from_array(var.data, 'Input_%d' % i)
  File "/home/i/.local/lib/python3.6/site-packages/onnx/numpy_helper.py", line 104, in from_array
    tensor.raw_data = arr.tobytes()  # note: tobytes() is only after 1.9.
AttributeError: 'cupy.core.core.ndarray' object has no attribute 'tobytes'

ValidationError caused by id mismatch

In the following code it seems there are cases where i.get_variable_or_none() returns Variable/Parameter and go into else branch even if it is not a parameter inside a Link nor network input.

for i in function.inputs:
# 'i' is a VariableNode, so check if it has a Variable/Parameter
var = i.get_variable_or_none()
if var is None: # No reference to Variable/Parameter
input_names.append(str(id(i))) # Use VariableNode as is
# To support networks which have only a single layer
if i.creator is None and \
str(id(i)) not in self.network_inputs:
self.network_inputs[str(id(i))] = i
else: # It is a parameter inside a Link or network input
input_names.append(str(id(var)))
if i.creator is None and \
not isinstance(var, chainer.Parameter):
self.network_inputs[str(id(var))] = var
# This is to get corresponding VariableNode id from the output
# Variable of the network
for o in function.outputs:
var = o().get_variable_or_none()
if var is not None: # If the output is kept
self.middle_output_var_to_varnode[id(var)] = id(o())
output_names = [str(id(o())) for o in function.outputs]

In such cases, consumer of the variable refer it using id of Variable while producer of the variable refer it using id of VariableNode. This mismatch causes onnx.onnx_cpp2py_export.checker.ValidationError like following:

onnx.onnx_cpp2py_export.checker.ValidationError: Nodes in a graph must be topologically sorted, however input '112084623768' of node: input: "112084623768" output: "112084576968" op_type: "Reshape" attribute { name: "shape" ints: 32 ints: 51 ints: 16 type: INTS }

Cannot get Dockerfile to work

Hi, I think onnx-chainer/docker/Dockerfile may have got a bit out of date because of various dependencies. I am running Ubuntu 16.04.3.

(1) The first problem is that the git clone of caffe2 does not work:

Step 30/45 : RUN git clone --recursive https://github.com/caffe2/caffe2.git $HOME/caffe2
 ---> Running in 18857916b52b
Cloning into '/root/caffe2'...
  [several Submodules are registered and paths are checked out OK, then:]
Cloning into 'third_party/aten'...
fatal: reference is not a tree: f3c627d517968c20e8269ead1d90cd3a6c199356

and then:

Cloning into 'third_party/eigen'...
fatal: could not read Username for 'https://github.com': No such device or address
Clone of 'https://github.com/RLovelett/eigen.git' into submodule path 'third_party/eigen' failed
The command '/bin/sh -c git clone --recursive https://github.com/caffe2/caffe2.git $HOME/caffe2' returned a non-zero code: 1

(2) If I take out the caffe2 section (the lines from "RUN git clone ...caffe2" to "RUN pip install onnx-caffe2==1.0.0" inclusive) then I get a similar problem from the mxnet section.

(3) If I take out all the parts that install other frameworks than chainer, i.e. I delete from "RUN git clone ...caffe2" to the end of the file, I can build an image OK, but I can't get it to find the onnx_chainer package:

docker run -it <my_image>
root@285853fd7e4c:/# which python
/miniconda/bin/python
root@285853fd7e4c:/# python
Python 3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:09:58)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import chainer
>>> import onnx
>>> import onnx_chainer
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'onnx_chainer'
>>>
root@285853fd7e4c:/# find / -name '*onnx_chainer*'
<no result>

Would it be possible (instead, or additionally) to provide a Dockerfile that adds onnx support to something in the chainer/chainer Docker repo?

Thanks

installation question

Hello, The step in installation "pip install git+git://github.com/onnx/onnx.git@8d0fc40162e0df1d14a0eba9e9696568153e54fd" gave out "Connection Timeout" error message. Could you give it a fix? Thanks!

F.local_response_normalization is not exported to the ONNX format

When a model contains LRNs (F.local_response_normalization), the LRN nodes are not exported to the ONNX format correctly.
Other normalization operations such as BN (L.BatchNormalization) work fine.

This is an example code:

#!/usr/bin/env python3

import numpy as np
import chainer
import chainer.links as L
import chainer.functions as F
import onnx_chainer

class Alex(chainer.Chain):
    insize = 227

    def __init__(self, bn=False):
        super(Alex, self).__init__()
        with self.init_scope():
            self.conv1 = L.Convolution2D(None,  96, 11, stride=4)
            self.conv2 = L.Convolution2D(None, 256,  5, pad=2)
            self.conv3 = L.Convolution2D(None, 384,  3, pad=1)
            self.conv4 = L.Convolution2D(None, 384,  3, pad=1)
            self.conv5 = L.Convolution2D(None, 256,  3, pad=1)
            self.fc6 = L.Linear(None, 4096)
            self.fc7 = L.Linear(None, 4096)
            self.fc8 = L.Linear(None, 1000)
            self.norm1 = L.BatchNormalization(96)  if bn else F.local_response_normalization
            self.norm2 = L.BatchNormalization(256) if bn else F.local_response_normalization

    def __call__(self, x):
        h = F.max_pooling_2d(self.norm1(F.relu(self.conv1(x))), 3, stride=2)
        h = F.max_pooling_2d(self.norm2(F.relu(self.conv2(h))), 3, stride=2)
        h = F.relu(self.conv3(h))
        h = F.relu(self.conv4(h))
        h = F.max_pooling_2d(F.relu(self.conv5(h)), 3, stride=2)
        h = F.dropout(F.relu(self.fc6(h)))
        h = F.dropout(F.relu(self.fc7(h)))
        h = self.fc8(h)
        return h

x = np.zeros((1, 3, Alex.insize, Alex.insize), dtype=np.float32)
chainer.config.train = False

model_onnx = onnx_chainer.export(Alex(), x, filename='alex.onnx')
for node in model_onnx.graph.node:
    print(node.op_type)

print()

model_bn_onnx = onnx_chainer.export(Alex(True), x, filename='alex_bn.onnx')
for node in model_bn_onnx.graph.node:
    print(node.op_type)

This is the output:

Conv
Relu
MaxPool
Conv
Relu
MaxPool
Conv
Relu
Conv
Relu
Conv
Relu
MaxPool
Reshape
FC
Relu
FC
Relu
FC

Conv
Relu
BatchNormalization
MaxPool
Conv
Relu
BatchNormalization
MaxPool
Conv
Relu
Conv
Relu
Conv
Relu
MaxPool
Reshape
FC
Relu
FC
Relu
FC

The software versions I'm using are as follows:

  • Python: 3.6.4
    • chainer: 4.2.0
    • numpy: 1.14.2
    • cupy: 4.2.0
    • protobuf: 3.5.2.post1
    • onnx: 1.0.0
    • onnx-chainer: 1.0.0a1
  • libprotoc: 3.3.2
  • CUDA: 8.0.61

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.