class_docstr: Currently we only use it to infer caffe shape, we use tensorflow engine
  to infer tensorflow op shapes, since tensorflow has too many ops.
class_docstr_tok: ["Currently","we","only","use","it","to","infer","caffe","shape",",","we","use","tensorflow","engine","to","infer","tensorflow","op","shapes",",","since","tensorflow","has","too","many","ops","."]
code: def add_output_shape(self, op, shapes):
      mace_check(
          len(op.output) == len(shapes),
          "Op %s (%s) output count is different from "
          "output shape count" % (op.name, op.type),
      )
      for i in six.moves.range(len(shapes)):
          output_name = op.output[i]
          output_shape = op.output_shape.add()
          output_shape.dims.extend(shapes[i])
          self._output_shape_cache[output_name] = shapes[i]
  
imports: import math
  import numpy
  import six
  from transform.transformer import Transformer
  from transform.base_converter import DataFormat
  from transform.base_converter import MaceOp
  from transform.base_converter import MaceKeyword
  from transform.base_converter import ConverterUtil
  from utils.util import mace_check
label_desc: Use image node_id 3 for calling the ShapeInference obj's underlying member method code with example usage: obj.add_output_shape(op, shapes) without return types