Lutz Roeder 5 лет назад
Родитель
Сommit
45d077f2e8
5 измененных файлов с 272 добавлено и 252 удалено
  1. 146 49
      source/npz.js
  2. 58 0
      source/pickle.js
  3. 16 164
      source/sklearn.js
  4. 16 3
      source/view.js
  5. 36 36
      test/models.json

+ 146 - 49
source/npz.js

@@ -9,63 +9,106 @@ npz.ModelFactory = class {
 
     match(context) {
         const entries = context.entries('zip');
-        return entries.length > 0 && entries.every((entry) => entry.name.endsWith('.npy'));
+        if (entries.length > 0 && entries.every((entry) => entry.name.endsWith('.npy'))) {
+            return true;
+        }
+        const tags = context.tags('pkl');
+        if (tags.size === 1 && tags.keys().next().value === '') {
+            if (npz.Utility.weights(tags.values().next().value)) {
+                return true;
+            }
+        }
+        return false;
     }
 
     open(context) {
         return context.require('./numpy').then((numpy) => {
-            const modules = [];
-            const modulesMap = new Map();
-            const dataTypeMap = new Map([
-                [ 'i1', 'int8'], [ 'i2', 'int16' ], [ 'i4', 'int32'], [ 'i8', 'int64' ],
-                [ 'u1', 'uint8'], [ 'u2', 'uint16' ], [ 'u4', 'uint32'], [ 'u8', 'uint64' ],
-                [ 'f2', 'float16'], [ 'f4', 'float32' ], [ 'f8', 'float64']
-            ]);
-            const execution = new python.Execution(null);
-            for (const entry of context.entries('zip')) {
-                if (!entry.name.endsWith('.npy')) {
-                    throw new npz.Error("Invalid file name '" + entry.name + "'.");
+            const tags = context.tags('pkl');
+            const groups = new Map();
+            let format = '';
+            if (tags.size === 1) {
+                format = 'NumPy Weights';
+                const weights = npz.Utility.weights(tags.values().next().value);
+                let separator = '_';
+                if (Array.from(weights.keys()).every((key) => key.indexOf('.') !== -1) &&
+                    !Array.from(weights.keys()).every((key) => key.indexOf('_') !== -1)) {
+                    separator = '.';
                 }
-                const name = entry.name.replace(/\.npy$/, '');
-                const parts = name.split('/');
-                const parameterName = parts.pop();
-                const moduleName = parts.join('/');
-                if (!modulesMap.has(moduleName)) {
-                    const newModule = { name: moduleName, parameters: [] };
-                    modules.push(newModule);
-                    modulesMap.set(moduleName, newModule);
+                for (const pair of weights) {
+                    const name = pair[0];
+                    const value = pair[1];
+                    const parts = name.split(separator);
+                    const parameterName = parts.length > 1 ? parts.pop() : '?';
+                    const groupName = parts.join(separator);
+                    if (!groups.has(groupName)) {
+                        groups.set(groupName, { name: groupName, parameters: [] });
+                    }
+                    const group = groups.get(groupName);
+                    group.parameters.push({
+                        name: parameterName,
+                        tensor: {
+                            name: name,
+                            byteOrder: value.dtype.byteorder,
+                            dataType: value.dtype.name,
+                            shape: value.shape,
+                            data: value.data
+                        }
+                    });
                 }
-                const module = modulesMap.get(moduleName);
-                const data = entry.data;
-                let array = new numpy.Array(data);
-                if (array.byteOrder === '|') {
-                    if (array.dataType !== 'O') {
-                        throw new npz.Error("Invalid data type '" + array.dataType + "'.");
+            }
+            else {
+                format = 'NumPy Zip';
+                const dataTypeMap = new Map([
+                    [ 'i1', 'int8'], [ 'i2', 'int16' ], [ 'i4', 'int32'], [ 'i8', 'int64' ],
+                    [ 'u1', 'uint8'], [ 'u2', 'uint16' ], [ 'u4', 'uint32'], [ 'u8', 'uint64' ],
+                    [ 'f2', 'float16'], [ 'f4', 'float32' ], [ 'f8', 'float64']
+                ]);
+                const execution = new python.Execution(null);
+                for (const entry of context.entries('zip')) {
+                    if (!entry.name.endsWith('.npy')) {
+                        throw new npz.Error("Invalid file name '" + entry.name + "'.");
+                    }
+                    const name = entry.name.replace(/\.npy$/, '');
+                    const parts = name.split('/');
+                    const parameterName = parts.pop();
+                    const groupName = parts.join('/');
+                    if (!groups.has(groupName)) {
+                        groups.set(groupName, { name: groupName, parameters: [] });
+                    }
+                    const group = groups.get(groupName);
+                    const data = entry.data;
+                    let array = new numpy.Array(data);
+                    if (array.byteOrder === '|') {
+                        if (array.dataType !== 'O') {
+                            throw new npz.Error("Invalid data type '" + array.dataType + "'.");
+                        }
+                        const unpickler = new python.Unpickler(array.data);
+                        const root = unpickler.load((name, args) => execution.invoke(name, args));
+                        array = { dataType: root.dtype.name, shape: null, data: null, byteOrder: '|' };
                     }
-                    const unpickler = new python.Unpickler(array.data);
-                    const root = unpickler.load((name, args) => execution.invoke(name, args));
-                    array = { dataType: root.dtype.name, shape: null, data: null, byteOrder: '|' };
+                    group.parameters.push({
+                        name: parameterName,
+                        tensor: {
+                            name: name,
+                            byteOrder: array.byteOrder,
+                            dataType: dataTypeMap.has(array.dataType) ? dataTypeMap.get(array.dataType) : array.dataType,
+                            shape: array.shape,
+                            data: array.data,
+                        }
+                    });
                 }
-
-                module.parameters.push({
-                    name: parameterName,
-                    dataType: dataTypeMap.has(array.dataType) ? dataTypeMap.get(array.dataType) : array.dataType,
-                    shape: array.shape,
-                    data: array.data,
-                    byteOrder: array.byteOrder
-                });
             }
-            return new npz.Model(modules, 'NumPy Zip');
+            return new npz.Model(format, groups.values());
         });
     }
 };
 
 npz.Model = class {
 
-    constructor(modules, format) {
+    constructor(format, groups) {
         this._format = format;
         this._graphs = [];
-        this._graphs.push(new npz.Graph(modules));
+        this._graphs.push(new npz.Graph(groups));
     }
 
     get format() {
@@ -79,10 +122,10 @@ npz.Model = class {
 
 npz.Graph = class {
 
-    constructor(modules) {
+    constructor(groups) {
         this._nodes = [];
-        for (const module of modules) {
-            this._nodes.push(new npz.Node(module));
+        for (const group of groups) {
+            this._nodes.push(new npz.Node(group));
         }
     }
 
@@ -144,14 +187,15 @@ npz.Argument = class {
 
 npz.Node = class {
 
-    constructor(module) {
-        this._name = module.name;
+    constructor(group) {
+        this._name = group.name;
         this._inputs = [];
-        for (const parameter of module.parameters) {
+        for (const parameter of group.parameters) {
             const name = this._name ? [ this._name, parameter.name ].join('/') : parameter.name;
-            const initializer = new npz.Tensor(name, parameter.dataType, parameter.shape, parameter.data, parameter.byteOrder);
+            const tensor = parameter.tensor;
+            const initializer = new npz.Tensor(name, tensor.dataType, tensor.shape, tensor.data, tensor.byteOrder);
             this._inputs.push(new npz.Parameter(parameter.name, [
-                new npz.Argument(name, initializer)
+                new npz.Argument(tensor.name || '', initializer)
             ]));
         }
     }
@@ -192,7 +236,7 @@ npz.Tensor = class  {
     }
 
     get kind() {
-        return '';
+        return 'NumPy Array';
     }
 
     get name() {
@@ -415,6 +459,59 @@ npz.TensorShape = class {
     }
 };
 
+npz.Utility = class {
+
+    static isTensor(obj) {
+        return obj && obj.__module__ === 'numpy' && obj.__name__ === 'ndarray';
+    }
+
+    static weights(obj) {
+        const keys = [ '', 'blobs' ];
+        for (const key of keys) {
+            const dict = key === '' ? obj : obj[key];
+            if (dict) {
+                const weights = new Map();
+                if (dict instanceof Map) {
+                    for (const pair of dict) {
+                        if (!npz.Utility.isTensor(pair[1])) {
+                            return null;
+                        }
+                        weights.set(pair[0], pair[1]);
+                    }
+                    return weights;
+                }
+                else if (!Array.isArray(dict)) {
+                    for (const key in dict) {
+                        const value = dict[key];
+                        if (key != 'weight_order' && key != 'lr') {
+                            if (!key || !npz.Utility.isTensor(value)) {
+                                return null;
+                            }
+                            weights.set(key, value);
+                        }
+                    }
+                    return weights;
+                }
+            }
+        }
+        for (const key of keys) {
+            const list = key === '' ? obj : obj[key];
+            if (list && Array.isArray(list)) {
+                const weights = new Map();
+                for (let i = 0; i < list.length; i++) {
+                    const value = list[i];
+                    if (!npz.Utility.isTensor(value, 'numpy.ndarray')) {
+                        return null;
+                    }
+                    weights.set(i.toString(), value);
+                }
+                return weights;
+            }
+        }
+        return null;
+    }
+};
+
 npz.Error = class extends Error {
 
     constructor(message) {

+ 58 - 0
source/pickle.js

@@ -0,0 +1,58 @@
+/* jshint esversion: 6 */
+
+// Experimental
+
+var pickle = pickle || {};
+var python = python || require('./python');
+var zip = zip || require('./zip');
+
+pickle.ModelFactory = class {
+
+    match(context) {
+        const stream = context.stream;
+        const signature = [ 0x80, undefined, 0x8a, 0x0a, 0x6c, 0xfc, 0x9c, 0x46, 0xf9, 0x20, 0x6a, 0xa8, 0x50, 0x19 ];
+        if (signature.length <= stream.length && stream.peek(signature.length).every((value, index) => signature[index] === undefined || signature[index] === value)) {
+            // Reject PyTorch models with .pkl file extension.
+            return false;
+        }
+        const tags = context.tags('pkl');
+        if (tags.size === 1 || tags.keys().next().value === '') {
+            return true;
+        }
+        return false;
+    }
+
+    open(/* context */) {
+        return new Promise((resolve) => {
+            resolve(new pickle.Model());
+        });
+    }
+};
+
+pickle.Model = class {
+
+    constructor() {
+        this._graphs = [];
+    }
+
+    get format() {
+        return 'Pickle';
+    }
+
+    get graphs() {
+        return this._graphs;
+    }
+};
+
+
+pickle.Error = class extends Error {
+
+    constructor(message) {
+        super(message);
+        this.name = 'Error loading Pickle model.';
+    }
+};
+
+if (typeof module !== 'undefined' && typeof module.exports === 'object') {
+    module.exports.ModelFactory = pickle.ModelFactory;
+}

+ 16 - 164
source/sklearn.js

@@ -3,33 +3,14 @@
 // Experimental
 
 var sklearn = sklearn || {};
-var python = python || require('./python');
-var zip = zip || require('./zip');
 
 sklearn.ModelFactory = class {
 
     match(context) {
-
-        const stream = context.stream;
-        const signature = [ 0x80, undefined, 0x8a, 0x0a, 0x6c, 0xfc, 0x9c, 0x46, 0xf9, 0x20, 0x6a, 0xa8, 0x50, 0x19 ];
-        if (signature.length <= stream.length && stream.peek(signature.length).every((value, index) => signature[index] === undefined || signature[index] === value)) {
-            // Reject PyTorch models with .pkl file extension.
-            return false;
-        }
-        if (stream.length > 2) {
-            const buffer = stream.peek(2);
-            if (buffer[0] === 0x80 && buffer[1] < 5) {
-                return true;
-            }
-            if (buffer[0] === 0x78) {
-                return true;
-            }
-        }
-        if (stream.length > 1) {
-            stream.seek(-1);
-            const value = stream.byte();
-            stream.seek(0);
-            if (value === 0x2e) {
+        const tags = context.tags('pkl');
+        if (tags.size === 1) {
+            const key = tags.keys().next().value;
+            if (key.startsWith('sklearn.') || key.startsWith('xgboost.sklearn.') || key.startsWith('lightgbm.sklearn.')) {
                 return true;
             }
         }
@@ -37,40 +18,19 @@ sklearn.ModelFactory = class {
     }
 
     open(context) {
-        const identifier = context.identifier;
         return sklearn.Metadata.open(context).then((metadata) => {
-            let container;
-            try {
-                const buffer = context.stream.peek();
-                container = new sklearn.Container(buffer, (error, fatal) => {
-                    const message = error && error.message ? error.message : error.toString();
-                    context.exception(new sklearn.Error(message.replace(/\.$/, '') + " in '" + identifier + "'."), fatal);
-                });
-            }
-            catch (error) {
-                const message = error && error.message ? error.message : error.toString();
-                throw new sklearn.Error('File is not scikit-learn (' + message.replace(/\.$/, '') + ').');
-            }
-            return new sklearn.Model(metadata, container);
+            const tags = context.tags('pkl');
+            const obj = tags.values().next().value;
+            return new sklearn.Model(metadata, obj);
         });
     }
 };
 
 sklearn.Model = class {
 
-    constructor(metadata, container) {
-        this._format = container.format;
-        this._graphs = [];
-        switch (container.type) {
-            case 'object': {
-                this._graphs = container.data.map((obj, index) => new sklearn.Graph(metadata, index.toString(), container.type, obj));
-                break;
-            }
-            case 'weights': {
-                this._graphs.push(new sklearn.Graph(metadata, '', container.type, container.data));
-                break;
-            }
-        }
+    constructor(metadata, obj) {
+        this._format = 'scikit-learn' + (obj._sklearn_version ? ' v' + obj._sklearn_version.toString() : '');
+        this._graphs = [ new sklearn.Graph(metadata, obj) ];
     }
 
     get format() {
@@ -84,53 +44,12 @@ sklearn.Model = class {
 
 sklearn.Graph = class {
 
-    constructor(metadata, index, type, obj) {
-        this._name = index.toString();
+    constructor(metadata, obj) {
+        this._name = '';
         this._metadata = metadata;
         this._nodes = [];
         this._groups = false;
-
-        switch (type) {
-            case 'object': {
-                this._process('', '', obj, ['data']);
-                break;
-            }
-            case 'weights': {
-                const group_map = new Map();
-                const groups = [];
-                let separator = '_';
-                if (Array.from(obj.keys()).every((key) => key.indexOf('.') !== -1) && !Array.from(obj.keys()).every((key) => key.indexOf('_') !== -1)) {
-                    separator = '.';
-                }
-                for (const pair of obj) {
-                    const key = pair[0];
-                    const parts = key.split(separator);
-                    const value = pair[1];
-                    const name = parts.length > 1 ? parts.pop() : '?';
-                    const id = parts.join(separator);
-                    let group = group_map.get(id);
-                    if (!group) {
-                        group = { id: id, arrays: [] };
-                        groups.push(group);
-                        group_map.set(id, group);
-                    }
-                    group.arrays.push({
-                        key: key,
-                        name: name,
-                        value: value
-                    });
-                }
-                this._nodes.push(...groups.map((group) => {
-                    const inputs = group.arrays.map((array) => {
-                        return new sklearn.Parameter(array.name, [
-                            new sklearn.Argument(array.key, null, new sklearn.Tensor(array.key, array.value))
-                        ]);
-                    });
-                    return new sklearn.Node(this._metadata, '', group.id, { __module__: '', __name__: 'Weights' }, inputs, []);
-                }));
-                break;
-            }
-        }
+        this._process('', '', obj, ['data']);
     }
 
     _process(group, name, obj, inputs) {
@@ -663,70 +582,10 @@ sklearn.Metadata = class {
     }
 };
 
-sklearn.Container = class {
-
-    constructor(buffer, exception) {
-        if (buffer.length > 0 && buffer[0] == 0x78) {
-            buffer = buffer.subarray(2, buffer.length - 2);
-            buffer = new zip.Inflater().inflateRaw(buffer);
-        }
-        const execution = new python.Execution(null, exception);
-        const unpickler = new python.Unpickler(buffer);
-        const obj = unpickler.load((name, args) => execution.invoke(name, args));
-        const weights = sklearn.Container.findWeights(obj);
-        if (weights) {
-            this._format = 'NumPy Weights';
-            this._type = 'weights';
-            this._data = weights;
-        }
-        else {
-            if (obj) {
-                this._type = 'object';
-                if (Array.isArray(obj)) {
-                    if (obj.length > 16 || Object(obj[0]) !== obj[0]) {
-                        throw new sklearn.Error('Unsupported pickle array format');
-                    }
-                }
-                this._data = Array.isArray(obj) ? obj : [ obj ];
-                const set = new Set(this._data.map((obj) => {
-                    if (obj && obj.__module__) {
-                        if (obj.__module__.startsWith('sklearn.')) {
-                            return 'scikit-learn' + (obj._sklearn_version ? ' v' + obj._sklearn_version.toString() : '');
-                        }
-                        else if (obj.__module__ === 'xgboost.sklearn') {
-                            return 'scikit-learn XGBoost' + (obj._sklearn_version ? ' v' + obj._sklearn_version.toString() : '');
-                        }
-                        else if (obj.__module__ === 'lightgbm.sklearn') {
-                            return 'scikit-learn LightGBM';
-                        }
-                        else if (obj.__module__.startsWith('gensim.')) {
-                            return 'gensim';
-                        }
-                    }
-                    return 'Pickle';
-                }));
-                const formats = Array.from(set.values());
-                if (formats.length > 1) {
-                    throw new sklearn.Error("Invalid array format '" + JSON.stringify(formats) + "'.");
-                }
-                this._format = formats[0];
-            }
-            else {
-                throw new sklearn.Error('File does not contain root module or state dictionary.');
-            }
-        }
-    }
-
-    get format() {
-        return this._format;
-    }
-
-    get type() {
-        return this._type;
-    }
+sklearn.Utility = class {
 
-    get data() {
-        return this._data;
+    static isTensor(obj) {
+        return obj && obj.__module__ === 'numpy' && obj.__name__ === 'ndarray';
     }
 
     static findWeights(obj) {
@@ -776,13 +635,6 @@ sklearn.Container = class {
     }
 };
 
-sklearn.Utility = class {
-
-    static isTensor(obj) {
-        return obj && obj.__module__ === 'numpy' && obj.__name__ === 'ndarray';
-    }
-};
-
 sklearn.Error = class extends Error {
 
     constructor(message) {

+ 16 - 3
source/view.js

@@ -1150,8 +1150,20 @@ view.ModelContext = class {
                     case 'pkl': {
                         if (this.stream.length > 2) {
                             const stream = this.stream.peek(1)[0] === 0x78 ? zip.Archive.open(this.stream).entries[0].stream : this.stream;
-                            const header = stream.peek(2);
-                            if (header[0] === 0x80 && header[1] < 7) {
+                            const match = (stream) => {
+                                const head = stream.peek(2);
+                                if (head[0] === 0x80 && head[1] < 7) {
+                                    return true;
+                                }
+                                stream.seek(-1);
+                                const tail = stream.peek(1);
+                                stream.seek(0);
+                                if (tail[0] === 0x2e) {
+                                    return true;
+                                }
+                                return false;
+                            };
+                            if (match(stream)) {
                                 const unpickler = new python.Unpickler(stream);
                                 const execution = new python.Execution(null, (error, fatal) => {
                                     const message = error && error.message ? error.message : error.toString();
@@ -1248,8 +1260,10 @@ view.ModelFactoryService = class {
         this.register('./tf', [ '.pb', '.meta', '.pbtxt', '.prototxt', '.pt', '.json', '.index', '.ckpt', '.graphdef', /.data-[0-9][0-9][0-9][0-9][0-9]-of-[0-9][0-9][0-9][0-9][0-9]$/, /^events.out.tfevents./ ]);
         this.register('./mediapipe', [ '.pbtxt' ]);
         this.register('./uff', [ '.uff', '.pb', '.pbtxt', '.uff.txt', '.trt', '.engine' ]);
+        this.register('./npz', [ '.npz', '.pkl' ]);
         this.register('./lasagne', [ '.pkl', '.pickle', '.joblib', '.model', '.pkl.z', '.joblib.z' ]);
         this.register('./sklearn', [ '.pkl', '.pickle', '.joblib', '.model', '.meta', '.pb', '.pt', '.h5', '.pkl.z', '.joblib.z' ]);
+        this.register('./pickle', [ '.pkl', '.pickle', '.joblib', '.model', '.meta', '.pb', '.pt', '.h5', '.pkl.z', '.joblib.z' ]);
         this.register('./cntk', [ '.model', '.cntk', '.cmf', '.dnn' ]);
         this.register('./paddle', [ '.paddle', '.pdmodel', '__model__', '.pbtxt', '.txt', '.tar', '.tar.gz' ]);
         this.register('./bigdl', [ '.model', '.bigdl' ]);
@@ -1268,7 +1282,6 @@ view.ModelFactoryService = class {
         this.register('./dnn', [ '.dnn' ]);
         this.register('./openvino', [ '.xml', '.bin' ]);
         this.register('./flux', [ '.bson' ]);
-        this.register('./npz', [ '.npz', '.h5', '.hd5', '.hdf5' ]);
         this.register('./dl4j', [ '.zip' ]);
         this.register('./mlnet', [ '.zip' ]);
         this.register('./acuity', [ '.json' ]);

+ 36 - 36
test/models.json

@@ -3028,6 +3028,20 @@
     "format": "NumPy Zip",
     "link":   "https://github.com/lutzroeder/netron/issues/337"
   },
+  {
+    "type":   "npz",
+    "target": "mobilenet_v2_normal_72820.pkl",
+    "source": "https://data.megengine.org.cn/models/weights/mobilenet_v2_normal_72820.pkl",
+    "format": "NumPy Weights",
+    "link":   "https://github.com/MegEngine/Models/tree/master/official/quantization"
+  },
+  {
+    "type":   "npz",
+    "target": "R-50.pkl",
+    "source": "https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl",
+    "format": "NumPy Weights",
+    "link":   "https://github.com/facebookresearch/Detectron"
+  },
   {
     "type":   "onnx",
     "target": "arcface-resnet100.onnx",
@@ -4011,6 +4025,27 @@
     "format": "PaddlePaddle",
     "link":   "https://github.com/lutzroeder/netron/issues/246"
   },
+  {
+    "type":   "pickle",
+    "target": "batches.meta",
+    "source": "https://raw.githubusercontent.com/MadryLab/cifar10_challenge/master/cifar10_data/batches.meta",
+    "format": "Pickle",
+    "link":   "https://github.com/MadryLab/cifar10_challenge"
+  },
+  {
+    "type":   "pickle",
+    "target": "svm.pkl",
+    "source": "https://raw.githubusercontent.com/dfridovi/imagelib/master/svm.pkl",
+    "format": "Pickle",
+    "link":   "https://github.com/dfridovi/imagelib/blob/master/svm.pkl"
+  },
+  {
+    "type":   "pickle",
+    "target": "robinhood-portfolio_data_user.pkl.pkl",
+    "source": "https://raw.githubusercontent.com/omdv/robinhood-portfolio/4622dc61e0556a85ce52c4de178d01a9838acbc5/data/user.pkl",
+    "format": "Pickle",
+    "link":   "https://github.com/omdv/robinhood-portfolio/tree/4622dc61e0556a85ce52c4de178d01a9838acbc5"
+  },
   {
     "type":   "pytorch",
     "target": "alexnet.pkl.pth.zip",
@@ -4754,13 +4789,6 @@
     "format": "RKNN v1.3.2",
     "link":   "https://github.com/lutzroeder/netron/issues/639"
   },
-  {
-    "type":   "sklearn",
-    "target": "batches.meta",
-    "source": "https://raw.githubusercontent.com/MadryLab/cifar10_challenge/master/cifar10_data/batches.meta",
-    "format": "Pickle",
-    "link":   "https://github.com/MadryLab/cifar10_challenge"
-  },
   {
     "type":   "sklearn",
     "target": "best_boston.pb",
@@ -4803,13 +4831,6 @@
     "format": "scikit-learn v0.24.0rc1",
     "link":   "https://github.com/lutzroeder/netron/issues/182"
   },
-  {
-    "type":   "sklearn",
-    "target": "mobilenet_v2_normal_72820.pkl",
-    "source": "https://data.megengine.org.cn/models/weights/mobilenet_v2_normal_72820.pkl",
-    "format": "NumPy Weights",
-    "link":   "https://github.com/MegEngine/Models/tree/master/official/quantization"
-  },
   {
     "type":   "sklearn",
     "target": "LDA_model.pkl",
@@ -4856,23 +4877,9 @@
     "type":   "sklearn",
     "target": "pima.xgboost.joblib.pkl",
     "source": "https://github.com/lutzroeder/netron/files/2656501/pima.xgboost.joblib.pkl.zip[pima.xgboost.joblib.pkl]",
-    "format": "scikit-learn XGBoost",
+    "format": "scikit-learn",
     "link":   "https://github.com/lutzroeder/netron/issues/182"
   },
-  {
-    "type":   "sklearn",
-    "target": "R-50.pkl",
-    "source": "https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl",
-    "format": "NumPy Weights",
-    "link":   "https://github.com/facebookresearch/Detectron"
-  },
-  {
-    "type":   "sklearn",
-    "target": "robinhood-portfolio_data_user.pkl.pkl",
-    "source": "https://raw.githubusercontent.com/omdv/robinhood-portfolio/4622dc61e0556a85ce52c4de178d01a9838acbc5/data/user.pkl",
-    "format": "Pickle",
-    "link":   "https://github.com/omdv/robinhood-portfolio/tree/4622dc61e0556a85ce52c4de178d01a9838acbc5"
-  },
   {
     "type":   "sklearn",
     "target": "svc.joblib.pkl",
@@ -4887,13 +4894,6 @@
     "format": "scikit-learn v0.19.1",
     "link":   "https://github.com/lutzroeder/netron/issues/182"
   },
-  {
-    "type":   "sklearn",
-    "target": "svm.pkl",
-    "source": "https://raw.githubusercontent.com/dfridovi/imagelib/master/svm.pkl",
-    "format": "scikit-learn",
-    "link":   "https://github.com/dfridovi/imagelib/blob/master/svm.pkl"
-  },
   {
     "type":   "sklearn",
     "target": "wiki-aa-mlp.pkl",