Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
face
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Кубота
face
Commits
2efff4f7
Commit
2efff4f7
authored
Jun 04, 2018
by
vincent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented mobilenetv1 for face detector
parent
6f8221a8
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
119 additions
and
30 deletions
+119
-30
extractParams.ts
src/faceDetectionNet/extractParams.ts
+9
-9
index.ts
src/faceDetectionNet/index.ts
+42
-9
mobileNetV1.ts
src/faceDetectionNet/mobileNetV1.ts
+53
-1
resizeLayer.ts
src/faceDetectionNet/resizeLayer.ts
+7
-3
types.ts
src/faceDetectionNet/types.ts
+4
-4
extractParams.ts
src/faceRecognitionNet/extractParams.ts
+1
-4
utils.ts
src/utils.ts
+3
-0
No files found.
src/faceDetectionNet/extractParams.ts
View file @
2efff4f7
...
@@ -5,27 +5,27 @@ import { FaceDetectionNet } from './types';
...
@@ -5,27 +5,27 @@ import { FaceDetectionNet } from './types';
function
mobilenetV1WeightsExtractorsFactory
(
extractWeights
:
(
numWeights
:
number
)
=>
Float32Array
)
{
function
mobilenetV1WeightsExtractorsFactory
(
extractWeights
:
(
numWeights
:
number
)
=>
Float32Array
)
{
function
extractDepthwiseConvParams
(
numChannels
:
number
):
FaceDetectionNet
.
MobileNetV1
.
DepthwiseConvParams
{
function
extractDepthwiseConvParams
(
numChannels
:
number
):
FaceDetectionNet
.
MobileNetV1
.
DepthwiseConvParams
{
const
weight
s
=
tf
.
tensor4d
(
extractWeights
(
3
*
3
*
numChannels
),
[
3
,
3
,
numChannels
,
1
])
const
filter
s
=
tf
.
tensor4d
(
extractWeights
(
3
*
3
*
numChannels
),
[
3
,
3
,
numChannels
,
1
])
const
batch_norm_
gamma
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
const
batch_norm_
scale
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
const
batch_norm_
beta
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
const
batch_norm_
offset
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
const
batch_norm_mean
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
const
batch_norm_mean
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
const
batch_norm_variance
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
const
batch_norm_variance
=
tf
.
tensor1d
(
extractWeights
(
numChannels
))
return
{
return
{
weight
s
,
filter
s
,
batch_norm_
gamma
,
batch_norm_
scale
,
batch_norm_
beta
,
batch_norm_
offset
,
batch_norm_mean
,
batch_norm_mean
,
batch_norm_variance
batch_norm_variance
}
}
}
}
function
extractPointwiseConvParams
(
channelsIn
:
number
,
channelsOut
:
number
):
FaceDetectionNet
.
MobileNetV1
.
PointwiseConvParams
{
function
extractPointwiseConvParams
(
channelsIn
:
number
,
channelsOut
:
number
):
FaceDetectionNet
.
MobileNetV1
.
PointwiseConvParams
{
const
weight
s
=
tf
.
tensor4d
(
extractWeights
(
channelsIn
*
channelsOut
),
[
1
,
1
,
channelsIn
,
channelsOut
])
const
filter
s
=
tf
.
tensor4d
(
extractWeights
(
channelsIn
*
channelsOut
),
[
1
,
1
,
channelsIn
,
channelsOut
])
const
batch_norm_offset
=
tf
.
tensor1d
(
extractWeights
(
channelsOut
))
const
batch_norm_offset
=
tf
.
tensor1d
(
extractWeights
(
channelsOut
))
return
{
return
{
weight
s
,
filter
s
,
batch_norm_offset
batch_norm_offset
}
}
}
}
...
@@ -59,7 +59,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
...
@@ -59,7 +59,7 @@ function extractorsFactory(extractWeights: (numWeights: number) => Float32Array)
function
extractMobilenetV1Params
():
FaceDetectionNet
.
MobileNetV1
.
Params
{
function
extractMobilenetV1Params
():
FaceDetectionNet
.
MobileNetV1
.
Params
{
const
conv_0_params
=
{
const
conv_0_params
=
{
weight
s
:
tf
.
tensor4d
(
extractWeights
(
3
*
3
*
3
*
32
),
[
3
,
3
,
3
,
32
]),
filter
s
:
tf
.
tensor4d
(
extractWeights
(
3
*
3
*
3
*
32
),
[
3
,
3
,
3
,
32
]),
batch_norm_offset
:
tf
.
tensor1d
(
extractWeights
(
32
))
batch_norm_offset
:
tf
.
tensor1d
(
extractWeights
(
32
))
}
}
...
...
src/faceDetectionNet/index.ts
View file @
2efff4f7
import
*
as
tf
from
'@tensorflow/tfjs-core'
;
import
*
as
tf
from
'@tensorflow/tfjs-core'
;
import
{
resizeLayer
}
from
'./resizeLayer
'
;
import
{
isFloat
}
from
'../utils
'
;
import
{
extractParams
}
from
'./extractParams'
;
import
{
extractParams
}
from
'./extractParams'
;
import
{
mobileNetV1
}
from
'./mobileNetV1'
;
import
{
mobileNetV1
}
from
'./mobileNetV1'
;
import
{
resizeLayer
}
from
'./resizeLayer'
;
function
fromData
(
input
:
number
[]):
tf
.
Tensor4D
{
const
pxPerChannel
=
input
.
length
/
3
const
dim
=
Math
.
sqrt
(
pxPerChannel
)
if
(
isFloat
(
dim
))
{
throw
new
Error
(
`invalid input size:
${
dim
}
x
${
dim
}
x3 (array length:
${
input
.
length
}
)`
)
}
return
tf
.
tensor4d
(
input
as
number
[],
[
1
,
580
,
580
,
3
])
}
function
fromImageData
(
input
:
ImageData
[])
{
const
idx
=
input
.
findIndex
(
data
=>
!
(
data
instanceof
ImageData
))
if
(
idx
!==
-
1
)
{
throw
new
Error
(
`expected input at index
${
idx
}
to be instanceof ImageData`
)
}
const
imgTensors
=
input
.
map
(
data
=>
tf
.
fromPixels
(
data
))
.
map
(
data
=>
tf
.
expandDims
(
data
,
0
))
as
tf
.
Tensor4D
[]
return
tf
.
cast
(
tf
.
concat
(
imgTensors
,
0
),
'float32'
)
}
export
function
faceDetectionNet
(
weights
:
Float32Array
)
{
export
function
faceDetectionNet
(
weights
:
Float32Array
)
{
const
params
=
extractParams
(
weights
)
const
params
=
extractParams
(
weights
)
async
function
forward
(
input
:
ImageData
|
ImageData
[])
{
async
function
forward
(
input
:
ImageData
|
ImageData
[]
|
number
[])
{
return
tf
.
tidy
(()
=>
{
const
imgTensors
=
(
input
instanceof
ImageData
?
[
input
]
:
input
)
const
imgDataArray
=
input
instanceof
ImageData
.
map
(
data
=>
tf
.
fromPixels
(
data
))
?
[
input
]
.
map
(
data
=>
tf
.
expandDims
(
data
,
0
))
as
tf
.
Tensor4D
[]
:
(
input
[
0
]
instanceof
ImageData
?
input
as
ImageData
[]
:
null
)
const
imgTensor
=
tf
.
cast
(
tf
.
concat
(
imgTensors
,
0
),
'float32'
)
const
imgTensor
=
imgDataArray
!==
null
?
fromImageData
(
imgDataArray
)
:
fromData
(
input
as
number
[])
let
out
=
resizeLayer
(
imgTensor
)
as
tf
.
Tensor4D
let
out
=
resizeLayer
(
imgTensor
)
as
tf
.
Tensor4D
out
=
mobileNetV1
(
out
,
params
.
mobilenetv1_params
)
out
=
mobileNetV1
(
out
,
params
.
mobilenetv1_params
)
return
out
return
out
})
}
}
return
{
return
{
...
...
src/faceDetectionNet/mobileNetV1.ts
View file @
2efff4f7
...
@@ -2,6 +2,57 @@ import * as tf from '@tensorflow/tfjs-core';
...
@@ -2,6 +2,57 @@ import * as tf from '@tensorflow/tfjs-core';
import
{
FaceDetectionNet
}
from
'./types'
;
import
{
FaceDetectionNet
}
from
'./types'
;
const
epsilon
=
0.0010000000474974513
function
depthwiseConvLayer
(
x
:
tf
.
Tensor4D
,
params
:
FaceDetectionNet
.
MobileNetV1
.
DepthwiseConvParams
,
strides
:
[
number
,
number
]
)
{
return
tf
.
tidy
(()
=>
{
let
out
=
tf
.
depthwiseConv2d
(
x
,
params
.
filters
,
strides
,
'same'
)
out
=
tf
.
batchNormalization
<
tf
.
Rank
.
R4
>
(
out
,
params
.
batch_norm_mean
,
params
.
batch_norm_variance
,
epsilon
,
params
.
batch_norm_scale
,
params
.
batch_norm_offset
)
return
tf
.
relu
(
out
)
})
}
function
pointwiseConvLayer
(
x
:
tf
.
Tensor4D
,
params
:
FaceDetectionNet
.
MobileNetV1
.
PointwiseConvParams
,
strides
:
[
number
,
number
]
)
{
return
tf
.
tidy
(()
=>
{
let
out
=
tf
.
conv2d
(
x
,
params
.
filters
,
strides
,
'same'
)
out
=
tf
.
add
(
out
,
params
.
batch_norm_offset
)
return
tf
.
relu
(
out
)
})
}
function
getStridesForLayerIdx
(
layerIdx
:
number
):
[
number
,
number
]
{
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
:
FaceDetectionNet
.
MobileNetV1
.
Params
)
{
return
x
return
tf
.
tidy
(()
=>
{
let
out
=
pointwiseConvLayer
(
x
,
params
.
conv_0_params
,
[
2
,
2
])
params
.
conv_pair_params
.
forEach
((
param
,
i
)
=>
{
const
depthwiseConvStrides
=
getStridesForLayerIdx
(
i
+
1
)
out
=
depthwiseConvLayer
(
out
,
param
.
depthwise_conv_params
,
depthwiseConvStrides
)
out
=
pointwiseConvLayer
(
out
,
param
.
pointwise_conv_params
,
[
1
,
1
])
})
return
out
})
}
}
\ No newline at end of file
src/faceDetectionNet/resizeLayer.ts
View file @
2efff4f7
import
*
as
tf
from
'@tensorflow/tfjs-core'
;
import
*
as
tf
from
'@tensorflow/tfjs-core'
;
// TODO: hardcoded params
const
resizedImageSize
=
[
512
,
512
]
as
[
number
,
number
]
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
(
x
:
tf
.
Tensor4D
)
{
export
function
resizeLayer
(
x
:
tf
.
Tensor4D
)
{
const
resized
=
tf
.
image
.
resizeBilinear
(
x
,
resizedImageSize
,
false
)
return
tf
.
tidy
(()
=>
{
return
tf
.
sub
(
tf
.
mul
(
resized
,
weight
),
bias
)
const
resized
=
tf
.
image
.
resizeBilinear
(
x
,
resizedImageSize
,
false
)
return
tf
.
sub
(
tf
.
mul
(
resized
,
weight
),
bias
)
})
}
}
\ No newline at end of file
src/faceDetectionNet/types.ts
View file @
2efff4f7
...
@@ -5,15 +5,15 @@ export namespace FaceDetectionNet {
...
@@ -5,15 +5,15 @@ export namespace FaceDetectionNet {
export
namespace
MobileNetV1
{
export
namespace
MobileNetV1
{
export
type
DepthwiseConvParams
=
{
export
type
DepthwiseConvParams
=
{
weights
:
tf
.
Tensor4D
// [3, 3, ch, 1]
filters
:
tf
.
Tensor4D
batch_norm_
gamma
:
tf
.
Tensor1D
batch_norm_
scale
:
tf
.
Tensor1D
batch_norm_
beta
:
tf
.
Tensor1D
batch_norm_
offset
:
tf
.
Tensor1D
batch_norm_mean
:
tf
.
Tensor1D
batch_norm_mean
:
tf
.
Tensor1D
batch_norm_variance
:
tf
.
Tensor1D
batch_norm_variance
:
tf
.
Tensor1D
}
}
export
type
PointwiseConvParams
=
{
export
type
PointwiseConvParams
=
{
weights
:
tf
.
Tensor4D
// [1, 1, ch_in, ch_out]
filters
:
tf
.
Tensor4D
batch_norm_offset
:
tf
.
Tensor1D
batch_norm_offset
:
tf
.
Tensor1D
}
}
...
...
src/faceRecognitionNet/extractParams.ts
View file @
2efff4f7
import
*
as
tf
from
'@tensorflow/tfjs-core'
;
import
*
as
tf
from
'@tensorflow/tfjs-core'
;
import
{
isFloat
}
from
'../utils'
;
import
{
FaceRecognitionNet
}
from
'./types'
;
import
{
FaceRecognitionNet
}
from
'./types'
;
function
isFloat
(
num
:
number
)
{
return
num
%
1
!==
0
}
function
extractorsFactory
(
extractWeights
:
(
numWeights
:
number
)
=>
Float32Array
)
{
function
extractorsFactory
(
extractWeights
:
(
numWeights
:
number
)
=>
Float32Array
)
{
function
extractFilterValues
(
numFilterValues
:
number
,
numFilters
:
number
,
filterSize
:
number
):
tf
.
Tensor4D
{
function
extractFilterValues
(
numFilterValues
:
number
,
numFilters
:
number
,
filterSize
:
number
):
tf
.
Tensor4D
{
...
...
src/utils.ts
0 → 100644
View file @
2efff4f7
export
function
isFloat
(
num
:
number
)
{
return
num
%
1
!==
0
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment