Commit 62163b6d by vincent

init faceLandmarkNet

parent c378f933
import * as tf from '@tensorflow/tfjs-core';
import { ConvParams, ExtractWeightsFunction } from './types';
export function extractConvParamsFactory(extractWeights: ExtractWeightsFunction) {
return function (
channelsIn: number,
channelsOut: number,
filterSize: number
): ConvParams {
const filters = tf.tensor4d(
extractWeights(channelsIn * channelsOut * filterSize * filterSize),
[filterSize, filterSize, channelsIn, channelsOut]
)
const bias = tf.tensor1d(extractWeights(channelsOut))
return {
filters,
bias
}
}
}
\ No newline at end of file
export function extractWeightsFactory(weights: Float32Array) {
let remainingWeights = weights
function extractWeights(numWeights: number): Float32Array {
const ret = remainingWeights.slice(0, numWeights)
remainingWeights = remainingWeights.slice(numWeights)
return ret
}
function getRemainingWeights(): Float32Array {
return remainingWeights
}
return {
extractWeights,
getRemainingWeights
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
export type ConvParams = {
filters: tf.Tensor4D
bias: tf.Tensor1D
}
export type ExtractWeightsFunction = (numWeights: number) => Float32Array
\ 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 { FaceDetectionNet } from './types'; import { FaceDetectionNet } from './types';
function convWithBias( function convWithBias(
x: tf.Tensor4D, x: tf.Tensor4D,
params: FaceDetectionNet.ConvWithBiasParams params: ConvParams
) { ) {
return tf.tidy(() => return tf.tidy(() =>
tf.add( tf.add(
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { extractWeightsFactory } from '../commons/extractWeightsFactory';
import { ConvParams } from '../commons/types';
import { FaceDetectionNet } from './types'; import { FaceDetectionNet } from './types';
function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) { function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) {
...@@ -20,11 +22,11 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -20,11 +22,11 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
} }
function extractConvWithBiasParams( function extractConvParams(
channelsIn: number, channelsIn: number,
channelsOut: number, channelsOut: number,
filterSize: number filterSize: number
): FaceDetectionNet.ConvWithBiasParams { ): ConvParams {
const filters = tf.tensor4d( const filters = tf.tensor4d(
extractWeights(channelsIn * channelsOut * filterSize * filterSize), extractWeights(channelsIn * channelsOut * filterSize * filterSize),
[filterSize, filterSize, channelsIn, channelsOut] [filterSize, filterSize, channelsIn, channelsOut]
...@@ -45,7 +47,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -45,7 +47,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
const { const {
filters, filters,
bias bias
} = extractConvWithBiasParams(channelsIn, channelsOut, filterSize) } = extractConvParams(channelsIn, channelsOut, filterSize)
return { return {
filters, filters,
...@@ -104,18 +106,18 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -104,18 +106,18 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
const conv_6_params = extractPointwiseConvParams(256, 64, 1) const conv_6_params = extractPointwiseConvParams(256, 64, 1)
const conv_7_params = extractPointwiseConvParams(64, 128, 3) const conv_7_params = extractPointwiseConvParams(64, 128, 3)
const box_encoding_0_predictor_params = extractConvWithBiasParams(512, 12, 1) const box_encoding_0_predictor_params = extractConvParams(512, 12, 1)
const class_predictor_0_params = extractConvWithBiasParams(512, 9, 1) const class_predictor_0_params = extractConvParams(512, 9, 1)
const box_encoding_1_predictor_params = extractConvWithBiasParams(1024, 24, 1) const box_encoding_1_predictor_params = extractConvParams(1024, 24, 1)
const class_predictor_1_params = extractConvWithBiasParams(1024, 18, 1) const class_predictor_1_params = extractConvParams(1024, 18, 1)
const box_encoding_2_predictor_params = extractConvWithBiasParams(512, 24, 1) const box_encoding_2_predictor_params = extractConvParams(512, 24, 1)
const class_predictor_2_params = extractConvWithBiasParams(512, 18, 1) const class_predictor_2_params = extractConvParams(512, 18, 1)
const box_encoding_3_predictor_params = extractConvWithBiasParams(256, 24, 1) const box_encoding_3_predictor_params = extractConvParams(256, 24, 1)
const class_predictor_3_params = extractConvWithBiasParams(256, 18, 1) const class_predictor_3_params = extractConvParams(256, 18, 1)
const box_encoding_4_predictor_params = extractConvWithBiasParams(256, 24, 1) const box_encoding_4_predictor_params = extractConvParams(256, 24, 1)
const class_predictor_4_params = extractConvWithBiasParams(256, 18, 1) const class_predictor_4_params = extractConvParams(256, 18, 1)
const box_encoding_5_predictor_params = extractConvWithBiasParams(128, 24, 1) const box_encoding_5_predictor_params = extractConvParams(128, 24, 1)
const class_predictor_5_params = extractConvWithBiasParams(128, 18, 1) const class_predictor_5_params = extractConvParams(128, 18, 1)
const box_predictor_0_params = { const box_predictor_0_params = {
box_encoding_predictor_params: box_encoding_0_predictor_params, box_encoding_predictor_params: box_encoding_0_predictor_params,
...@@ -169,11 +171,10 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -169,11 +171,10 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
export function extractParams(weights: Float32Array): FaceDetectionNet.NetParams { export function extractParams(weights: Float32Array): FaceDetectionNet.NetParams {
const extractWeights = (numWeights: number): Float32Array => { const {
const ret = weights.slice(0, numWeights) extractWeights,
weights = weights.slice(numWeights) getRemainingWeights
return ret } = extractWeightsFactory(weights)
}
const { const {
extractMobilenetV1Params, extractMobilenetV1Params,
...@@ -190,8 +191,8 @@ export function extractParams(weights: Float32Array): FaceDetectionNet.NetParams ...@@ -190,8 +191,8 @@ export function extractParams(weights: Float32Array): FaceDetectionNet.NetParams
extra_dim extra_dim
} }
if (weights.length !== 0) { if (getRemainingWeights().length !== 0) {
throw new Error(`weights remaing after extract: ${weights.length}`) throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`)
} }
return { return {
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { ConvParams } from '../commons/types';
export namespace FaceDetectionNet { export namespace FaceDetectionNet {
export type PointwiseConvParams = { export type PointwiseConvParams = {
...@@ -29,14 +31,9 @@ export namespace FaceDetectionNet { ...@@ -29,14 +31,9 @@ export namespace FaceDetectionNet {
} }
export type ConvWithBiasParams = {
filters: tf.Tensor4D
bias: tf.Tensor1D
}
export type BoxPredictionParams = { export type BoxPredictionParams = {
box_encoding_predictor_params: ConvWithBiasParams box_encoding_predictor_params: ConvParams
class_predictor_params: ConvWithBiasParams class_predictor_params: ConvParams
} }
export type PredictionLayerParams = { export type PredictionLayerParams = {
......
import { extractConvParamsFactory } from '../commons/extractConvParamsFactory';
import { extractWeightsFactory } from '../commons/extractWeightsFactory';
import { FaceLandmarkNet } from './types';
import * as tf from '@tensorflow/tfjs-core';
export function extractParams(weights: Float32Array): FaceLandmarkNet.NetParams {
const {
extractWeights,
getRemainingWeights
} = extractWeightsFactory(weights)
const extractConvParams = extractConvParamsFactory(extractWeights)
function extractFcParams(channelsIn: number, channelsOut: number,): FaceLandmarkNet.FCParams {
const fc_weights = tf.tensor2d(extractWeights(channelsIn * channelsOut), [channelsIn, channelsOut])
const fc_bias = tf.tensor1d(extractWeights(channelsOut))
return {
weights: fc_weights,
bias: fc_bias
}
}
if (getRemainingWeights().length !== 0) {
throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`)
}
return {
conv0_params: extractConvParams(3, 32, 3),
conv1_params: extractConvParams(32, 64, 3),
conv2_params: extractConvParams(64, 64, 3),
conv3_params: extractConvParams(64, 64, 3),
conv4_params: extractConvParams(64, 64, 3),
conv5_params: extractConvParams(64, 128, 3),
conv6_params: extractConvParams(128, 128, 3),
conv7_params: extractConvParams(128, 256, 3),
fc0_params: extractFcParams(6400, 1024),
fc1_params:extractFcParams(1024, 136)
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { getImageTensor } from '../getImageTensor';
import { NetInput } from '../NetInput';
import { padToSquare } from '../padToSquare';
import { TNetInput } from '../types';
import { extractParams } from './extractParams';
export function faceLandmarkNet(weights: Float32Array) {
const params = extractParams(weights)
function forward(input: tf.Tensor | NetInput | TNetInput) {
return tf.tidy(() => {
let x = padToSquare(getImageTensor(input), true)
// work with 128 x 128 sized face images
if (x.shape[1] !== 128 || x.shape[2] !== 128) {
x = tf.image.resizeBilinear(x, [128, 128])
}
// pool 1
tf.maxPool(x, [2, 2], [2, 2], 'valid')
// pool 2
tf.maxPool(x, [2, 2], [2, 2], 'valid')
// pool 3
tf.maxPool(x, [2, 2], [2, 2], 'valid')
// pool 4
tf.maxPool(x, [2, 2], [1, 1], 'valid')
// TODO
return x
})
}
return {
forward
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
import { ConvParams } from '../commons/types';
export namespace FaceLandmarkNet {
export type FCParams = {
weights: tf.Tensor2D
bias: tf.Tensor1D
}
export type NetParams = {
conv0_params: ConvParams
conv1_params: ConvParams
conv2_params: ConvParams
conv3_params: ConvParams
conv4_params: ConvParams
conv5_params: ConvParams
conv6_params: ConvParams
conv7_params: ConvParams
fc0_params: FCParams
fc1_params: FCParams
}
}
\ No newline at end of file
...@@ -11,10 +11,10 @@ function convLayer( ...@@ -11,10 +11,10 @@ function convLayer(
withRelu: boolean, withRelu: boolean,
padding: 'valid' | 'same' = 'same' padding: 'valid' | 'same' = 'same'
): tf.Tensor4D { ): tf.Tensor4D {
const { filters, biases } = params.conv const { filters, bias } = params.conv
let out = tf.conv2d(x, filters, [stride, stride], padding) let out = tf.conv2d(x, filters, [stride, stride], padding)
out = tf.add(out, biases) out = tf.add(out, bias)
out = scale(out, params.scale) out = scale(out, params.scale)
return withRelu ? tf.relu(out) : out return withRelu ? tf.relu(out) : out
} }
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { extractWeightsFactory } from '../commons/extractWeightsFactory';
import { ExtractWeightsFunction } from '../commons/types';
import { isFloat } from '../utils'; import { isFloat } from '../utils';
import { FaceRecognitionNet } from './types'; import { FaceRecognitionNet } from './types';
function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) { function extractorsFactory(extractWeights: ExtractWeightsFunction) {
function extractFilterValues(numFilterValues: number, numFilters: number, filterSize: number): tf.Tensor4D { function extractFilterValues(numFilterValues: number, numFilters: number, filterSize: number): tf.Tensor4D {
const weights = extractWeights(numFilterValues) const weights = extractWeights(numFilterValues)
const depth = weights.length / (numFilters * filterSize * filterSize) const depth = weights.length / (numFilters * filterSize * filterSize)
if (isFloat(depth)) { if (isFloat(depth)) {
throw new Error(`depth has to be an integer: ${depth}, weights.length: ${weights.length}, numFilters: ${numFilters}, filterSize: ${filterSize}`) throw new Error(`depth has to be an integer: ${depth}, weights.length: ${weights.length}, numFilters: ${numFilters}, filterSize: ${filterSize}`)
} }
...@@ -29,15 +30,19 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -29,15 +30,19 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
} }
function extractConvLayerParams(numFilterValues: number, numFilters: number, filterSize: number): FaceRecognitionNet.ConvLayerParams { function extractConvLayerParams(
numFilterValues: number,
numFilters: number,
filterSize: number
): FaceRecognitionNet.ConvLayerParams {
const conv_filters = extractFilterValues(numFilterValues, numFilters, filterSize) const conv_filters = extractFilterValues(numFilterValues, numFilters, filterSize)
const conv_biases = tf.tensor1d(extractWeights(numFilters)) const conv_bias = tf.tensor1d(extractWeights(numFilters))
const scale = extractScaleLayerParams(numFilters) const scale = extractScaleLayerParams(numFilters)
return { return {
conv: { conv: {
filters: conv_filters, filters: conv_filters,
biases: conv_biases bias: conv_bias
}, },
scale scale
} }
...@@ -61,11 +66,10 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -61,11 +66,10 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
export function extractParams(weights: Float32Array): FaceRecognitionNet.NetParams { export function extractParams(weights: Float32Array): FaceRecognitionNet.NetParams {
const extractWeights = (numWeights: number): Float32Array => { const {
const ret = weights.slice(0, numWeights) extractWeights,
weights = weights.slice(numWeights) getRemainingWeights
return ret } = extractWeightsFactory(weights)
}
const { const {
extractConvLayerParams, extractConvLayerParams,
...@@ -93,8 +97,8 @@ export function extractParams(weights: Float32Array): FaceRecognitionNet.NetPara ...@@ -93,8 +97,8 @@ export function extractParams(weights: Float32Array): FaceRecognitionNet.NetPara
const fc = tf.transpose(tf.tensor2d(extractWeights(256 * 128), [128, 256]), [1, 0]) const fc = tf.transpose(tf.tensor2d(extractWeights(256 * 128), [128, 256]), [1, 0])
if (weights.length !== 0) { if (getRemainingWeights().length !== 0) {
throw new Error(`weights remaing after extract: ${weights.length}`) throw new Error(`weights remaing after extract: ${getRemainingWeights().length}`)
} }
return { return {
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { ConvParams } from '../commons/types';
export namespace FaceRecognitionNet { export namespace FaceRecognitionNet {
export type ScaleLayerParams = { export type ScaleLayerParams = {
...@@ -11,11 +13,6 @@ export namespace FaceRecognitionNet { ...@@ -11,11 +13,6 @@ export namespace FaceRecognitionNet {
conv2: ConvLayerParams conv2: ConvLayerParams
} }
export type ConvParams = {
filters: tf.Tensor4D
biases: tf.Tensor1D
}
export type ConvLayerParams = { export type ConvLayerParams = {
conv: ConvParams conv: ConvParams
scale: ScaleLayerParams scale: ScaleLayerParams
......
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