Jelajahi Sumber

Add CNTK .cmf and .dnn extensions

Lutz Roeder 7 tahun lalu
induk
melakukan
52fa83adc5
9 mengubah file dengan 234 tambahan dan 29 penghapusan
  1. 6 0
      electron-builder.yml
  2. 18 13
      src/app.js
  3. 30 0
      src/cntk-metadata.json
  4. 105 11
      src/cntk.js
  5. 1 1
      src/view-browser.html
  6. 1 1
      src/view-electron.html
  7. 1 1
      src/view-electron.js
  8. 1 1
      src/view.js
  9. 71 1
      test/models.json

+ 6 - 0
electron-builder.yml

@@ -18,6 +18,12 @@ fileAssociations:
     ext: mlmodel
   - name: "MXNet Model"
     ext: model
+  - name: "CNTK Model"
+    ext: model
+  - name: "CNTK Model"
+    ext: cmf
+  - name: "CNTK Model"
+    ext: dnn
   - name: "Caffe Model"
     ext: caffemodel
   - name: "TensorFlow Meta Graph"

+ 18 - 13
src/app.js

@@ -112,19 +112,18 @@ class Application {
         var showOpenDialogOptions = { 
             properties: [ 'openFile' ], 
             filters: [
-                { name: 'All Model Files',  extensions: [ 'onnx', 'pb', 'h5', 'hdf5', 'json', 'keras', 'mlmodel', 'caffemodel', 'model', 'meta', 'tflite', 'lite', 'pt', 'pth', 't7', 'pkl', 'joblib', 'pbtxt', 'prototxt', 'xml' ] }
-                /* 
-                { name: 'ONNX Model', extensions: [ 'onnx', 'pb', 'pbtxt' ] },
-                { name: 'Keras Model', extensions: [ 'h5', 'hdf5', 'json', 'keras' ] },
-                { name: 'CoreML Model', extensions: [ 'mlmodel' ] },
-                { name: 'Caffe Model', extensions: [ 'caffemodel', 'pbtxt' ] },
-                { name: 'Caffe2 Model', extensions: [ 'pb', 'pbtxt' ] },
-                { name: 'MXNet Model', extensions: [ 'model', 'json' ] },
-                { name: 'PyTorch Model', extensions: [ 'pt', 'pth' ] },
-                { name: 'TensorFlow Graph', extensions: [ 'pb', 'meta', 'pbtxt' ] },
-                { name: 'TensorFlow Saved Model', extensions: [ 'pb', 'pbtxt' ] },
-                { name: 'TensorFlow Lite Model', extensions: [ 'tflite', 'lite' ] } 
-                */
+                { name: 'All Model Files',  extensions: [ 
+                    'onnx', 'pb',
+                    'h5', 'hdf5', 'json', 'keras',
+                    'mlmodel',
+                    'caffemodel',
+                    'model', 'dnn', 'cmf', 
+                    'meta',
+                    'tflite', 'lite',
+                    'pt', 'pth', 't7',
+                    'pkl', 'joblib',
+                    'pbtxt', 'prototxt',
+                    'xml' ] }
             ]
         };
         electron.dialog.showOpenDialog(showOpenDialogOptions, (selectedFiles) => {
@@ -608,6 +607,12 @@ class View {
         this._window.webContents.on('dom-ready', () => {
             this._ready = true;
         });
+        this._window.webContents.on('new-window', (event, url) => {
+            if (url.startsWith('http://') || url.startsWith('https://')) {
+                event.preventDefault();
+                electron.shell.openExternal(url);
+            }
+        });
         var location = url.format({
             pathname: path.join(__dirname, 'view-electron.html'),
             protocol: 'file:',

+ 30 - 0
src/cntk-metadata.json

@@ -155,6 +155,17 @@
       "operator": 12
     }
   },
+  {
+    "name": "TransposeDimensions",
+    "schema": {
+      "inputs": [
+        { "name": "input" }
+      ],
+      "outputs": [
+        { "name": "output" }
+      ]
+    }
+  },
   {
     "name": "Where",
     "schema": {
@@ -616,6 +627,13 @@
       "attributes": [
         { "name": "spatialScale", "default": 0.0625 },
         { "name": "poolKind", "type": "PoolKind", "default": "None" }
+      ],
+      "inputs": [
+        { "name": "inputs" },
+        { "name": "ROIs" }
+      ],
+      "outputs": [
+        { "name": "outputs" }
       ]
     }
   },
@@ -972,6 +990,18 @@
       ]
     }
   },
+  {
+    "name": "Function:Softmax",
+    "schema": {
+      "category": "Activation",
+      "inputs": [
+        { "name": "input" }
+      ],
+      "outputs": [
+        { "name": "output" }
+      ]
+    }
+  },
   {
     "name": "Function:linear",
     "schema": {

+ 105 - 11
src/cntk.js

@@ -11,12 +11,13 @@ cntk.ModelFactory = class {
     match(context, host) {
         var extension = context.identifier.split('.').pop().toLowerCase();
         var buffer = null;
-        if (extension == 'model') {
+        if (extension == 'model' || extension == 'cmf' || extension == 'dnn') {
             buffer = context.buffer;
+            // Filter MXNet Model server ZIP files
             if (buffer && buffer.length > 2 && buffer[0] == 0x50 && buffer[1] == 0x4B) {
                 return false;
             }
-            // Filter PyTorch models published with incorrect .h5 file extension.
+            // Filter PyTorch models published with incorrect file extension.
             var torch = [ 0x8a, 0x0a, 0x6c, 0xfc, 0x9c, 0x46, 0xf9, 0x20, 0x6a, 0xa8, 0x50, 0x19 ];
             if (buffer && buffer.length > torch.length + 2 && 
                 buffer[0] == 0x80 && buffer[1] > 0x00 && buffer[1] < 0x05) {
@@ -28,6 +29,7 @@ cntk.ModelFactory = class {
         }
         if (extension == 'cntk') {
             buffer = context.buffer;
+            // Check protobuf data to exclude .cntk text files
             if (buffer && buffer.length > 3 && buffer[0] == 0x08 && buffer[1] < 0x10 && buffer[2] == 0x12) {
                 return true;
             }
@@ -420,14 +422,27 @@ cntk.Node = class {
                     }
                 }
                 else {
-                    this._operator = this._metadata.getOperatorName(obj.op);
-                    if (this._operator == null) {
-                        this._operator = obj.op.toString();
-                    }                
+                    if (!obj.hasOwnProperty('op')) {
+                        this._operator = obj.type;
+                        // if ( === false
+                        if (obj.user_defined_state) {
+                            Object.keys(obj.user_defined_state).forEach((key) => {
+                                this._attributes.push(new cntk.Attribute(this._metadata, this._operator, key, obj.user_defined_state[key]));
+                            });
+                        }
+                    }
+                    else {
+                        this._operator = this._metadata.getOperatorName(obj.op);
+                        if (this._operator == null) {
+                            this._operator = obj.op ? obj.op.toString() : '?';
+                        }                
+                    }
+                }
+                if (obj.attributes) {
+                    Object.keys(obj.attributes).forEach((key) => {
+                        this._attributes.push(new cntk.Attribute(this._metadata, this._operator, key, obj.attributes[key]));
+                    });
                 }
-                Object.keys(obj.attributes).forEach((key) => {
-                    this._attributes.push(new cntk.Attribute(this._metadata, this._operator, key, obj.attributes[key]));
-                });
                 obj.inputs.forEach((input) => {
                     var connection = connections[input];
                     if (connection) {
@@ -830,7 +845,7 @@ cntk.Metadata = class {
 
     getOperatorName(code) {
         // cntk/Source/CNTKv2LibraryDll/API/Internals/PrimitiveOpType.h
-        return this._operatorMap[code.toString()] || null;
+        return this._operatorMap[code] || null;
     }
 
     getSchema(operator) {
@@ -1063,7 +1078,86 @@ cntk_v1.ComputationNetwork = class {
                 this.convertRunningVariancePending = true;
             }
         };
-        
+        op.Tanh = function(reader) {};
+        op.Sigmoid = function(reader) {};
+        op.Logistic = function(reader) {};
+        op.SquareError = function(reader) {};
+        op.ErrorPrediction = function(reader) {};
+        op.RowStack = function(reader) {
+            this.spliceDim = (reader.version >= 3) ? reader.int32() : 1;
+        };
+        op.Slice = function(reader) {
+            var num = 1;
+            if (reader.version >= 22) {
+                num = reader.int32();
+            }
+            this.index = [];
+            this.axis = [];
+            this.strideMultiplier = [];
+            for (var i = 0; i < num; i++) {
+                this.index.push([ [ reader.uint64(), reader.uint64() ] ]);
+                if (reader.version >= 3) {
+                    this.axis.push(reader.int32());
+                }
+                if (reader.version >= 27) {
+                    this.strideMultiplier.push(reader.int32());
+                }
+            }
+        };
+        op.PastValue = function(reader) {
+            this.timeStep = reader.int32();
+            if (reader.version > 3)
+            {
+                this.sampleLayout = new cntk_v1.TensorShape(reader, false);
+            }
+            else
+            {
+                var rows = reader.uint64();
+                reader.uint64();
+                this.sampleLayout = new cntk_v1.TensorShape([ rows ], true);
+            }
+            if (reader.version >= 2)
+            {
+                this.initialStateValue = reader.int32();
+            }
+        };
+        op.FutureValue = function(reader) {
+            this.timeStep = reader.int32();
+            if (reader.version > 3)
+            {
+                this.sampleLayout = new cntk_v1.TensorShape(reader, false);
+            }
+            else
+            {
+                var rows = reader.uint64();
+                reader.uint64();
+                this.sampleLayout = new cntk_v1.TensorShape([ rows ], true);
+            }
+            if (reader.version >= 2)
+            {
+                this.initialStateValue = reader.int32();
+            }
+        };
+        op.TransposeDimensions = function(reader) {
+            if (reader.version >= 3) 
+            {
+                this.axis1 = reader.int32();
+                this.axis2 = reader.int32();
+                if (reader.version >= 25 && this.axis1 == 0 && this.axis2 == 0)
+                {
+                    var size = reader.uint64();
+                    this.perm = [];
+                    for (var i = 0; i < size; i++) {
+                        this.perm.push(reader.uint64());
+                    }
+                }
+            }
+            else {
+                this.axis1 = 1;
+                this.axis2 = 2;
+            }
+        };
+
         var nodes = [];
         this.nodes = {};
         for (var i = 0; i < numNodes; i++) {

+ 1 - 1
src/view-browser.html

@@ -69,7 +69,7 @@
         </svg>
     </a>
     <button id='open-file-button' class='center' style='top: 200px; width: 125px; opacity: 0;'>Open Model...</button>
-    <input type='file' id='open-file-dialog' style='display:none' multiple='false' accept='.onnx, .pb, .meta, .tflite, .keras, .h5, .hdf5, .json, .model, .mlmodel, .caffemodel, .pbtxt, .prototxt, .pkl, .pt, .pth, .t7, .joblib, .xml'>
+    <input type='file' id='open-file-dialog' style='display:none' multiple='false' accept='.onnx, .pb, .meta, .tflite, .keras, .h5, .hdf5, .json, .model, .dnn, .cmf, .mlmodel, .caffemodel, .pbtxt, .prototxt, .pkl, .pt, .pth, .t7, .joblib, .xml'>
     <!-- Preload fonts to workaround Chrome SVG layout issue -->
     <div style='font-weight: normal; color: rgba(0, 0, 0, 0.01); user-select: none;'>.</div>
     <div style='font-weight: 600; color: rgba(0, 0, 0, 0.01); user-select: none;'>.</div>

+ 1 - 1
src/view-electron.html

@@ -9,7 +9,7 @@
 </head>
 <body style='opacity: 0;'>
 <div id='welcome' class='background' style='display: block'>
-    <a class='center logo' target='_blank'>
+    <a class='center logo' href='https://github.com/lutzroeder/netron' target='_blank'>
         <svg xmlns='http://www.w3.org/2000/svg' class='logo absolute' width='128' height='128' viewBox='0 0 1024 1024'>
             <circle class='stroke' cx='512' cy='512' r='431' fill='none' stroke-width='32'/>
             <circle class='border' cx='512' cy='512' r='450' fill='none' stroke-width='6' /> 

+ 1 - 1
src/view-electron.js

@@ -231,7 +231,7 @@ host.ElectronHost = class {
                 if (err.stack) {
                     var match = err.stack.match(/\n    at (.*)\((.*)\)/);
                     if (match) {
-                        description.push(match[1] + '(' + match[2].split('/').pop() + ')');
+                        description.push(match[1] + '(' + match[2].split('/').pop().split('\\').pop() + ')');
                     }
                 }
     

+ 1 - 1
src/view.js

@@ -1078,7 +1078,7 @@ view.ModelFactoryService = class {
         this.register('./tflite', [ '.tflite', '.lite' ]);
         this.register('./tf', [ '.pb', '.meta', '.pbtxt', '.prototxt' ]);
         this.register('./sklearn', [ '.pkl', '.joblib' ]);
-        this.register('./cntk', [ '.model', '.cntk' ]);
+        this.register('./cntk', [ '.model', '.cntk', '.cmf', '.dnn' ]);
         this.register('./openvino', [ '.xml', '.dot' ]);
         this.register('./paddle', [ '.paddle', '__model__' ]);
     }

+ 71 - 1
test/models.json

@@ -772,6 +772,13 @@
     "format": "Caffe2",
     "link":   "https://github.com/caffe2/models"
   },
+  {
+    "type":   "cntk",
+    "target": "v1/01_OneHidden.dnn",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tests/UnitTests/NetworkTests/Models/01_OneHidden.dnn",
+    "format": "CNTK v1.18",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
   {
     "type":   "cntk",
     "target": "v1/AlexNet.model",
@@ -784,6 +791,20 @@
     "source": "https://www.cntk.ai/Models/AlexNet/AlexNetBS.model",
     "format": "CNTK v1.15"
   },
+  {
+    "type":   "cntk",
+    "target": "v1/cifar10.pretrained.cmf",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tutorials/ImageHandsOn/cifar10.pretrained.cmf",
+    "format": "CNTK v1.14",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
+  {
+    "type":   "cntk",
+    "target": "v1/cifar10.ResNet.cmf",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tutorials/ImageHandsOn/cifar10.ResNet.cmf",
+    "format": "CNTK v1.10",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
   {
     "type":   "cntk",
     "target": "v1/ResNet_18.model",
@@ -804,6 +825,41 @@
     "format": "CNTK v1.15",
     "link":   "https://github.com/Microsoft/CNTK/blob/7c838d3b6c448004e5a06aa00c984a629f880416/PretrainedModels/download_model.py"
   },
+  {
+    "type":   "cntk",
+    "target": "v1/ResNet20_CIFAR10_DataAug.dnn",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tests/UnitTests/NetworkTests/Models/ResNet20_CIFAR10_DataAug.dnn",
+    "format": "CNTK v1.18",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
+  {
+    "type":   "cntk",
+    "target": "v1/slu.forward.backward.cmf",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tutorials/SLUHandsOn/slu.forward.backward.cmf",
+    "format": "CNTK v1.14",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
+  {
+    "type":   "cntk",
+    "target": "v1/slu.forward.cmf",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tutorials/SLUHandsOn/slu.forward.cmf",
+    "format": "CNTK v1.14",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
+  {
+    "type":   "cntk",
+    "target": "v1/slu.forward.nobn.cmf",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tutorials/SLUHandsOn/slu.forward.nobn.cmf",
+    "format": "CNTK v1.14",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
+  {
+    "type":   "cntk",
+    "target": "v1/slu.forward.lookahead.cmf",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/Tutorials/SLUHandsOn/slu.forward.lookahead.cmf",
+    "format": "CNTK v1.14",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
   {
     "type":   "cntk",
     "target": "v2/AlexNet_ImageNet_Caffe.model",
@@ -851,6 +907,20 @@
     "format": "CNTK v2",
     "link":   "https://cntk.ai/pythondocs/CNTK_302A_Evaluation_of_Pretrained_Super-resolution_Models.html"
   },
+  {
+    "type":   "cntk",
+    "target": "v2/HotailorPOC2.model",
+    "source": "https://privdatastorage.blob.core.windows.net/github/cntk-python-web-service-on-azure/HotailorPOC2.model",
+    "format": "CNTK v2",
+    "link":   "https://github.com/karolzak/cntk-python-web-service-on-azure"
+  },
+  {
+    "type":   "cntk",
+    "target": "v2/initial_policy_network.dnn",
+    "source": "https://raw.githubusercontent.com/Microsoft/CNTK/master/bindings/python/cntk/contrib/deeprl/tests/data/initial_policy_network.dnn",
+    "format": "CNTK v2",
+    "link":   "https://github.com/Microsoft/CNTK"
+  },
   {
     "type":   "cntk",
     "target": "v2/InceptionV3_ImageNet_CNTK.model",
@@ -3354,4 +3424,4 @@
     "format": "Torch v7",
     "link":   "https://github.com/cpra/fer-cnn-sota"
   }
- ]
+]