Commit 482becb0 by vincent

load quantized weights for face detection net

parent 91ad7ab0
...@@ -15201,6 +15201,28 @@ ...@@ -15201,6 +15201,28 @@
}); });
} }
function scale(x, params) {
return add(mul(x, params.weights), params.biases);
}
function convLayer(x, params, strides, withRelu, padding) {
if (padding === void 0) { padding = 'same'; }
var _a = params.conv, filters = _a.filters, bias = _a.bias;
var out = conv2d(x, filters, strides, padding);
out = add(out, bias);
out = scale(out, params.scale);
return withRelu ? relu(out) : out;
}
function conv(x, params) {
return convLayer(x, params, [1, 1], true);
}
function convNoRelu(x, params) {
return convLayer(x, params, [1, 1], false);
}
function convDown(x, params) {
return convLayer(x, params, [2, 2], true, 'valid');
}
function extractWeightsFactory(weights) { function extractWeightsFactory(weights) {
var remainingWeights = weights; var remainingWeights = weights;
function extractWeights(numWeights) { function extractWeights(numWeights) {
...@@ -15218,175 +15240,209 @@ ...@@ -15218,175 +15240,209 @@
} }
function extractorsFactory(extractWeights) { function extractorsFactory(extractWeights) {
function extractDepthwiseConvParams(numChannels) { function extractFilterValues(numFilterValues, numFilters, filterSize) {
var filters = tensor4d(extractWeights(3 * 3 * numChannels), [3, 3, numChannels, 1]); var weights = extractWeights(numFilterValues);
var batch_norm_scale = tensor1d(extractWeights(numChannels)); var depth = weights.length / (numFilters * filterSize * filterSize);
var batch_norm_offset = tensor1d(extractWeights(numChannels)); if (isFloat(depth)) {
var batch_norm_mean = tensor1d(extractWeights(numChannels)); throw new Error("depth has to be an integer: " + depth + ", weights.length: " + weights.length + ", numFilters: " + numFilters + ", filterSize: " + filterSize);
var batch_norm_variance = tensor1d(extractWeights(numChannels)); }
return { return transpose(tensor4d(weights, [numFilters, depth, filterSize, filterSize]), [2, 3, 1, 0]);
filters: filters,
batch_norm_scale: batch_norm_scale,
batch_norm_offset: batch_norm_offset,
batch_norm_mean: batch_norm_mean,
batch_norm_variance: batch_norm_variance
};
}
function extractConvParams(channelsIn, channelsOut, filterSize) {
var filters = tensor4d(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]);
var bias = tensor1d(extractWeights(channelsOut));
return {
filters: filters,
bias: bias
};
}
function extractPointwiseConvParams(channelsIn, channelsOut, filterSize) {
var _a = extractConvParams(channelsIn, channelsOut, filterSize), filters = _a.filters, bias = _a.bias;
return {
filters: filters,
batch_norm_offset: bias
};
} }
function extractConvPairParams(channelsIn, channelsOut) { function extractScaleLayerParams(numWeights) {
var depthwise_conv_params = extractDepthwiseConvParams(channelsIn); var weights = tensor1d(extractWeights(numWeights));
var pointwise_conv_params = extractPointwiseConvParams(channelsIn, channelsOut, 1); var biases = tensor1d(extractWeights(numWeights));
return { return {
depthwise_conv_params: depthwise_conv_params, weights: weights,
pointwise_conv_params: pointwise_conv_params biases: biases
}; };
} }
function extractMobilenetV1Params() { function extractConvLayerParams(numFilterValues, numFilters, filterSize) {
var conv_0_params = extractPointwiseConvParams(3, 32, 3); var conv_filters = extractFilterValues(numFilterValues, numFilters, filterSize);
var channelNumPairs = [ var conv_bias = tensor1d(extractWeights(numFilters));
[32, 64], var scale = extractScaleLayerParams(numFilters);
[64, 128],
[128, 128],
[128, 256],
[256, 256],
[256, 512],
[512, 512],
[512, 512],
[512, 512],
[512, 512],
[512, 512],
[512, 1024],
[1024, 1024]
];
var conv_pair_params = channelNumPairs.map(function (_a) {
var channelsIn = _a[0], channelsOut = _a[1];
return extractConvPairParams(channelsIn, channelsOut);
});
return { return {
conv_0_params: conv_0_params, conv: {
conv_pair_params: conv_pair_params filters: conv_filters,
bias: conv_bias
},
scale: scale
}; };
} }
function extractPredictionLayerParams() { function extractResidualLayerParams(numFilterValues, numFilters, filterSize, isDown) {
var conv_0_params = extractPointwiseConvParams(1024, 256, 1); if (isDown === void 0) { isDown = false; }
var conv_1_params = extractPointwiseConvParams(256, 512, 3); var conv1 = extractConvLayerParams((isDown ? 0.5 : 1) * numFilterValues, numFilters, filterSize);
var conv_2_params = extractPointwiseConvParams(512, 128, 1); var conv2 = extractConvLayerParams(numFilterValues, numFilters, filterSize);
var conv_3_params = extractPointwiseConvParams(128, 256, 3);
var conv_4_params = extractPointwiseConvParams(256, 128, 1);
var conv_5_params = extractPointwiseConvParams(128, 256, 3);
var conv_6_params = extractPointwiseConvParams(256, 64, 1);
var conv_7_params = extractPointwiseConvParams(64, 128, 3);
var box_encoding_0_predictor_params = extractConvParams(512, 12, 1);
var class_predictor_0_params = extractConvParams(512, 9, 1);
var box_encoding_1_predictor_params = extractConvParams(1024, 24, 1);
var class_predictor_1_params = extractConvParams(1024, 18, 1);
var box_encoding_2_predictor_params = extractConvParams(512, 24, 1);
var class_predictor_2_params = extractConvParams(512, 18, 1);
var box_encoding_3_predictor_params = extractConvParams(256, 24, 1);
var class_predictor_3_params = extractConvParams(256, 18, 1);
var box_encoding_4_predictor_params = extractConvParams(256, 24, 1);
var class_predictor_4_params = extractConvParams(256, 18, 1);
var box_encoding_5_predictor_params = extractConvParams(128, 24, 1);
var class_predictor_5_params = extractConvParams(128, 18, 1);
var box_predictor_0_params = {
box_encoding_predictor_params: box_encoding_0_predictor_params,
class_predictor_params: class_predictor_0_params
};
var box_predictor_1_params = {
box_encoding_predictor_params: box_encoding_1_predictor_params,
class_predictor_params: class_predictor_1_params
};
var box_predictor_2_params = {
box_encoding_predictor_params: box_encoding_2_predictor_params,
class_predictor_params: class_predictor_2_params
};
var box_predictor_3_params = {
box_encoding_predictor_params: box_encoding_3_predictor_params,
class_predictor_params: class_predictor_3_params
};
var box_predictor_4_params = {
box_encoding_predictor_params: box_encoding_4_predictor_params,
class_predictor_params: class_predictor_4_params
};
var box_predictor_5_params = {
box_encoding_predictor_params: box_encoding_5_predictor_params,
class_predictor_params: class_predictor_5_params
};
return { return {
conv_0_params: conv_0_params, conv1: conv1,
conv_1_params: conv_1_params, conv2: conv2
conv_2_params: conv_2_params,
conv_3_params: conv_3_params,
conv_4_params: conv_4_params,
conv_5_params: conv_5_params,
conv_6_params: conv_6_params,
conv_7_params: conv_7_params,
box_predictor_0_params: box_predictor_0_params,
box_predictor_1_params: box_predictor_1_params,
box_predictor_2_params: box_predictor_2_params,
box_predictor_3_params: box_predictor_3_params,
box_predictor_4_params: box_predictor_4_params,
box_predictor_5_params: box_predictor_5_params
}; };
} }
return { return {
extractMobilenetV1Params: extractMobilenetV1Params, extractConvLayerParams: extractConvLayerParams,
extractPredictionLayerParams: extractPredictionLayerParams extractResidualLayerParams: extractResidualLayerParams
}; };
} }
function extractParams(weights) { function extractParams(weights) {
var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights;
var _b = extractorsFactory(extractWeights), extractMobilenetV1Params = _b.extractMobilenetV1Params, extractPredictionLayerParams = _b.extractPredictionLayerParams; var _b = extractorsFactory(extractWeights), extractConvLayerParams = _b.extractConvLayerParams, extractResidualLayerParams = _b.extractResidualLayerParams;
var mobilenetv1_params = extractMobilenetV1Params(); var conv32_down = extractConvLayerParams(4704, 32, 7);
var prediction_layer_params = extractPredictionLayerParams(); var conv32_1 = extractResidualLayerParams(9216, 32, 3);
var extra_dim = tensor3d(extractWeights(5118 * 4), [1, 5118, 4]); var conv32_2 = extractResidualLayerParams(9216, 32, 3);
var output_layer_params = { var conv32_3 = extractResidualLayerParams(9216, 32, 3);
extra_dim: extra_dim var conv64_down = extractResidualLayerParams(36864, 64, 3, true);
}; var conv64_1 = extractResidualLayerParams(36864, 64, 3);
var conv64_2 = extractResidualLayerParams(36864, 64, 3);
var conv64_3 = extractResidualLayerParams(36864, 64, 3);
var conv128_down = extractResidualLayerParams(147456, 128, 3, true);
var conv128_1 = extractResidualLayerParams(147456, 128, 3);
var conv128_2 = extractResidualLayerParams(147456, 128, 3);
var conv256_down = extractResidualLayerParams(589824, 256, 3, true);
var conv256_1 = extractResidualLayerParams(589824, 256, 3);
var conv256_2 = extractResidualLayerParams(589824, 256, 3);
var conv256_down_out = extractResidualLayerParams(589824, 256, 3);
var fc = transpose(tensor2d(extractWeights(256 * 128), [128, 256]), [1, 0]);
if (getRemainingWeights().length !== 0) { if (getRemainingWeights().length !== 0) {
throw new Error("weights remaing after extract: " + getRemainingWeights().length); throw new Error("weights remaing after extract: " + getRemainingWeights().length);
} }
return { return {
mobilenetv1_params: mobilenetv1_params, conv32_down: conv32_down,
prediction_layer_params: prediction_layer_params, conv32_1: conv32_1,
output_layer_params: output_layer_params conv32_2: conv32_2,
conv32_3: conv32_3,
conv64_down: conv64_down,
conv64_1: conv64_1,
conv64_2: conv64_2,
conv64_3: conv64_3,
conv128_down: conv128_down,
conv128_1: conv128_1,
conv128_2: conv128_2,
conv256_down: conv256_down,
conv256_1: conv256_1,
conv256_2: conv256_2,
conv256_down_out: conv256_down_out,
fc: fc
}; };
} }
var Rect = /** @class */ (function () { function normalize(x) {
function Rect(x, y, width, height) { return tidy(function () {
this.x = x; var avg_r = fill([1, 150, 150, 1], 122.782);
this.y = y; var avg_g = fill([1, 150, 150, 1], 117.001);
this.width = width; var avg_b = fill([1, 150, 150, 1], 104.298);
this.height = height; var avg_rgb = concat([avg_r, avg_g, avg_b], 3);
} return div(sub(x, avg_rgb), scalar(256));
Rect.prototype.floor = function () { });
return new Rect(Math.floor(this.x), Math.floor(this.y), Math.floor(this.width), Math.floor(this.height)); }
};
return Rect;
}());
var FaceDetection = /** @class */ (function () { function residual(x, params) {
function FaceDetection(score, relativeBox, imageDims) { var out = conv(x, params.conv1);
var width = imageDims.width, height = imageDims.height; out = convNoRelu(out, params.conv2);
this._imageWidth = width; out = add(out, x);
this._imageHeight = height; out = relu(out);
this._score = score; return out;
this._box = new Rect(relativeBox.x * width, relativeBox.y * height, relativeBox.width * width, relativeBox.height * height); }
function residualDown(x, params) {
var out = convDown(x, params.conv1);
out = convNoRelu(out, params.conv2);
var pooled = avgPool(x, 2, 2, 'valid');
var zeros$$1 = zeros(pooled.shape);
var isPad = pooled.shape[3] !== out.shape[3];
var isAdjustShape = pooled.shape[1] !== out.shape[1] || pooled.shape[2] !== out.shape[2];
if (isAdjustShape) {
var padShapeX = out.shape.slice();
padShapeX[1] = 1;
var zerosW = zeros(padShapeX);
out = concat([out, zerosW], 1);
var padShapeY = out.shape.slice();
padShapeY[2] = 1;
var zerosH = zeros(padShapeY);
out = concat([out, zerosH], 2);
}
pooled = isPad ? concat([pooled, zeros$$1], 3) : pooled;
out = add(pooled, out);
out = relu(out);
return out;
}
function faceRecognitionNet(weights) {
var _this = this;
var params = extractParams(weights);
function forward(input) {
return tidy(function () {
var x = padToSquare(getImageTensor(input), true);
// work with 150 x 150 sized face images
if (x.shape[1] !== 150 || x.shape[2] !== 150) {
x = image.resizeBilinear(x, [150, 150]);
}
x = normalize(x);
var out = convDown(x, params.conv32_down);
out = maxPool(out, 3, 2, 'valid');
out = residual(out, params.conv32_1);
out = residual(out, params.conv32_2);
out = residual(out, params.conv32_3);
out = residualDown(out, params.conv64_down);
out = residual(out, params.conv64_1);
out = residual(out, params.conv64_2);
out = residual(out, params.conv64_3);
out = residualDown(out, params.conv128_down);
out = residual(out, params.conv128_1);
out = residual(out, params.conv128_2);
out = residualDown(out, params.conv256_down);
out = residual(out, params.conv256_1);
out = residual(out, params.conv256_2);
out = residualDown(out, params.conv256_down_out);
var globalAvg = out.mean([1, 2]);
var fullyConnected = matMul(globalAvg, params.fc);
return fullyConnected;
});
}
var computeFaceDescriptor = function (input) { return __awaiter$e(_this, void 0, void 0, function () {
var result, data;
return __generator$e(this, function (_a) {
switch (_a.label) {
case 0:
result = forward(input);
return [4 /*yield*/, result.data()];
case 1:
data = _a.sent();
result.dispose();
return [2 /*return*/, data];
}
});
}); };
var computeFaceDescriptorSync = function (input) {
var result = forward(input);
var data = result.dataSync();
result.dispose();
return data;
};
return {
computeFaceDescriptor: computeFaceDescriptor,
computeFaceDescriptorSync: computeFaceDescriptorSync,
forward: forward
};
}
var Rect = /** @class */ (function () {
function Rect(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
Rect.prototype.floor = function () {
return new Rect(Math.floor(this.x), Math.floor(this.y), Math.floor(this.width), Math.floor(this.height));
};
return Rect;
}());
var FaceDetection = /** @class */ (function () {
function FaceDetection(score, relativeBox, imageDims) {
var width = imageDims.width, height = imageDims.height;
this._imageWidth = width;
this._imageHeight = height;
this._score = score;
this._box = new Rect(relativeBox.x * width, relativeBox.y * height, relativeBox.width * width, relativeBox.height * height);
} }
FaceDetection.prototype.getScore = function () { FaceDetection.prototype.getScore = function () {
return this._score; return this._score;
...@@ -15409,538 +15465,682 @@ ...@@ -15409,538 +15465,682 @@
return FaceDetection; return FaceDetection;
}()); }());
function pointwiseConvLayer(x, params, strides) { /**
return tidy(function () { * Extracts the image regions containing the detected faces.
var out = conv2d(x, params.filters, strides, 'same'); *
out = add(out, params.batch_norm_offset); * @param input The image that face detection has been performed on.
return clipByValue(out, 0, 6); * @param detections The face detection results or face bounding boxes for that image.
* @returns The Canvases of the corresponding image region for each detected face.
*/
function extractFaces(image, detections) {
var ctx = getContext2dOrThrow(image);
var boxes = detections.map(function (det) { return det instanceof FaceDetection
? det.forSize(image.width, image.height).getBox().floor()
: det; });
return boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var faceImg = createCanvas({ width: width, height: height });
getContext2dOrThrow(faceImg)
.putImageData(ctx.getImageData(x, y, width, height), 0, 0);
return faceImg;
}); });
} }
var epsilon = 0.0010000000474974513; /**
function depthwiseConvLayer(x, params, strides) { * Extracts the tensors of the image regions containing the detected faces.
return tidy(function () { * Useful if you want to compute the face descriptors for the face images.
var out = depthwiseConv2d(x, params.filters, strides, 'same'); * Using this method is faster then extracting a canvas for each face and
out = batchNormalization(out, params.batch_norm_mean, params.batch_norm_variance, epsilon, params.batch_norm_scale, params.batch_norm_offset); * converting them to tensors individually.
return clipByValue(out, 0, 6); *
}); * @param input The image that face detection has been performed on.
} * @param detections The face detection results or face bounding boxes for that image.
function getStridesForLayerIdx(layerIdx) { * @returns Tensors of the corresponding image region for each detected face.
return [2, 4, 6, 12].some(function (idx) { return idx === layerIdx; }) ? [2, 2] : [1, 1]; */
} function extractFaceTensors(image$$1, detections) {
function mobileNetV1(x, params) {
return tidy(function () { return tidy(function () {
var conv11 = null; var imgTensor = getImageTensor(image$$1);
var out = pointwiseConvLayer(x, params.conv_0_params, [2, 2]); // TODO handle batches
params.conv_pair_params.forEach(function (param, i) { var _a = imgTensor.shape, batchSize = _a[0], imgHeight = _a[1], imgWidth = _a[2], numChannels = _a[3];
var layerIdx = i + 1; var boxes = detections.map(function (det) { return det instanceof FaceDetection
var depthwiseConvStrides = getStridesForLayerIdx(layerIdx); ? det.forSize(imgWidth, imgHeight).getBox().floor()
out = depthwiseConvLayer(out, param.depthwise_conv_params, depthwiseConvStrides); : det; });
out = pointwiseConvLayer(out, param.pointwise_conv_params, [1, 1]); var faceTensors = boxes.map(function (_a) {
if (layerIdx === 11) { var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
conv11 = out; return slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels]);
}
}); });
if (conv11 === null) { return faceTensors;
throw new Error('mobileNetV1 - output of conv layer 11 is null');
}
return {
out: out,
conv11: conv11
};
}); });
} }
function nonMaxSuppression(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold) { function extractorsFactory$1(extractWeights) {
var numBoxes = boxes.shape[0]; function extractDepthwiseConvParams(numChannels) {
var outputSize = Math.min(maxOutputSize, numBoxes); var filters = tensor4d(extractWeights(3 * 3 * numChannels), [3, 3, numChannels, 1]);
var candidates = scores var batch_norm_scale = tensor1d(extractWeights(numChannels));
.map(function (score, boxIndex) { return ({ score: score, boxIndex: boxIndex }); }) var batch_norm_offset = tensor1d(extractWeights(numChannels));
.filter(function (c) { return c.score > scoreThreshold; }) var batch_norm_mean = tensor1d(extractWeights(numChannels));
.sort(function (c1, c2) { return c2.score - c1.score; }); var batch_norm_variance = tensor1d(extractWeights(numChannels));
var suppressFunc = function (x) { return x <= iouThreshold ? 1 : 0; }; return {
var selected = []; filters: filters,
candidates.forEach(function (c) { batch_norm_scale: batch_norm_scale,
if (selected.length >= outputSize) { batch_norm_offset: batch_norm_offset,
return; batch_norm_mean: batch_norm_mean,
} batch_norm_variance: batch_norm_variance
var originalScore = c.score; };
for (var j = selected.length - 1; j >= 0; --j) {
var iou = IOU(boxes, c.boxIndex, selected[j]);
if (iou === 0.0) {
continue;
}
c.score *= suppressFunc(iou);
if (c.score <= scoreThreshold) {
break;
}
}
if (originalScore === c.score) {
selected.push(c.boxIndex);
}
});
return selected;
}
function IOU(boxes, i, j) {
var yminI = Math.min(boxes.get(i, 0), boxes.get(i, 2));
var xminI = Math.min(boxes.get(i, 1), boxes.get(i, 3));
var ymaxI = Math.max(boxes.get(i, 0), boxes.get(i, 2));
var xmaxI = Math.max(boxes.get(i, 1), boxes.get(i, 3));
var yminJ = Math.min(boxes.get(j, 0), boxes.get(j, 2));
var xminJ = Math.min(boxes.get(j, 1), boxes.get(j, 3));
var ymaxJ = Math.max(boxes.get(j, 0), boxes.get(j, 2));
var xmaxJ = Math.max(boxes.get(j, 1), boxes.get(j, 3));
var areaI = (ymaxI - yminI) * (xmaxI - xminI);
var areaJ = (ymaxJ - yminJ) * (xmaxJ - xminJ);
if (areaI <= 0 || areaJ <= 0) {
return 0.0;
} }
var intersectionYmin = Math.max(yminI, yminJ); function extractConvParams(channelsIn, channelsOut, filterSize) {
var intersectionXmin = Math.max(xminI, xminJ); var filters = tensor4d(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]);
var intersectionYmax = Math.min(ymaxI, ymaxJ); var bias = tensor1d(extractWeights(channelsOut));
var intersectionXmax = Math.min(xmaxI, xmaxJ);
var intersectionArea = Math.max(intersectionYmax - intersectionYmin, 0.0) *
Math.max(intersectionXmax - intersectionXmin, 0.0);
return intersectionArea / (areaI + areaJ - intersectionArea);
}
function getCenterCoordinatesAndSizesLayer(x) {
var vec = unstack(transpose(x, [1, 0]));
var sizes = [
sub(vec[2], vec[0]),
sub(vec[3], vec[1])
];
var centers = [
add(vec[0], div(sizes[0], scalar(2))),
add(vec[1], div(sizes[1], scalar(2)))
];
return {
sizes: sizes,
centers: centers
};
}
function decodeBoxesLayer(x0, x1) {
var _a = getCenterCoordinatesAndSizesLayer(x0), sizes = _a.sizes, centers = _a.centers;
var vec = unstack(transpose(x1, [1, 0]));
var div0_out = div(mul(exp(div(vec[2], scalar(5))), sizes[0]), scalar(2));
var add0_out = add(mul(div(vec[0], scalar(10)), sizes[0]), centers[0]);
var div1_out = div(mul(exp(div(vec[3], scalar(5))), sizes[1]), scalar(2));
var add1_out = add(mul(div(vec[1], scalar(10)), sizes[1]), centers[1]);
return transpose(stack([
sub(add0_out, div0_out),
sub(add1_out, div1_out),
add(add0_out, div0_out),
add(add1_out, div1_out)
]), [1, 0]);
}
function outputLayer(boxPredictions, classPredictions, params) {
return tidy(function () {
var batchSize = boxPredictions.shape[0];
var boxes = decodeBoxesLayer(reshape(tile(params.extra_dim, [batchSize, 1, 1]), [-1, 4]), reshape(boxPredictions, [-1, 4]));
boxes = reshape(boxes, [batchSize, (boxes.shape[0] / batchSize), 4]);
var scoresAndClasses = sigmoid(slice(classPredictions, [0, 0, 1], [-1, -1, -1]));
var scores = slice(scoresAndClasses, [0, 0, 0], [-1, -1, 1]);
scores = reshape(scores, [batchSize, scores.shape[1]]);
var boxesByBatch = unstack(boxes);
var scoresByBatch = unstack(scores);
return { return {
boxes: boxesByBatch, filters: filters,
scores: scoresByBatch bias: bias
}; };
}); }
} function extractPointwiseConvParams(channelsIn, channelsOut, filterSize) {
var _a = extractConvParams(channelsIn, channelsOut, filterSize), filters = _a.filters, bias = _a.bias;
function convLayer(x, params, padding, withRelu) {
if (padding === void 0) { padding = 'same'; }
if (withRelu === void 0) { withRelu = false; }
return tidy(function () {
var out = add(conv2d(x, params.filters, [1, 1], padding), params.bias);
return withRelu ? relu(out) : out;
});
}
function boxPredictionLayer(x, params) {
return tidy(function () {
var batchSize = x.shape[0];
var boxPredictionEncoding = reshape(convLayer(x, params.box_encoding_predictor_params), [batchSize, -1, 1, 4]);
var classPrediction = reshape(convLayer(x, params.class_predictor_params), [batchSize, -1, 3]);
return { return {
boxPredictionEncoding: boxPredictionEncoding, filters: filters,
classPrediction: classPrediction batch_norm_offset: bias
}; };
}); }
} function extractConvPairParams(channelsIn, channelsOut) {
var depthwise_conv_params = extractDepthwiseConvParams(channelsIn);
function predictionLayer(x, conv11, params) { var pointwise_conv_params = extractPointwiseConvParams(channelsIn, channelsOut, 1);
return tidy(function () {
var conv0 = pointwiseConvLayer(x, params.conv_0_params, [1, 1]);
var conv1 = pointwiseConvLayer(conv0, params.conv_1_params, [2, 2]);
var conv2 = pointwiseConvLayer(conv1, params.conv_2_params, [1, 1]);
var conv3 = pointwiseConvLayer(conv2, params.conv_3_params, [2, 2]);
var conv4 = pointwiseConvLayer(conv3, params.conv_4_params, [1, 1]);
var conv5 = pointwiseConvLayer(conv4, params.conv_5_params, [2, 2]);
var conv6 = pointwiseConvLayer(conv5, params.conv_6_params, [1, 1]);
var conv7 = pointwiseConvLayer(conv6, params.conv_7_params, [2, 2]);
var boxPrediction0 = boxPredictionLayer(conv11, params.box_predictor_0_params);
var boxPrediction1 = boxPredictionLayer(x, params.box_predictor_1_params);
var boxPrediction2 = boxPredictionLayer(conv1, params.box_predictor_2_params);
var boxPrediction3 = boxPredictionLayer(conv3, params.box_predictor_3_params);
var boxPrediction4 = boxPredictionLayer(conv5, params.box_predictor_4_params);
var boxPrediction5 = boxPredictionLayer(conv7, params.box_predictor_5_params);
var boxPredictions = concat([
boxPrediction0.boxPredictionEncoding,
boxPrediction1.boxPredictionEncoding,
boxPrediction2.boxPredictionEncoding,
boxPrediction3.boxPredictionEncoding,
boxPrediction4.boxPredictionEncoding,
boxPrediction5.boxPredictionEncoding
], 1);
var classPredictions = concat([
boxPrediction0.classPrediction,
boxPrediction1.classPrediction,
boxPrediction2.classPrediction,
boxPrediction3.classPrediction,
boxPrediction4.classPrediction,
boxPrediction5.classPrediction
], 1);
return { return {
boxPredictions: boxPredictions, depthwise_conv_params: depthwise_conv_params,
classPredictions: classPredictions pointwise_conv_params: pointwise_conv_params
}; };
}); }
} function extractMobilenetV1Params() {
var conv_0_params = extractPointwiseConvParams(3, 32, 3);
var resizedImageSize = [512, 512]; var channelNumPairs = [
var weight = scalar(0.007843137718737125); [32, 64],
var bias = scalar(1); [64, 128],
function resizeLayer(x) { [128, 128],
return tidy(function () { [128, 256],
var resized = image.resizeBilinear(x, resizedImageSize, false); [256, 256],
return sub(mul(resized, weight), bias); [256, 512],
}); [512, 512],
} [512, 512],
[512, 512],
function faceDetectionNet(weights) { [512, 512],
var params = extractParams(weights); [512, 512],
function forwardTensor(imgTensor) { [512, 1024],
return tidy(function () { [1024, 1024]
var resized = resizeLayer(imgTensor); ];
var features = mobileNetV1(resized, params.mobilenetv1_params); var conv_pair_params = channelNumPairs.map(function (_a) {
var _a = predictionLayer(features.out, features.conv11, params.prediction_layer_params), boxPredictions = _a.boxPredictions, classPredictions = _a.classPredictions; var channelsIn = _a[0], channelsOut = _a[1];
return outputLayer(boxPredictions, classPredictions, params.output_layer_params); return extractConvPairParams(channelsIn, channelsOut);
}); });
return {
conv_0_params: conv_0_params,
conv_pair_params: conv_pair_params
};
} }
function forward(input) { function extractPredictionLayerParams() {
return tidy(function () { return forwardTensor(padToSquare(getImageTensor(input))); }); var conv_0_params = extractPointwiseConvParams(1024, 256, 1);
var conv_1_params = extractPointwiseConvParams(256, 512, 3);
var conv_2_params = extractPointwiseConvParams(512, 128, 1);
var conv_3_params = extractPointwiseConvParams(128, 256, 3);
var conv_4_params = extractPointwiseConvParams(256, 128, 1);
var conv_5_params = extractPointwiseConvParams(128, 256, 3);
var conv_6_params = extractPointwiseConvParams(256, 64, 1);
var conv_7_params = extractPointwiseConvParams(64, 128, 3);
var box_encoding_0_predictor_params = extractConvParams(512, 12, 1);
var class_predictor_0_params = extractConvParams(512, 9, 1);
var box_encoding_1_predictor_params = extractConvParams(1024, 24, 1);
var class_predictor_1_params = extractConvParams(1024, 18, 1);
var box_encoding_2_predictor_params = extractConvParams(512, 24, 1);
var class_predictor_2_params = extractConvParams(512, 18, 1);
var box_encoding_3_predictor_params = extractConvParams(256, 24, 1);
var class_predictor_3_params = extractConvParams(256, 18, 1);
var box_encoding_4_predictor_params = extractConvParams(256, 24, 1);
var class_predictor_4_params = extractConvParams(256, 18, 1);
var box_encoding_5_predictor_params = extractConvParams(128, 24, 1);
var class_predictor_5_params = extractConvParams(128, 18, 1);
var box_predictor_0_params = {
box_encoding_predictor_params: box_encoding_0_predictor_params,
class_predictor_params: class_predictor_0_params
};
var box_predictor_1_params = {
box_encoding_predictor_params: box_encoding_1_predictor_params,
class_predictor_params: class_predictor_1_params
};
var box_predictor_2_params = {
box_encoding_predictor_params: box_encoding_2_predictor_params,
class_predictor_params: class_predictor_2_params
};
var box_predictor_3_params = {
box_encoding_predictor_params: box_encoding_3_predictor_params,
class_predictor_params: class_predictor_3_params
};
var box_predictor_4_params = {
box_encoding_predictor_params: box_encoding_4_predictor_params,
class_predictor_params: class_predictor_4_params
};
var box_predictor_5_params = {
box_encoding_predictor_params: box_encoding_5_predictor_params,
class_predictor_params: class_predictor_5_params
};
return {
conv_0_params: conv_0_params,
conv_1_params: conv_1_params,
conv_2_params: conv_2_params,
conv_3_params: conv_3_params,
conv_4_params: conv_4_params,
conv_5_params: conv_5_params,
conv_6_params: conv_6_params,
conv_7_params: conv_7_params,
box_predictor_0_params: box_predictor_0_params,
box_predictor_1_params: box_predictor_1_params,
box_predictor_2_params: box_predictor_2_params,
box_predictor_3_params: box_predictor_3_params,
box_predictor_4_params: box_predictor_4_params,
box_predictor_5_params: box_predictor_5_params
};
} }
function locateFaces(input, minConfidence, maxResults) { return {
if (minConfidence === void 0) { minConfidence = 0.8; } extractMobilenetV1Params: extractMobilenetV1Params,
if (maxResults === void 0) { maxResults = 100; } extractPredictionLayerParams: extractPredictionLayerParams
return __awaiter$e(this, void 0, void 0, function () { };
var paddedHeightRelative, paddedWidthRelative, imageDimensions, _a, _boxes, _scores, boxes, scores, i, scoresData, _b, _c, iouThreshold, indices, results; }
return __generator$e(this, function (_d) { function extractParams$1(weights) {
switch (_d.label) { var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights;
case 0: var _b = extractorsFactory$1(extractWeights), extractMobilenetV1Params = _b.extractMobilenetV1Params, extractPredictionLayerParams = _b.extractPredictionLayerParams;
paddedHeightRelative = 1, paddedWidthRelative = 1; var mobilenetv1_params = extractMobilenetV1Params();
_a = tidy(function () { var prediction_layer_params = extractPredictionLayerParams();
var imgTensor = getImageTensor(input); var extra_dim = tensor3d(extractWeights(5118 * 4), [1, 5118, 4]);
var _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1]; var output_layer_params = {
imageDimensions = { width: width, height: height }; extra_dim: extra_dim
imgTensor = padToSquare(imgTensor); };
paddedHeightRelative = imgTensor.shape[1] / height; if (getRemainingWeights().length !== 0) {
paddedWidthRelative = imgTensor.shape[2] / width; throw new Error("weights remaing after extract: " + getRemainingWeights().length);
return forwardTensor(imgTensor);
}), _boxes = _a.boxes, _scores = _a.scores;
boxes = _boxes[0];
scores = _scores[0];
for (i = 1; i < _boxes.length; i++) {
_boxes[i].dispose();
_scores[i].dispose();
}
_c = (_b = Array).from;
return [4 /*yield*/, scores.data()];
case 1:
scoresData = _c.apply(_b, [_d.sent()]);
iouThreshold = 0.5;
indices = nonMaxSuppression(boxes, scoresData, maxResults, iouThreshold, minConfidence);
results = indices
.map(function (idx) {
var _a = [
Math.max(0, boxes.get(idx, 0)),
Math.min(1.0, boxes.get(idx, 2))
].map(function (val) { return val * paddedHeightRelative; }), top = _a[0], bottom = _a[1];
var _b = [
Math.max(0, boxes.get(idx, 1)),
Math.min(1.0, boxes.get(idx, 3))
].map(function (val) { return val * paddedWidthRelative; }), left = _b[0], right = _b[1];
return new FaceDetection(scoresData[idx], new Rect(left, top, right - left, bottom - top), imageDimensions);
});
boxes.dispose();
scores.dispose();
return [2 /*return*/, results];
}
});
});
} }
return { return {
forward: forward, mobilenetv1_params: mobilenetv1_params,
locateFaces: locateFaces prediction_layer_params: prediction_layer_params,
output_layer_params: output_layer_params
}; };
} }
function scale(x, params) { function isTensor(tensor$$1, dim) {
return add(mul(x, params.weights), params.biases); return tensor$$1 instanceof Tensor && tensor$$1.shape.length === dim;
} }
function isTensor1D(tensor$$1) {
function convLayer$1(x, params, strides, withRelu, padding) { return isTensor(tensor$$1, 1);
if (padding === void 0) { padding = 'same'; }
var _a = params.conv, filters = _a.filters, bias = _a.bias;
var out = conv2d(x, filters, strides, padding);
out = add(out, bias);
out = scale(out, params.scale);
return withRelu ? relu(out) : out;
} }
function conv(x, params) { function isTensor2D(tensor$$1) {
return convLayer$1(x, params, [1, 1], true); return isTensor(tensor$$1, 2);
} }
function convNoRelu(x, params) { function isTensor3D(tensor$$1) {
return convLayer$1(x, params, [1, 1], false); return isTensor(tensor$$1, 3);
} }
function convDown(x, params) { function isTensor4D(tensor$$1) {
return convLayer$1(x, params, [2, 2], true, 'valid'); return isTensor(tensor$$1, 4);
} }
function extractorsFactory$1(extractWeights) { function getModelUris(uri, defaultModelName) {
function extractFilterValues(numFilterValues, numFilters, filterSize) { var parts = (uri || '').split('/');
var weights = extractWeights(numFilterValues); var modelBaseUri = ((uri || '').endsWith('.json')
var depth = weights.length / (numFilters * filterSize * filterSize); ? parts.slice(0, parts.length - 1)
if (isFloat(depth)) { : parts).filter(function (s) { return s; }).join('/');
throw new Error("depth has to be an integer: " + depth + ", weights.length: " + weights.length + ", numFilters: " + numFilters + ", filterSize: " + filterSize); var defaultManifestFilename = defaultModelName + "-weights_manifest.json";
} var manifestUri = !uri || !modelBaseUri
return transpose(tensor4d(weights, [numFilters, depth, filterSize, filterSize]), [2, 3, 1, 0]); ? defaultManifestFilename
} : (uri.endsWith('.json')
function extractScaleLayerParams(numWeights) { ? uri
var weights = tensor1d(extractWeights(numWeights)); : modelBaseUri + "/" + defaultManifestFilename);
var biases = tensor1d(extractWeights(numWeights)); return { manifestUri: manifestUri, modelBaseUri: modelBaseUri };
return { }
weights: weights, function loadWeightMap(uri, defaultModelName) {
biases: biases return __awaiter$e(this, void 0, void 0, function () {
}; var _a, manifestUri, modelBaseUri, manifest;
} return __generator$e(this, function (_b) {
function extractConvLayerParams(numFilterValues, numFilters, filterSize) { switch (_b.label) {
var conv_filters = extractFilterValues(numFilterValues, numFilters, filterSize); case 0:
var conv_bias = tensor1d(extractWeights(numFilters)); _a = getModelUris(uri, defaultModelName), manifestUri = _a.manifestUri, modelBaseUri = _a.modelBaseUri;
var scale = extractScaleLayerParams(numFilters); return [4 /*yield*/, fetch(manifestUri)];
return { case 1: return [4 /*yield*/, (_b.sent()).json()];
conv: { case 2:
filters: conv_filters, manifest = _b.sent();
bias: conv_bias return [2 /*return*/, loadWeights(manifest, modelBaseUri)];
}, }
scale: scale });
});
}
var DEFAULT_MODEL_NAME = 'face_detection_model';
function extractorsFactory$2(weightMap) {
function extractPointwiseConvParams(prefix, idx) {
var pointwise_conv_params = {
filters: weightMap[prefix + "/Conv2d_" + idx + "_pointwise/weights"],
batch_norm_offset: weightMap[prefix + "/Conv2d_" + idx + "_pointwise/convolution_bn_offset"]
}; };
if (!isTensor4D(pointwise_conv_params.filters)) {
throw new Error("expected weightMap[" + prefix + "/Conv2d_" + idx + "_pointwise/weights] to be a Tensor4D, instead have " + pointwise_conv_params.filters);
}
if (!isTensor1D(pointwise_conv_params.batch_norm_offset)) {
throw new Error("expected weightMap[" + prefix + "/Conv2d_" + idx + "_pointwise/convolution_bn_offset] to be a Tensor1D, instead have " + pointwise_conv_params.batch_norm_offset);
}
return pointwise_conv_params;
} }
function extractResidualLayerParams(numFilterValues, numFilters, filterSize, isDown) { function extractConvPairParams(idx) {
if (isDown === void 0) { isDown = false; } var depthwise_conv_params = {
var conv1 = extractConvLayerParams((isDown ? 0.5 : 1) * numFilterValues, numFilters, filterSize); filters: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/depthwise_weights"],
var conv2 = extractConvLayerParams(numFilterValues, numFilters, filterSize); batch_norm_scale: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/gamma"],
return { batch_norm_offset: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/beta"],
conv1: conv1, batch_norm_mean: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_mean"],
conv2: conv2 batch_norm_variance: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_variance"],
};
if (!isTensor4D(depthwise_conv_params.filters)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/depthwise_weights] to be a Tensor4D, instead have " + depthwise_conv_params.filters);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_scale)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/gamma] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_scale);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_offset)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/beta] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_offset);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_mean)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_mean] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_mean);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_variance)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_variance] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_variance);
}
return {
depthwise_conv_params: depthwise_conv_params,
pointwise_conv_params: extractPointwiseConvParams('MobilenetV1', idx)
};
}
function extractMobilenetV1Params() {
return {
conv_0_params: extractPointwiseConvParams('MobilenetV1', 0),
conv_pair_params: Array(13).fill(0).map(function (_, i) { return extractConvPairParams(i + 1); })
};
}
function extractBoxPredictorParams(idx) {
var params = {
box_encoding_predictor_params: {
filters: weightMap["Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/weights"],
bias: weightMap["Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/biases"]
},
class_predictor_params: {
filters: weightMap["Prediction/BoxPredictor_" + idx + "/ClassPredictor/weights"],
bias: weightMap["Prediction/BoxPredictor_" + idx + "/ClassPredictor/biases"]
}
};
if (!isTensor4D(params.box_encoding_predictor_params.filters)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/weights] to be a Tensor4D, instead have " + params.box_encoding_predictor_params.filters);
}
if (!isTensor1D(params.box_encoding_predictor_params.bias)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/biases] to be a Tensor1D, instead have " + params.box_encoding_predictor_params.bias);
}
if (!isTensor4D(params.class_predictor_params.filters)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/ClassPredictor/weights] to be a Tensor4D, instead have " + params.class_predictor_params.filters);
}
if (!isTensor1D(params.class_predictor_params.bias)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/ClassPredictor/biases] to be a Tensor1D, instead have " + params.class_predictor_params.bias);
}
return params;
}
function extractPredictionLayerParams() {
return {
conv_0_params: extractPointwiseConvParams('Prediction', 0),
conv_1_params: extractPointwiseConvParams('Prediction', 1),
conv_2_params: extractPointwiseConvParams('Prediction', 2),
conv_3_params: extractPointwiseConvParams('Prediction', 3),
conv_4_params: extractPointwiseConvParams('Prediction', 4),
conv_5_params: extractPointwiseConvParams('Prediction', 5),
conv_6_params: extractPointwiseConvParams('Prediction', 6),
conv_7_params: extractPointwiseConvParams('Prediction', 7),
box_predictor_0_params: extractBoxPredictorParams(0),
box_predictor_1_params: extractBoxPredictorParams(1),
box_predictor_2_params: extractBoxPredictorParams(2),
box_predictor_3_params: extractBoxPredictorParams(3),
box_predictor_4_params: extractBoxPredictorParams(4),
box_predictor_5_params: extractBoxPredictorParams(5)
}; };
} }
return { return {
extractConvLayerParams: extractConvLayerParams, extractMobilenetV1Params: extractMobilenetV1Params,
extractResidualLayerParams: extractResidualLayerParams extractPredictionLayerParams: extractPredictionLayerParams
};
}
function extractParams$1(weights) {
var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights;
var _b = extractorsFactory$1(extractWeights), extractConvLayerParams = _b.extractConvLayerParams, extractResidualLayerParams = _b.extractResidualLayerParams;
var conv32_down = extractConvLayerParams(4704, 32, 7);
var conv32_1 = extractResidualLayerParams(9216, 32, 3);
var conv32_2 = extractResidualLayerParams(9216, 32, 3);
var conv32_3 = extractResidualLayerParams(9216, 32, 3);
var conv64_down = extractResidualLayerParams(36864, 64, 3, true);
var conv64_1 = extractResidualLayerParams(36864, 64, 3);
var conv64_2 = extractResidualLayerParams(36864, 64, 3);
var conv64_3 = extractResidualLayerParams(36864, 64, 3);
var conv128_down = extractResidualLayerParams(147456, 128, 3, true);
var conv128_1 = extractResidualLayerParams(147456, 128, 3);
var conv128_2 = extractResidualLayerParams(147456, 128, 3);
var conv256_down = extractResidualLayerParams(589824, 256, 3, true);
var conv256_1 = extractResidualLayerParams(589824, 256, 3);
var conv256_2 = extractResidualLayerParams(589824, 256, 3);
var conv256_down_out = extractResidualLayerParams(589824, 256, 3);
var fc = transpose(tensor2d(extractWeights(256 * 128), [128, 256]), [1, 0]);
if (getRemainingWeights().length !== 0) {
throw new Error("weights remaing after extract: " + getRemainingWeights().length);
}
return {
conv32_down: conv32_down,
conv32_1: conv32_1,
conv32_2: conv32_2,
conv32_3: conv32_3,
conv64_down: conv64_down,
conv64_1: conv64_1,
conv64_2: conv64_2,
conv64_3: conv64_3,
conv128_down: conv128_down,
conv128_1: conv128_1,
conv128_2: conv128_2,
conv256_down: conv256_down,
conv256_1: conv256_1,
conv256_2: conv256_2,
conv256_down_out: conv256_down_out,
fc: fc
}; };
} }
function loadQuantizedParams(uri) {
return __awaiter$e(this, void 0, void 0, function () {
var weightMap, _a, extractMobilenetV1Params, extractPredictionLayerParams, extra_dim;
return __generator$e(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, loadWeightMap(uri, DEFAULT_MODEL_NAME)];
case 1:
weightMap = _b.sent();
_a = extractorsFactory$2(weightMap), extractMobilenetV1Params = _a.extractMobilenetV1Params, extractPredictionLayerParams = _a.extractPredictionLayerParams;
extra_dim = weightMap['Output/extra_dim'];
if (!isTensor3D(extra_dim)) {
throw new Error("expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have " + extra_dim);
}
return [2 /*return*/, {
mobilenetv1_params: extractMobilenetV1Params(),
prediction_layer_params: extractPredictionLayerParams(),
output_layer_params: {
extra_dim: extra_dim
}
}];
}
});
});
}
function normalize(x) { function pointwiseConvLayer(x, params, strides) {
return tidy(function () { return tidy(function () {
var avg_r = fill([1, 150, 150, 1], 122.782); var out = conv2d(x, params.filters, strides, 'same');
var avg_g = fill([1, 150, 150, 1], 117.001); out = add(out, params.batch_norm_offset);
var avg_b = fill([1, 150, 150, 1], 104.298); return clipByValue(out, 0, 6);
var avg_rgb = concat([avg_r, avg_g, avg_b], 3);
return div(sub(x, avg_rgb), scalar(256));
}); });
} }
function residual(x, params) { var epsilon = 0.0010000000474974513;
var out = conv(x, params.conv1); function depthwiseConvLayer(x, params, strides) {
out = convNoRelu(out, params.conv2); return tidy(function () {
out = add(out, x); var out = depthwiseConv2d(x, params.filters, strides, 'same');
out = relu(out); out = batchNormalization(out, params.batch_norm_mean, params.batch_norm_variance, epsilon, params.batch_norm_scale, params.batch_norm_offset);
return out; return clipByValue(out, 0, 6);
});
} }
function residualDown(x, params) { function getStridesForLayerIdx(layerIdx) {
var out = convDown(x, params.conv1); return [2, 4, 6, 12].some(function (idx) { return idx === layerIdx; }) ? [2, 2] : [1, 1];
out = convNoRelu(out, params.conv2);
var pooled = avgPool(x, 2, 2, 'valid');
var zeros$$1 = zeros(pooled.shape);
var isPad = pooled.shape[3] !== out.shape[3];
var isAdjustShape = pooled.shape[1] !== out.shape[1] || pooled.shape[2] !== out.shape[2];
if (isAdjustShape) {
var padShapeX = out.shape.slice();
padShapeX[1] = 1;
var zerosW = zeros(padShapeX);
out = concat([out, zerosW], 1);
var padShapeY = out.shape.slice();
padShapeY[2] = 1;
var zerosH = zeros(padShapeY);
out = concat([out, zerosH], 2);
}
pooled = isPad ? concat([pooled, zeros$$1], 3) : pooled;
out = add(pooled, out);
out = relu(out);
return out;
} }
function mobileNetV1(x, params) {
function faceRecognitionNet(weights) { return tidy(function () {
var _this = this; var conv11 = null;
var params = extractParams$1(weights); var out = pointwiseConvLayer(x, params.conv_0_params, [2, 2]);
function forward(input) { params.conv_pair_params.forEach(function (param, i) {
return tidy(function () { var layerIdx = i + 1;
var x = padToSquare(getImageTensor(input), true); var depthwiseConvStrides = getStridesForLayerIdx(layerIdx);
// work with 150 x 150 sized face images out = depthwiseConvLayer(out, param.depthwise_conv_params, depthwiseConvStrides);
if (x.shape[1] !== 150 || x.shape[2] !== 150) { out = pointwiseConvLayer(out, param.pointwise_conv_params, [1, 1]);
x = image.resizeBilinear(x, [150, 150]); if (layerIdx === 11) {
conv11 = out;
} }
x = normalize(x);
var out = convDown(x, params.conv32_down);
out = maxPool(out, 3, 2, 'valid');
out = residual(out, params.conv32_1);
out = residual(out, params.conv32_2);
out = residual(out, params.conv32_3);
out = residualDown(out, params.conv64_down);
out = residual(out, params.conv64_1);
out = residual(out, params.conv64_2);
out = residual(out, params.conv64_3);
out = residualDown(out, params.conv128_down);
out = residual(out, params.conv128_1);
out = residual(out, params.conv128_2);
out = residualDown(out, params.conv256_down);
out = residual(out, params.conv256_1);
out = residual(out, params.conv256_2);
out = residualDown(out, params.conv256_down_out);
var globalAvg = out.mean([1, 2]);
var fullyConnected = matMul(globalAvg, params.fc);
return fullyConnected;
}); });
} if (conv11 === null) {
var computeFaceDescriptor = function (input) { return __awaiter$e(_this, void 0, void 0, function () { throw new Error('mobileNetV1 - output of conv layer 11 is null');
var result, data; }
return __generator$e(this, function (_a) { return {
switch (_a.label) { out: out,
case 0: conv11: conv11
result = forward(input); };
return [4 /*yield*/, result.data()]; });
case 1: }
data = _a.sent();
result.dispose(); function nonMaxSuppression(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold) {
return [2 /*return*/, data]; var numBoxes = boxes.shape[0];
var outputSize = Math.min(maxOutputSize, numBoxes);
var candidates = scores
.map(function (score, boxIndex) { return ({ score: score, boxIndex: boxIndex }); })
.filter(function (c) { return c.score > scoreThreshold; })
.sort(function (c1, c2) { return c2.score - c1.score; });
var suppressFunc = function (x) { return x <= iouThreshold ? 1 : 0; };
var selected = [];
candidates.forEach(function (c) {
if (selected.length >= outputSize) {
return;
}
var originalScore = c.score;
for (var j = selected.length - 1; j >= 0; --j) {
var iou = IOU(boxes, c.boxIndex, selected[j]);
if (iou === 0.0) {
continue;
} }
}); c.score *= suppressFunc(iou);
}); }; if (c.score <= scoreThreshold) {
var computeFaceDescriptorSync = function (input) { break;
var result = forward(input); }
var data = result.dataSync(); }
result.dispose(); if (originalScore === c.score) {
return data; selected.push(c.boxIndex);
}; }
});
return selected;
}
function IOU(boxes, i, j) {
var yminI = Math.min(boxes.get(i, 0), boxes.get(i, 2));
var xminI = Math.min(boxes.get(i, 1), boxes.get(i, 3));
var ymaxI = Math.max(boxes.get(i, 0), boxes.get(i, 2));
var xmaxI = Math.max(boxes.get(i, 1), boxes.get(i, 3));
var yminJ = Math.min(boxes.get(j, 0), boxes.get(j, 2));
var xminJ = Math.min(boxes.get(j, 1), boxes.get(j, 3));
var ymaxJ = Math.max(boxes.get(j, 0), boxes.get(j, 2));
var xmaxJ = Math.max(boxes.get(j, 1), boxes.get(j, 3));
var areaI = (ymaxI - yminI) * (xmaxI - xminI);
var areaJ = (ymaxJ - yminJ) * (xmaxJ - xminJ);
if (areaI <= 0 || areaJ <= 0) {
return 0.0;
}
var intersectionYmin = Math.max(yminI, yminJ);
var intersectionXmin = Math.max(xminI, xminJ);
var intersectionYmax = Math.min(ymaxI, ymaxJ);
var intersectionXmax = Math.min(xmaxI, xmaxJ);
var intersectionArea = Math.max(intersectionYmax - intersectionYmin, 0.0) *
Math.max(intersectionXmax - intersectionXmin, 0.0);
return intersectionArea / (areaI + areaJ - intersectionArea);
}
function getCenterCoordinatesAndSizesLayer(x) {
var vec = unstack(transpose(x, [1, 0]));
var sizes = [
sub(vec[2], vec[0]),
sub(vec[3], vec[1])
];
var centers = [
add(vec[0], div(sizes[0], scalar(2))),
add(vec[1], div(sizes[1], scalar(2)))
];
return { return {
computeFaceDescriptor: computeFaceDescriptor, sizes: sizes,
computeFaceDescriptorSync: computeFaceDescriptorSync, centers: centers
forward: forward
}; };
} }
function decodeBoxesLayer(x0, x1) {
var _a = getCenterCoordinatesAndSizesLayer(x0), sizes = _a.sizes, centers = _a.centers;
var vec = unstack(transpose(x1, [1, 0]));
var div0_out = div(mul(exp(div(vec[2], scalar(5))), sizes[0]), scalar(2));
var add0_out = add(mul(div(vec[0], scalar(10)), sizes[0]), centers[0]);
var div1_out = div(mul(exp(div(vec[3], scalar(5))), sizes[1]), scalar(2));
var add1_out = add(mul(div(vec[1], scalar(10)), sizes[1]), centers[1]);
return transpose(stack([
sub(add0_out, div0_out),
sub(add1_out, div1_out),
add(add0_out, div0_out),
add(add1_out, div1_out)
]), [1, 0]);
}
function outputLayer(boxPredictions, classPredictions, params) {
return tidy(function () {
var batchSize = boxPredictions.shape[0];
var boxes = decodeBoxesLayer(reshape(tile(params.extra_dim, [batchSize, 1, 1]), [-1, 4]), reshape(boxPredictions, [-1, 4]));
boxes = reshape(boxes, [batchSize, (boxes.shape[0] / batchSize), 4]);
var scoresAndClasses = sigmoid(slice(classPredictions, [0, 0, 1], [-1, -1, -1]));
var scores = slice(scoresAndClasses, [0, 0, 0], [-1, -1, 1]);
scores = reshape(scores, [batchSize, scores.shape[1]]);
var boxesByBatch = unstack(boxes);
var scoresByBatch = unstack(scores);
return {
boxes: boxesByBatch,
scores: scoresByBatch
};
});
}
/** function convLayer$1(x, params, padding, withRelu) {
* Extracts the image regions containing the detected faces. if (padding === void 0) { padding = 'same'; }
* if (withRelu === void 0) { withRelu = false; }
* @param input The image that face detection has been performed on. return tidy(function () {
* @param detections The face detection results or face bounding boxes for that image. var out = add(conv2d(x, params.filters, [1, 1], padding), params.bias);
* @returns The Canvases of the corresponding image region for each detected face. return withRelu ? relu(out) : out;
*/
function extractFaces(image, detections) {
var ctx = getContext2dOrThrow(image);
var boxes = detections.map(function (det) { return det instanceof FaceDetection
? det.forSize(image.width, image.height).getBox().floor()
: det; });
return boxes.map(function (_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var faceImg = createCanvas({ width: width, height: height });
getContext2dOrThrow(faceImg)
.putImageData(ctx.getImageData(x, y, width, height), 0, 0);
return faceImg;
}); });
} }
/** function boxPredictionLayer(x, params) {
* Extracts the tensors of the image regions containing the detected faces.
* Useful if you want to compute the face descriptors for the face images.
* Using this method is faster then extracting a canvas for each face and
* converting them to tensors individually.
*
* @param input The image that face detection has been performed on.
* @param detections The face detection results or face bounding boxes for that image.
* @returns Tensors of the corresponding image region for each detected face.
*/
function extractFaceTensors(image$$1, detections) {
return tidy(function () { return tidy(function () {
var imgTensor = getImageTensor(image$$1); var batchSize = x.shape[0];
// TODO handle batches var boxPredictionEncoding = reshape(convLayer$1(x, params.box_encoding_predictor_params), [batchSize, -1, 1, 4]);
var _a = imgTensor.shape, batchSize = _a[0], imgHeight = _a[1], imgWidth = _a[2], numChannels = _a[3]; var classPrediction = reshape(convLayer$1(x, params.class_predictor_params), [batchSize, -1, 3]);
var boxes = detections.map(function (det) { return det instanceof FaceDetection return {
? det.forSize(imgWidth, imgHeight).getBox().floor() boxPredictionEncoding: boxPredictionEncoding,
: det; }); classPrediction: classPrediction
var faceTensors = boxes.map(function (_a) { };
var x = _a.x, y = _a.y, width = _a.width, height = _a.height; });
return slice(imgTensor, [0, y, x, 0], [1, height, width, numChannels]); }
});
return faceTensors; function predictionLayer(x, conv11, params) {
return tidy(function () {
var conv0 = pointwiseConvLayer(x, params.conv_0_params, [1, 1]);
var conv1 = pointwiseConvLayer(conv0, params.conv_1_params, [2, 2]);
var conv2 = pointwiseConvLayer(conv1, params.conv_2_params, [1, 1]);
var conv3 = pointwiseConvLayer(conv2, params.conv_3_params, [2, 2]);
var conv4 = pointwiseConvLayer(conv3, params.conv_4_params, [1, 1]);
var conv5 = pointwiseConvLayer(conv4, params.conv_5_params, [2, 2]);
var conv6 = pointwiseConvLayer(conv5, params.conv_6_params, [1, 1]);
var conv7 = pointwiseConvLayer(conv6, params.conv_7_params, [2, 2]);
var boxPrediction0 = boxPredictionLayer(conv11, params.box_predictor_0_params);
var boxPrediction1 = boxPredictionLayer(x, params.box_predictor_1_params);
var boxPrediction2 = boxPredictionLayer(conv1, params.box_predictor_2_params);
var boxPrediction3 = boxPredictionLayer(conv3, params.box_predictor_3_params);
var boxPrediction4 = boxPredictionLayer(conv5, params.box_predictor_4_params);
var boxPrediction5 = boxPredictionLayer(conv7, params.box_predictor_5_params);
var boxPredictions = concat([
boxPrediction0.boxPredictionEncoding,
boxPrediction1.boxPredictionEncoding,
boxPrediction2.boxPredictionEncoding,
boxPrediction3.boxPredictionEncoding,
boxPrediction4.boxPredictionEncoding,
boxPrediction5.boxPredictionEncoding
], 1);
var classPredictions = concat([
boxPrediction0.classPrediction,
boxPrediction1.classPrediction,
boxPrediction2.classPrediction,
boxPrediction3.classPrediction,
boxPrediction4.classPrediction,
boxPrediction5.classPrediction
], 1);
return {
boxPredictions: boxPredictions,
classPredictions: classPredictions
};
});
}
var resizedImageSize = [512, 512];
var weight = scalar(0.007843137718737125);
var bias = scalar(1);
function resizeLayer(x) {
return tidy(function () {
var resized = image.resizeBilinear(x, resizedImageSize, false);
return sub(mul(resized, weight), bias);
}); });
} }
var FaceDetectionNet = /** @class */ (function () {
function FaceDetectionNet() {
}
FaceDetectionNet.prototype.load = function (weightsOrUrl) {
return __awaiter$e(this, void 0, void 0, function () {
var _a;
return __generator$e(this, function (_b) {
switch (_b.label) {
case 0:
if (weightsOrUrl instanceof Float32Array) {
this.extractWeights(weightsOrUrl);
return [2 /*return*/];
}
if (weightsOrUrl && typeof weightsOrUrl !== 'string') {
throw new Error('FaceDetectionNet.load - expected model uri, or weights as Float32Array');
}
_a = this;
return [4 /*yield*/, loadQuantizedParams(weightsOrUrl)];
case 1:
_a._params = _b.sent();
return [2 /*return*/];
}
});
});
};
FaceDetectionNet.prototype.extractWeights = function (weights) {
this._params = extractParams$1(weights);
};
FaceDetectionNet.prototype.forwardTensor = function (imgTensor) {
var _this = this;
return tidy(function () {
var resized = resizeLayer(imgTensor);
var features = mobileNetV1(resized, _this._params.mobilenetv1_params);
var _a = predictionLayer(features.out, features.conv11, _this._params.prediction_layer_params), boxPredictions = _a.boxPredictions, classPredictions = _a.classPredictions;
return outputLayer(boxPredictions, classPredictions, _this._params.output_layer_params);
});
};
FaceDetectionNet.prototype.forward = function (input) {
var _this = this;
return tidy(function () { return _this.forwardTensor(padToSquare(getImageTensor(input))); });
};
FaceDetectionNet.prototype.locateFaces = function (input, minConfidence, maxResults) {
if (minConfidence === void 0) { minConfidence = 0.8; }
if (maxResults === void 0) { maxResults = 100; }
return __awaiter$e(this, void 0, void 0, function () {
var _this = this;
var paddedHeightRelative, paddedWidthRelative, imageDimensions, _a, _boxes, _scores, boxes, scores, i, scoresData, _b, _c, iouThreshold, indices, results;
return __generator$e(this, function (_d) {
switch (_d.label) {
case 0:
paddedHeightRelative = 1, paddedWidthRelative = 1;
_a = tidy(function () {
var imgTensor = getImageTensor(input);
var _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1];
imageDimensions = { width: width, height: height };
imgTensor = padToSquare(imgTensor);
paddedHeightRelative = imgTensor.shape[1] / height;
paddedWidthRelative = imgTensor.shape[2] / width;
return _this.forwardTensor(imgTensor);
}), _boxes = _a.boxes, _scores = _a.scores;
boxes = _boxes[0];
scores = _scores[0];
for (i = 1; i < _boxes.length; i++) {
_boxes[i].dispose();
_scores[i].dispose();
}
_c = (_b = Array).from;
return [4 /*yield*/, scores.data()];
case 1:
scoresData = _c.apply(_b, [_d.sent()]);
iouThreshold = 0.5;
indices = nonMaxSuppression(boxes, scoresData, maxResults, iouThreshold, minConfidence);
results = indices
.map(function (idx) {
var _a = [
Math.max(0, boxes.get(idx, 0)),
Math.min(1.0, boxes.get(idx, 2))
].map(function (val) { return val * paddedHeightRelative; }), top = _a[0], bottom = _a[1];
var _b = [
Math.max(0, boxes.get(idx, 1)),
Math.min(1.0, boxes.get(idx, 3))
].map(function (val) { return val * paddedWidthRelative; }), left = _b[0], right = _b[1];
return new FaceDetection(scoresData[idx], new Rect(left, top, right - left, bottom - top), imageDimensions);
});
boxes.dispose();
scores.dispose();
return [2 /*return*/, results];
}
});
});
};
return FaceDetectionNet;
}());
function faceDetectionNet(weights) {
var net = new FaceDetectionNet();
net.extractWeights(weights);
return net;
}
var Point = /** @class */ (function () { var Point = /** @class */ (function () {
function Point(x, y) { function Point(x, y) {
this.x = x; this.x = x;
...@@ -16122,84 +16322,48 @@ ...@@ -16122,84 +16322,48 @@
}); });
} }
function getModelUris(uri, defaultModelName) { var DEFAULT_MODEL_NAME$1 = 'face_landmark_68_model';
var parts = (uri || '').split('/'); function extractorsFactory$3(weightMap) {
var modelBaseUri = ((uri || '').endsWith('.json') function extractConvParams(prefix) {
? parts.slice(0, parts.length - 1) var params = {
: parts).filter(function (s) { return s; }).join('/'); filters: weightMap[prefix + "/kernel"],
var defaultManifestFilename = defaultModelName + "-weights_manifest.json"; bias: weightMap[prefix + "/bias"]
var manifestUri = !uri || !modelBaseUri };
? defaultManifestFilename if (!isTensor4D(params.filters)) {
: (uri.endsWith('.json') throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor4D, instead have " + params.filters);
? uri }
: modelBaseUri + "/" + defaultManifestFilename); if (!isTensor1D(params.bias)) {
return { manifestUri: manifestUri, modelBaseUri: modelBaseUri }; 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"]
};
if (!isTensor2D(params.weights)) {
throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor2D, instead have " + params.weights);
}
if (!isTensor1D(params.bias)) {
throw new Error("expected weightMap[" + prefix + "/bias] to be a Tensor1D, instead have " + params.bias);
}
return params;
}
return {
extractConvParams: extractConvParams,
extractFcParams: extractFcParams
};
} }
function loadWeightMap(uri, defaultModelName) { function loadQuantizedParams$1(uri) {
return __awaiter$e(this, void 0, void 0, function () { return __awaiter$e(this, void 0, void 0, function () {
var _a, manifestUri, modelBaseUri, manifest; var weightMap, _a, extractConvParams, extractFcParams;
return __generator$e(this, function (_b) { return __generator$e(this, function (_b) {
switch (_b.label) { switch (_b.label) {
case 0: case 0: return [4 /*yield*/, loadWeightMap(uri, DEFAULT_MODEL_NAME$1)];
_a = getModelUris(uri, defaultModelName), manifestUri = _a.manifestUri, modelBaseUri = _a.modelBaseUri;
return [4 /*yield*/, fetch(manifestUri)];
case 1: return [4 /*yield*/, (_b.sent()).json()];
case 2:
manifest = _b.sent();
return [2 /*return*/, loadWeights(manifest, modelBaseUri)];
}
});
});
}
function isTensor(tensor$$1, dim) {
return tensor$$1 instanceof Tensor && tensor$$1.shape.length === dim;
}
function isTensor1D(tensor$$1) {
return isTensor(tensor$$1, 1);
}
function isTensor2D(tensor$$1) {
return isTensor(tensor$$1, 2);
}
function isTensor4D(tensor$$1) {
return isTensor(tensor$$1, 4);
}
var DEFAULT_MODEL_NAME = 'face_landmark_68_model';
function loadQuantizedParams(uri) {
return __awaiter$e(this, void 0, void 0, function () {
function extractConvParams(prefix) {
var params = {
filters: weightMap[prefix + "/kernel"],
bias: weightMap[prefix + "/bias"]
};
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) {
var params = {
weights: weightMap[prefix + "/kernel"],
bias: weightMap[prefix + "/bias"]
};
if (!isTensor2D(params.weights)) {
throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor2D, instead have " + params.weights);
}
if (!isTensor1D(params.bias)) {
throw new Error("expected weightMap[" + prefix + "/bias] to be a Tensor1D, instead have " + params.bias);
}
return params;
}
var weightMap;
return __generator$e(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, loadWeightMap(uri, DEFAULT_MODEL_NAME)];
case 1: case 1:
weightMap = _a.sent(); weightMap = _b.sent();
_a = extractorsFactory$3(weightMap), extractConvParams = _a.extractConvParams, extractFcParams = _a.extractFcParams;
return [2 /*return*/, { return [2 /*return*/, {
conv0_params: extractConvParams('conv2d_0'), conv0_params: extractConvParams('conv2d_0'),
conv1_params: extractConvParams('conv2d_1'), conv1_params: extractConvParams('conv2d_1'),
...@@ -16218,7 +16382,7 @@ ...@@ -16218,7 +16382,7 @@
} }
function conv$1(x, params) { function conv$1(x, params) {
return convLayer(x, params, 'valid', true); return convLayer$1(x, params, 'valid', true);
} }
function maxPool$1(x, strides) { function maxPool$1(x, strides) {
if (strides === void 0) { strides = [2, 2]; } if (strides === void 0) { strides = [2, 2]; }
...@@ -16241,7 +16405,7 @@ ...@@ -16241,7 +16405,7 @@
throw new Error('FaceLandmarkNet.load - expected model uri, or weights as Float32Array'); throw new Error('FaceLandmarkNet.load - expected model uri, or weights as Float32Array');
} }
_a = this; _a = this;
return [4 /*yield*/, loadQuantizedParams(weightsOrUrl)]; return [4 /*yield*/, loadQuantizedParams$1(weightsOrUrl)];
case 1: case 1:
_a._params = _b.sent(); _a._params = _b.sent();
return [2 /*return*/]; return [2 /*return*/];
...@@ -16303,19 +16467,20 @@ ...@@ -16303,19 +16467,20 @@
}()); }());
function faceLandmarkNet(weights) { function faceLandmarkNet(weights) {
var faceLandmarkNet = new FaceLandmarkNet(); var net = new FaceLandmarkNet();
faceLandmarkNet.extractWeights(weights); net.extractWeights(weights);
return faceLandmarkNet; return net;
} }
exports.euclideanDistance = euclideanDistance; exports.euclideanDistance = euclideanDistance;
exports.faceDetectionNet = faceDetectionNet;
exports.faceRecognitionNet = faceRecognitionNet; exports.faceRecognitionNet = faceRecognitionNet;
exports.NetInput = NetInput; exports.NetInput = NetInput;
exports.tf = index; exports.tf = index;
exports.padToSquare = padToSquare; exports.padToSquare = padToSquare;
exports.extractFaces = extractFaces; exports.extractFaces = extractFaces;
exports.extractFaceTensors = extractFaceTensors; exports.extractFaceTensors = extractFaceTensors;
exports.faceDetectionNet = faceDetectionNet;
exports.FaceDetectionNet = FaceDetectionNet;
exports.faceLandmarkNet = faceLandmarkNet; exports.faceLandmarkNet = faceLandmarkNet;
exports.FaceLandmarkNet = FaceLandmarkNet; exports.FaceLandmarkNet = FaceLandmarkNet;
exports.isFloat = isFloat; exports.isFloat = isFloat;
......
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 { NetInput } from '../NetInput';
import { TNetInput } from '../types';
import { FaceDetection } from './FaceDetection';
export declare class FaceDetectionNet {
private _params;
load(weightsOrUrl: Float32Array | string | undefined): Promise<void>;
extractWeights(weights: Float32Array): void;
private forwardTensor(imgTensor);
forward(input: tf.Tensor | NetInput | TNetInput): {
boxes: tf.Tensor<tf.Rank.R2>[];
scores: tf.Tensor<tf.Rank.R1>[];
};
locateFaces(input: tf.Tensor | NetInput | TNetInput, minConfidence?: number, maxResults?: number): Promise<FaceDetection[]>;
}
import * as tslib_1 from "tslib";
import * as tf from '@tensorflow/tfjs-core';
import { getImageTensor } from '../getImageTensor';
import { padToSquare } from '../padToSquare';
import { Rect } from '../Rect';
import { extractParams } from './extractParams';
import { FaceDetection } from './FaceDetection';
import { loadQuantizedParams } from './loadQuantizedParams';
import { mobileNetV1 } from './mobileNetV1';
import { nonMaxSuppression } from './nonMaxSuppression';
import { outputLayer } from './outputLayer';
import { predictionLayer } from './predictionLayer';
import { resizeLayer } from './resizeLayer';
var FaceDetectionNet = /** @class */ (function () {
function FaceDetectionNet() {
}
FaceDetectionNet.prototype.load = function (weightsOrUrl) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (weightsOrUrl instanceof Float32Array) {
this.extractWeights(weightsOrUrl);
return [2 /*return*/];
}
if (weightsOrUrl && typeof weightsOrUrl !== 'string') {
throw new Error('FaceDetectionNet.load - expected model uri, or weights as Float32Array');
}
_a = this;
return [4 /*yield*/, loadQuantizedParams(weightsOrUrl)];
case 1:
_a._params = _b.sent();
return [2 /*return*/];
}
});
});
};
FaceDetectionNet.prototype.extractWeights = function (weights) {
this._params = extractParams(weights);
};
FaceDetectionNet.prototype.forwardTensor = function (imgTensor) {
var _this = this;
return tf.tidy(function () {
var resized = resizeLayer(imgTensor);
var features = mobileNetV1(resized, _this._params.mobilenetv1_params);
var _a = predictionLayer(features.out, features.conv11, _this._params.prediction_layer_params), boxPredictions = _a.boxPredictions, classPredictions = _a.classPredictions;
return outputLayer(boxPredictions, classPredictions, _this._params.output_layer_params);
});
};
FaceDetectionNet.prototype.forward = function (input) {
var _this = this;
return tf.tidy(function () { return _this.forwardTensor(padToSquare(getImageTensor(input))); });
};
FaceDetectionNet.prototype.locateFaces = function (input, minConfidence, maxResults) {
if (minConfidence === void 0) { minConfidence = 0.8; }
if (maxResults === void 0) { maxResults = 100; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _this = this;
var paddedHeightRelative, paddedWidthRelative, imageDimensions, _a, _boxes, _scores, boxes, scores, i, scoresData, _b, _c, iouThreshold, indices, results;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
paddedHeightRelative = 1, paddedWidthRelative = 1;
_a = tf.tidy(function () {
var imgTensor = getImageTensor(input);
var _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1];
imageDimensions = { width: width, height: height };
imgTensor = padToSquare(imgTensor);
paddedHeightRelative = imgTensor.shape[1] / height;
paddedWidthRelative = imgTensor.shape[2] / width;
return _this.forwardTensor(imgTensor);
}), _boxes = _a.boxes, _scores = _a.scores;
boxes = _boxes[0];
scores = _scores[0];
for (i = 1; i < _boxes.length; i++) {
_boxes[i].dispose();
_scores[i].dispose();
}
_c = (_b = Array).from;
return [4 /*yield*/, scores.data()];
case 1:
scoresData = _c.apply(_b, [_d.sent()]);
iouThreshold = 0.5;
indices = nonMaxSuppression(boxes, scoresData, maxResults, iouThreshold, minConfidence);
results = indices
.map(function (idx) {
var _a = [
Math.max(0, boxes.get(idx, 0)),
Math.min(1.0, boxes.get(idx, 2))
].map(function (val) { return val * paddedHeightRelative; }), top = _a[0], bottom = _a[1];
var _b = [
Math.max(0, boxes.get(idx, 1)),
Math.min(1.0, boxes.get(idx, 3))
].map(function (val) { return val * paddedWidthRelative; }), left = _b[0], right = _b[1];
return new FaceDetection(scoresData[idx], new Rect(left, top, right - left, bottom - top), imageDimensions);
});
boxes.dispose();
scores.dispose();
return [2 /*return*/, results];
}
});
});
};
return FaceDetectionNet;
}());
export { FaceDetectionNet };
//# sourceMappingURL=FaceDetectionNet.js.map
\ No newline at end of file
{"version":3,"file":"FaceDetectionNet.js","sourceRoot":"","sources":["../../src/faceDetectionNet/FaceDetectionNet.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C;IAAA;IAiHA,CAAC;IA7Gc,+BAAI,GAAjB,UAAkB,YAA+C;;;;;;wBAC/D,IAAI,YAAY,YAAY,YAAY,EAAE;4BACxC,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAA;4BACjC,sBAAM;yBACP;wBAED,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE;4BACpD,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAA;yBAC1F;wBACD,KAAA,IAAI,CAAA;wBAAW,qBAAM,mBAAmB,CAAC,YAAY,CAAC,EAAA;;wBAAtD,GAAK,OAAO,GAAG,SAAuC,CAAA;;;;;KACvD;IAEM,yCAAc,GAArB,UAAsB,OAAqB;QACzC,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;IAEO,wCAAa,GAArB,UAAsB,SAAsB;QAA5C,iBAaC;QAZC,OAAO,EAAE,CAAC,IAAI,CAAC;YAEb,IAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAgB,CAAA;YACrD,IAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,EAAE,KAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAA;YAEhE,IAAA,0FAGkF,EAFtF,kCAAc,EACd,sCAAgB,CACsE;YAExF,OAAO,WAAW,CAAC,cAAc,EAAE,gBAAgB,EAAE,KAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;QACxF,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,kCAAO,GAAd,UAAe,KAAuC;QAAtD,iBAIC;QAHC,OAAO,EAAE,CAAC,IAAI,CACZ,cAAM,OAAA,KAAI,CAAC,aAAa,CAAC,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,EAAtD,CAAsD,CAC7D,CAAA;IACH,CAAC;IAEY,sCAAW,GAAxB,UACE,KAAuC,EACvC,aAA2B,EAC3B,UAAwB;QADxB,8BAAA,EAAA,mBAA2B;QAC3B,2BAAA,EAAA,gBAAwB;;;;;;;wBAGpB,oBAAoB,GAAG,CAAC,EAAE,mBAAmB,GAAG,CAAC,CAAA;wBAG/C,KAGF,EAAE,CAAC,IAAI,CAAC;4BAEV,IAAI,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;4BAC/B,IAAA,6BAA0C,EAAzC,cAAM,EAAE,aAAK,CAA4B;4BAChD,eAAe,GAAG,EAAE,KAAK,OAAA,EAAE,MAAM,QAAA,EAAE,CAAA;4BAEnC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;4BAClC,oBAAoB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAA;4BAClD,mBAAmB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;4BAEhD,OAAO,KAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;wBACtC,CAAC,CAAC,EAbO,MAAM,WAAA,EACL,OAAO,YAAA,CAYf;wBAGI,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;wBACjB,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;wBACzB,KAAS,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;4BACtC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;4BACnB,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;yBACrB;wBAGkB,KAAA,CAAA,KAAA,KAAK,CAAA,CAAC,IAAI,CAAA;wBAAC,qBAAM,MAAM,CAAC,IAAI,EAAE,EAAA;;wBAA3C,UAAU,GAAG,cAAW,SAAmB,EAAC;wBAE5C,YAAY,GAAG,GAAG,CAAA;wBAClB,OAAO,GAAG,iBAAiB,CAC/B,KAAK,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,CACd,CAAA;wBAEK,OAAO,GAAG,OAAO;6BACpB,GAAG,CAAC,UAAA,GAAG;4BACA,IAAA;;;wFAGkC,EAHjC,WAAG,EAAE,cAAM,CAGsB;4BAClC,IAAA;;;uFAGiC,EAHhC,YAAI,EAAE,aAAK,CAGqB;4BACvC,OAAO,IAAI,aAAa,CACtB,UAAU,CAAC,GAAG,CAAC,EACf,IAAI,IAAI,CACN,IAAI,EACJ,GAAG,EACH,KAAK,GAAG,IAAI,EACZ,MAAM,GAAG,GAAG,CACb,EACD,eAA6B,CAC9B,CAAA;wBACH,CAAC,CAAC,CAAA;wBAEJ,KAAK,CAAC,OAAO,EAAE,CAAA;wBACf,MAAM,CAAC,OAAO,EAAE,CAAA;wBAEhB,sBAAO,OAAO,EAAA;;;;KACf;IACH,uBAAC;AAAD,CAAC,AAjHD,IAiHC"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types'; import { BoxPredictionParams } from './types';
export declare function boxPredictionLayer(x: tf.Tensor4D, params: FaceDetectionNet.BoxPredictionParams): { export declare function boxPredictionLayer(x: tf.Tensor4D, params: BoxPredictionParams): {
boxPredictionEncoding: tf.Tensor<tf.Rank>; boxPredictionEncoding: tf.Tensor<tf.Rank>;
classPrediction: tf.Tensor<tf.Rank>; classPrediction: tf.Tensor<tf.Rank>;
}; };
{"version":3,"file":"boxPredictionLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/boxPredictionLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,MAAM,6BACJ,CAAc,EACd,MAA4C;IAE5C,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAE5B,IAAM,qBAAqB,GAAG,EAAE,CAAC,OAAO,CACtC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,6BAA6B,CAAC,EAClD,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACtB,CAAA;QACD,IAAM,eAAe,GAAG,EAAE,CAAC,OAAO,CAChC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,sBAAsB,CAAC,EAC3C,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CACnB,CAAA;QAED,OAAO;YACL,qBAAqB,uBAAA;YACrB,eAAe,iBAAA;SAChB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"} {"version":3,"file":"boxPredictionLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/boxPredictionLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,MAAM,6BACJ,CAAc,EACd,MAA2B;IAE3B,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAE5B,IAAM,qBAAqB,GAAG,EAAE,CAAC,OAAO,CACtC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,6BAA6B,CAAC,EAClD,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACtB,CAAA;QACD,IAAM,eAAe,GAAG,EAAE,CAAC,OAAO,CAChC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,sBAAsB,CAAC,EAC3C,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CACnB,CAAA;QAED,OAAO;YACL,qBAAqB,uBAAA;YACrB,eAAe,iBAAA;SAChB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
\ No newline at end of file \ No newline at end of file
import { FaceDetectionNet } from './types'; import { NetParams } from './types';
export declare function extractParams(weights: Float32Array): FaceDetectionNet.NetParams; export declare function extractParams(weights: Float32Array): NetParams;
{"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/faceDetectionNet/extractParams.ts"],"names":[],"mappings":"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"} {"version":3,"file":"extractParams.js","sourceRoot":"","sources":["../../src/faceDetectionNet/extractParams.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAIzE,2BAA2B,cAAoD;IAE7E,oCAAoC,WAAmB;QACrD,IAAM,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,CAAA;QACxF,IAAM,gBAAgB,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QACjE,IAAM,iBAAiB,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAClE,IAAM,eAAe,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAChE,IAAM,mBAAmB,GAAG,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;QAEpE,OAAO;YACL,OAAO,SAAA;YACP,gBAAgB,kBAAA;YAChB,iBAAiB,mBAAA;YACjB,eAAe,iBAAA;YACf,mBAAmB,qBAAA;SACpB,CAAA;IACH,CAAC;IAED,2BACE,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;IAED,oCACE,UAAkB,EAClB,WAAmB,EACnB,UAAkB;QAEZ,IAAA,2DAGoD,EAFxD,oBAAO,EACP,cAAI,CACoD;QAE1D,OAAO;YACL,OAAO,SAAA;YACP,iBAAiB,EAAE,IAAI;SACxB,CAAA;IACH,CAAC;IAED,+BACE,UAAkB,EAClB,WAAmB;QAEnB,IAAM,qBAAqB,GAAG,0BAA0B,CAAC,UAAU,CAAC,CAAA;QACpE,IAAM,qBAAqB,GAAG,0BAA0B,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;QAEpF,OAAO;YACL,qBAAqB,uBAAA;YACrB,qBAAqB,uBAAA;SACtB,CAAA;IACH,CAAC;IAED;QAEE,IAAM,aAAa,GAAG,0BAA0B,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAE1D,IAAM,eAAe,GAAG;YACtB,CAAC,EAAE,EAAE,EAAE,CAAC;YACR,CAAC,EAAE,EAAE,GAAG,CAAC;YACT,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,GAAG,CAAC;YACV,CAAC,GAAG,EAAE,IAAI,CAAC;YACX,CAAC,IAAI,EAAE,IAAI,CAAC;SACb,CAAA;QAED,IAAM,gBAAgB,GAAG,eAAe,CAAC,GAAG,CAC1C,UAAC,EAAyB;gBAAxB,kBAAU,EAAE,mBAAW;YAAM,OAAA,qBAAqB,CAAC,UAAU,EAAE,WAAW,CAAC;QAA9C,CAA8C,CAC9E,CAAA;QAED,OAAO;YACL,aAAa,eAAA;YACb,gBAAgB,kBAAA;SACjB,CAAA;IAEH,CAAC;IAED;QACE,IAAM,aAAa,GAAG,0BAA0B,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC9D,IAAM,aAAa,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7D,IAAM,aAAa,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7D,IAAM,aAAa,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7D,IAAM,aAAa,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7D,IAAM,aAAa,GAAG,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7D,IAAM,aAAa,GAAG,0BAA0B,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAC5D,IAAM,aAAa,GAAG,0BAA0B,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAE5D,IAAM,+BAA+B,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACrE,IAAM,wBAAwB,GAAG,iBAAiB,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAC7D,IAAM,+BAA+B,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACtE,IAAM,wBAAwB,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAC/D,IAAM,+BAA+B,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACrE,IAAM,wBAAwB,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAC9D,IAAM,+BAA+B,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACrE,IAAM,wBAAwB,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAC9D,IAAM,+BAA+B,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACrE,IAAM,wBAAwB,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAC9D,IAAM,+BAA+B,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACrE,IAAM,wBAAwB,GAAG,iBAAiB,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAE9D,IAAM,sBAAsB,GAAG;YAC7B,6BAA6B,EAAE,+BAA+B;YAC9D,sBAAsB,EAAE,wBAAwB;SACjD,CAAA;QACD,IAAM,sBAAsB,GAAG;YAC7B,6BAA6B,EAAE,+BAA+B;YAC9D,sBAAsB,EAAE,wBAAwB;SACjD,CAAA;QACD,IAAM,sBAAsB,GAAG;YAC7B,6BAA6B,EAAE,+BAA+B;YAC9D,sBAAsB,EAAE,wBAAwB;SACjD,CAAA;QACD,IAAM,sBAAsB,GAAG;YAC7B,6BAA6B,EAAE,+BAA+B;YAC9D,sBAAsB,EAAE,wBAAwB;SACjD,CAAA;QACD,IAAM,sBAAsB,GAAG;YAC7B,6BAA6B,EAAE,+BAA+B;YAC9D,sBAAsB,EAAE,wBAAwB;SACjD,CAAA;QACD,IAAM,sBAAsB,GAAG;YAC7B,6BAA6B,EAAE,+BAA+B;YAC9D,sBAAsB,EAAE,wBAAwB;SACjD,CAAA;QAED,OAAO;YACL,aAAa,eAAA;YACb,aAAa,eAAA;YACb,aAAa,eAAA;YACb,aAAa,eAAA;YACb,aAAa,eAAA;YACb,aAAa,eAAA;YACb,aAAa,eAAA;YACb,aAAa,eAAA;YACb,sBAAsB,wBAAA;YACtB,sBAAsB,wBAAA;YACtB,sBAAsB,wBAAA;YACtB,sBAAsB,wBAAA;YACtB,sBAAsB,wBAAA;YACtB,sBAAsB,wBAAA;SACvB,CAAA;IACH,CAAC;IAGD,OAAO;QACL,wBAAwB,0BAAA;QACxB,4BAA4B,8BAAA;KAC7B,CAAA;AAEH,CAAC;AAED,MAAM,wBAAwB,OAAqB;IAC3C,IAAA,mCAG4B,EAFhC,kCAAc,EACd,4CAAmB,CACa;IAE5B,IAAA,sCAG+B,EAFnC,sDAAwB,EACxB,8DAA4B,CACO;IAErC,IAAM,kBAAkB,GAAG,wBAAwB,EAAE,CAAA;IACrD,IAAM,uBAAuB,GAAG,4BAA4B,EAAE,CAAA;IAC9D,IAAM,SAAS,GAAG,EAAE,CAAC,QAAQ,CAC3B,cAAc,CAAC,IAAI,GAAG,CAAC,CAAC,EACxB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CACb,CAAA;IACD,IAAM,mBAAmB,GAAG;QAC1B,SAAS,WAAA;KACV,CAAA;IAED,IAAI,mBAAmB,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;QACtC,MAAM,IAAI,KAAK,CAAC,oCAAkC,mBAAmB,EAAE,CAAC,MAAQ,CAAC,CAAA;KAClF;IAED,OAAO;QACL,kBAAkB,oBAAA;QAClB,uBAAuB,yBAAA;QACvB,mBAAmB,qBAAA;KACpB,CAAA;AACH,CAAC"}
\ No newline at end of file \ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import { FaceDetectionNet } from './FaceDetectionNet';
import { NetInput } from '../NetInput'; export * from './FaceDetectionNet';
import { FaceDetection } from './FaceDetection'; export declare function faceDetectionNet(weights: Float32Array): FaceDetectionNet;
export declare function faceDetectionNet(weights: Float32Array): {
forward: (input: string | HTMLCanvasElement | HTMLImageElement | HTMLVideoElement | (string | HTMLCanvasElement | HTMLImageElement | HTMLVideoElement)[] | tf.Tensor<tf.Rank> | NetInput) => {
boxes: tf.Tensor<tf.Rank.R2>[];
scores: tf.Tensor<tf.Rank.R1>[];
};
locateFaces: (input: string | HTMLCanvasElement | HTMLImageElement | HTMLVideoElement | (string | HTMLCanvasElement | HTMLImageElement | HTMLVideoElement)[] | tf.Tensor<tf.Rank> | NetInput, minConfidence?: number, maxResults?: number) => Promise<FaceDetection[]>;
};
import * as tslib_1 from "tslib"; import { FaceDetectionNet } from './FaceDetectionNet';
import * as tf from '@tensorflow/tfjs-core'; export * from './FaceDetectionNet';
import { getImageTensor } from '../getImageTensor';
import { padToSquare } from '../padToSquare';
import { extractParams } from './extractParams';
import { FaceDetection } from './FaceDetection';
import { mobileNetV1 } from './mobileNetV1';
import { nonMaxSuppression } from './nonMaxSuppression';
import { outputLayer } from './outputLayer';
import { predictionLayer } from './predictionLayer';
import { resizeLayer } from './resizeLayer';
import { Rect } from '../Rect';
export function faceDetectionNet(weights) { export function faceDetectionNet(weights) {
var params = extractParams(weights); var net = new FaceDetectionNet();
function forwardTensor(imgTensor) { net.extractWeights(weights);
return tf.tidy(function () { return net;
var resized = resizeLayer(imgTensor);
var features = mobileNetV1(resized, params.mobilenetv1_params);
var _a = predictionLayer(features.out, features.conv11, params.prediction_layer_params), boxPredictions = _a.boxPredictions, classPredictions = _a.classPredictions;
return outputLayer(boxPredictions, classPredictions, params.output_layer_params);
});
}
function forward(input) {
return tf.tidy(function () { return forwardTensor(padToSquare(getImageTensor(input))); });
}
function locateFaces(input, minConfidence, maxResults) {
if (minConfidence === void 0) { minConfidence = 0.8; }
if (maxResults === void 0) { maxResults = 100; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var paddedHeightRelative, paddedWidthRelative, imageDimensions, _a, _boxes, _scores, boxes, scores, i, scoresData, _b, _c, iouThreshold, indices, results;
return tslib_1.__generator(this, function (_d) {
switch (_d.label) {
case 0:
paddedHeightRelative = 1, paddedWidthRelative = 1;
_a = tf.tidy(function () {
var imgTensor = getImageTensor(input);
var _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1];
imageDimensions = { width: width, height: height };
imgTensor = padToSquare(imgTensor);
paddedHeightRelative = imgTensor.shape[1] / height;
paddedWidthRelative = imgTensor.shape[2] / width;
return forwardTensor(imgTensor);
}), _boxes = _a.boxes, _scores = _a.scores;
boxes = _boxes[0];
scores = _scores[0];
for (i = 1; i < _boxes.length; i++) {
_boxes[i].dispose();
_scores[i].dispose();
}
_c = (_b = Array).from;
return [4 /*yield*/, scores.data()];
case 1:
scoresData = _c.apply(_b, [_d.sent()]);
iouThreshold = 0.5;
indices = nonMaxSuppression(boxes, scoresData, maxResults, iouThreshold, minConfidence);
results = indices
.map(function (idx) {
var _a = [
Math.max(0, boxes.get(idx, 0)),
Math.min(1.0, boxes.get(idx, 2))
].map(function (val) { return val * paddedHeightRelative; }), top = _a[0], bottom = _a[1];
var _b = [
Math.max(0, boxes.get(idx, 1)),
Math.min(1.0, boxes.get(idx, 3))
].map(function (val) { return val * paddedWidthRelative; }), left = _b[0], right = _b[1];
return new FaceDetection(scoresData[idx], new Rect(left, top, right - left, bottom - top), imageDimensions);
});
boxes.dispose();
scores.dispose();
return [2 /*return*/, results];
}
});
});
}
return {
forward: forward,
locateFaces: locateFaces
};
} }
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceDetectionNet/index.ts"],"names":[],"mappings":"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"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceDetectionNet/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,cAAc,oBAAoB,CAAC;AAEnC,MAAM,2BAA2B,OAAqB;IACpD,IAAM,GAAG,GAAG,IAAI,gBAAgB,EAAE,CAAA;IAClC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC"}
\ No newline at end of file \ No newline at end of file
export declare function loadQuantizedParams(uri: string | undefined): Promise<any>;
import * as tslib_1 from "tslib";
import { isTensor1D, isTensor4D, isTensor3D } from '../commons/isTensor';
import { loadWeightMap } from '../commons/loadWeightMap';
var DEFAULT_MODEL_NAME = 'face_detection_model';
function extractorsFactory(weightMap) {
function extractPointwiseConvParams(prefix, idx) {
var pointwise_conv_params = {
filters: weightMap[prefix + "/Conv2d_" + idx + "_pointwise/weights"],
batch_norm_offset: weightMap[prefix + "/Conv2d_" + idx + "_pointwise/convolution_bn_offset"]
};
if (!isTensor4D(pointwise_conv_params.filters)) {
throw new Error("expected weightMap[" + prefix + "/Conv2d_" + idx + "_pointwise/weights] to be a Tensor4D, instead have " + pointwise_conv_params.filters);
}
if (!isTensor1D(pointwise_conv_params.batch_norm_offset)) {
throw new Error("expected weightMap[" + prefix + "/Conv2d_" + idx + "_pointwise/convolution_bn_offset] to be a Tensor1D, instead have " + pointwise_conv_params.batch_norm_offset);
}
return pointwise_conv_params;
}
function extractConvPairParams(idx) {
var depthwise_conv_params = {
filters: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/depthwise_weights"],
batch_norm_scale: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/gamma"],
batch_norm_offset: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/beta"],
batch_norm_mean: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_mean"],
batch_norm_variance: weightMap["MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_variance"],
};
if (!isTensor4D(depthwise_conv_params.filters)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/depthwise_weights] to be a Tensor4D, instead have " + depthwise_conv_params.filters);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_scale)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/gamma] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_scale);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_offset)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/beta] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_offset);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_mean)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_mean] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_mean);
}
if (!isTensor1D(depthwise_conv_params.batch_norm_variance)) {
throw new Error("expected weightMap[MobilenetV1/Conv2d_" + idx + "_depthwise/BatchNorm/moving_variance] to be a Tensor1D, instead have " + depthwise_conv_params.batch_norm_variance);
}
return {
depthwise_conv_params: depthwise_conv_params,
pointwise_conv_params: extractPointwiseConvParams('MobilenetV1', idx)
};
}
function extractMobilenetV1Params() {
return {
conv_0_params: extractPointwiseConvParams('MobilenetV1', 0),
conv_pair_params: Array(13).fill(0).map(function (_, i) { return extractConvPairParams(i + 1); })
};
}
function extractBoxPredictorParams(idx) {
var params = {
box_encoding_predictor_params: {
filters: weightMap["Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/weights"],
bias: weightMap["Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/biases"]
},
class_predictor_params: {
filters: weightMap["Prediction/BoxPredictor_" + idx + "/ClassPredictor/weights"],
bias: weightMap["Prediction/BoxPredictor_" + idx + "/ClassPredictor/biases"]
}
};
if (!isTensor4D(params.box_encoding_predictor_params.filters)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/weights] to be a Tensor4D, instead have " + params.box_encoding_predictor_params.filters);
}
if (!isTensor1D(params.box_encoding_predictor_params.bias)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor/biases] to be a Tensor1D, instead have " + params.box_encoding_predictor_params.bias);
}
if (!isTensor4D(params.class_predictor_params.filters)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/ClassPredictor/weights] to be a Tensor4D, instead have " + params.class_predictor_params.filters);
}
if (!isTensor1D(params.class_predictor_params.bias)) {
throw new Error("expected weightMap[Prediction/BoxPredictor_" + idx + "/ClassPredictor/biases] to be a Tensor1D, instead have " + params.class_predictor_params.bias);
}
return params;
}
function extractPredictionLayerParams() {
return {
conv_0_params: extractPointwiseConvParams('Prediction', 0),
conv_1_params: extractPointwiseConvParams('Prediction', 1),
conv_2_params: extractPointwiseConvParams('Prediction', 2),
conv_3_params: extractPointwiseConvParams('Prediction', 3),
conv_4_params: extractPointwiseConvParams('Prediction', 4),
conv_5_params: extractPointwiseConvParams('Prediction', 5),
conv_6_params: extractPointwiseConvParams('Prediction', 6),
conv_7_params: extractPointwiseConvParams('Prediction', 7),
box_predictor_0_params: extractBoxPredictorParams(0),
box_predictor_1_params: extractBoxPredictorParams(1),
box_predictor_2_params: extractBoxPredictorParams(2),
box_predictor_3_params: extractBoxPredictorParams(3),
box_predictor_4_params: extractBoxPredictorParams(4),
box_predictor_5_params: extractBoxPredictorParams(5)
};
}
return {
extractMobilenetV1Params: extractMobilenetV1Params,
extractPredictionLayerParams: extractPredictionLayerParams
};
}
export function loadQuantizedParams(uri) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var weightMap, _a, extractMobilenetV1Params, extractPredictionLayerParams, extra_dim;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, loadWeightMap(uri, DEFAULT_MODEL_NAME)];
case 1:
weightMap = _b.sent();
_a = extractorsFactory(weightMap), extractMobilenetV1Params = _a.extractMobilenetV1Params, extractPredictionLayerParams = _a.extractPredictionLayerParams;
extra_dim = weightMap['Output/extra_dim'];
if (!isTensor3D(extra_dim)) {
throw new Error("expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have " + extra_dim);
}
return [2 /*return*/, {
mobilenetv1_params: extractMobilenetV1Params(),
prediction_layer_params: extractPredictionLayerParams(),
output_layer_params: {
extra_dim: extra_dim
}
}];
}
});
});
}
//# sourceMappingURL=loadQuantizedParams.js.map
\ No newline at end of file
{"version":3,"file":"loadQuantizedParams.js","sourceRoot":"","sources":["../../src/faceDetectionNet/loadQuantizedParams.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types'; import { MobileNetV1 } from './types';
export declare function mobileNetV1(x: tf.Tensor4D, params: FaceDetectionNet.MobileNetV1.Params): { export declare function mobileNetV1(x: tf.Tensor4D, params: MobileNetV1.Params): {
out: tf.Tensor<tf.Rank.R4>; out: tf.Tensor<tf.Rank.R4>;
conv11: any; conv11: any;
}; };
{"version":3,"file":"mobileNetV1.js","sourceRoot":"","sources":["../../src/faceDetectionNet/mobileNetV1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,IAAM,OAAO,GAAG,qBAAqB,CAAA;AAErC,4BACE,CAAc,EACd,MAAwD,EACxD,OAAyB;IAEzB,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAI,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QAChE,GAAG,GAAG,EAAE,CAAC,kBAAkB,CACzB,GAAG,EACH,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,mBAAmB,EAC1B,OAAO,EACP,MAAM,CAAC,gBAAgB,EACvB,MAAM,CAAC,iBAAiB,CACzB,CAAA;QACD,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAElC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,+BAA+B,QAAgB;IAC7C,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,KAAK,QAAQ,EAAhB,CAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACtE,CAAC;AAED,MAAM,sBAAsB,CAAc,EAAE,MAA2C;IACrF,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAI,MAAM,GAAG,IAAI,CAAA;QACjB,IAAI,GAAG,GAAG,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAE7D,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAC,KAAK,EAAE,CAAC;YACvC,IAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAA;YACtB,IAAM,oBAAoB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAA;YAC5D,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,CAAA;YAChF,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAClE,IAAI,QAAQ,KAAK,EAAE,EAAE;gBACnB,MAAM,GAAG,GAAG,CAAA;aACb;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,MAAM,KAAK,IAAI,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;SACjE;QAED,OAAO;YACL,GAAG,KAAA;YACH,MAAM,EAAE,MAAa;SACtB,CAAA;IAEH,CAAC,CAAC,CAAA;AACJ,CAAC"} {"version":3,"file":"mobileNetV1.js","sourceRoot":"","sources":["../../src/faceDetectionNet/mobileNetV1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,IAAM,OAAO,GAAG,qBAAqB,CAAA;AAErC,4BACE,CAAc,EACd,MAAuC,EACvC,OAAyB;IAEzB,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAI,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QAChE,GAAG,GAAG,EAAE,CAAC,kBAAkB,CACzB,GAAG,EACH,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,mBAAmB,EAC1B,OAAO,EACP,MAAM,CAAC,gBAAgB,EACvB,MAAM,CAAC,iBAAiB,CACzB,CAAA;QACD,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAElC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,+BAA+B,QAAgB;IAC7C,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,KAAK,QAAQ,EAAhB,CAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACtE,CAAC;AAED,MAAM,sBAAsB,CAAc,EAAE,MAA0B;IACpE,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAI,MAAM,GAAG,IAAI,CAAA;QACjB,IAAI,GAAG,GAAG,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAE7D,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAC,KAAK,EAAE,CAAC;YACvC,IAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAA;YACtB,IAAM,oBAAoB,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAA;YAC5D,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,CAAA;YAChF,GAAG,GAAG,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,qBAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YAClE,IAAI,QAAQ,KAAK,EAAE,EAAE;gBACnB,MAAM,GAAG,GAAG,CAAA;aACb;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,MAAM,KAAK,IAAI,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;SACjE;QAED,OAAO;YACL,GAAG,KAAA;YACH,MAAM,EAAE,MAAa;SACtB,CAAA;IAEH,CAAC,CAAC,CAAA;AACJ,CAAC"}
\ No newline at end of file \ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types'; import { OutputLayerParams } from './types';
export declare function outputLayer(boxPredictions: tf.Tensor4D, classPredictions: tf.Tensor4D, params: FaceDetectionNet.OutputLayerParams): { export declare function outputLayer(boxPredictions: tf.Tensor4D, classPredictions: tf.Tensor4D, params: OutputLayerParams): {
boxes: tf.Tensor<tf.Rank.R2>[]; boxes: tf.Tensor<tf.Rank.R2>[];
scores: tf.Tensor<tf.Rank.R1>[]; scores: tf.Tensor<tf.Rank.R1>[];
}; };
{"version":3,"file":"outputLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/outputLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,2CAA2C,CAAc;IACvD,IAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAE/C,IAAM,KAAK,GAAG;QACZ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;KACvB,CAAA;IAED,IAAM,OAAO,GAAG;QACd,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/C,CAAA;IAED,OAAO;QACL,KAAK,OAAA;QACL,OAAO,SAAA;KACR,CAAA;AACH,CAAC;AAED,0BAA0B,EAAe,EAAE,EAAe;IAClD,IAAA,0CAGmC,EAFvC,gBAAK,EACL,oBAAO,CACgC;IAEzC,IAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAEhD,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7F,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAEpF,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7F,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAEpF,OAAO,EAAE,CAAC,SAAS,CACjB,EAAE,CAAC,KAAK,CAAC;QACP,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;KAC3B,CAAC,EACF,CAAC,CAAC,EAAE,CAAC,CAAC,CACP,CAAA;AACH,CAAC;AAED,MAAM,sBACJ,cAA2B,EAC3B,gBAA6B,EAC7B,MAA0C;IAE1C,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAEzC,IAAI,KAAK,GAAG,gBAAgB,CAC1B,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAgB,EAChF,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAgB,CACnD,CAAA;QACD,KAAK,GAAG,EAAE,CAAC,OAAO,CAChB,KAAK,EACL,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAC7C,CAAA;QAED,IAAM,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxF,IAAI,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAc,CAAA;QAE5E,MAAM,GAAG,EAAE,CAAC,OAAO,CACjB,MAAM,EACN,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC7B,CAAA;QAED,IAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAkB,CAAA;QACvD,IAAM,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAkB,CAAA;QAEzD,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,aAAa;SACtB,CAAA;IAEH,CAAC,CAAC,CAAA;AACJ,CAAC"} {"version":3,"file":"outputLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/outputLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAK5C,2CAA2C,CAAc;IACvD,IAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAE/C,IAAM,KAAK,GAAG;QACZ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;KACvB,CAAA;IAED,IAAM,OAAO,GAAG;QACd,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/C,CAAA;IAED,OAAO;QACL,KAAK,OAAA;QACL,OAAO,SAAA;KACR,CAAA;AACH,CAAC;AAED,0BAA0B,EAAe,EAAE,EAAe;IAClD,IAAA,0CAGmC,EAFvC,gBAAK,EACL,oBAAO,CACgC;IAEzC,IAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAEhD,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7F,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAEpF,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7F,IAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAEpF,OAAO,EAAE,CAAC,SAAS,CACjB,EAAE,CAAC,KAAK,CAAC;QACP,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;KAC3B,CAAC,EACF,CAAC,CAAC,EAAE,CAAC,CAAC,CACP,CAAA;AACH,CAAC;AAED,MAAM,sBACJ,cAA2B,EAC3B,gBAA6B,EAC7B,MAAyB;IAEzB,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAEzC,IAAI,KAAK,GAAG,gBAAgB,CAC1B,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAgB,EAChF,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAgB,CACnD,CAAA;QACD,KAAK,GAAG,EAAE,CAAC,OAAO,CAChB,KAAK,EACL,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAC7C,CAAA;QAED,IAAM,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxF,IAAI,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAc,CAAA;QAE5E,MAAM,GAAG,EAAE,CAAC,OAAO,CACjB,MAAM,EACN,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC7B,CAAA;QAED,IAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAkB,CAAA;QACvD,IAAM,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAkB,CAAA;QAEzD,OAAO;YACL,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,aAAa;SACtB,CAAA;IAEH,CAAC,CAAC,CAAA;AACJ,CAAC"}
\ No newline at end of file \ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types'; import { PointwiseConvParams } from './types';
export declare function pointwiseConvLayer(x: tf.Tensor4D, params: FaceDetectionNet.PointwiseConvParams, strides: [number, number]): tf.Tensor<tf.Rank.R4>; export declare function pointwiseConvLayer(x: tf.Tensor4D, params: PointwiseConvParams, strides: [number, number]): tf.Tensor<tf.Rank.R4>;
{"version":3,"file":"pointwiseConvLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/pointwiseConvLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,MAAM,6BACJ,CAAc,EACd,MAA4C,EAC5C,OAAyB;IAEzB,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAI,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QACvD,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;QAC3C,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAElC,CAAC,CAAC,CAAA;AACJ,CAAC"} {"version":3,"file":"pointwiseConvLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/pointwiseConvLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAI5C,MAAM,6BACJ,CAAc,EACd,MAA2B,EAC3B,OAAyB;IAEzB,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAI,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;QACvD,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;QAC3C,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAElC,CAAC,CAAC,CAAA;AACJ,CAAC"}
\ No newline at end of file \ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types'; import { PredictionLayerParams } from './types';
export declare function predictionLayer(x: tf.Tensor4D, conv11: tf.Tensor4D, params: FaceDetectionNet.PredictionLayerParams): { export declare function predictionLayer(x: tf.Tensor4D, conv11: tf.Tensor4D, params: PredictionLayerParams): {
boxPredictions: tf.Tensor<tf.Rank.R4>; boxPredictions: tf.Tensor<tf.Rank.R4>;
classPredictions: tf.Tensor<tf.Rank.R4>; classPredictions: tf.Tensor<tf.Rank.R4>;
}; };
{"version":3,"file":"predictionLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/predictionLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,MAAM,0BACJ,CAAc,EACd,MAAmB,EACnB,MAA8C;IAE9C,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAM,KAAK,GAAG,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACjE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAErE,IAAM,cAAc,GAAG,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAChF,IAAM,cAAc,GAAG,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC3E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC/E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC/E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC/E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAE/E,IAAM,cAAc,GAAG,EAAE,CAAC,MAAM,CAAC;YAC/B,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;SACrC,EAAE,CAAC,CAAgB,CAAA;QAEpB,IAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC;YACjC,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;SAC/B,EAAE,CAAC,CAAgB,CAAA;QAEpB,OAAO;YACL,cAAc,gBAAA;YACd,gBAAgB,kBAAA;SACjB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"} {"version":3,"file":"predictionLayer.js","sourceRoot":"","sources":["../../src/faceDetectionNet/predictionLayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,MAAM,0BACJ,CAAc,EACd,MAAmB,EACnB,MAA6B;IAE7B,OAAO,EAAE,CAAC,IAAI,CAAC;QAEb,IAAM,KAAK,GAAG,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACjE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrE,IAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAErE,IAAM,cAAc,GAAG,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAChF,IAAM,cAAc,GAAG,kBAAkB,CAAC,CAAC,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC3E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC/E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC/E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAC/E,IAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;QAE/E,IAAM,cAAc,GAAG,EAAE,CAAC,MAAM,CAAC;YAC/B,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;YACpC,cAAc,CAAC,qBAAqB;SACrC,EAAE,CAAC,CAAgB,CAAA;QAEpB,IAAM,gBAAgB,GAAG,EAAE,CAAC,MAAM,CAAC;YACjC,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;YAC9B,cAAc,CAAC,eAAe;SAC/B,EAAE,CAAC,CAAgB,CAAA;QAEpB,OAAO;YACL,cAAc,gBAAA;YACd,gBAAgB,kBAAA;SACjB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
\ No newline at end of file \ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { ConvParams } from '../commons/types'; import { ConvParams } from '../commons/types';
export declare namespace FaceDetectionNet { export declare type PointwiseConvParams = {
type PointwiseConvParams = { filters: tf.Tensor4D;
batch_norm_offset: tf.Tensor1D;
};
export declare namespace MobileNetV1 {
type DepthwiseConvParams = {
filters: tf.Tensor4D; filters: tf.Tensor4D;
batch_norm_scale: tf.Tensor1D;
batch_norm_offset: tf.Tensor1D; batch_norm_offset: tf.Tensor1D;
batch_norm_mean: tf.Tensor1D;
batch_norm_variance: tf.Tensor1D;
}; };
namespace MobileNetV1 { type ConvPairParams = {
type DepthwiseConvParams = { depthwise_conv_params: DepthwiseConvParams;
filters: tf.Tensor4D; pointwise_conv_params: PointwiseConvParams;
batch_norm_scale: tf.Tensor1D;
batch_norm_offset: tf.Tensor1D;
batch_norm_mean: tf.Tensor1D;
batch_norm_variance: tf.Tensor1D;
};
type ConvPairParams = {
depthwise_conv_params: DepthwiseConvParams;
pointwise_conv_params: PointwiseConvParams;
};
type Params = {
conv_0_params: PointwiseConvParams;
conv_pair_params: ConvPairParams[];
};
}
type BoxPredictionParams = {
box_encoding_predictor_params: ConvParams;
class_predictor_params: ConvParams;
}; };
type PredictionLayerParams = { type Params = {
conv_0_params: PointwiseConvParams; conv_0_params: PointwiseConvParams;
conv_1_params: PointwiseConvParams; conv_pair_params: ConvPairParams[];
conv_2_params: PointwiseConvParams;
conv_3_params: PointwiseConvParams;
conv_4_params: PointwiseConvParams;
conv_5_params: PointwiseConvParams;
conv_6_params: PointwiseConvParams;
conv_7_params: PointwiseConvParams;
box_predictor_0_params: BoxPredictionParams;
box_predictor_1_params: BoxPredictionParams;
box_predictor_2_params: BoxPredictionParams;
box_predictor_3_params: BoxPredictionParams;
box_predictor_4_params: BoxPredictionParams;
box_predictor_5_params: BoxPredictionParams;
};
type OutputLayerParams = {
extra_dim: tf.Tensor3D;
};
type NetParams = {
mobilenetv1_params: MobileNetV1.Params;
prediction_layer_params: PredictionLayerParams;
output_layer_params: OutputLayerParams;
}; };
} }
export declare type BoxPredictionParams = {
box_encoding_predictor_params: ConvParams;
class_predictor_params: ConvParams;
};
export declare type PredictionLayerParams = {
conv_0_params: PointwiseConvParams;
conv_1_params: PointwiseConvParams;
conv_2_params: PointwiseConvParams;
conv_3_params: PointwiseConvParams;
conv_4_params: PointwiseConvParams;
conv_5_params: PointwiseConvParams;
conv_6_params: PointwiseConvParams;
conv_7_params: PointwiseConvParams;
box_predictor_0_params: BoxPredictionParams;
box_predictor_1_params: BoxPredictionParams;
box_predictor_2_params: BoxPredictionParams;
box_predictor_3_params: BoxPredictionParams;
box_predictor_4_params: BoxPredictionParams;
box_predictor_5_params: BoxPredictionParams;
};
export declare type OutputLayerParams = {
extra_dim: tf.Tensor3D;
};
export declare type NetParams = {
mobilenetv1_params: MobileNetV1.Params;
prediction_layer_params: PredictionLayerParams;
output_layer_params: OutputLayerParams;
};
import { FaceLandmarkNet } from './FaceLandmarkNet'; import { FaceLandmarkNet } from './FaceLandmarkNet';
export * from './FaceLandmarkNet'; export * from './FaceLandmarkNet';
export function faceLandmarkNet(weights) { export function faceLandmarkNet(weights) {
var faceLandmarkNet = new FaceLandmarkNet(); var net = new FaceLandmarkNet();
faceLandmarkNet.extractWeights(weights); net.extractWeights(weights);
return faceLandmarkNet; return net;
} }
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,cAAc,mBAAmB,CAAC;AAElC,MAAM,0BAA0B,OAAqB;IACnD,IAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;IAC7C,eAAe,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IACvC,OAAO,eAAe,CAAA;AACxB,CAAC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,cAAc,mBAAmB,CAAC;AAElC,MAAM,0BAA0B,OAAqB;IACnD,IAAM,GAAG,GAAG,IAAI,eAAe,EAAE,CAAA;IACjC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;IAC3B,OAAO,GAAG,CAAA;AACZ,CAAC"}
\ No newline at end of file \ No newline at end of file
...@@ -2,40 +2,47 @@ import * as tslib_1 from "tslib"; ...@@ -2,40 +2,47 @@ import * as tslib_1 from "tslib";
import { loadWeightMap } from '../commons/loadWeightMap'; import { loadWeightMap } from '../commons/loadWeightMap';
import { isTensor4D, isTensor1D, isTensor2D } from '../commons/isTensor'; import { isTensor4D, isTensor1D, isTensor2D } from '../commons/isTensor';
var DEFAULT_MODEL_NAME = 'face_landmark_68_model'; var DEFAULT_MODEL_NAME = 'face_landmark_68_model';
export function loadQuantizedParams(uri) { function extractorsFactory(weightMap) {
return tslib_1.__awaiter(this, void 0, void 0, function () { function extractConvParams(prefix) {
function extractConvParams(prefix) { var params = {
var params = { filters: weightMap[prefix + "/kernel"],
filters: weightMap[prefix + "/kernel"], bias: weightMap[prefix + "/bias"]
bias: weightMap[prefix + "/bias"] };
}; if (!isTensor4D(params.filters)) {
if (!isTensor4D(params.filters)) { throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor4D, instead have " + 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) { if (!isTensor1D(params.bias)) {
var params = { throw new Error("expected weightMap[" + prefix + "/bias] to be a Tensor1D, instead have " + params.bias);
weights: weightMap[prefix + "/kernel"],
bias: weightMap[prefix + "/bias"]
};
if (!isTensor2D(params.weights)) {
throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor2D, instead have " + params.weights);
}
if (!isTensor1D(params.bias)) {
throw new Error("expected weightMap[" + prefix + "/bias] to be a Tensor1D, instead have " + params.bias);
}
return params;
} }
var weightMap; return params;
return tslib_1.__generator(this, function (_a) { }
switch (_a.label) { function extractFcParams(prefix) {
var params = {
weights: weightMap[prefix + "/kernel"],
bias: weightMap[prefix + "/bias"]
};
if (!isTensor2D(params.weights)) {
throw new Error("expected weightMap[" + prefix + "/kernel] to be a Tensor2D, instead have " + params.weights);
}
if (!isTensor1D(params.bias)) {
throw new Error("expected weightMap[" + prefix + "/bias] to be a Tensor1D, instead have " + params.bias);
}
return params;
}
return {
extractConvParams: extractConvParams,
extractFcParams: extractFcParams
};
}
export function loadQuantizedParams(uri) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var weightMap, _a, extractConvParams, extractFcParams;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, loadWeightMap(uri, DEFAULT_MODEL_NAME)]; case 0: return [4 /*yield*/, loadWeightMap(uri, DEFAULT_MODEL_NAME)];
case 1: case 1:
weightMap = _a.sent(); weightMap = _b.sent();
_a = extractorsFactory(weightMap), extractConvParams = _a.extractConvParams, extractFcParams = _a.extractFcParams;
return [2 /*return*/, { return [2 /*return*/, {
conv0_params: extractConvParams('conv2d_0'), conv0_params: extractConvParams('conv2d_0'),
conv1_params: extractConvParams('conv2d_1'), conv1_params: extractConvParams('conv2d_1'),
......
{"version":3,"file":"loadQuantizedParams.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/loadQuantizedParams.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEzE,IAAM,kBAAkB,GAAG,wBAAwB,CAAA;AAEnD,MAAM,8BAAoC,GAAuB;;QAG/D,2BAA2B,MAAc;YACvC,IAAM,MAAM,GAAG;gBACb,OAAO,EAAE,SAAS,CAAI,MAAM,YAAS,CAAgB;gBACrD,IAAI,EAAE,SAAS,CAAI,MAAM,UAAO,CAAgB;aACjD,CAAA;YAED,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;gBAC/B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,gDAA2C,MAAM,CAAC,OAAS,CAAC,CAAA;aACzG;YAED,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBAC5B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,8CAAyC,MAAM,CAAC,IAAM,CAAC,CAAA;aACpG;YAED,OAAO,MAAM,CAAA;QACf,CAAC;QAED,yBAAyB,MAAc;YACrC,IAAM,MAAM,GAAG;gBACb,OAAO,EAAE,SAAS,CAAI,MAAM,YAAS,CAAgB;gBACrD,IAAI,EAAE,SAAS,CAAI,MAAM,UAAO,CAAgB;aACjD,CAAA;YAED,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;gBAC/B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,gDAA2C,MAAM,CAAC,OAAS,CAAC,CAAA;aACzG;YAED,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBAC5B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,8CAAyC,MAAM,CAAC,IAAM,CAAC,CAAA;aACpG;YAED,OAAO,MAAM,CAAA;QACf,CAAC;;;;wBAlCiB,qBAAM,aAAa,CAAC,GAAG,EAAE,kBAAkB,CAAC,EAAA;;oBAAxD,SAAS,GAAG,SAA4C;oBAoC9D,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"} {"version":3,"file":"loadQuantizedParams.js","sourceRoot":"","sources":["../../src/faceLandmarkNet/loadQuantizedParams.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;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,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAC/B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,gDAA2C,MAAM,CAAC,OAAS,CAAC,CAAA;SACzG;QAED,IAAI,CAAC,UAAU,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,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAC/B,MAAM,IAAI,KAAK,CAAC,wBAAsB,MAAM,gDAA2C,MAAM,CAAC,OAAS,CAAC,CAAA;SACzG;QAED,IAAI,CAAC,UAAU,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,MAAM,8BAAoC,GAAuB;;;;;wBAC7C,qBAAM,aAAa,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"}
\ No newline at end of file \ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { euclideanDistance } from './euclideanDistance'; import { euclideanDistance } from './euclideanDistance';
import { faceDetectionNet } from './faceDetectionNet';
import { faceRecognitionNet } from './faceRecognitionNet'; import { faceRecognitionNet } from './faceRecognitionNet';
import { NetInput } from './NetInput'; import { NetInput } from './NetInput';
import { padToSquare } from './padToSquare'; import { padToSquare } from './padToSquare';
export { euclideanDistance, faceDetectionNet, faceRecognitionNet, NetInput, tf, padToSquare }; export { euclideanDistance, faceRecognitionNet, NetInput, tf, padToSquare };
export * from './extractFaces'; export * from './extractFaces';
export * from './extractFaceTensors'; export * from './extractFaceTensors';
export * from './faceDetectionNet';
export * from './faceLandmarkNet'; export * from './faceLandmarkNet';
export * from './utils'; export * from './utils';
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { euclideanDistance } from './euclideanDistance'; import { euclideanDistance } from './euclideanDistance';
import { faceDetectionNet } from './faceDetectionNet';
import { faceRecognitionNet } from './faceRecognitionNet'; import { faceRecognitionNet } from './faceRecognitionNet';
import { NetInput } from './NetInput'; import { NetInput } from './NetInput';
import { padToSquare } from './padToSquare'; import { padToSquare } from './padToSquare';
export { euclideanDistance, faceDetectionNet, faceRecognitionNet, NetInput, tf, padToSquare }; export { euclideanDistance, faceRecognitionNet, NetInput, tf, padToSquare };
export * from './extractFaces'; export * from './extractFaces';
export * from './extractFaceTensors'; export * from './extractFaceTensors';
export * from './faceDetectionNet';
export * from './faceLandmarkNet'; export * from './faceLandmarkNet';
export * from './utils'; export * from './utils';
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map
\ No newline at end of file
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,EACR,EAAE,EACF,WAAW,EACZ,CAAA;AAED,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAA"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,EAAE,EACF,WAAW,EACZ,CAAA;AAED,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAA"}
\ No newline at end of file \ No newline at end of file
...@@ -12,24 +12,12 @@ async function fetchImage(uri) { ...@@ -12,24 +12,12 @@ async function fetchImage(uri) {
return (await axios.get(uri, { responseType: 'blob' })).data return (await axios.get(uri, { responseType: 'blob' })).data
} }
async function initFaceDetectionNet() {
const res = await axios.get('face_detection_model.weights', { responseType: 'arraybuffer' })
const weights = new Float32Array(res.data)
return faceapi.faceDetectionNet(weights)
}
async function initFaceRecognitionNet() { async function initFaceRecognitionNet() {
const res = await axios.get('face_recognition_model.weights', { responseType: 'arraybuffer' }) const res = await axios.get('uncompressed/face_recognition_model.weights', { responseType: 'arraybuffer' })
const weights = new Float32Array(res.data) const weights = new Float32Array(res.data)
return faceapi.faceRecognitionNet(weights) return faceapi.faceRecognitionNet(weights)
} }
async function initFaceLandmarkNet() {
const res = await axios.get('face_landmark_68_model.weights', { responseType: 'arraybuffer' })
const weights = new Float32Array(res.data)
return faceapi.faceLandmarkNet(weights)
}
// fetch first image of each class and compute their descriptors // fetch first image of each class and compute their descriptors
async function initTrainDescriptorsByClass(net, numImagesForTraining = 1) { async function initTrainDescriptorsByClass(net, numImagesForTraining = 1) {
const maxAvailableImagesPerClass = 5 const maxAvailableImagesPerClass = 5
......
...@@ -80,7 +80,8 @@ ...@@ -80,7 +80,8 @@
} }
async function run() { async function run() {
net = await initFaceDetectionNet() net = new faceapi.FaceDetectionNet()
await net.load('/')
$('#loader').hide() $('#loader').hide()
onSelectionChanged($('#selectList select').val()) onSelectionChanged($('#selectList select').val())
} }
......
...@@ -89,8 +89,10 @@ ...@@ -89,8 +89,10 @@
} }
async function run() { async function run() {
detectionNet = await initFaceDetectionNet() detectionNet = new faceapi.FaceDetectionNet()
landmarkNet = await initFaceLandmarkNet() await detectionNet.load('/')
landmarkNet = new faceapi.FaceLandmarkNet()
await landmarkNet.load('/')
$('#loader').hide() $('#loader').hide()
onSelectionChanged($('#selectList select').val()) onSelectionChanged($('#selectList select').val())
} }
......
...@@ -143,9 +143,11 @@ ...@@ -143,9 +143,11 @@
} }
async function run() { async function run() {
detectionNet = await initFaceDetectionNet() detectionNet = new faceapi.FaceDetectionNet()
await detectionNet.load('/')
landmarkNet = new faceapi.FaceLandmarkNet()
await landmarkNet.load('/')
recognitionNet = await initFaceRecognitionNet() recognitionNet = await initFaceRecognitionNet()
landmarkNet = await initFaceLandmarkNet()
trainDescriptorsByClass = await initTrainDescriptorsByClass(recognitionNet, 1) trainDescriptorsByClass = await initTrainDescriptorsByClass(recognitionNet, 1)
$('#loader').hide() $('#loader').hide()
onSelectionChanged($('#selectList select').val()) onSelectionChanged($('#selectList select').val())
......
...@@ -93,8 +93,10 @@ ...@@ -93,8 +93,10 @@
} }
async function run() { async function run() {
detectionNet = await initFaceDetectionNet() detectionNet = new faceapi.FaceDetectionNet()
landmarkNet = await initFaceLandmarkNet() await detectionNet.load('/')
landmarkNet = new faceapi.FaceLandmarkNet()
await landmarkNet.load('/')
$('#loader').hide() $('#loader').hide()
onSelectionChanged($('#selectList select').val()) onSelectionChanged($('#selectList select').val())
} }
......
...@@ -75,7 +75,8 @@ ...@@ -75,7 +75,8 @@
} }
async function run() { async function run() {
net = await initFaceDetectionNet() net = new faceapi.FaceDetectionNet()
await net.load('/')
$('#loader').hide() $('#loader').hide()
onSelectionChanged($('#selectList select').val()) onSelectionChanged($('#selectList select').val())
} }
......
...@@ -87,7 +87,8 @@ ...@@ -87,7 +87,8 @@
} }
async function run() { async function run() {
net = await initFaceDetectionNet() net = new faceapi.FaceDetectionNet()
await net.load('/')
$('#loader').hide() $('#loader').hide()
} }
......
import * as tf from '@tensorflow/tfjs-core';
import { getImageTensor } from '../getImageTensor';
import { NetInput } from '../NetInput';
import { padToSquare } from '../padToSquare';
import { Rect } from '../Rect';
import { Dimensions, TNetInput } from '../types';
import { extractParams } from './extractParams';
import { FaceDetection } from './FaceDetection';
import { loadQuantizedParams } from './loadQuantizedParams';
import { mobileNetV1 } from './mobileNetV1';
import { nonMaxSuppression } from './nonMaxSuppression';
import { outputLayer } from './outputLayer';
import { predictionLayer } from './predictionLayer';
import { resizeLayer } from './resizeLayer';
import { NetParams } from './types';
export class FaceDetectionNet {
private _params: NetParams
public async load(weightsOrUrl: Float32Array | string | undefined): Promise<void> {
if (weightsOrUrl instanceof Float32Array) {
this.extractWeights(weightsOrUrl)
return
}
if (weightsOrUrl && typeof weightsOrUrl !== 'string') {
throw new Error('FaceDetectionNet.load - expected model uri, or weights as Float32Array')
}
this._params = await loadQuantizedParams(weightsOrUrl)
}
public extractWeights(weights: Float32Array) {
this._params = extractParams(weights)
}
private forwardTensor(imgTensor: tf.Tensor4D) {
return tf.tidy(() => {
const resized = resizeLayer(imgTensor) as tf.Tensor4D
const features = mobileNetV1(resized, this._params.mobilenetv1_params)
const {
boxPredictions,
classPredictions
} = predictionLayer(features.out, features.conv11, this._params.prediction_layer_params)
return outputLayer(boxPredictions, classPredictions, this._params.output_layer_params)
})
}
public forward(input: tf.Tensor | NetInput | TNetInput) {
return tf.tidy(
() => this.forwardTensor(padToSquare(getImageTensor(input)))
)
}
public async locateFaces(
input: tf.Tensor | NetInput | TNetInput,
minConfidence: number = 0.8,
maxResults: number = 100,
): Promise<FaceDetection[]> {
let paddedHeightRelative = 1, paddedWidthRelative = 1
let imageDimensions: Dimensions | undefined
const {
boxes: _boxes,
scores: _scores
} = tf.tidy(() => {
let imgTensor = getImageTensor(input)
const [height, width] = imgTensor.shape.slice(1)
imageDimensions = { width, height }
imgTensor = padToSquare(imgTensor)
paddedHeightRelative = imgTensor.shape[1] / height
paddedWidthRelative = imgTensor.shape[2] / width
return this.forwardTensor(imgTensor)
})
// TODO batches
const boxes = _boxes[0]
const scores = _scores[0]
for (let i = 1; i < _boxes.length; i++) {
_boxes[i].dispose()
_scores[i].dispose()
}
// TODO find a better way to filter by minConfidence
const scoresData = Array.from(await scores.data())
const iouThreshold = 0.5
const indices = nonMaxSuppression(
boxes,
scoresData,
maxResults,
iouThreshold,
minConfidence
)
const results = indices
.map(idx => {
const [top, bottom] = [
Math.max(0, boxes.get(idx, 0)),
Math.min(1.0, boxes.get(idx, 2))
].map(val => val * paddedHeightRelative)
const [left, right] = [
Math.max(0, boxes.get(idx, 1)),
Math.min(1.0, boxes.get(idx, 3))
].map(val => val * paddedWidthRelative)
return new FaceDetection(
scoresData[idx],
new Rect(
left,
top,
right - left,
bottom - top
),
imageDimensions as Dimensions
)
})
boxes.dispose()
scores.dispose()
return results
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { convLayer } from '../commons/convLayer'; import { convLayer } from '../commons/convLayer';
import { FaceDetectionNet } from './types'; import { BoxPredictionParams } from './types';
export function boxPredictionLayer( export function boxPredictionLayer(
x: tf.Tensor4D, x: tf.Tensor4D,
params: FaceDetectionNet.BoxPredictionParams params: BoxPredictionParams
) { ) {
return tf.tidy(() => { return tf.tidy(() => {
......
...@@ -2,11 +2,11 @@ import * as tf from '@tensorflow/tfjs-core'; ...@@ -2,11 +2,11 @@ import * as tf from '@tensorflow/tfjs-core';
import { extractWeightsFactory } from '../commons/extractWeightsFactory'; import { extractWeightsFactory } from '../commons/extractWeightsFactory';
import { ConvParams } from '../commons/types'; import { ConvParams } from '../commons/types';
import { FaceDetectionNet } from './types'; import { MobileNetV1, NetParams, PointwiseConvParams, PredictionLayerParams } from './types';
function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) { function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) {
function extractDepthwiseConvParams(numChannels: number): FaceDetectionNet.MobileNetV1.DepthwiseConvParams { function extractDepthwiseConvParams(numChannels: number): MobileNetV1.DepthwiseConvParams {
const filters = tf.tensor4d(extractWeights(3 * 3 * numChannels), [3, 3, numChannels, 1]) const filters = tf.tensor4d(extractWeights(3 * 3 * numChannels), [3, 3, numChannels, 1])
const batch_norm_scale = tf.tensor1d(extractWeights(numChannels)) const batch_norm_scale = tf.tensor1d(extractWeights(numChannels))
const batch_norm_offset = tf.tensor1d(extractWeights(numChannels)) const batch_norm_offset = tf.tensor1d(extractWeights(numChannels))
...@@ -43,7 +43,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -43,7 +43,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
channelsIn: number, channelsIn: number,
channelsOut: number, channelsOut: number,
filterSize: number filterSize: number
): FaceDetectionNet.PointwiseConvParams { ): PointwiseConvParams {
const { const {
filters, filters,
bias bias
...@@ -55,7 +55,10 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -55,7 +55,10 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
} }
function extractConvPairParams(channelsIn: number, channelsOut: number): FaceDetectionNet.MobileNetV1.ConvPairParams { function extractConvPairParams(
channelsIn: number,
channelsOut: number
): MobileNetV1.ConvPairParams {
const depthwise_conv_params = extractDepthwiseConvParams(channelsIn) const depthwise_conv_params = extractDepthwiseConvParams(channelsIn)
const pointwise_conv_params = extractPointwiseConvParams(channelsIn, channelsOut, 1) const pointwise_conv_params = extractPointwiseConvParams(channelsIn, channelsOut, 1)
...@@ -65,7 +68,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -65,7 +68,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
} }
function extractMobilenetV1Params(): FaceDetectionNet.MobileNetV1.Params { function extractMobilenetV1Params(): MobileNetV1.Params {
const conv_0_params = extractPointwiseConvParams(3, 32, 3) const conv_0_params = extractPointwiseConvParams(3, 32, 3)
...@@ -96,7 +99,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -96,7 +99,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
function extractPredictionLayerParams(): FaceDetectionNet.PredictionLayerParams { function extractPredictionLayerParams(): PredictionLayerParams {
const conv_0_params = extractPointwiseConvParams(1024, 256, 1) const conv_0_params = extractPointwiseConvParams(1024, 256, 1)
const conv_1_params = extractPointwiseConvParams(256, 512, 3) const conv_1_params = extractPointwiseConvParams(256, 512, 3)
const conv_2_params = extractPointwiseConvParams(512, 128, 1) const conv_2_params = extractPointwiseConvParams(512, 128, 1)
...@@ -170,7 +173,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -170,7 +173,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
export function extractParams(weights: Float32Array): FaceDetectionNet.NetParams { export function extractParams(weights: Float32Array): NetParams {
const { const {
extractWeights, extractWeights,
getRemainingWeights getRemainingWeights
......
import * as tf from '@tensorflow/tfjs-core'; import { FaceDetectionNet } from './FaceDetectionNet';
import { getImageTensor } from '../getImageTensor'; export * from './FaceDetectionNet';
import { NetInput } from '../NetInput';
import { padToSquare } from '../padToSquare';
import { TNetInput, Dimensions } from '../types';
import { extractParams } from './extractParams';
import { FaceDetection } from './FaceDetection';
import { mobileNetV1 } from './mobileNetV1';
import { nonMaxSuppression } from './nonMaxSuppression';
import { outputLayer } from './outputLayer';
import { predictionLayer } from './predictionLayer';
import { resizeLayer } from './resizeLayer';
import { Rect } from '../Rect';
export function faceDetectionNet(weights: Float32Array) { export function faceDetectionNet(weights: Float32Array) {
const params = extractParams(weights) const net = new FaceDetectionNet()
net.extractWeights(weights)
function forwardTensor(imgTensor: tf.Tensor4D) { return net
return tf.tidy(() => {
const resized = resizeLayer(imgTensor) as tf.Tensor4D
const features = mobileNetV1(resized, params.mobilenetv1_params)
const {
boxPredictions,
classPredictions
} = predictionLayer(features.out, features.conv11, params.prediction_layer_params)
return outputLayer(boxPredictions, classPredictions, params.output_layer_params)
})
}
function forward(input: tf.Tensor | NetInput | TNetInput) {
return tf.tidy(
() => forwardTensor(padToSquare(getImageTensor(input)))
)
}
async function locateFaces(
input: tf.Tensor | NetInput | TNetInput,
minConfidence: number = 0.8,
maxResults: number = 100,
): Promise<FaceDetection[]> {
let paddedHeightRelative = 1, paddedWidthRelative = 1
let imageDimensions: Dimensions | undefined
const {
boxes: _boxes,
scores: _scores
} = tf.tidy(() => {
let imgTensor = getImageTensor(input)
const [height, width] = imgTensor.shape.slice(1)
imageDimensions = { width, height }
imgTensor = padToSquare(imgTensor)
paddedHeightRelative = imgTensor.shape[1] / height
paddedWidthRelative = imgTensor.shape[2] / width
return forwardTensor(imgTensor)
})
// TODO batches
const boxes = _boxes[0]
const scores = _scores[0]
for (let i = 1; i < _boxes.length; i++) {
_boxes[i].dispose()
_scores[i].dispose()
}
// TODO find a better way to filter by minConfidence
const scoresData = Array.from(await scores.data())
const iouThreshold = 0.5
const indices = nonMaxSuppression(
boxes,
scoresData,
maxResults,
iouThreshold,
minConfidence
)
const results = indices
.map(idx => {
const [top, bottom] = [
Math.max(0, boxes.get(idx, 0)),
Math.min(1.0, boxes.get(idx, 2))
].map(val => val * paddedHeightRelative)
const [left, right] = [
Math.max(0, boxes.get(idx, 1)),
Math.min(1.0, boxes.get(idx, 3))
].map(val => val * paddedWidthRelative)
return new FaceDetection(
scoresData[idx],
new Rect(
left,
top,
right - left,
bottom - top
),
imageDimensions as Dimensions
)
})
boxes.dispose()
scores.dispose()
return results
}
return {
forward,
locateFaces
}
} }
\ No newline at end of file
import { isTensor1D, isTensor4D, isTensor3D } from '../commons/isTensor';
import { loadWeightMap } from '../commons/loadWeightMap';
import { BoxPredictionParams, MobileNetV1, PointwiseConvParams, PredictionLayerParams } from './types';
const DEFAULT_MODEL_NAME = 'face_detection_model'
function extractorsFactory(weightMap: any) {
function extractPointwiseConvParams(prefix: string, idx: number): PointwiseConvParams {
const pointwise_conv_params = {
filters: weightMap[`${prefix}/Conv2d_${idx}_pointwise/weights`],
batch_norm_offset: weightMap[`${prefix}/Conv2d_${idx}_pointwise/convolution_bn_offset`]
}
if (!isTensor4D(pointwise_conv_params.filters)) {
throw new Error(`expected weightMap[${prefix}/Conv2d_${idx}_pointwise/weights] to be a Tensor4D, instead have ${pointwise_conv_params.filters}`)
}
if (!isTensor1D(pointwise_conv_params.batch_norm_offset)) {
throw new Error(`expected weightMap[${prefix}/Conv2d_${idx}_pointwise/convolution_bn_offset] to be a Tensor1D, instead have ${pointwise_conv_params.batch_norm_offset}`)
}
return pointwise_conv_params
}
function extractConvPairParams(idx: number): MobileNetV1.ConvPairParams {
const depthwise_conv_params = {
filters: weightMap[`MobilenetV1/Conv2d_${idx}_depthwise/depthwise_weights`],
batch_norm_scale: weightMap[`MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/gamma`],
batch_norm_offset: weightMap[`MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/beta`],
batch_norm_mean: weightMap[`MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/moving_mean`],
batch_norm_variance: weightMap[`MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/moving_variance`],
}
if (!isTensor4D(depthwise_conv_params.filters)) {
throw new Error(`expected weightMap[MobilenetV1/Conv2d_${idx}_depthwise/depthwise_weights] to be a Tensor4D, instead have ${depthwise_conv_params.filters}`)
}
if (!isTensor1D(depthwise_conv_params.batch_norm_scale)) {
throw new Error(`expected weightMap[MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/gamma] to be a Tensor1D, instead have ${depthwise_conv_params.batch_norm_scale}`)
}
if (!isTensor1D(depthwise_conv_params.batch_norm_offset)) {
throw new Error(`expected weightMap[MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/beta] to be a Tensor1D, instead have ${depthwise_conv_params.batch_norm_offset}`)
}
if (!isTensor1D(depthwise_conv_params.batch_norm_mean)) {
throw new Error(`expected weightMap[MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/moving_mean] to be a Tensor1D, instead have ${depthwise_conv_params.batch_norm_mean}`)
}
if (!isTensor1D(depthwise_conv_params.batch_norm_variance)) {
throw new Error(`expected weightMap[MobilenetV1/Conv2d_${idx}_depthwise/BatchNorm/moving_variance] to be a Tensor1D, instead have ${depthwise_conv_params.batch_norm_variance}`)
}
return {
depthwise_conv_params,
pointwise_conv_params: extractPointwiseConvParams('MobilenetV1', idx)
}
}
function extractMobilenetV1Params(): MobileNetV1.Params {
return {
conv_0_params: extractPointwiseConvParams('MobilenetV1', 0),
conv_pair_params: Array(13).fill(0).map((_, i) => extractConvPairParams(i + 1))
}
}
function extractBoxPredictorParams(idx: number): BoxPredictionParams {
const params = {
box_encoding_predictor_params: {
filters: weightMap[`Prediction/BoxPredictor_${idx}/BoxEncodingPredictor/weights`],
bias: weightMap[`Prediction/BoxPredictor_${idx}/BoxEncodingPredictor/biases`]
},
class_predictor_params: {
filters: weightMap[`Prediction/BoxPredictor_${idx}/ClassPredictor/weights`],
bias: weightMap[`Prediction/BoxPredictor_${idx}/ClassPredictor/biases`]
}
}
if (!isTensor4D(params.box_encoding_predictor_params.filters)) {
throw new Error(`expected weightMap[Prediction/BoxPredictor_${idx}/BoxEncodingPredictor/weights] to be a Tensor4D, instead have ${params.box_encoding_predictor_params.filters}`)
}
if (!isTensor1D(params.box_encoding_predictor_params.bias)) {
throw new Error(`expected weightMap[Prediction/BoxPredictor_${idx}/BoxEncodingPredictor/biases] to be a Tensor1D, instead have ${params.box_encoding_predictor_params.bias}`)
}
if (!isTensor4D(params.class_predictor_params.filters)) {
throw new Error(`expected weightMap[Prediction/BoxPredictor_${idx}/ClassPredictor/weights] to be a Tensor4D, instead have ${params.class_predictor_params.filters}`)
}
if (!isTensor1D(params.class_predictor_params.bias)) {
throw new Error(`expected weightMap[Prediction/BoxPredictor_${idx}/ClassPredictor/biases] to be a Tensor1D, instead have ${params.class_predictor_params.bias}`)
}
return params
}
function extractPredictionLayerParams(): PredictionLayerParams {
return {
conv_0_params: extractPointwiseConvParams('Prediction', 0),
conv_1_params: extractPointwiseConvParams('Prediction', 1),
conv_2_params: extractPointwiseConvParams('Prediction', 2),
conv_3_params: extractPointwiseConvParams('Prediction', 3),
conv_4_params: extractPointwiseConvParams('Prediction', 4),
conv_5_params: extractPointwiseConvParams('Prediction', 5),
conv_6_params: extractPointwiseConvParams('Prediction', 6),
conv_7_params: extractPointwiseConvParams('Prediction', 7),
box_predictor_0_params: extractBoxPredictorParams(0),
box_predictor_1_params: extractBoxPredictorParams(1),
box_predictor_2_params: extractBoxPredictorParams(2),
box_predictor_3_params: extractBoxPredictorParams(3),
box_predictor_4_params: extractBoxPredictorParams(4),
box_predictor_5_params: extractBoxPredictorParams(5)
}
}
return {
extractMobilenetV1Params,
extractPredictionLayerParams
}
}
export async function loadQuantizedParams(uri: string | undefined): Promise<any> {//Promise<NetParams> {
const weightMap = await loadWeightMap(uri, DEFAULT_MODEL_NAME)
const {
extractMobilenetV1Params,
extractPredictionLayerParams
} = extractorsFactory(weightMap)
const extra_dim = weightMap['Output/extra_dim']
if (!isTensor3D(extra_dim)) {
throw new Error(`expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have ${extra_dim}`)
}
return {
mobilenetv1_params: extractMobilenetV1Params(),
prediction_layer_params: extractPredictionLayerParams(),
output_layer_params: {
extra_dim
}
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { pointwiseConvLayer } from './pointwiseConvLayer'; import { pointwiseConvLayer } from './pointwiseConvLayer';
import { FaceDetectionNet } from './types'; import { MobileNetV1 } from './types';
const epsilon = 0.0010000000474974513 const epsilon = 0.0010000000474974513
function depthwiseConvLayer( function depthwiseConvLayer(
x: tf.Tensor4D, x: tf.Tensor4D,
params: FaceDetectionNet.MobileNetV1.DepthwiseConvParams, params: MobileNetV1.DepthwiseConvParams,
strides: [number, number] strides: [number, number]
) { ) {
return tf.tidy(() => { return tf.tidy(() => {
...@@ -30,7 +30,7 @@ function getStridesForLayerIdx(layerIdx: number): [number, number] { ...@@ -30,7 +30,7 @@ function getStridesForLayerIdx(layerIdx: number): [number, number] {
return [2, 4, 6, 12].some(idx => idx === layerIdx) ? [2, 2] : [1, 1] return [2, 4, 6, 12].some(idx => idx === layerIdx) ? [2, 2] : [1, 1]
} }
export function mobileNetV1(x: tf.Tensor4D, params: FaceDetectionNet.MobileNetV1.Params) { export function mobileNetV1(x: tf.Tensor4D, params: MobileNetV1.Params) {
return tf.tidy(() => { return tf.tidy(() => {
let conv11 = null let conv11 = null
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types'; import { OutputLayerParams } from './types';
function getCenterCoordinatesAndSizesLayer(x: tf.Tensor2D) { function getCenterCoordinatesAndSizesLayer(x: tf.Tensor2D) {
const vec = tf.unstack(tf.transpose(x, [1, 0])) const vec = tf.unstack(tf.transpose(x, [1, 0]))
...@@ -49,7 +50,7 @@ function decodeBoxesLayer(x0: tf.Tensor2D, x1: tf.Tensor2D) { ...@@ -49,7 +50,7 @@ function decodeBoxesLayer(x0: tf.Tensor2D, x1: tf.Tensor2D) {
export function outputLayer( export function outputLayer(
boxPredictions: tf.Tensor4D, boxPredictions: tf.Tensor4D,
classPredictions: tf.Tensor4D, classPredictions: tf.Tensor4D,
params: FaceDetectionNet.OutputLayerParams params: OutputLayerParams
) { ) {
return tf.tidy(() => { return tf.tidy(() => {
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types'; import { PointwiseConvParams } from './types';
export function pointwiseConvLayer( export function pointwiseConvLayer(
x: tf.Tensor4D, x: tf.Tensor4D,
params: FaceDetectionNet.PointwiseConvParams, params: PointwiseConvParams,
strides: [number, number] strides: [number, number]
) { ) {
return tf.tidy(() => { return tf.tidy(() => {
......
...@@ -2,12 +2,12 @@ import * as tf from '@tensorflow/tfjs-core'; ...@@ -2,12 +2,12 @@ import * as tf from '@tensorflow/tfjs-core';
import { boxPredictionLayer } from './boxPredictionLayer'; import { boxPredictionLayer } from './boxPredictionLayer';
import { pointwiseConvLayer } from './pointwiseConvLayer'; import { pointwiseConvLayer } from './pointwiseConvLayer';
import { FaceDetectionNet } from './types'; import { PredictionLayerParams } from './types';
export function predictionLayer( export function predictionLayer(
x: tf.Tensor4D, x: tf.Tensor4D,
conv11: tf.Tensor4D, conv11: tf.Tensor4D,
params: FaceDetectionNet.PredictionLayerParams params: PredictionLayerParams
) { ) {
return tf.tidy(() => { return tf.tidy(() => {
......
...@@ -2,64 +2,61 @@ import * as tf from '@tensorflow/tfjs-core'; ...@@ -2,64 +2,61 @@ import * as tf from '@tensorflow/tfjs-core';
import { ConvParams } from '../commons/types'; import { ConvParams } from '../commons/types';
export namespace FaceDetectionNet { export type PointwiseConvParams = {
filters: tf.Tensor4D
batch_norm_offset: tf.Tensor1D
}
export namespace MobileNetV1 {
export type PointwiseConvParams = { export type DepthwiseConvParams = {
filters: tf.Tensor4D filters: tf.Tensor4D
batch_norm_scale: tf.Tensor1D
batch_norm_offset: tf.Tensor1D batch_norm_offset: tf.Tensor1D
batch_norm_mean: tf.Tensor1D
batch_norm_variance: tf.Tensor1D
} }
export namespace MobileNetV1 { export type ConvPairParams = {
depthwise_conv_params: DepthwiseConvParams
export type DepthwiseConvParams = { pointwise_conv_params: PointwiseConvParams
filters: tf.Tensor4D
batch_norm_scale: tf.Tensor1D
batch_norm_offset: tf.Tensor1D
batch_norm_mean: tf.Tensor1D
batch_norm_variance: tf.Tensor1D
}
export type ConvPairParams = {
depthwise_conv_params: DepthwiseConvParams
pointwise_conv_params: PointwiseConvParams
}
export type Params = {
conv_0_params: PointwiseConvParams
conv_pair_params: ConvPairParams[]
}
}
export type BoxPredictionParams = {
box_encoding_predictor_params: ConvParams
class_predictor_params: ConvParams
} }
export type PredictionLayerParams = { export type Params = {
conv_0_params: PointwiseConvParams conv_0_params: PointwiseConvParams
conv_1_params: PointwiseConvParams conv_pair_params: ConvPairParams[]
conv_2_params: PointwiseConvParams
conv_3_params: PointwiseConvParams
conv_4_params: PointwiseConvParams
conv_5_params: PointwiseConvParams
conv_6_params: PointwiseConvParams
conv_7_params: PointwiseConvParams
box_predictor_0_params: BoxPredictionParams
box_predictor_1_params: BoxPredictionParams
box_predictor_2_params: BoxPredictionParams
box_predictor_3_params: BoxPredictionParams
box_predictor_4_params: BoxPredictionParams
box_predictor_5_params: BoxPredictionParams
} }
export type OutputLayerParams = { }
extra_dim: tf.Tensor3D
}
export type NetParams = { export type BoxPredictionParams = {
mobilenetv1_params: MobileNetV1.Params, box_encoding_predictor_params: ConvParams
prediction_layer_params: PredictionLayerParams, class_predictor_params: ConvParams
output_layer_params: OutputLayerParams }
}
export type PredictionLayerParams = {
conv_0_params: PointwiseConvParams
conv_1_params: PointwiseConvParams
conv_2_params: PointwiseConvParams
conv_3_params: PointwiseConvParams
conv_4_params: PointwiseConvParams
conv_5_params: PointwiseConvParams
conv_6_params: PointwiseConvParams
conv_7_params: PointwiseConvParams
box_predictor_0_params: BoxPredictionParams
box_predictor_1_params: BoxPredictionParams
box_predictor_2_params: BoxPredictionParams
box_predictor_3_params: BoxPredictionParams
box_predictor_4_params: BoxPredictionParams
box_predictor_5_params: BoxPredictionParams
}
export type OutputLayerParams = {
extra_dim: tf.Tensor3D
}
export type NetParams = {
mobilenetv1_params: MobileNetV1.Params,
prediction_layer_params: PredictionLayerParams,
output_layer_params: OutputLayerParams
} }
...@@ -3,7 +3,7 @@ import { FaceLandmarkNet } from './FaceLandmarkNet'; ...@@ -3,7 +3,7 @@ import { FaceLandmarkNet } from './FaceLandmarkNet';
export * from './FaceLandmarkNet'; export * from './FaceLandmarkNet';
export function faceLandmarkNet(weights: Float32Array) { export function faceLandmarkNet(weights: Float32Array) {
const faceLandmarkNet = new FaceLandmarkNet() const net = new FaceLandmarkNet()
faceLandmarkNet.extractWeights(weights) net.extractWeights(weights)
return faceLandmarkNet return net
} }
\ No newline at end of file
...@@ -7,8 +7,7 @@ import { isTensor4D, isTensor1D, isTensor2D } from '../commons/isTensor'; ...@@ -7,8 +7,7 @@ import { isTensor4D, isTensor1D, isTensor2D } from '../commons/isTensor';
const DEFAULT_MODEL_NAME = 'face_landmark_68_model' const DEFAULT_MODEL_NAME = 'face_landmark_68_model'
export async function loadQuantizedParams(uri: string | undefined): Promise<NetParams> { function extractorsFactory(weightMap: any) {
const weightMap = await loadWeightMap(uri, DEFAULT_MODEL_NAME)
function extractConvParams(prefix: string): ConvParams { function extractConvParams(prefix: string): ConvParams {
const params = { const params = {
...@@ -45,6 +44,20 @@ export async function loadQuantizedParams(uri: string | undefined): Promise<NetP ...@@ -45,6 +44,20 @@ export async function loadQuantizedParams(uri: string | undefined): Promise<NetP
} }
return { return {
extractConvParams,
extractFcParams
}
}
export async function loadQuantizedParams(uri: string | undefined): Promise<NetParams> {
const weightMap = await loadWeightMap(uri, DEFAULT_MODEL_NAME)
const {
extractConvParams,
extractFcParams
} = extractorsFactory(weightMap)
return {
conv0_params: extractConvParams('conv2d_0'), conv0_params: extractConvParams('conv2d_0'),
conv1_params: extractConvParams('conv2d_1'), conv1_params: extractConvParams('conv2d_1'),
conv2_params: extractConvParams('conv2d_2'), conv2_params: extractConvParams('conv2d_2'),
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { euclideanDistance } from './euclideanDistance'; import { euclideanDistance } from './euclideanDistance';
import { faceDetectionNet } from './faceDetectionNet';
import { faceRecognitionNet } from './faceRecognitionNet'; import { faceRecognitionNet } from './faceRecognitionNet';
import { NetInput } from './NetInput'; import { NetInput } from './NetInput';
import { padToSquare } from './padToSquare'; import { padToSquare } from './padToSquare';
export { export {
euclideanDistance, euclideanDistance,
faceDetectionNet,
faceRecognitionNet, faceRecognitionNet,
NetInput, NetInput,
tf, tf,
...@@ -17,5 +15,6 @@ export { ...@@ -17,5 +15,6 @@ export {
export * from './extractFaces' export * from './extractFaces'
export * from './extractFaceTensors' export * from './extractFaceTensors'
export * from './faceDetectionNet';
export * from './faceLandmarkNet'; export * from './faceLandmarkNet';
export * from './utils' export * from './utils'
\ No newline at end of file
[{"paths":["face_detection_model-shard1","face_detection_model-shard2"],"weights":[{"dtype":"float32","shape":[1,1,512,9],"quantization":{"scale":0.0026856216729856004,"min":-0.34107395246917127,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/ClassPredictor/weights"},{"dtype":"float32","shape":[9],"quantization":{"scale":0.00198518248165355,"min":-0.32159956202787515,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,1024,18],"quantization":{"scale":0.003060340296988394,"min":-0.489654447518143,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.0008040678851744708,"min":-0.12221831854651957,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,512,18],"quantization":{"scale":0.0012513800578958848,"min":-0.16017664741067325,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.000338070518245884,"min":-0.05510549447407909,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,256,18],"quantization":{"scale":0.0011819932975021064,"min":-0.1453851755927591,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.00015985782386041154,"min":-0.026536398760828316,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,256,18],"quantization":{"scale":0.0007035591438704846,"min":-0.08513065640832863,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.00008793946574716008,"min":-0.013190919862074012,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/ClassPredictor/biases"},{"dtype":"float32","shape":[1,1,128,18],"quantization":{"scale":0.00081320781918133,"min":-0.11059626340866088,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/ClassPredictor/weights"},{"dtype":"float32","shape":[18],"quantization":{"scale":0.0000980533805547976,"min":-0.014609953702664841,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/ClassPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":3,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/stack_1/2"},{"dtype":"int32","shape":[3],"quantization":{"scale":0.00392156862745098,"min":0,"dtype":"uint8"},"name":"Postprocessor/Slice/begin"},{"dtype":"int32","shape":[3],"quantization":{"scale":1,"min":-1,"dtype":"uint8"},"name":"Postprocessor/Slice/size"},{"dtype":"float32","shape":[1,1,512,12],"quantization":{"scale":0.003730384859384275,"min":-0.4327246436885759,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[12],"quantization":{"scale":0.0018744708568442102,"min":-0.3917644090804399,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":3072,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/stack_1/1"},{"dtype":"float32","shape":[1,1,1024,24],"quantization":{"scale":0.00157488017689948,"min":-0.20000978246623397,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.0002823906713256649,"min":-0.043488163384152394,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":1536,"dtype":"uint8"},"name":"Prediction/BoxPredictor_1/stack_1/1"},{"dtype":"float32","shape":[1,1,512,24],"quantization":{"scale":0.0007974451663447361,"min":-0.11004743295557358,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.0001350417988849621,"min":-0.02039131163162928,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":384,"dtype":"uint8"},"name":"Prediction/BoxPredictor_2/stack_1/1"},{"dtype":"float32","shape":[1,1,256,24],"quantization":{"scale":0.0007113990246080885,"min":-0.0860792819775787,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.000050115815418608046,"min":-0.007617603943628423,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":96,"dtype":"uint8"},"name":"Prediction/BoxPredictor_3/stack_1/1"},{"dtype":"float32","shape":[1,1,256,24],"quantization":{"scale":0.000590049314732645,"min":-0.06903576982371946,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.00003513663861097074,"min":-0.006359731588585704,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/BoxEncodingPredictor/biases"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":24,"dtype":"uint8"},"name":"Prediction/BoxPredictor_4/stack_1/1"},{"dtype":"float32","shape":[1,1,128,24],"quantization":{"scale":0.0005990567744946948,"min":-0.07907549423329971,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/BoxEncodingPredictor/weights"},{"dtype":"float32","shape":[24],"quantization":{"scale":0.00003392884288640583,"min":-0.006039334033780238,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/BoxEncodingPredictor/biases"},{"dtype":"float32","shape":[],"quantization":{"scale":1,"min":0.007843137718737125,"dtype":"uint8"},"name":"Preprocessor/mul/x"},{"dtype":"int32","shape":[2],"quantization":{"scale":1,"min":512,"dtype":"uint8"},"name":"Preprocessor/ResizeImage/size"},{"dtype":"float32","shape":[],"quantization":{"scale":1,"min":1,"dtype":"uint8"},"name":"Preprocessor/sub/y"},{"dtype":"float32","shape":[3,3,3,32],"quantization":{"scale":0.03948551065781537,"min":-5.014659853542552,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_0_pointwise/weights"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.0498106133704092,"min":-7.371970778820562,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_0_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,32,1],"quantization":{"scale":0.036833542468501075,"min":-4.714693435968138,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/depthwise_weights"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.012173276705046495,"min":-0.012173276705046495,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.032182769214405736,"min":-2.4780732295092416,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.028287527607936486,"min":-3.366215785344442,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[32],"quantization":{"scale":0.04716738532571232,"min":3.9071404665769224e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,32,64],"quantization":{"scale":0.04010109433940812,"min":-4.290817094316669,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_pointwise/weights"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.2212210038129021,"min":-34.51047659481273,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_1_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,64,1],"quantization":{"scale":0.010024750933927648,"min":-1.343316625146305,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/depthwise_weights"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.006120916675118839,"min":0.5227176547050476,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.02317035385206634,"min":-0.7646216771181892,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.04980821422502106,"min":-5.8275610643274645,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.051751047022202436,"min":3.916113799002297e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,64,128],"quantization":{"scale":0.021979344124887504,"min":-2.1319963801140878,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.09958663267247816,"min":-11.054116226645077,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_2_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,1],"quantization":{"scale":0.01943492702409333,"min":-2.6237151482525993,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/depthwise_weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.017852897737540452,"min":0.40204083919525146,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.029888209174661076,"min":-1.972621805527631,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.029319268581913967,"min":-5.130872001834945,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.014018708584355373,"min":3.9083178263362604e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,128,128],"quantization":{"scale":0.020776657964669022,"min":-2.5347522716896207,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.14383157094319662,"min":-9.636715253194174,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_3_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,1],"quantization":{"scale":0.004463558571011412,"min":-0.5981168485155293,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/depthwise_weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.006487431245691636,"min":0.47910428047180176,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.026542164297664865,"min":-1.2209395576925839,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.05119945675719018,"min":-8.60150873520795,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.03081628388049556,"min":3.911508751095344e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,128,256],"quantization":{"scale":0.010758659886378868,"min":-1.0328313490923713,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.08058219610476026,"min":-9.34753474815219,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_4_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,256,1],"quantization":{"scale":0.01145936741548426,"min":-1.3292866201961742,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/depthwise_weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.0083988838336047,"min":0.36280909180641174,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.02858148649627087,"min":-3.6584302715226715,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.03988401375564874,"min":-7.099354448505476,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.009090481683904049,"min":0.020878996700048447,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,256,256],"quantization":{"scale":0.008951201625898773,"min":-1.1189002032373465,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.051758006974762565,"min":-5.745138774198645,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_5_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,256,1],"quantization":{"scale":0.004110433190476661,"min":-0.6042336790000691,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/depthwise_weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.013170199768216002,"min":0.3386639356613159,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.03599378548416437,"min":-3.70735990486893,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.026967673208199296,"min":-3.748506575939702,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.012615410486857097,"min":3.9111388979838637e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,256,512],"quantization":{"scale":0.00822840648538926,"min":-1.1848905338960536,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.06608965817619772,"min":-7.468131373910342,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_6_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.008801074355256323,"min":-0.9593171047229393,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.030577416513480393,"min":0.3285980224609375,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04778536441279393,"min":-8.935863145192464,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04331884945140165,"min":-9.660103427662568,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04126455444367785,"min":0.000604183878749609,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.009305818408143287,"min":-1.1446156642016243,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04640720217835669,"min":-4.733534622192383,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_7_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.008138792655047248,"min":-0.9766551186056698,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.027351748358969596,"min":0.34030041098594666,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04415061053107767,"min":-7.019947074441349,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.02476683784933651,"min":-2.9224868662217083,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.02547598832684076,"min":0.00026032101595774293,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.01083052625843123,"min":-1.2563410459780227,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.06360894371481503,"min":-7.951117964351878,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_8_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.006704086883395326,"min":-0.8648272079579971,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.015343831567203297,"min":0.2711026668548584,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.03378283930759804,"min":-4.797163181678922,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.021910778213949763,"min":-3.987761634938857,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.009284070410007296,"min":0.000021581046894425526,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.012783036979974485,"min":-1.9046725100161983,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.07273082733154297,"min":-9.52773838043213,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_9_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.006126228033327589,"min":-0.7351473639993107,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.029703759212119908,"min":0.28687000274658203,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.04394429898729511,"min":-6.3279790541704966,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.016566915605582443,"min":-2.7501079905266854,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.012152872833551145,"min":3.913338286370366e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.01354524388032801,"min":-1.7473364605623134,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.08566816367355047,"min":-9.937506986131854,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_10_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.006012305558896532,"min":-0.7876120282154457,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.01469323155926723,"min":0.29223933815956116,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.030889174517463234,"min":-3.2433633243336395,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.014836942448335536,"min":-2.047498057870304,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.007234466105343445,"min":0.00013165915152058005,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,512],"quantization":{"scale":0.016261722527298274,"min":-1.4798167499841428,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.091437328563017,"min":-14.172785927267636,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_11_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,512,1],"quantization":{"scale":0.004750356487199372,"min":-0.650798838746314,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/depthwise_weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.008174965545242907,"min":0.3120670020580292,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.030133422215779623,"min":-2.41067377726237,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.006088157261119169,"min":-0.7853722866843729,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.003668997334498985,"min":3.9124486300013356e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,512,1024],"quantization":{"scale":0.010959514449624454,"min":-1.4028178495519301,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_pointwise/weights"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.10896045834410424,"min":-14.818622334798176,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_12_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,1024,1],"quantization":{"scale":0.004633033509347953,"min":-0.5652300881404502,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/depthwise_weights"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.022285057224479377,"min":0.23505790531635284,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/gamma"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.0324854850769043,"min":-3.9957146644592285,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/beta"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.014760061806323482,"min":-2.125448900110581,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/moving_mean"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.0036057423142825855,"min":3.9067056828997994e-36,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_depthwise/BatchNorm/moving_variance"},{"dtype":"float32","shape":[1,1,1024,1024],"quantization":{"scale":0.017311988157384536,"min":-2.094750567043529,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_pointwise/weights"},{"dtype":"float32","shape":[1024],"quantization":{"scale":0.16447528764313343,"min":-25.658144872328815,"dtype":"uint8"},"name":"MobilenetV1/Conv2d_13_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,1024,256],"quantization":{"scale":0.0026493051472832175,"min":-0.36825341547236723,"dtype":"uint8"},"name":"Prediction/Conv2d_0_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.012474596734140433,"min":-2.3078003958159803,"dtype":"uint8"},"name":"Prediction/Conv2d_0_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,256,512],"quantization":{"scale":0.014533351449405445,"min":-1.8166689311756807,"dtype":"uint8"},"name":"Prediction/Conv2d_1_pointwise/weights"},{"dtype":"float32","shape":[512],"quantization":{"scale":0.024268776762719248,"min":-2.4754152297973633,"dtype":"uint8"},"name":"Prediction/Conv2d_1_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,512,128],"quantization":{"scale":0.002208403746287028,"min":-0.28709248701731366,"dtype":"uint8"},"name":"Prediction/Conv2d_2_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.012451349052728392,"min":-1.5937726787492341,"dtype":"uint8"},"name":"Prediction/Conv2d_2_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,256],"quantization":{"scale":0.026334229637594783,"min":-2.8967652601354263,"dtype":"uint8"},"name":"Prediction/Conv2d_3_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.02509917792151956,"min":-1.4055539636050953,"dtype":"uint8"},"name":"Prediction/Conv2d_3_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,256,128],"quantization":{"scale":0.004565340046789132,"min":-0.3971845840706545,"dtype":"uint8"},"name":"Prediction/Conv2d_4_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.017302456556581983,"min":-2.5953684834872974,"dtype":"uint8"},"name":"Prediction/Conv2d_4_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,128,256],"quantization":{"scale":0.025347338470758176,"min":-3.8527954475552426,"dtype":"uint8"},"name":"Prediction/Conv2d_5_pointwise/weights"},{"dtype":"float32","shape":[256],"quantization":{"scale":0.033134659598855414,"min":-2.9158500446992766,"dtype":"uint8"},"name":"Prediction/Conv2d_5_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[1,1,256,64],"quantization":{"scale":0.002493104397081861,"min":-0.2817207968702503,"dtype":"uint8"},"name":"Prediction/Conv2d_6_pointwise/weights"},{"dtype":"float32","shape":[64],"quantization":{"scale":0.011383360974928912,"min":-1.2749364291920382,"dtype":"uint8"},"name":"Prediction/Conv2d_6_pointwise/convolution_bn_offset"},{"dtype":"float32","shape":[3,3,64,128],"quantization":{"scale":0.020821522731407017,"min":-2.7484410005457263,"dtype":"uint8"},"name":"Prediction/Conv2d_7_pointwise/weights"},{"dtype":"float32","shape":[128],"quantization":{"scale":0.052144218893612135,"min":-3.5979511036592373,"dtype":"uint8"},"name":"Prediction/Conv2d_7_pointwise/convolution_bn_offset"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":6,"dtype":"uint8"},"name":"Prediction/BoxPredictor_5/stack_1/1"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":1,"dtype":"uint8"},"name":"concat_1/axis"},{"dtype":"int32","shape":[1],"quantization":{"scale":1,"min":0,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/strided_slice/stack"},{"dtype":"int32","shape":[1],"quantization":{"scale":1,"min":1,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/strided_slice/stack_1"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":5118,"dtype":"uint8"},"name":"Postprocessor/stack/1"},{"dtype":"int32","shape":[],"quantization":{"scale":1,"min":4,"dtype":"uint8"},"name":"Prediction/BoxPredictor_0/stack/3"},{"dtype":"float32","shape":[1, 5118, 4],"name":"Output/extra_dim"}]}]
\ 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