Commit 6f8221a8 by vincent

extractors for mobilenetv1 params

parent cb52d620
import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types';
function mobilenetV1WeightsExtractorsFactory(extractWeights: (numWeights: number) => Float32Array) {
function extractDepthwiseConvParams(numChannels: number): FaceDetectionNet.MobileNetV1.DepthwiseConvParams {
const weights = tf.tensor4d(extractWeights(3 * 3 * numChannels), [3, 3, numChannels, 1])
const batch_norm_gamma = tf.tensor1d(extractWeights(numChannels))
const batch_norm_beta = tf.tensor1d(extractWeights(numChannels))
const batch_norm_mean = tf.tensor1d(extractWeights(numChannels))
const batch_norm_variance = tf.tensor1d(extractWeights(numChannels))
return {
weights,
batch_norm_gamma,
batch_norm_beta,
batch_norm_mean,
batch_norm_variance
}
}
function extractPointwiseConvParams(channelsIn: number, channelsOut: number): FaceDetectionNet.MobileNetV1.PointwiseConvParams {
const weights = tf.tensor4d(extractWeights(channelsIn * channelsOut), [1, 1, channelsIn, channelsOut])
const batch_norm_offset = tf.tensor1d(extractWeights(channelsOut))
return {
weights,
batch_norm_offset
}
}
function extractConvPairParams(channelsIn: number, channelsOut: number): FaceDetectionNet.MobileNetV1.ConvPairParams {
const depthwise_conv_params = extractDepthwiseConvParams(channelsIn)
const pointwise_conv_params = extractPointwiseConvParams(channelsIn, channelsOut)
return {
depthwise_conv_params,
pointwise_conv_params
}
}
return {
extractPointwiseConvParams,
extractConvPairParams
}
}
function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) {
const {
extractPointwiseConvParams,
extractConvPairParams
} = mobilenetV1WeightsExtractorsFactory(extractWeights)
function extractMobilenetV1Params(): FaceDetectionNet.MobileNetV1.Params {
const conv_0_params = {
weights: tf.tensor4d(extractWeights(3 * 3 * 3 * 32), [3, 3, 3, 32]),
batch_norm_offset: tf.tensor1d(extractWeights(32))
}
const channelNumPairs = [
[32, 64],
[64, 128],
[128, 128],
[128, 256],
[256, 256],
[256, 512],
[512, 512],
[512, 512],
[512, 512],
[512, 512],
[512, 512],
[512, 1024],
[1024, 1024]
]
const conv_pair_params = channelNumPairs.map(
([channelsIn, channelsOut]) => extractConvPairParams(channelsIn, channelsOut)
)
return {
conv_0_params,
conv_pair_params
}
}
return {
extractMobilenetV1Params
}
}
export function extractParams(weights: Float32Array): FaceDetectionNet.NetParams {
const extractWeights = (numWeights: number): Float32Array => {
console.log(numWeights)
const ret = weights.slice(0, numWeights)
weights = weights.slice(numWeights)
return ret
}
const {
extractMobilenetV1Params
} = extractorsFactory(extractWeights)
const mobilenetv1_params = extractMobilenetV1Params()
if (weights.length !== 0) {
throw new Error(`weights remaing after extract: ${weights.length}`)
}
return {
mobilenetv1_params
}
}
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { resizeLayer } from './resizeLayer'; import { resizeLayer } from './resizeLayer';
import { extractParams } from './extractParams';
import { mobileNetV1 } from './mobileNetV1';
export function faceDetectionNet() { export function faceDetectionNet(weights: Float32Array) {
const params = extractParams(weights)
async function forward(input: ImageData|ImageData[]) { async function forward(input: ImageData|ImageData[]) {
...@@ -12,12 +15,11 @@ export function faceDetectionNet() { ...@@ -12,12 +15,11 @@ export function faceDetectionNet() {
const imgTensor = tf.cast(tf.concat(imgTensors, 0), 'float32') const imgTensor = tf.cast(tf.concat(imgTensors, 0), 'float32')
const resized = resizeLayer(imgTensor) let out = resizeLayer(imgTensor) as tf.Tensor4D
out = mobileNetV1(out, params.mobilenetv1_params)
return out
return resized
} }
return { return {
......
import * as tf from '@tensorflow/tfjs-core';
import { FaceDetectionNet } from './types';
export function mobileNetV1(x: tf.Tensor4D, params: FaceDetectionNet.MobileNetV1.Params) {
return x
}
\ No newline at end of file
...@@ -5,7 +5,7 @@ const resizedImageSize = [512, 512] as [number, number] ...@@ -5,7 +5,7 @@ const resizedImageSize = [512, 512] as [number, number]
const weight = tf.scalar(0.007843137718737125) const weight = tf.scalar(0.007843137718737125)
const bias = tf.scalar(1) const bias = tf.scalar(1)
export function resizeLayer(imgTensor: tf.Tensor4D) { export function resizeLayer(x: tf.Tensor4D) {
const resizedImgs = tf.image.resizeBilinear(imgTensor, resizedImageSize, false) const resized = tf.image.resizeBilinear(x, resizedImageSize, false)
return tf.sub(tf.mul(resizedImgs, weight), bias) return tf.sub(tf.mul(resized, weight), bias)
} }
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core';
export namespace FaceDetectionNet {
export namespace MobileNetV1 {
export type DepthwiseConvParams = {
weights: tf.Tensor4D // [3, 3, ch, 1]
batch_norm_gamma: tf.Tensor1D
batch_norm_beta: tf.Tensor1D
batch_norm_mean: tf.Tensor1D
batch_norm_variance: tf.Tensor1D
}
export type PointwiseConvParams = {
weights: tf.Tensor4D // [1, 1, ch_in, ch_out]
batch_norm_offset: 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 NetParams = {
mobilenetv1_params: MobileNetV1.Params
}
}
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { scale, ScaleLayerParams } from './scaleLayer'; import { scale } from './scaleLayer';
import { FaceRecognitionNet } from './types';
export type ConvParams = {
filters: tf.Tensor4D
biases: tf.Tensor1D
}
export type ConvLayerParams = {
conv: ConvParams
scale: ScaleLayerParams
}
function convLayer( function convLayer(
x: tf.Tensor4D, x: tf.Tensor4D,
params: ConvLayerParams, params: FaceRecognitionNet.ConvLayerParams,
stride: number, stride: number,
withRelu: boolean, withRelu: boolean,
padding: 'valid' | 'same' = 'same' padding: 'valid' | 'same' = 'same'
...@@ -27,14 +19,14 @@ function convLayer( ...@@ -27,14 +19,14 @@ function convLayer(
return withRelu ? tf.relu(out) : out return withRelu ? tf.relu(out) : out
} }
export function conv(x: tf.Tensor4D, params: ConvLayerParams) { export function conv(x: tf.Tensor4D, params: FaceRecognitionNet.ConvLayerParams) {
return convLayer(x, params, 1, true) return convLayer(x, params, 1, true)
} }
export function convNoRelu(x: tf.Tensor4D, params: ConvLayerParams) { export function convNoRelu(x: tf.Tensor4D, params: FaceRecognitionNet.ConvLayerParams) {
return convLayer(x, params, 1, false) return convLayer(x, params, 1, false)
} }
export function convDown(x: tf.Tensor4D, params: ConvLayerParams) { export function convDown(x: tf.Tensor4D, params: FaceRecognitionNet.ConvLayerParams) {
return convLayer(x, params, 2, true, 'valid') return convLayer(x, params, 2, true, 'valid')
} }
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { ConvLayerParams } from './convLayer'; import { FaceRecognitionNet } from './types';
import { FaceRecognitionNetParams } from './FaceRecognitionNetParams';
import { ResidualLayerParams } from './residualLayer';
import { ScaleLayerParams } from './scaleLayer';
function isFloat(num: number) { function isFloat(num: number) {
return num % 1 !== 0 return num % 1 !== 0
...@@ -26,7 +23,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -26,7 +23,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
) )
} }
function extractScaleLayerParams(numWeights: number): ScaleLayerParams { function extractScaleLayerParams(numWeights: number): FaceRecognitionNet.ScaleLayerParams {
const weights = tf.tensor1d(extractWeights(numWeights)) const weights = tf.tensor1d(extractWeights(numWeights))
const biases = tf.tensor1d(extractWeights(numWeights)) const biases = tf.tensor1d(extractWeights(numWeights))
return { return {
...@@ -35,7 +32,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -35,7 +32,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
} }
function extractConvLayerParams(numFilterValues: number, numFilters: number, filterSize: number): 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_biases = tf.tensor1d(extractWeights(numFilters))
const scale = extractScaleLayerParams(numFilters) const scale = extractScaleLayerParams(numFilters)
...@@ -49,9 +46,9 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -49,9 +46,9 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
} }
function extractResidualLayerParams(numFilterValues: number, numFilters: number, filterSize: number, isDown: boolean = false): ResidualLayerParams { function extractResidualLayerParams(numFilterValues: number, numFilters: number, filterSize: number, isDown: boolean = false): FaceRecognitionNet.ResidualLayerParams {
const conv1: ConvLayerParams = extractConvLayerParams((isDown ? 0.5 : 1) * numFilterValues, numFilters, filterSize) const conv1: FaceRecognitionNet.ConvLayerParams = extractConvLayerParams((isDown ? 0.5 : 1) * numFilterValues, numFilters, filterSize)
const conv2: ConvLayerParams = extractConvLayerParams(numFilterValues, numFilters, filterSize) const conv2: FaceRecognitionNet.ConvLayerParams = extractConvLayerParams(numFilterValues, numFilters, filterSize)
return { return {
conv1, conv1,
...@@ -66,7 +63,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array) ...@@ -66,7 +63,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
} }
export function extractParams(weights: Float32Array): FaceRecognitionNetParams { export function extractParams(weights: Float32Array): FaceRecognitionNet.NetParams {
const extractWeights = (numWeights: number): Float32Array => { const extractWeights = (numWeights: number): Float32Array => {
const ret = weights.slice(0, numWeights) const ret = weights.slice(0, numWeights)
weights = weights.slice(numWeights) weights = weights.slice(numWeights)
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { conv, convNoRelu, ConvLayerParams, convDown } from './convLayer'; import { conv, convDown, convNoRelu } from './convLayer';
import { FaceRecognitionNet } from './types';
export type ResidualLayerParams = { export function residual(x: tf.Tensor4D, params: FaceRecognitionNet.ResidualLayerParams): tf.Tensor4D {
conv1: ConvLayerParams
conv2: ConvLayerParams
}
export function residual(x: tf.Tensor4D, params: ResidualLayerParams): tf.Tensor4D {
let out = conv(x, params.conv1) let out = conv(x, params.conv1)
out = convNoRelu(out, params.conv2) out = convNoRelu(out, params.conv2)
out = tf.add(out, x) out = tf.add(out, x)
...@@ -15,7 +11,7 @@ export function residual(x: tf.Tensor4D, params: ResidualLayerParams): tf.Tensor ...@@ -15,7 +11,7 @@ export function residual(x: tf.Tensor4D, params: ResidualLayerParams): tf.Tensor
return out return out
} }
export function residualDown(x: tf.Tensor4D, params: ResidualLayerParams): tf.Tensor4D { export function residualDown(x: tf.Tensor4D, params: FaceRecognitionNet.ResidualLayerParams): tf.Tensor4D {
let out = convDown(x, params.conv1) let out = convDown(x, params.conv1)
out = convNoRelu(out, params.conv2) out = convNoRelu(out, params.conv2)
......
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { FaceRecognitionNet } from './types';
export type ScaleLayerParams = { export function scale(x: tf.Tensor4D, params: FaceRecognitionNet.ScaleLayerParams): tf.Tensor4D {
weights: tf.Tensor1D
biases: tf.Tensor1D
}
export function scale(x: tf.Tensor4D, params: ScaleLayerParams): tf.Tensor4D {
return tf.add(tf.mul(x, params.weights), params.biases) return tf.add(tf.mul(x, params.weights), params.biases)
} }
\ No newline at end of file
import * as tf from '@tensorflow/tfjs-core'; import * as tf from '@tensorflow/tfjs-core';
import { ConvLayerParams } from './convLayer'; export namespace FaceRecognitionNet {
import { ResidualLayerParams } from './residualLayer';
export type ScaleLayerParams = {
weights: tf.Tensor1D
biases: tf.Tensor1D
}
export type ResidualLayerParams = {
conv1: ConvLayerParams
conv2: ConvLayerParams
}
export type ConvParams = {
filters: tf.Tensor4D
biases: tf.Tensor1D
}
export type ConvLayerParams = {
conv: ConvParams
scale: ScaleLayerParams
}
export type NetParams = {
conv32_down: ConvLayerParams
conv32_1: ResidualLayerParams
conv32_2: ResidualLayerParams
conv32_3: ResidualLayerParams
conv64_down: ResidualLayerParams
conv64_1: ResidualLayerParams
conv64_2: ResidualLayerParams
conv64_3: ResidualLayerParams
conv128_down: ResidualLayerParams
conv128_1: ResidualLayerParams
conv128_2: ResidualLayerParams
conv256_down: ResidualLayerParams
conv256_1: ResidualLayerParams
conv256_2: ResidualLayerParams
conv256_down_out: ResidualLayerParams
fc: tf.Tensor2D
}
export type FaceRecognitionNetParams = {
conv32_down: ConvLayerParams
conv32_1: ResidualLayerParams
conv32_2: ResidualLayerParams
conv32_3: ResidualLayerParams
conv64_down: ResidualLayerParams
conv64_1: ResidualLayerParams
conv64_2: ResidualLayerParams
conv64_3: ResidualLayerParams
conv128_down: ResidualLayerParams
conv128_1: ResidualLayerParams
conv128_2: ResidualLayerParams
conv256_down: ResidualLayerParams
conv256_1: ResidualLayerParams
conv256_2: ResidualLayerParams
conv256_down_out: ResidualLayerParams
fc: tf.Tensor2D
} }
\ 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