leondgarse / Keras_insightface

Insightface Keras implementation
MIT License
230 stars 56 forks source link

How can you convert onnx file to keras and change the ordering from CHW to HWC? #86

Closed ltkhang closed 2 years ago

ltkhang commented 2 years ago

Hi,

I am trying to convert the ONNX models from the official insightface repo into keras with onnx2keras lib. However, I got an error when setting the parameter "change_ordering" to True which raise the error "ValueError: Layer weight shape (1, 1, 112) not compatible with provided weight shape (64, 1, 1)" in the PreLu layer.

leondgarse commented 2 years ago
ltkhang commented 2 years ago
  • I‘m not using onnx2keras, which is not easy to control. Mine is converted technically like define a same model architecture like pytorch one -> match layers in order or define same layer name like pytorch model -> convert pytorch weights NCHW to NHWC by permute or transform layer by layer -> load weights and save keras model.
  • I've tried converting the ONNX models earlier, but they fused the Conv2d and BatchNorm layers, which makes it not able for training, not sure if their latest model still fused.

can you share with us the code and guide for converting from onnx model (r18-r50) of insightface to keras?

Yes they still fuse Conv2d with BatchNorm and raise the error I mentioned above.

leondgarse commented 2 years ago

Wait, I've just tested onnx2keras, follow this:

# Install onnx2keras from source, with a little modify
$ git clone https://github.com/gmalivenko/onnx2keras.git
$ cd onnx2keras
$ vi onnx2keras/converter.py
- 203             1: 3,
+ 203             1: -1,

$ pip install .

I actually once tried creating a PR about this Fix an axis issue for Concatenate layer #111. but may not work well for all common cases.

# Convert to channel last keras model
import onnx
from onnx2keras import onnx_to_keras

# Load ONNX model
onnx_model_file = 'glint360k_cosface_r50_fp16_0.1.onnx'
onnx_model = onnx.load(onnx_model_file)
k_model = onnx_to_keras(onnx_model, [onnx_model.graph.input[0].name], name_policy="renumerate", change_ordering=True)

save_name = os.path.splitext(onnx_model_file)[0] + "_channel_last.h5"
k_model.save(save_name)
mm = keras.models.load_model(save_name)
print(mm(tf.ones([1, 112, 112, 3])).shape)
# TensorShape([1, 512])
ltkhang commented 2 years ago

Wait, I've just tested onnx2keras, follow this:

# Install onnx2keras from source, with a little modify
$ git clone https://github.com/gmalivenko/onnx2keras.git
$ cd onnx2keras
$ vi onnx2keras/converter.py
- 203             1: 3,
+ 203             1: -1,

$ pip install .

I actually once tried creating a PR about this Fix an axis issue for Concatenate layer #111. but may not work well for all common cases.

# Convert to channel last keras model
import onnx
from onnx2keras import onnx_to_keras

# Load ONNX model
onnx_model_file = 'glint360k_cosface_r50_fp16_0.1.onnx'
onnx_model = onnx.load(onnx_model_file)
k_model = onnx_to_keras(onnx_model, [onnx_model.graph.input[0].name], name_policy="renumerate", change_ordering=True)

save_name = os.path.splitext(onnx_model_file)[0] + "_channel_last.h5"
k_model.save(save_name)
mm = keras.models.load_model(save_name)
print(mm(tf.ones([1, 112, 112, 3])).shape)
# TensorShape([1, 512])

I worked! thank you so much!