Convert SSD model from caffe to Tensoflow and TfLite

This programe is convert the caffe model to tensorflow, which contains mobilenet and ssd.

Models

If you just wanna to use one model file, download it directly.

  1. caffe : MobileNetSSD_deploy_backbone.prototxt, mbv1_ssd_05_300_300_car_4_models3_iter_60000.caffemodel
  2. tensorflow : ssd.pb/*
  3. tflite : ssd.tflite

Installion

If you need convert other model files, you need do the following steps.

  1. Install PyCaffe with Anaconda
  2. Install Tensorflow 1.14 version with Pypi
  3. Install MMdnn newest version with Pypi

pip install -U git+https://gitee.com/starhiking/MMdnn.git@master -i https://pypi.tuna.tsinghua.edu.cn/simple

Note : MMdnn must use 0.30 version and Tensorflow use 1.14 version

Caffe -> Tensorflow

  1. Delete layers : (permute, pirorBox ...). The details are between ssd and backbone

MobileNetSSD_deploy.prototxt -> MobileNetSSD_deploy_backbone.prototxt

  1. run the following command :

     mmconvert -sf caffe -in newssd_300_backbone.prototxt -iw mbv1_ssd_05_300_300_car_4_models3_iter_60000.caffemodel -df tensorflow -om ssd.pb
    

Note: the node names will be regenerated by operator indexs.

Tensorflow -> TfLite

  1. run the last command:

     tflite_convert --saved_model_dir=ssd.pb --output_format=TFLITE --output_file=./ssd.tflite --inference_type=FLOAT  --input_arrays=data --input_shapes=1,300,300,3  --output_arrays=add,add_1,add_2,add_3,add_4,add_5,add_6,add_7,add_8,add_9,add_10,add_11
    

Note: the indexs in details will resort by dict. eg. add, add_1, add_10, add_11, add_2...

Result

We have used np.ones((300,300,3))*127 as input for testing the last two conv layers (conv17_2_mbox_loc, conv17_2_mbox_conf). The scripts of caffe, tflite and tensorflow are in the folder, and the results are in result.log

Remember the post processing need to be done in your codes.

Tips

Tensorflow will product different names with caffe. saved_model_cli show --dir ssd.pb --all can get the names of input and ouputs. Also tensorflow-cpu may have no SERVING tag, you can modify it to TRINING.

Senior Usage

Using mmconvert will generate the middle files, which contain network file(py) and weight file(npy).

For example in Senior_example/ , We can modify the KitModel in *.py to add some post processing in the network.

And convert_mvssd.py needs do same adjustment as KitModel outputs. (the same number of outputs). Last, it is required to modify the convoluntion function as reference in following:

def convolution(input, name, group, **kwargs):
    w = tf.Variable(__weights_dict[name]['weights'], trainable=is_train, name=name + "_weight")
    if group == 1:
        layer = tf.nn.convolution(input, w, name=name, **kwargs)
    
    elif group == input.shape[-1].value:
        if len(kwargs['strides'])==2:
            kwargs['strides']=[1]+kwargs['strides']+[1]
            layer=  tf.nn.depthwise_conv2d(input,tf.expand_dims(tf.squeeze(w),-1), name=name, **kwargs)

    else:
        weight_groups = tf.split(w, num_or_size_splits=group, axis=-1)
        xs = tf.split(input, num_or_size_splits=group, axis=-1)
        convolved = [tf.nn.convolution(x, weight, name=name, **kwargs) for
                    (x, weight) in zip(xs, weight_groups)]
        layer = tf.concat(convolved, axis=-1)


    if 'bias' in __weights_dict[name]:
        b = tf.Variable(__weights_dict[name]['bias'], trainable=is_train, name=name + "_bias")
        layer = layer + b
    return layer

The command line need to modify as in ImageNet_example, such as:

    python  Senior_example/convert_mvssd.py -n Senior_example/mv_ssd.py -w Senior_example/mv_ssd.npy --dump test --dump_tag TRAINING

Folder Structure

input.npy: input file for the network. mv_ssd.npy: network middle variable. mv_ssd.py: network file for python. load_xxx.py: xxx framework computate the results. test,ssd.pb: folder for save tensorflow model file. ssd.tflite,ssd_2_branch.tflite: tflite for backbone and overall network.