"object has no attribute 'unknown_rank'" when converting keras model to UFF

I have a Keras model which I saved into a .pb file, and when I try to convert it into UFF model using “from_tensorflow_frozen_model” function I am getting this error:

AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'unknown_rank'

This model is made out of the following layers: activation, average pooling, batch normalization, convolution, dense, and flatten. Batch normalization and Dense layers are not listed in supported layers, is one of those layers causing the error? Is there a way I can use this model in TensorRT?

Full output:

Warning: No conversion function registered for layer: Merge yet.
Converting as custom op Merge batch_normalization_4/cond/Merge
name: "batch_normalization_4/cond/Merge"
op: "Merge"
input: "batch_normalization_4/cond/batchnorm/add_1"
input: "batch_normalization_4/cond/Switch_1:1"
attr {
  key: "N"
  value {
    i: 2
  }
}
attr {
  key: "T"
  value {
    type: DT_FLOAT
  }
}

Warning: No conversion function registered for layer: Switch yet.
Converting as custom op Switch batch_normalization_4/cond/Switch_1
name: "batch_normalization_4/cond/Switch_1"
op: "Switch"
input: "batch_normalization_4/batchnorm/add_1"
input: "batch_normalization_4/cond/pred_id"
attr {
  key: "T"
  value {
    type: DT_FLOAT
  }
}
attr {
  key: "_class"
  value {
    list {
      s: "loc:@batch_normalization_4/batchnorm/add_1"
    }
  }
}

Warning: No conversion function registered for layer: PlaceholderWithDefault yet.
Converting as custom op PlaceholderWithDefault batch_normalization_1/keras_learning_phase
name: "batch_normalization_1/keras_learning_phase"
op: "PlaceholderWithDefault"
input: "batch_normalization_1/keras_learning_phase/input"
attr {
  key: "dtype"
  value {
    type: DT_BOOL
  }
}
attr {
  key: "shape"
  value {
    shape {
    }
  }
}

Traceback (most recent call last):
  File "freeze_keras.py", line 51, in <module>
    uff_model = uff.from_tensorflow_frozen_model(out_folder + "graph_frozen.pb", [out_names], output_filename='out_uff.uff', text=True)
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/conversion_helpers.py", line 103, in from_tensorflow_frozen_model
    return from_tensorflow(graphdef, output_nodes, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/conversion_helpers.py", line 75, in from_tensorflow
    name="main")
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/converter.py", line 64, in convert_tf2uff_graph
    uff_graph, input_replacements)
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/converter.py", line 51, in convert_tf2uff_node
    op, name, tf_node, inputs, uff_graph, tf_nodes=tf_nodes)
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/converter.py", line 28, in convert_layer
    fields = cls.parse_tf_attrs(tf_node.attr)
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/converter.py", line 177, in parse_tf_attrs
    for key, val in attrs.items()}
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/converter.py", line 177, in <dictcomp>
    for key, val in attrs.items()}
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/converter.py", line 172, in parse_tf_attr_value
    return cls.convert_tf2uff_field(code, val)
  File "/usr/local/lib/python2.7/dist-packages/uff/converters/tensorflow/converter.py", line 161, in convert_tf2uff_field
    if shp.unknown_rank:
AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'unknown_rank'

Hi,

Yes. Some non-supported layer(Merge, Switch and PlaceholderWithDefault) lead to this AttributeError.

To workaround this, you can try to add the non-supported layer implementation with our plugin API.
Here is sample to demonstrate this feature for your reference:
https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#uffssd_sample

Thanks.

Hello,

Switch, Merge, and PlaceholderWithDefault are not layers, but operations from the Batch Normalization layer. According to this topic https://devtalk.nvidia.com/default/topic/1027575/jetson-tx1/how-to-implement-batch-normalization-layer-by-tensorrt-scale-layer-/ “TensorRT can parse the ‘BatchNorm’ type directly.” Do I still need to implement Batch Normalization layer myself via a plugin API to get this network working in TensorRT?

Hi,

TensorFlow is an operation-based framework. It automatically divides layer into several basic op.
Instead of implementing a BatchNorm layer, it’s required to write the non-supported basic operation.

You can find an example in our TensorRT 4.0 package: /usr/src/tensorrt/samples/sampleUffSSD/.
Here is the corresponding document:
https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#uffssd_sample

Thanks