Skip to content

Latest commit

 

History

History
152 lines (94 loc) · 5.06 KB

README.md

File metadata and controls

152 lines (94 loc) · 5.06 KB

CNTK README

CNTK pre-trained model

We tested some CNTK pre-trained models to others, get more detail from this file

Models Caffe Keras Tensorflow CNTK MXNet PyTorch CoreML ONNX
Inception_v3
ResNet 18
ResNet 152

- Correctness tested

o - Some difference after conversion

space - not tested


Usage

Download CNTK pre-trained model

$ mmdownload -f cntk

Supported models: ['resnet18', 'resnet50', 'resnet152', 'resnet101', 'inception_v3', 'Fast-RCNN_Pascal', 'alexnet', 'Fast-RCNN_grocery100']

$ mmdownload -f cntk -n resnet50 -o ./

Downloading file [./ResNet50_ImageNet_CNTK.model] from [https://www.cntk.ai/Models/CNTK_Pretrained/ResNet50_ImageNet_CNTK.model]
progress: 100264.0 KB downloaded, 100%
Selected GPU[0] GeForce GTX 980 Ti as the process wide default device.
Cntk Model resnet50 saved as [./ResNet50_ImageNet_CNTK.model].

One-step conversion

Above [email protected], we provide one command to achieve the conversion

$  mmconvert -sf cntk -iw ResNet50_ImageNet_CNTK.model -df cntk -om cntk_resnet50.dnn --inputShape 3,224,224
.
.
.
CNTK model file is saved as [cntk_resnet50.dnn], generated by [f499918b3e7346a78dbaf02559231d53.py] and [f499918b3e7346a78dbaf02559231d53.npy].

Then you get the CNTK original model cntk_resnet50.dnn converted from CNTK. Temporal files are removed automatically.


Step-by-step conversion (for debugging)

Convert architecture from CNTK to IR (CNTK -> IR)

You can use following bash command to convert the network model(architecture and weights) [ResNet50_ImageNet_CNTK.model] to IR architecture file [resnet50_cntk.pb], [resnet50_cntk.json] and IR weights file [resnet50_cntk.npy]

$ mmtoir -f cntk -n ResNet50_ImageNet_CNTK.model -d resnet50_cntk
.
.
.
IR network structure is saved as [resnet50_cntk.json].
IR network structure is saved as [resnet50_cntk.pb].
IR weights are saved as [resnet50_cntk.npy].

Convert models from IR to CNTK code snippet (IR -> CNTK)

You can use following bash command to convert the IR architecture file [resnet50_cntk.pb] and weights file [resnet50_cntk.npy] to CNTK Python code file[cntk_resnet50.py]

$ mmtocode -f cntk -n resnet50_cntk.pb -w resnet50_cntk.npy -d cntk_resnet50.py

Parse file [resnet50_cntk.pb] with binary format successfully.
Target network code snippet is saved as [cntk_resnet50.py].

Generate CNTK model from code snippet file and weight file

You can use following bash command to generate CNTK model file [cntk_resnet50.dnn] from python code [cntk_resnet50.py] and weights file [resnet50_cntk.npy] for further usage.

$ python -m mmdnn.conversion.examples.cntk.imagenet_test -n cntk_resnet50.py -w resnet50_cntk.npy --dump cntk_resnet50.dnn

CNTK model file is saved as [cntk_resnet50.dnn], generated by [cntk_resnet50.py] and [resnet50_cntk.npy].

Develop version

Ubuntu 16.04 with

  • CNTK CPU 2.4

@ 2018/02/08

Limitation

  • Main dataflow in network is NHWC (channel last) format, but CNTK CNN-related operators take NCHW (channel first) format data. So we transpose the data format before and after each CNN-related operators (such as Convolution, Pooling, LRN, BN and so on). The data transpose sacrifices some computing performance. There is some methods to reduce the performance gap.

    1. Like PyTorch and MXNet emitter, change the main dataflow format to NCHW (channel last) and tranpose the weights in IR-Code step.

    2. Remove unnecessary transpose during building the network.

  • Currently no RNN-related operations support

FAQ

Retrain the converted CNTK model

If you want to retrain the converted model, you can change all layers from "Channel Last" to "Channel First" in the converted code file and then change the code in **def batch_normalization(input, name, epsilon, kwargs):

from

def batch_normalization(input, name, epsilon, **kwargs):
    mean = cntk.Parameter(init = _weights_dict[name]['mean'],
        name = name + "_mean")
    var = cntk.Parameter(init = _weights_dict[name]['var'],
        name = name + "_var")
    layer = (input - mean) / cntk.sqrt(var + epsilon)

    ......

to

def batch_normalization(input, name, epsilon, **kwargs):
    layer = cntk.layers.BatchNormalization( map_rank = 1, name=name )(input)
    mean = cntk.Parameter(init = _weights_dict[name]['mean'],
        name = name + "_mean")
    layer.aggregate_mean = mean
    var = cntk.Parameter(init = _weights_dict[name]['var'],
        name = name + "_var")
    layer.aggregate_variance = var
    layer.aggregate_count    = 4096.0

    ......

Thanks to this issue