Unverified Commit a6a68a56 by justadudewhohacks Committed by GitHub

Merge pull request #40 from justadudewhohacks/trainable

NeuralNetwork base class + trainable
parents 57b51bd4 4b69fc27
import * as tf from '@tensorflow/tfjs-core';
import { ParamMapping } from './types';
export declare class NeuralNetwork<TNetParams> {
protected _params: TNetParams | undefined;
protected _paramMappings: ParamMapping[];
readonly params: TNetParams | undefined;
readonly paramMappings: ParamMapping[];
getParamFromPath(paramPath: string): tf.Tensor;
reassignParamFromPath(paramPath: string, tensor: tf.Tensor): void;
getParamList(): {
path: string;
tensor: tf.Tensor<tf.Rank>;
}[];
getTrainableParams(): {
path: string;
tensor: tf.Tensor<tf.Rank>;
}[];
getFrozenParams(): {
path: string;
tensor: tf.Tensor<tf.Rank>;
}[];
variable(): void;
freeze(): void;
dispose(): void;
private traversePropertyPath(paramPath);
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
var NeuralNetwork = /** @class */ (function () {
function NeuralNetwork() {
this._params = undefined;
this._paramMappings = [];
}
Object.defineProperty(NeuralNetwork.prototype, "params", {
get: function () {
return this._params;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NeuralNetwork.prototype, "paramMappings", {
get: function () {
return this._paramMappings;
},
enumerable: true,
configurable: true
});
NeuralNetwork.prototype.getParamFromPath = function (paramPath) {
var _a = this.traversePropertyPath(paramPath), obj = _a.obj, objProp = _a.objProp;
return obj[objProp];
};
NeuralNetwork.prototype.reassignParamFromPath = function (paramPath, tensor) {
var _a = this.traversePropertyPath(paramPath), obj = _a.obj, objProp = _a.objProp;
obj[objProp].dispose();
obj[objProp] = tensor;
};
NeuralNetwork.prototype.getParamList = function () {
var _this = this;
return this._paramMappings.map(function (_a) {
var paramPath = _a.paramPath;
return ({
path: paramPath,
tensor: _this.getParamFromPath(paramPath)
});
});
};
NeuralNetwork.prototype.getTrainableParams = function () {
return this.getParamList().filter(function (param) { return param.tensor instanceof tf.Variable; });
};
NeuralNetwork.prototype.getFrozenParams = function () {
return this.getParamList().filter(function (param) { return !(param.tensor instanceof tf.Variable); });
};
NeuralNetwork.prototype.variable = function () {
var _this = this;
this.getFrozenParams().forEach(function (_a) {
var path = _a.path, tensor = _a.tensor;
_this.reassignParamFromPath(path, tf.variable(tensor));
});
};
NeuralNetwork.prototype.freeze = function () {
var _this = this;
this.getTrainableParams().forEach(function (_a) {
var path = _a.path, tensor = _a.tensor;
_this.reassignParamFromPath(path, tf.tensor(tensor));
});
};
NeuralNetwork.prototype.dispose = function () {
this.getParamList().forEach(function (param) { return param.tensor.dispose(); });
this._params = undefined;
};
NeuralNetwork.prototype.traversePropertyPath = function (paramPath) {
if (!this.params) {
throw new Error("traversePropertyPath - model has no loaded params");
}
var result = paramPath.split('/').reduce(function (res, objProp) {
if (!res.nextObj.hasOwnProperty(objProp)) {
throw new Error("traversePropertyPath - object does not have property " + objProp + ", for path " + paramPath);
}
return { obj: res.nextObj, objProp: objProp, nextObj: res.nextObj[objProp] };
}, { nextObj: this.params });
var obj = result.obj, objProp = result.objProp;
if (!obj || !objProp || !(obj[objProp] instanceof tf.Tensor)) {
throw new Error("traversePropertyPath - parameter is not a tensor, for path " + paramPath);
}
return { obj: obj, objProp: objProp };
};
return NeuralNetwork;
}());
exports.NeuralNetwork = NeuralNetwork;
//# sourceMappingURL=NeuralNetwork.js.map
\ No newline at end of file
{"version":3,"file":"NeuralNetwork.js","sourceRoot":"","sources":["../../src/commons/NeuralNetwork.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import { ConvParams, ExtractWeightsFunction } from './types';
export declare function extractConvParamsFactory(extractWeights: ExtractWeightsFunction): (channelsIn: number, channelsOut: number, filterSize: number) => ConvParams;
import { ConvParams, ExtractWeightsFunction, ParamMapping } from './types';
export declare function extractConvParamsFactory(extractWeights: ExtractWeightsFunction, paramMappings: ParamMapping[]): (channelsIn: number, channelsOut: number, filterSize: number, mappedPrefix: string) => ConvParams;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tf = require("@tensorflow/tfjs-core");
function extractConvParamsFactory(extractWeights) {
return function (channelsIn, channelsOut, filterSize) {
function extractConvParamsFactory(extractWeights, paramMappings) {
return function (channelsIn, channelsOut, filterSize, mappedPrefix) {
var filters = tf.tensor4d(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]);
var bias = tf.tensor1d(extractWeights(channelsOut));
paramMappings.push({ paramPath: mappedPrefix + "/filters" }, { paramPath: mappedPrefix + "/bias" });
return {
filters: filters,
bias: bias
......
{"version":3,"file":"extractConvParamsFactory.js","sourceRoot":"","sources":["../../src/commons/extractConvParamsFactory.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAI5C,kCAAyC,cAAsC;IAC7E,OAAO,UACL,UAAkB,EAClB,WAAmB,EACnB,UAAkB;QAElB,IAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CACzB,cAAc,CAAC,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC,EAClE,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAClD,CAAA;QACD,IAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAErD,OAAO;YACL,OAAO,SAAA;YACP,IAAI,MAAA;SACL,CAAA;IACH,CAAC,CAAA;AACH,CAAC;AAjBD,4DAiBC"}
\ No newline at end of file
{"version":3,"file":"extractConvParamsFactory.js","sourceRoot":"","sources":["../../src/commons/extractConvParamsFactory.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAI5C,kCAAyC,cAAsC,EAAE,aAA6B;IAC5G,OAAO,UACL,UAAkB,EAClB,WAAmB,EACnB,UAAkB,EAClB,YAAoB;QAEpB,IAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CACzB,cAAc,CAAC,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC,EAClE,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAClD,CAAA;QACD,IAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAErD,aAAa,CAAC,IAAI,CAChB,EAAE,SAAS,EAAK,YAAY,aAAU,EAAE,EACxC,EAAE,SAAS,EAAK,YAAY,UAAO,EAAE,CACtC,CAAA;QAED,OAAO;YACL,OAAO,SAAA;YACP,IAAI,MAAA;SACL,CAAA;IACH,CAAC,CAAA;AACH,CAAC;AAvBD,4DAuBC"}
\ No newline at end of file
export declare function extractWeightEntry(weightMap: any, path: string, paramRank: number): {
path: string;
tensor: any;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var isTensor_1 = require("./isTensor");
function extractWeightEntry(weightMap, path, paramRank) {
var tensor = weightMap[path];
if (!isTensor_1.isTensor(tensor, paramRank)) {
throw new Error("expected weightMap[" + path + "] to be a Tensor" + paramRank + "D, instead have " + tensor);
}
return { path: path, tensor: tensor };
}
exports.extractWeightEntry = extractWeightEntry;
//# sourceMappingURL=extractWeightEntry.js.map
\ No newline at end of file
{"version":3,"file":"extractWeightEntry.js","sourceRoot":"","sources":["../../src/commons/extractWeightEntry.ts"],"names":[],"mappings":";;AAAA,uCAAsC;AAEtC,4BAAmC,SAAc,EAAE,IAAY,EAAE,SAAiB;IAChF,IAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAE9B,IAAI,CAAC,mBAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,wBAAsB,IAAI,wBAAmB,SAAS,wBAAmB,MAAQ,CAAC,CAAA;KACnG;IAED,OAAO,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAA;AACzB,CAAC;AARD,gDAQC"}
\ No newline at end of file
......@@ -10,3 +10,7 @@ export declare type BatchReshapeInfo = {
paddingX: number;
paddingY: number;
};
export declare type ParamMapping = {
originalPath?: string;
paramPath: string;
};
import * as tf from '@tensorflow/tfjs-core';
import { NeuralNetwork } from '../commons/NeuralNetwork';
import { NetInput } from '../NetInput';
import { TNetInput } from '../types';
import { FaceLandmarks } from './FaceLandmarks';
export declare class FaceLandmarkNet {
private _params;
import { NetParams } from './types';
export declare class FaceLandmarkNet extends NeuralNetwork<NetParams> {
load(weightsOrUrl: Float32Array | string | undefined): Promise<void>;
extractWeights(weights: Float32Array): void;
forwardInput(input: NetInput): tf.Tensor2D;
......
......@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tf = require("@tensorflow/tfjs-core");
var convLayer_1 = require("../commons/convLayer");
var NeuralNetwork_1 = require("../commons/NeuralNetwork");
var Point_1 = require("../Point");
var toNetInput_1 = require("../toNetInput");
var utils_1 = require("../utils");
......@@ -17,12 +18,14 @@ function maxPool(x, strides) {
if (strides === void 0) { strides = [2, 2]; }
return tf.maxPool(x, [2, 2], strides, 'valid');
}
var FaceLandmarkNet = /** @class */ (function () {
var FaceLandmarkNet = /** @class */ (function (_super) {
tslib_1.__extends(FaceLandmarkNet, _super);
function FaceLandmarkNet() {
return _super !== null && _super.apply(this, arguments) || this;
}
FaceLandmarkNet.prototype.load = function (weightsOrUrl) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a;
var _a, paramMappings, params;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
......@@ -33,17 +36,20 @@ var FaceLandmarkNet = /** @class */ (function () {
if (weightsOrUrl && typeof weightsOrUrl !== 'string') {
throw new Error('FaceLandmarkNet.load - expected model uri, or weights as Float32Array');
}
_a = this;
return [4 /*yield*/, loadQuantizedParams_1.loadQuantizedParams(weightsOrUrl)];
case 1:
_a._params = _b.sent();
_a = _b.sent(), paramMappings = _a.paramMappings, params = _a.params;
this._paramMappings = paramMappings;
this._params = params;
return [2 /*return*/];
}
});
});
};
FaceLandmarkNet.prototype.extractWeights = function (weights) {
this._params = extractParams_1.extractParams(weights);
var _a = extractParams_1.extractParams(weights), paramMappings = _a.paramMappings, params = _a.params;
this._paramMappings = paramMappings;
this._params = params;
};
FaceLandmarkNet.prototype.forwardInput = function (input) {
var params = this._params;
......@@ -141,6 +147,6 @@ var FaceLandmarkNet = /** @class */ (function () {
});
};
return FaceLandmarkNet;
}());
}(NeuralNetwork_1.NeuralNetwork));
exports.FaceLandmarkNet = FaceLandmarkNet;
//# sourceMappingURL=FaceLandmarkNet.js.map
\ No newline at end of file
{"version":3,"file":"FaceLandmarkNet.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmarkNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
{"version":3,"file":"FaceLandmarkNet.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/FaceLandmarkNet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import { ParamMapping } from '../commons/types';
import { NetParams } from './types';
export declare function extractParams(weights: Float32Array): NetParams;
export declare function extractParams(weights: Float32Array): {
params: NetParams;
paramMappings: ParamMapping[];
};
......@@ -4,40 +4,45 @@ var tf = require("@tensorflow/tfjs-core");
var extractConvParamsFactory_1 = require("../commons/extractConvParamsFactory");
var extractWeightsFactory_1 = require("../commons/extractWeightsFactory");
function extractParams(weights) {
var paramMappings = [];
var _a = extractWeightsFactory_1.extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights;
var extractConvParams = extractConvParamsFactory_1.extractConvParamsFactory(extractWeights);
function extractFcParams(channelsIn, channelsOut) {
var extractConvParams = extractConvParamsFactory_1.extractConvParamsFactory(extractWeights, paramMappings);
function extractFcParams(channelsIn, channelsOut, mappedPrefix) {
var fc_weights = tf.tensor2d(extractWeights(channelsIn * channelsOut), [channelsIn, channelsOut]);
var fc_bias = tf.tensor1d(extractWeights(channelsOut));
paramMappings.push({ paramPath: mappedPrefix + "/weights" }, { paramPath: mappedPrefix + "/bias" });
return {
weights: fc_weights,
bias: fc_bias
};
}
var conv0_params = extractConvParams(3, 32, 3);
var conv1_params = extractConvParams(32, 64, 3);
var conv2_params = extractConvParams(64, 64, 3);
var conv3_params = extractConvParams(64, 64, 3);
var conv4_params = extractConvParams(64, 64, 3);
var conv5_params = extractConvParams(64, 128, 3);
var conv6_params = extractConvParams(128, 128, 3);
var conv7_params = extractConvParams(128, 256, 3);
var fc0_params = extractFcParams(6400, 1024);
var fc1_params = extractFcParams(1024, 136);
var conv0_params = extractConvParams(3, 32, 3, 'conv0_params');
var conv1_params = extractConvParams(32, 64, 3, 'conv1_params');
var conv2_params = extractConvParams(64, 64, 3, 'conv2_params');
var conv3_params = extractConvParams(64, 64, 3, 'conv3_params');
var conv4_params = extractConvParams(64, 64, 3, 'conv4_params');
var conv5_params = extractConvParams(64, 128, 3, 'conv5_params');
var conv6_params = extractConvParams(128, 128, 3, 'conv6_params');
var conv7_params = extractConvParams(128, 256, 3, 'conv7_params');
var fc0_params = extractFcParams(6400, 1024, 'fc0_params');
var fc1_params = extractFcParams(1024, 136, 'fc1_params');
if (getRemainingWeights().length !== 0) {
throw new Error("weights remaing after extract: " + getRemainingWeights().length);
}
return {
conv0_params: conv0_params,
conv1_params: conv1_params,
conv2_params: conv2_params,
conv3_params: conv3_params,
conv4_params: conv4_params,
conv5_params: conv5_params,
conv6_params: conv6_params,
conv7_params: conv7_params,
fc0_params: fc0_params,
fc1_params: fc1_params
paramMappings: paramMappings,
params: {
conv0_params: conv0_params,
conv1_params: conv1_params,
conv2_params: conv2_params,
conv3_params: conv3_params,
conv4_params: conv4_params,
conv5_params: conv5_params,
conv6_params: conv6_params,
conv7_params: conv7_params,
fc0_params: fc0_params,
fc1_params: fc1_params
}
};
}
exports.extractParams = extractParams;
......
{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/extractParams.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,gFAA+E;AAC/E,0EAAyE;AAGzE,uBAA8B,OAAqB;IAC3C,IAAA,2DAG4B,EAFhC,kCAAc,EACd,4CAAmB,CACa;IAElC,IAAM,iBAAiB,GAAG,mDAAwB,CAAC,cAAc,CAAC,CAAA;IAElE,yBAAyB,UAAkB,EAAE,WAAmB;QAC9D,IAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAA;QACnG,IAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QACxD,OAAO;YACL,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,OAAO;SACd,CAAA;IACH,CAAC;IAED,IAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IAChD,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACjD,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACjD,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACjD,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACjD,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IAClD,IAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IACnD,IAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IACnD,IAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAC9C,IAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAE7C,IAAI,mBAAmB,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;QACtC,MAAM,IAAI,KAAK,CAAC,oCAAkC,mBAAmB,EAAE,CAAC,MAAQ,CAAC,CAAA;KAClF;IAED,OAAO;QACL,YAAY,cAAA;QACZ,YAAY,cAAA;QACZ,YAAY,cAAA;QACZ,YAAY,cAAA;QACZ,YAAY,cAAA;QACZ,YAAY,cAAA;QACZ,YAAY,cAAA;QACZ,YAAY,cAAA;QACZ,UAAU,YAAA;QACV,UAAU,YAAA;KACX,CAAA;AACH,CAAC;AA5CD,sCA4CC"}
\ No newline at end of file
{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/extractParams.ts"],"names":[],"mappings":";;AAAA,0CAA4C;AAE5C,gFAA+E;AAC/E,0EAAyE;AAIzE,uBAA8B,OAAqB;IACjD,IAAM,aAAa,GAAmB,EAAE,CAAA;IAElC,IAAA,2DAG4B,EAFhC,kCAAc,EACd,4CAAmB,CACa;IAElC,IAAM,iBAAiB,GAAG,mDAAwB,CAAC,cAAc,EAAE,aAAa,CAAC,CAAA;IAEjF,yBAAyB,UAAkB,EAAE,WAAmB,EAAE,YAAoB;QACpF,IAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAA;QACnG,IAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAExD,aAAa,CAAC,IAAI,CAChB,EAAE,SAAS,EAAK,YAAY,aAAU,EAAE,EACxC,EAAE,SAAS,EAAK,YAAY,UAAO,EAAE,CACtC,CAAA;QAED,OAAO;YACL,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,OAAO;SACd,CAAA;IACH,CAAC;IAED,IAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IAChE,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IACjE,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IACjE,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IACjE,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IACjE,IAAM,YAAY,GAAG,iBAAiB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IAClE,IAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IACnE,IAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,cAAc,CAAC,CAAA;IACnE,IAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAA;IAC5D,IAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,CAAA;IAE3D,IAAI,mBAAmB,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;QACtC,MAAM,IAAI,KAAK,CAAC,oCAAkC,mBAAmB,EAAE,CAAC,MAAQ,CAAC,CAAA;KAClF;IAED,OAAO;QACL,aAAa,eAAA;QACb,MAAM,EAAE;YACN,YAAY,cAAA;YACZ,YAAY,cAAA;YACZ,YAAY,cAAA;YACZ,YAAY,cAAA;YACZ,YAAY,cAAA;YACZ,YAAY,cAAA;YACZ,YAAY,cAAA;YACZ,YAAY,cAAA;YACZ,UAAU,YAAA;YACV,UAAU,YAAA;SACX;KACF,CAAA;AACH,CAAC;AAvDD,sCAuDC"}
\ No newline at end of file
import { ParamMapping } from '../commons/types';
import { NetParams } from './types';
export declare function loadQuantizedParams(uri: string | undefined): Promise<NetParams>;
export declare function loadQuantizedParams(uri: string | undefined): Promise<{
params: NetParams;
paramMappings: ParamMapping[];
}>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var extractWeightEntry_1 = require("../commons/extractWeightEntry");
var loadWeightMap_1 = require("../commons/loadWeightMap");
var isTensor_1 = require("../commons/isTensor");
var DEFAULT_MODEL_NAME = 'face_landmark_68_model';
function extractorsFactory(weightMap) {
function extractConvParams(prefix) {
var params = {
filters: weightMap[prefix + "/kernel"],
bias: weightMap[prefix + "/bias"]
function extractorsFactory(weightMap, paramMappings) {
function extractConvParams(prefix, mappedPrefix) {
var filtersEntry = extractWeightEntry_1.extractWeightEntry(weightMap, prefix + "/kernel", 4);
var biasEntry = extractWeightEntry_1.extractWeightEntry(weightMap, prefix + "/bias", 1);
paramMappings.push({ originalPath: filtersEntry.path, paramPath: mappedPrefix + "/filters" }, { originalPath: biasEntry.path, paramPath: mappedPrefix + "/bias" });
return {
filters: filtersEntry.tensor,
bias: biasEntry.tensor
};
if (!isTensor_1.isTensor4D(params.filters)) {
throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor4D, instead have " + params.filters);
}
if (!isTensor_1.isTensor1D(params.bias)) {
throw new Error("expected weightMap[" + prefix + "/bias] to be a Tensor1D, instead have " + params.bias);
}
return params;
}
function extractFcParams(prefix) {
var params = {
weights: weightMap[prefix + "/kernel"],
bias: weightMap[prefix + "/bias"]
function extractFcParams(prefix, mappedPrefix) {
var weightsEntry = extractWeightEntry_1.extractWeightEntry(weightMap, prefix + "/kernel", 2);
var biasEntry = extractWeightEntry_1.extractWeightEntry(weightMap, prefix + "/bias", 1);
paramMappings.push({ originalPath: weightsEntry.path, paramPath: mappedPrefix + "/weights" }, { originalPath: biasEntry.path, paramPath: mappedPrefix + "/bias" });
return {
weights: weightsEntry.tensor,
bias: biasEntry.tensor
};
if (!isTensor_1.isTensor2D(params.weights)) {
throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor2D, instead have " + params.weights);
}
if (!isTensor_1.isTensor1D(params.bias)) {
throw new Error("expected weightMap[" + prefix + "/bias] to be a Tensor1D, instead have " + params.bias);
}
return params;
}
return {
extractConvParams: extractConvParams,
......@@ -38,25 +30,27 @@ function extractorsFactory(weightMap) {
}
function loadQuantizedParams(uri) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var weightMap, _a, extractConvParams, extractFcParams;
var weightMap, paramMappings, _a, extractConvParams, extractFcParams, params;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, loadWeightMap_1.loadWeightMap(uri, DEFAULT_MODEL_NAME)];
case 1:
weightMap = _b.sent();
_a = extractorsFactory(weightMap), extractConvParams = _a.extractConvParams, extractFcParams = _a.extractFcParams;
return [2 /*return*/, {
conv0_params: extractConvParams('conv2d_0'),
conv1_params: extractConvParams('conv2d_1'),
conv2_params: extractConvParams('conv2d_2'),
conv3_params: extractConvParams('conv2d_3'),
conv4_params: extractConvParams('conv2d_4'),
conv5_params: extractConvParams('conv2d_5'),
conv6_params: extractConvParams('conv2d_6'),
conv7_params: extractConvParams('conv2d_7'),
fc0_params: extractFcParams('dense'),
fc1_params: extractFcParams('logits')
}];
paramMappings = [];
_a = extractorsFactory(weightMap, paramMappings), extractConvParams = _a.extractConvParams, extractFcParams = _a.extractFcParams;
params = {
conv0_params: extractConvParams('conv2d_0', 'conv0_params'),
conv1_params: extractConvParams('conv2d_1', 'conv1_params'),
conv2_params: extractConvParams('conv2d_2', 'conv2_params'),
conv3_params: extractConvParams('conv2d_3', 'conv3_params'),
conv4_params: extractConvParams('conv2d_4', 'conv4_params'),
conv5_params: extractConvParams('conv2d_5', 'conv5_params'),
conv6_params: extractConvParams('conv2d_6', 'conv6_params'),
conv7_params: extractConvParams('conv2d_7', 'conv7_params'),
fc0_params: extractFcParams('dense', 'fc0_params'),
fc1_params: extractFcParams('logits', 'fc1_params')
};
return [2 /*return*/, { params: params, paramMappings: paramMappings }];
}
});
});
......
{"version":3,"file":"loadQuantizedParams.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/loadQuantizedParams.ts"],"names":[],"mappings":";;;AAEA,0DAAyD;AAGzD,gDAAyE;AAEzE,IAAM,kBAAkB,GAAG,wBAAwB,CAAA;AAEnD,2BAA2B,SAAc;IAEvC,2BAA2B,MAAc;QACvC,IAAM,MAAM,GAAG;YACb,OAAO,EAAE,SAAS,CAAI,MAAM,YAAS,CAAgB;YACrD,IAAI,EAAE,SAAS,CAAI,MAAM,UAAO,CAAgB;SACjD,CAAA;QAED,IAAI,CAAC,qBAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAC/B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,gDAA2C,MAAM,CAAC,OAAS,CAAC,CAAA;SACzG;QAED,IAAI,CAAC,qBAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,8CAAyC,MAAM,CAAC,IAAM,CAAC,CAAA;SACpG;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED,yBAAyB,MAAc;QACrC,IAAM,MAAM,GAAG;YACb,OAAO,EAAE,SAAS,CAAI,MAAM,YAAS,CAAgB;YACrD,IAAI,EAAE,SAAS,CAAI,MAAM,UAAO,CAAgB;SACjD,CAAA;QAED,IAAI,CAAC,qBAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAC/B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,gDAA2C,MAAM,CAAC,OAAS,CAAC,CAAA;SACzG;QAED,IAAI,CAAC,qBAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC5B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,8CAAyC,MAAM,CAAC,IAAM,CAAC,CAAA;SACpG;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED,OAAO;QACL,iBAAiB,mBAAA;QACjB,eAAe,iBAAA;KAChB,CAAA;AACH,CAAC;AAED,6BAA0C,GAAuB;;;;;wBAC7C,qBAAM,6BAAa,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAA;;oBAAxD,SAAS,GAAG,SAA4C;oBAExD,KAGF,iBAAiB,CAAC,SAAS,CAAC,EAF9B,iBAAiB,uBAAA,EACjB,eAAe,qBAAA,CACe;oBAEhC,sBAAO;4BACL,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,YAAY,EAAE,iBAAiB,CAAC,UAAU,CAAC;4BAC3C,UAAU,EAAE,eAAe,CAAC,OAAO,CAAC;4BACpC,UAAU,EAAE,eAAe,CAAC,QAAQ,CAAC;yBACtC,EAAA;;;;CACF;AApBD,kDAoBC"}
\ No newline at end of file
{"version":3,"file":"loadQuantizedParams.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/loadQuantizedParams.ts"],"names":[],"mappings":";;;AAEA,oEAAmE;AACnE,0DAAyD;AAIzD,IAAM,kBAAkB,GAAG,wBAAwB,CAAA;AAEnD,2BAA2B,SAAc,EAAE,aAA6B;IAEtE,2BAA2B,MAAc,EAAE,YAAoB;QAC7D,IAAM,YAAY,GAAG,uCAAkB,CAAC,SAAS,EAAK,MAAM,YAAS,EAAE,CAAC,CAAC,CAAA;QACzE,IAAM,SAAS,GAAG,uCAAkB,CAAC,SAAS,EAAK,MAAM,UAAO,EAAE,CAAC,CAAC,CAAA;QACpE,aAAa,CAAC,IAAI,CAChB,EAAE,YAAY,EAAE,YAAY,CAAC,IAAI,EAAE,SAAS,EAAK,YAAY,aAAU,EAAE,EACzE,EAAE,YAAY,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,EAAK,YAAY,UAAO,EAAE,CACpE,CAAA;QACD,OAAO;YACL,OAAO,EAAE,YAAY,CAAC,MAAqB;YAC3C,IAAI,EAAE,SAAS,CAAC,MAAqB;SACtC,CAAA;IACH,CAAC;IAED,yBAAyB,MAAc,EAAE,YAAoB;QAC3D,IAAM,YAAY,GAAG,uCAAkB,CAAC,SAAS,EAAK,MAAM,YAAS,EAAE,CAAC,CAAC,CAAA;QACzE,IAAM,SAAS,GAAG,uCAAkB,CAAC,SAAS,EAAK,MAAM,UAAO,EAAE,CAAC,CAAC,CAAA;QACpE,aAAa,CAAC,IAAI,CAChB,EAAE,YAAY,EAAE,YAAY,CAAC,IAAI,EAAE,SAAS,EAAK,YAAY,aAAU,EAAE,EACzE,EAAE,YAAY,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,EAAK,YAAY,UAAO,EAAE,CACpE,CAAA;QACD,OAAO;YACL,OAAO,EAAE,YAAY,CAAC,MAAqB;YAC3C,IAAI,EAAE,SAAS,CAAC,MAAqB;SACtC,CAAA;IACH,CAAC;IAED,OAAO;QACL,iBAAiB,mBAAA;QACjB,eAAe,iBAAA;KAChB,CAAA;AACH,CAAC;AAED,6BACE,GAAuB;;;;;wBAGL,qBAAM,6BAAa,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAA;;oBAAxD,SAAS,GAAG,SAA4C;oBACxD,aAAa,GAAmB,EAAE,CAAA;oBAElC,KAGF,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,EAF7C,iBAAiB,uBAAA,EACjB,eAAe,qBAAA,CAC8B;oBAEzC,MAAM,GAAG;wBACb,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,YAAY,EAAE,iBAAiB,CAAC,UAAU,EAAE,cAAc,CAAC;wBAC3D,UAAU,EAAE,eAAe,CAAC,OAAO,EAAE,YAAY,CAAC;wBAClD,UAAU,EAAE,eAAe,CAAC,QAAQ,EAAE,YAAY,CAAC;qBACpD,CAAA;oBAED,sBAAO,EAAE,MAAM,QAAA,EAAE,aAAa,eAAA,EAAE,EAAA;;;;CACjC;AA1BD,kDA0BC"}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
import * as tf from '@tensorflow/tfjs-core';
import { ParamMapping } from './types';
export class NeuralNetwork<TNetParams> {
protected _params: TNetParams | undefined = undefined
protected _paramMappings: ParamMapping[] = []
public get params(): TNetParams | undefined {
return this._params
}
public get paramMappings(): ParamMapping[] {
return this._paramMappings
}
public getParamFromPath(paramPath: string): tf.Tensor {
const { obj, objProp } = this.traversePropertyPath(paramPath)
return obj[objProp]
}
public reassignParamFromPath(paramPath: string, tensor: tf.Tensor) {
const { obj, objProp } = this.traversePropertyPath(paramPath)
obj[objProp].dispose()
obj[objProp] = tensor
}
public getParamList() {
return this._paramMappings.map(({ paramPath }) => ({
path: paramPath,
tensor: this.getParamFromPath(paramPath)
}))
}
public getTrainableParams() {
return this.getParamList().filter(param => param.tensor instanceof tf.Variable)
}
public getFrozenParams() {
return this.getParamList().filter(param => !(param.tensor instanceof tf.Variable))
}
public variable() {
this.getFrozenParams().forEach(({ path, tensor }) => {
this.reassignParamFromPath(path, tf.variable(tensor))
})
}
public freeze() {
this.getTrainableParams().forEach(({ path, tensor }) => {
this.reassignParamFromPath(path, tf.tensor(tensor as any))
})
}
public dispose() {
this.getParamList().forEach(param => param.tensor.dispose())
this._params = undefined
}
private traversePropertyPath(paramPath: string) {
if (!this.params) {
throw new Error(`traversePropertyPath - model has no loaded params`)
}
const result = paramPath.split('/').reduce((res: { nextObj: any, obj?: any, objProp?: string }, objProp) => {
if (!res.nextObj.hasOwnProperty(objProp)) {
throw new Error(`traversePropertyPath - object does not have property ${objProp}, for path ${paramPath}`)
}
return { obj: res.nextObj, objProp, nextObj: res.nextObj[objProp] }
}, { nextObj: this.params })
const { obj, objProp } = result
if (!obj || !objProp || !(obj[objProp] instanceof tf.Tensor)) {
throw new Error(`traversePropertyPath - parameter is not a tensor, for path ${paramPath}`)
}
return { obj, objProp }
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { ConvParams, ExtractWeightsFunction } from './types';
import { ConvParams, ExtractWeightsFunction, ParamMapping } from './types';
export function extractConvParamsFactory(extractWeights: ExtractWeightsFunction) {
export function extractConvParamsFactory(extractWeights: ExtractWeightsFunction, paramMappings: ParamMapping[]) {
return function (
channelsIn: number,
channelsOut: number,
filterSize: number
filterSize: number,
mappedPrefix: string
): ConvParams {
const filters = tf.tensor4d(
extractWeights(channelsIn * channelsOut * filterSize * filterSize),
......@@ -14,6 +15,11 @@ export function extractConvParamsFactory(extractWeights: ExtractWeightsFunction)
)
const bias = tf.tensor1d(extractWeights(channelsOut))
paramMappings.push(
{ paramPath: `${mappedPrefix}/filters` },
{ paramPath: `${mappedPrefix}/bias` }
)
return {
filters,
bias
......
import { isTensor } from './isTensor';
export function extractWeightEntry(weightMap: any, path: string, paramRank: number) {
const tensor = weightMap[path]
if (!isTensor(tensor, paramRank)) {
throw new Error(`expected weightMap[${path}] to be a Tensor${paramRank}D, instead have ${tensor}`)
}
return { path, tensor }
}
\ No newline at end of file
......@@ -13,3 +13,8 @@ export type BatchReshapeInfo = {
paddingX: number
paddingY: number
}
export type ParamMapping = {
originalPath?: string
paramPath: string
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { convLayer } from '../commons/convLayer';
import { NeuralNetwork } from '../commons/NeuralNetwork';
import { ConvParams } from '../commons/types';
import { NetInput } from '../NetInput';
import { Point } from '../Point';
......@@ -21,9 +22,7 @@ function maxPool(x: tf.Tensor4D, strides: [number, number] = [2, 2]): tf.Tensor4
return tf.maxPool(x, [2, 2], strides, 'valid')
}
export class FaceLandmarkNet {
private _params: NetParams
export class FaceLandmarkNet extends NeuralNetwork<NetParams> {
public async load(weightsOrUrl: Float32Array | string | undefined): Promise<void> {
if (weightsOrUrl instanceof Float32Array) {
......@@ -34,11 +33,23 @@ export class FaceLandmarkNet {
if (weightsOrUrl && typeof weightsOrUrl !== 'string') {
throw new Error('FaceLandmarkNet.load - expected model uri, or weights as Float32Array')
}
this._params = await loadQuantizedParams(weightsOrUrl)
const {
paramMappings,
params
} = await loadQuantizedParams(weightsOrUrl)
this._paramMappings = paramMappings
this._params = params
}
public extractWeights(weights: Float32Array) {
this._params = extractParams(weights)
const {
paramMappings,
params
} = extractParams(weights)
this._paramMappings = paramMappings
this._params = params
}
public forwardInput(input: NetInput): tf.Tensor2D {
......
......@@ -2,50 +2,62 @@ import * as tf from '@tensorflow/tfjs-core';
import { extractConvParamsFactory } from '../commons/extractConvParamsFactory';
import { extractWeightsFactory } from '../commons/extractWeightsFactory';
import { ParamMapping } from '../commons/types';
import { FCParams, NetParams } from './types';
export function extractParams(weights: Float32Array): NetParams {
export function extractParams(weights: Float32Array): { params: NetParams, paramMappings: ParamMapping[] } {
const paramMappings: ParamMapping[] = []
const {
extractWeights,
getRemainingWeights
} = extractWeightsFactory(weights)
const extractConvParams = extractConvParamsFactory(extractWeights)
const extractConvParams = extractConvParamsFactory(extractWeights, paramMappings)
function extractFcParams(channelsIn: number, channelsOut: number,): FCParams {
function extractFcParams(channelsIn: number, channelsOut: number, mappedPrefix: string): FCParams {
const fc_weights = tf.tensor2d(extractWeights(channelsIn * channelsOut), [channelsIn, channelsOut])
const fc_bias = tf.tensor1d(extractWeights(channelsOut))
paramMappings.push(
{ paramPath: `${mappedPrefix}/weights` },
{ paramPath: `${mappedPrefix}/bias` }
)
return {
weights: fc_weights,
bias: fc_bias
}
}
const conv0_params = extractConvParams(3, 32, 3)
const conv1_params = extractConvParams(32, 64, 3)
const conv2_params = extractConvParams(64, 64, 3)
const conv3_params = extractConvParams(64, 64, 3)
const conv4_params = extractConvParams(64, 64, 3)
const conv5_params = extractConvParams(64, 128, 3)
const conv6_params = extractConvParams(128, 128, 3)
const conv7_params = extractConvParams(128, 256, 3)
const fc0_params = extractFcParams(6400, 1024)
const fc1_params = extractFcParams(1024, 136)
const conv0_params = extractConvParams(3, 32, 3, 'conv0_params')
const conv1_params = extractConvParams(32, 64, 3, 'conv1_params')
const conv2_params = extractConvParams(64, 64, 3, 'conv2_params')
const conv3_params = extractConvParams(64, 64, 3, 'conv3_params')
const conv4_params = extractConvParams(64, 64, 3, 'conv4_params')
const conv5_params = extractConvParams(64, 128, 3, 'conv5_params')
const conv6_params = extractConvParams(128, 128, 3, 'conv6_params')
const conv7_params = extractConvParams(128, 256, 3, 'conv7_params')
const fc0_params = extractFcParams(6400, 1024, 'fc0_params')
const fc1_params = extractFcParams(1024, 136, 'fc1_params')
if (getRemainingWeights().length !== 0) {
throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`)
}
return {
conv0_params,
conv1_params,
conv2_params,
conv3_params,
conv4_params,
conv5_params,
conv6_params,
conv7_params,
fc0_params,
fc1_params
paramMappings,
params: {
conv0_params,
conv1_params,
conv2_params,
conv3_params,
conv4_params,
conv5_params,
conv6_params,
conv7_params,
fc0_params,
fc1_params
}
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { extractWeightEntry } from '../commons/extractWeightEntry';
import { loadWeightMap } from '../commons/loadWeightMap';
import { ConvParams } from '../commons/types';
import { ConvParams, ParamMapping } from '../commons/types';
import { FCParams, NetParams } from './types';
import { isTensor4D, isTensor1D, isTensor2D } from '../commons/isTensor';
const DEFAULT_MODEL_NAME = 'face_landmark_68_model'
function extractorsFactory(weightMap: any) {
function extractorsFactory(weightMap: any, paramMappings: ParamMapping[]) {
function extractConvParams(prefix: string): ConvParams {
const params = {
filters: weightMap[`${prefix}/kernel`] as tf.Tensor4D,
bias: weightMap[`${prefix}/bias`] as tf.Tensor1D
function extractConvParams(prefix: string, mappedPrefix: string): ConvParams {
const filtersEntry = extractWeightEntry(weightMap, `${prefix}/kernel`, 4)
const biasEntry = extractWeightEntry(weightMap, `${prefix}/bias`, 1)
paramMappings.push(
{ originalPath: filtersEntry.path, paramPath: `${mappedPrefix}/filters` },
{ originalPath: biasEntry.path, paramPath: `${mappedPrefix}/bias` }
)
return {
filters: filtersEntry.tensor as tf.Tensor4D,
bias: biasEntry.tensor as tf.Tensor1D
}
if (!isTensor4D(params.filters)) {
throw new Error(`expected weightMap[${prefix}/kernel] to be a Tensor4D, instead have ${params.filters}`)
}
if (!isTensor1D(params.bias)) {
throw new Error(`expected weightMap[${prefix}/bias] to be a Tensor1D, instead have ${params.bias}`)
}
return params
}
function extractFcParams(prefix: string): FCParams {
const params = {
weights: weightMap[`${prefix}/kernel`] as tf.Tensor2D,
bias: weightMap[`${prefix}/bias`] as tf.Tensor1D
}
if (!isTensor2D(params.weights)) {
throw new Error(`expected weightMap[${prefix}/kernel] to be a Tensor2D, instead have ${params.weights}`)
function extractFcParams(prefix: string, mappedPrefix: string): FCParams {
const weightsEntry = extractWeightEntry(weightMap, `${prefix}/kernel`, 2)
const biasEntry = extractWeightEntry(weightMap, `${prefix}/bias`, 1)
paramMappings.push(
{ originalPath: weightsEntry.path, paramPath: `${mappedPrefix}/weights` },
{ originalPath: biasEntry.path, paramPath: `${mappedPrefix}/bias` }
)
return {
weights: weightsEntry.tensor as tf.Tensor2D,
bias: biasEntry.tensor as tf.Tensor1D
}
if (!isTensor1D(params.bias)) {
throw new Error(`expected weightMap[${prefix}/bias] to be a Tensor1D, instead have ${params.bias}`)
}
return params
}
return {
......@@ -49,24 +41,30 @@ function extractorsFactory(weightMap: any) {
}
}
export async function loadQuantizedParams(uri: string | undefined): Promise<NetParams> {
export async function loadQuantizedParams(
uri: string | undefined
): Promise<{ params: NetParams, paramMappings: ParamMapping[] }> {
const weightMap = await loadWeightMap(uri, DEFAULT_MODEL_NAME)
const paramMappings: ParamMapping[] = []
const {
extractConvParams,
extractFcParams
} = extractorsFactory(weightMap)
} = extractorsFactory(weightMap, paramMappings)
return {
conv0_params: extractConvParams('conv2d_0'),
conv1_params: extractConvParams('conv2d_1'),
conv2_params: extractConvParams('conv2d_2'),
conv3_params: extractConvParams('conv2d_3'),
conv4_params: extractConvParams('conv2d_4'),
conv5_params: extractConvParams('conv2d_5'),
conv6_params: extractConvParams('conv2d_6'),
conv7_params: extractConvParams('conv2d_7'),
fc0_params: extractFcParams('dense'),
fc1_params: extractFcParams('logits')
const params = {
conv0_params: extractConvParams('conv2d_0', 'conv0_params'),
conv1_params: extractConvParams('conv2d_1', 'conv1_params'),
conv2_params: extractConvParams('conv2d_2', 'conv2_params'),
conv3_params: extractConvParams('conv2d_3', 'conv3_params'),
conv4_params: extractConvParams('conv2d_4', 'conv4_params'),
conv5_params: extractConvParams('conv2d_5', 'conv5_params'),
conv6_params: extractConvParams('conv2d_6', 'conv6_params'),
conv7_params: extractConvParams('conv2d_7', 'conv7_params'),
fc0_params: extractFcParams('dense', 'fc0_params'),
fc1_params: extractFcParams('logits', 'fc1_params')
}
return { params, paramMappings }
}
\ No newline at end of file
import { NeuralNetwork } from '../../../src/commons/NeuralNetwork';
import * as tf from '@tensorflow/tfjs-core';
class FakeNeuralNetwork extends NeuralNetwork<any> {
constructor(
convFilter: tf.Tensor = tf.tensor(0),
convBias: tf.Tensor = tf.tensor(0),
fcWeights: tf.Tensor = tf.tensor(0)
) {
super()
this._params = {
conv: {
filter: convFilter,
bias: convBias,
},
fc: fcWeights
}
this._paramMappings = [
{ originalPath: 'conv2d/filter', paramPath: 'conv/filter' },
{ originalPath: 'conv2d/bias', paramPath: 'conv/bias' },
{ originalPath: 'dense/weights', paramPath: 'fc' }
]
}
}
describe('NeuralNetwork', () => {
describe('getParamFromPath', () => {
it('returns correct params', () => tf.tidy(() => {
const convFilter = tf.tensor(0)
const convBias = tf.tensor(0)
const fcWeights = tf.tensor(0)
const net = new FakeNeuralNetwork(convFilter, convBias, fcWeights)
expect(net.getParamFromPath('conv/filter')).toEqual(convFilter)
expect(net.getParamFromPath('conv/bias')).toEqual(convBias)
expect(net.getParamFromPath('fc')).toEqual(fcWeights)
}))
it('throws if param is not a tensor', () => tf.tidy(() => {
const net = new FakeNeuralNetwork(null as any)
const fakePath = 'conv/filter'
expect(
() => net.getParamFromPath(fakePath)
).toThrowError(`traversePropertyPath - parameter is not a tensor, for path ${fakePath}`)
}))
it('throws if key path invalid', () => tf.tidy(() => {
const net = new FakeNeuralNetwork()
const fakePath = 'conv2d/foo'
expect(
() => net.getParamFromPath(fakePath)
).toThrowError(`traversePropertyPath - object does not have property conv2d, for path ${fakePath}`)
}))
})
describe('reassignParamFromPath', () => {
it('sets correct params', () => tf.tidy(() => {
const net = new FakeNeuralNetwork()
const convFilter = tf.tensor(0)
const convBias = tf.tensor(0)
const fcWeights = tf.tensor(0)
net.reassignParamFromPath('conv/filter', convFilter)
net.reassignParamFromPath('conv/bias', convBias)
net.reassignParamFromPath('fc', fcWeights)
expect(net.params.conv.filter).toEqual(convFilter)
expect(net.params.conv.bias).toEqual(convBias)
expect(net.params.fc).toEqual(fcWeights)
}))
it('throws if param is not a tensor', () => tf.tidy(() => {
const net = new FakeNeuralNetwork(null as any)
const fakePath = 'conv/filter'
expect(
() => net.reassignParamFromPath(fakePath, tf.tensor(0))
).toThrowError(`traversePropertyPath - parameter is not a tensor, for path ${fakePath}`)
}))
it('throws if key path invalid', () => tf.tidy(() => {
const net = new FakeNeuralNetwork()
const fakePath = 'conv2d/foo'
expect(
() => net.reassignParamFromPath(fakePath, tf.tensor(0))
).toThrowError(`traversePropertyPath - object does not have property conv2d, for path ${fakePath}`)
}))
})
describe('getParamList', () => {
it('returns param tensors with path', () => tf.tidy(() => {
const convFilter = tf.tensor(0)
const convBias = tf.tensor(0)
const fcWeights = tf.tensor(0)
const net = new FakeNeuralNetwork(convFilter, convBias, fcWeights)
const paramList = net.getParamList()
expect(paramList.length).toEqual(3)
expect(paramList[0].path).toEqual('conv/filter')
expect(paramList[1].path).toEqual('conv/bias')
expect(paramList[2].path).toEqual('fc')
expect(paramList[0].tensor).toEqual(convFilter)
expect(paramList[1].tensor).toEqual(convBias)
expect(paramList[2].tensor).toEqual(fcWeights)
}))
})
describe('getFrozenParams', () => {
it('returns all frozen params', () => tf.tidy(() => {
const convFilter = tf.tensor(0)
const convBias = tf.tensor(0)
const fcWeights = tf.variable(tf.scalar(0))
const net = new FakeNeuralNetwork(convFilter, convBias, fcWeights)
const frozenParams = net.getFrozenParams()
expect(frozenParams.length).toEqual(2)
expect(frozenParams[0].path).toEqual('conv/filter')
expect(frozenParams[1].path).toEqual('conv/bias')
expect(frozenParams[0].tensor).toEqual(convFilter)
expect(frozenParams[1].tensor).toEqual(convBias)
}))
})
describe('getTrainableParams', () => {
it('returns all trainable params', () => tf.tidy(() => {
const convFilter = tf.variable(tf.scalar(0))
const convBias = tf.variable(tf.scalar(0))
const fcWeights = tf.tensor(0)
const net = new FakeNeuralNetwork(convFilter, convBias, fcWeights)
const trainableParams = net.getTrainableParams()
expect(trainableParams.length).toEqual(2)
expect(trainableParams[0].path).toEqual('conv/filter')
expect(trainableParams[1].path).toEqual('conv/bias')
expect(trainableParams[0].tensor).toEqual(convFilter)
expect(trainableParams[1].tensor).toEqual(convBias)
}))
})
describe('dispose', () => {
it('disposes all param tensors', () => tf.tidy(() => {
const numTensors = tf.memory().numTensors
const net = new FakeNeuralNetwork()
net.dispose()
expect(net.params).toBe(undefined)
expect(tf.memory().numTensors - numTensors).toEqual(0)
}))
})
describe('variable', () => {
it('make all param tensors trainable', () => tf.tidy(() => {
const net = new FakeNeuralNetwork()
net.variable()
expect(net.params.conv.filter instanceof tf.Variable).toBe(true)
expect(net.params.conv.bias instanceof tf.Variable).toBe(true)
expect(net.params.fc instanceof tf.Variable).toBe(true)
}))
it('disposes old tensors', () => tf.tidy(() => {
const net = new FakeNeuralNetwork()
const numTensors = tf.memory().numTensors
net.variable()
expect(tf.memory().numTensors - numTensors).toEqual(0)
}))
})
describe('freeze', () => {
it('freezes all param variables', () => tf.tidy(() => {
const net = new FakeNeuralNetwork(
tf.variable(tf.scalar(0)),
tf.variable(tf.scalar(0)),
tf.variable(tf.scalar(0))
)
net.freeze()
expect(net.params.conv.filter instanceof tf.Variable).toBe(false)
expect(net.params.conv.bias instanceof tf.Variable).toBe(false)
expect(net.params.fc instanceof tf.Variable).toBe(false)
}))
it('disposes old tensors', () => tf.tidy(() => {
const net = new FakeNeuralNetwork(
tf.variable(tf.scalar(0)),
tf.variable(tf.scalar(0)),
tf.variable(tf.scalar(0))
)
const numTensors = tf.memory().numTensors
net.freeze()
expect(tf.memory().numTensors - numTensors).toEqual(0)
}))
})
})
{
"scripts": {
"start": "node server.js"
},
"author": "justadudewhohacks",
"license": "MIT",
"dependencies": {
"express": "^4.16.3",
"file-saver": "^1.3.8"
}
}
async function promiseSequential(promises) {
const curr = promises[0]
if (!curr) {
return
}
await curr()
return promiseSequential(promises.slice(1))
}
async function trainStep(batchCreators) {
await promiseSequential(batchCreators.map((batchCreator, dataIdx) => async () => {
const { batchInput, landmarksBatchTensor } = await batchCreator()
let ts = Date.now()
const cost = optimizer.minimize(() => {
const out = window.trainNet.forwardInput(batchInput.managed())
const loss = lossFunction(
landmarksBatchTensor,
out
)
return loss
}, true)
ts = Date.now() - ts
console.log(`loss[${dataIdx}]: ${await cost.data()}, ${ts} ms (${ts / batchInput.batchSize} ms / batch element)`)
landmarksBatchTensor.dispose()
cost.dispose()
await tf.nextFrame()
}))
}
function createBatchCreators(data, batchSize) {
if (batchSize < 1) {
throw new Error('invalid batch size: ' + batchSize)
}
const batches = []
const pushToBatch = (remaining) => {
if (remaining.length) {
batches.push(remaining.slice(0, batchSize))
pushToBatch(remaining.slice(batchSize))
}
return batches
}
pushToBatch(data)
const batchCreators = batches.map(dataForBatch => async () => {
const imgs = dataForBatch.map(d => d.img)
const allLandmarks = dataForBatch.map(d => landmarkPositionsToArray(d.landmarks))
const batchInput = await faceapi.toNetInput(imgs)
const landmarksBatchTensor = tf.tidy(() => {
const landmarkTensors = allLandmarks.map(arr => tf.tensor2d(arr, [1, 136]))
return tf.stack(landmarkTensors, 0).as2D(-1, 136)
})
return {
batchInput,
landmarksBatchTensor
}
})
return batchCreators
}
function landmarkPositionsToArray(landmarks) {
return landmarks.getRelativePositions().map(pt => [pt.x, pt.y])
.reduce((flat, arr) => flat.concat(arr))
}
function toFaceLandmarks(landmarks, { naturalWidth, naturalHeight }) {
return new faceapi.FaceLandmarks(
landmarks.map(l => new faceapi.Point(l.x / naturalWidth, l.y / naturalHeight)),
{ width: naturalWidth, height: naturalHeight }
)
}
async function loadImagesInBatch(allLandmarks, offset = 0) {
return Promise.all(allLandmarks.map(async (landmarks, i) => {
const imgUri = `/train_images/${i + offset}.png`
const img = await faceapi.bufferToImage(await fetchImage(imgUri))
return {
imgUri,
img,
landmarks: toFaceLandmarks(landmarks, img)
}
}))
}
async function getTrainData() {
const landmarksJson = (await (await fetch('/train_landmarks.json')).json())
const numLandmarks = Object.keys(landmarksJson).length
const allLandmarks = Array.from(
new Array(numLandmarks),
(_, i) => landmarksJson[i]
)
const batch1 = await loadImagesInBatch(allLandmarks.slice(0, 4000))
const batch2 = await loadImagesInBatch(allLandmarks.slice(4000), 4000)
return batch1.concat(batch2)
}
// https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array
function shuffle(a) {
var j, x, i;
for (i = a.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = a[i];
a[i] = a[j];
a[j] = x;
}
return a;
}
\ No newline at end of file
function onKeyDown(e) {
e.target.value = (
parseInt(e.target.value) + (e.keyCode === 38 ? 1 : (e.keyCode === 40 ? -1 : 0))
) || e.target.value || 0
const uri = '/train_images/' + e.target.value + '.png'
console.log(uri)
onSelectionChanged(uri)
}
function onChangeDrawLines(e) {
window.drawLines = $(e.target).prop('checked')
redraw()
}
async function onSelectionChanged(uri) {
const imgBuf = await fetchImage(uri)
window.currentImg = await faceapi.bufferToImage(imgBuf)
window.landmarks = await Promise.all(window.nets.map(
async net => net.detectLandmarks(window.currentImg)
))
redraw(uri)
}
function drawLandmarkCanvas(img, landmarks, drawOpts) {
const canvas = faceapi.createCanvasFromMedia(img)
$('#faceContainer').append(canvas)
faceapi.drawLandmarks(
canvas,
landmarks,
drawOpts
)
}
function redraw(uri) {
$('#faceContainer').empty()
const drawOpts = { lineWidth: window.drawLines ? 2 : 4, drawLines: window.drawLines }
window.landmarks.forEach(landmarks => {
drawLandmarkCanvas(window.currentImg, landmarks, drawOpts)
})
const trainImgAndLandmarks = window.trainData.find(t => t.imgUri === uri)
if (trainImgAndLandmarks) {
drawLandmarkCanvas(trainImgAndLandmarks.img, trainImgAndLandmarks.landmarks, drawOpts)
}
}
async function loadNet(file) {
const res = await fetch(file)
const weights = new Float32Array(await res.arrayBuffer())
return faceapi.faceLandmarkNet(weights)
}
async function init() {
//await faceapi.loadFaceLandmarkModel('/')
//window.nets.push(faceapi.landmarkNet)
//window.nets.push(await loadNet('retrained/landmarks_v0.weights'))
//window.nets.push(await loadNet('retrained/landmarks_v2.weights'))
window.trainNet = await loadNet('retrained/landmarks_v6.weights')
window.nets.push(trainNet)
$('#loader').hide()
await run()
await onSelectionChanged($('#selectList select').val())
}
$(document).ready(function() {
$('#imgByNr').keydown(onKeyDown);
renderFaceImageSelectList(
'#selectList',
onSelectionChanged,
{ className: 'sheldon', imageIdx: 1 }
)
init()
})
\ No newline at end of file
require('./.env')
const express = require('express')
const path = require('path')
const app = express()
const viewsDir = path.join(__dirname, 'views')
app.use(express.static(viewsDir))
app.use(express.static(path.join(__dirname, './public')))
app.use(express.static(path.join(__dirname, './tmp')))
app.use(express.static(path.join(__dirname, './node_modules/file-saver')))
app.use(express.static(path.join(__dirname, '../../examples/public')))
app.use(express.static(path.join(__dirname, '../../weights')))
app.use(express.static(path.join(__dirname, '../../dist')))
const trainDataPath = path.resolve(process.env.TRAIN_DATA_PATH)
app.use(express.static(trainDataPath))
app.get('/', (req, res) => res.redirect('/face_landmarks'))
app.get('/face_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'faceLandmarks.html')))
app.listen(3000, () => console.log('Listening on port 3000!'))
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script src="face-api.js"></script>
<script src="commons.js"></script>
<script src="faceLandmarksUi.js"></script>
<script src="faceLandmarksTrain.js"></script>
<script src="FileSaver.js"></script>
</head>
<body>
<div id="navbar"></div>
<div class="center-content page-container">
<div>
<div class="progress" id="loader">
<div class="indeterminate"></div>
</div>
<div class="row side-by-side">
<div class="center-content">
<div id="faceContainer"></div>
<div id="selectList"></div>
</div>
</div>
<p>
<input type="checkbox" id="drawLinesCheckbox" checked="checked" onchange="onChangeDrawLines(event)" />
<label for="drawLinesCheckbox">Draw Lines</label>
</p>
<div class="row">
<label for="imgByNr">Enter image NR: </label>
<input id="imgByNr" type="text" class="bold">
</div>
</div>
</div>
<script>
tf = faceapi.tf
window.saveEveryNthIteration = 2
window.drawLines = true
window.nets = []
window.landmarks = []
window.trainSteps = 100
window.learningRate = 0.01
//window.optimizer = tf.train.sgd(learningRate)
window.optimizer = tf.train.adam(0.001, 0.9, 0.999, 1e-8)
function lossFunction(labels, out) {
return tf.losses.meanSquaredError(labels, out)
}
async function run() {
window.trainData = await getTrainData()
window.trainNet.variable()
return
await train()
}
async function train(batchSize = 10) {
for (let i = 0; i < trainSteps; i++) {
console.log('step', i)
const batchCreators = createBatchCreators(shuffle(window.trainData), batchSize)
let ts = Date.now()
await trainStep(batchCreators)
ts = Date.now() - ts
console.log('step %s done (%s ms)', i, ts)
if (((i + 1) % saveEveryNthIteration) === 0) {
saveWeights(i)
}
}
}
function saveWeights(idx = 0) {
const binaryWeights = new Float32Array(
window.trainNet.getParamList()
.map(({ tensor }) => Array.from(tensor.dataSync()))
.reduce((flat, arr) => flat.concat(arr))
)
saveAs(new Blob([binaryWeights]), 'landmark_trained_weights_' + idx + '.weights')
}
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment