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
4f45297b
Commit
4f45297b
authored
Aug 17, 2018
by
vincent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added test script to validate model accuracy on fddb benchmark
parent
a97cd220
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
185 additions
and
44 deletions
+185
-44
serveTinyYolov2.js
tools/train/serveTinyYolov2.js
+4
-0
trainUtils.js
tools/train/shared/trainUtils.js
+31
-1
loss.js
tools/train/tinyYolov2/loss.js
+2
-0
test.html
tools/train/tinyYolov2/test.html
+131
-0
train.html
tools/train/tinyYolov2/train.html
+8
-6
train.js
tools/train/tinyYolov2/train.js
+0
-29
verify.html
tools/train/tinyYolov2/verify.html
+9
-8
No files found.
tools/train/serveTinyYolov2.js
View file @
4f45297b
...
...
@@ -15,10 +15,12 @@ app.use(express.static(path.join(__dirname, '../../weights')))
app
.
use
(
express
.
static
(
path
.
join
(
__dirname
,
'../../dist'
)))
const
trainDataPath
=
path
.
resolve
(
process
.
env
.
TRAIN_DATA_PATH
)
const
testDataPath
=
path
.
resolve
(
process
.
env
.
TEST_DATA_PATH
)
const
imagesPath
=
path
.
join
(
trainDataPath
,
'./final_images'
)
const
detectionsPath
=
path
.
join
(
trainDataPath
,
'./final_detections'
)
app
.
use
(
express
.
static
(
imagesPath
))
app
.
use
(
express
.
static
(
detectionsPath
))
app
.
use
(
express
.
static
(
testDataPath
))
const
detectionFilenames
=
fs
.
readdirSync
(
detectionsPath
)
const
detectionFilenamesMultibox
=
JSON
.
parse
(
fs
.
readFileSync
(
path
.
join
(
__dirname
,
'./tinyYolov2/multibox.json'
)))
...
...
@@ -29,5 +31,6 @@ app.get('/detection_filenames', (req, res) => res.status(202).send(detectionFile
app
.
get
(
'/detection_filenames_multibox'
,
(
req
,
res
)
=>
res
.
status
(
202
).
send
(
detectionFilenamesMultibox
))
app
.
get
(
'/'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
publicDir
,
'train.html'
)))
app
.
get
(
'/verify'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
publicDir
,
'verify.html'
)))
app
.
get
(
'/test'
,
(
req
,
res
)
=>
res
.
sendFile
(
path
.
join
(
publicDir
,
'test.html'
)))
app
.
listen
(
3000
,
()
=>
console
.
log
(
'Listening on port 3000!'
))
\ No newline at end of file
tools/train/shared/trainUtils.js
View file @
4f45297b
const
log
=
(
str
,
...
args
)
=>
console
.
log
(
`[
${[(
new
Date
()).
toTimeString
().
substr
(
0
,
8
)]}
]
${
str
||
''
}
`
,
...
args
)
async
function
promiseSequential
(
promises
)
{
const
curr
=
promises
[
0
]
if
(
!
curr
)
{
...
...
@@ -29,4 +31,31 @@ function saveWeights(net, filename = 'train_tmp') {
saveAs
(
new
Blob
([
binaryWeights
]),
filename
)
}
const
log
=
(
str
,
...
args
)
=>
console
.
log
(
`[
${[(
new
Date
()).
toTimeString
().
substr
(
0
,
8
)]}
]
${
str
||
''
}
`
,
...
args
)
function
imageToSquare
(
img
)
{
const
scale
=
608
/
Math
.
max
(
img
.
height
,
img
.
width
)
const
width
=
scale
*
img
.
width
const
height
=
scale
*
img
.
height
const
canvas1
=
faceapi
.
createCanvasFromMedia
(
img
)
const
targetCanvas
=
faceapi
.
createCanvas
({
width
:
608
,
height
:
608
})
targetCanvas
.
getContext
(
'2d'
).
putImageData
(
canvas1
.
getContext
(
'2d'
).
getImageData
(
0
,
0
,
width
,
height
),
0
,
0
)
return
targetCanvas
}
function
getPaddingsAndReshapedSize
(
img
,
inputSize
)
{
const
[
h
,
w
]
=
[
img
.
height
,
img
.
width
]
const
maxDim
=
Math
.
max
(
h
,
w
)
const
f
=
inputSize
/
maxDim
const
reshapedImgDims
=
{
height
:
Math
.
floor
(
h
*
f
),
width
:
Math
.
floor
(
w
*
f
)
}
const
paddings
=
new
faceapi
.
Point
(
maxDim
/
img
.
width
,
maxDim
/
img
.
height
)
return
{
paddings
,
reshapedImgDims
}
}
\ No newline at end of file
tools/train/tinyYolov2/loss.js
View file @
4f45297b
...
...
@@ -102,6 +102,8 @@ function computeBoxAdjustments(groundTruthBoxes, reshapedImgDims) {
const
dx
=
inverseSigmoid
(
dCenterX
/
CELL_SIZE
)
const
dy
=
inverseSigmoid
(
dCenterY
/
CELL_SIZE
)
//const dx = dCenterX / CELL_SIZE
//const dy = dCenterY / CELL_SIZE
const
dw
=
Math
.
log
((
width
/
CELL_SIZE
)
/
getAnchors
()[
anchor
].
x
)
const
dh
=
Math
.
log
((
height
/
CELL_SIZE
)
/
getAnchors
()[
anchor
].
y
)
...
...
tools/train/tinyYolov2/test.html
0 → 100644
View file @
4f45297b
<!DOCTYPE html>
<html>
<head>
<script
src=
"face-api.js"
></script>
<script
src=
"commons.js"
></script>
<script
src=
"trainUtils.js"
></script>
<script
src=
"loss.js"
></script>
<script
src=
"FileSaver.js"
></script>
<link
rel=
"stylesheet"
href=
"styles.css"
>
<link
rel=
"stylesheet"
href=
"https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.css"
>
<script
type=
"text/javascript"
src=
"https://code.jquery.com/jquery-2.1.1.min.js"
></script>
<script
src=
"https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"
></script>
</head>
<body>
<script>
window
.
tf
=
faceapi
.
tf
// hyper parameters
window
.
objectScale
=
5
window
.
noObjectScale
=
1
window
.
coordScale
=
1
const
weightsUrl
=
`/tmp/tmp__224_35060__320_41188__416_31050__608_16520.weights`
//const inputSizes = [160, 224, 320, 416]
const
inputSizes
=
[
512
,
608
]
async
function
loadNetWeights
(
uri
)
{
return
new
Float32Array
(
await
(
await
fetch
(
uri
)).
arrayBuffer
())
}
async
function
fetchFddbJson
()
{
return
fetch
(
'/fddb-detections.json'
).
then
(
res
=>
res
.
json
())
}
async
function
run
()
{
window
.
fddbJson
=
await
fetchFddbJson
()
const
weights
=
await
loadNetWeights
(
weightsUrl
)
window
.
net
=
new
faceapi
.
TinyYolov2
(
true
)
await
window
.
net
.
load
(
weights
)
await
promiseSequential
(
inputSizes
.
map
(
inputSize
=>
async
()
=>
{
await
promiseSequential
(
window
.
fddbJson
.
map
(({
filePath
,
rects
})
=>
()
=>
{
return
test
(
filePath
,
rects
,
inputSize
)
}))
const
losses
=
Object
.
keys
(
window
.
lossMap
[
inputSize
]).
map
(
k
=>
window
.
lossMap
[
inputSize
][
k
])
const
totalLoss
=
losses
.
map
(
l
=>
l
.
totalLoss
)
.
reduce
((
sum
,
l
)
=>
sum
+
l
)
const
avgLoss
=
totalLoss
/
losses
.
length
log
(
`totalLoss (
${
inputSize
}
):
${
totalLoss
}
`
)
log
(
`avgLoss (
${
inputSize
}
):
${
avgLoss
}
`
)
window
.
losses
=
window
.
losses
||
{}
window
.
losses
[
inputSize
]
=
{
totalLoss
,
avgLoss
}
}))
console
.
log
(
window
.
losses
)
}
async
function
test
(
fileUri
,
rects
,
inputSize
)
{
const
img
=
await
faceapi
.
bufferToImage
(
await
fetchImage
(
fileUri
))
const
groundTruthBoxes
=
rects
.
map
(({
x
,
y
,
width
,
height
})
=>
new
faceapi
.
Rect
(
x
,
y
,
width
,
height
))
.
map
(
rect
=>
rect
.
clipAtImageBorders
(
img
.
width
,
img
.
height
))
.
map
(({
x
,
y
,
width
,
height
})
=>
({
x
:
x
/
img
.
width
,
y
:
y
/
img
.
height
,
width
:
width
/
img
.
width
,
height
:
height
/
img
.
height
,
}))
const
{
reshapedImgDims
,
paddings
}
=
getPaddingsAndReshapedSize
(
img
,
inputSize
)
const
squareImg
=
imageToSquare
(
img
)
const
netInput
=
(
await
faceapi
.
toNetInput
(
squareImg
)).
managed
()
const
losses
=
tf
.
tidy
(()
=>
{
const
outTensor
=
window
.
net
.
forwardInput
(
netInput
,
inputSize
)
const
{
noObjectLoss
,
objectLoss
,
coordLoss
,
totalLoss
}
=
computeLoss
(
outTensor
,
groundTruthBoxes
,
reshapedImgDims
,
paddings
)
const
losses
=
{
totalLoss
:
totalLoss
.
dataSync
()[
0
],
noObjectLoss
:
noObjectLoss
.
dataSync
()[
0
],
objectLoss
:
objectLoss
.
dataSync
()[
0
],
coordLoss
:
coordLoss
.
dataSync
()[
0
]
}
return
losses
})
log
(
`
${
fileUri
}
:`
)
log
(
`ground truth boxes:
${
groundTruthBoxes
.
length
}
`
)
log
(
`noObjectLoss:
${
losses
.
noObjectLoss
}
`
)
log
(
`objectLoss:
${
losses
.
objectLoss
}
`
)
log
(
`coordLoss:
${
losses
.
coordLoss
}
`
)
log
(
`totalLoss:
${
losses
.
totalLoss
}
`
)
if
(
Object
.
keys
(
losses
).
map
(
k
=>
losses
[
k
]).
some
(
loss
=>
isNaN
(
loss
)
||
loss
===
Infinity
))
{
console
.
log
(
groundTruthBoxes
)
console
.
log
(
img
)
console
.
log
(
losses
)
throw
new
Error
(
'corrupted loss value'
)
}
window
.
lossMap
=
window
.
lossMap
||
{}
window
.
lossMap
[
inputSize
]
=
window
.
lossMap
[
inputSize
]
||
{}
window
.
lossMap
[
inputSize
][
fileUri
]
=
losses
}
$
(
document
).
ready
(
function
()
{
run
()
})
</script>
</body>
</html>
\ No newline at end of file
tools/train/tinyYolov2/train.html
View file @
4f45297b
...
...
@@ -17,22 +17,25 @@
<script>
tf
=
faceapi
.
tf
const
startIdx224
=
35060
const
startIdx320
=
41188
const
startIdx416
=
31050
const
startIdx160
=
26600
const
startIdx224
=
61660
const
startIdx320
=
67788
const
startIdx416
=
57650
const
startIdx608
=
16520
const
weightsUrl
=
`/tmp/tmp__224_
${
startIdx224
}
__320_
${
startIdx320
}
__416_
${
startIdx416
}
__608_
${
startIdx608
}
.weights`
//const weightsUrl = `/tmp/tmp__160_${startIdx160}__224_${startIdx224}__320_${startIdx320}__416_${startIdx416}__608_${startIdx608}.weights`
const
weightsUrl
=
`/tmp/tmp_multiscale_count_8700.weights`
const
fromEpoch
=
0
const
trainOnlyMultibox
=
false
const
trainSizes
=
[
160
,
224
,
320
,
416
]
const
trainSizes
=
[
416
,
512
,
608
]
//const trainSizes = [608]
window
.
debug
=
false
window
.
logTrainSteps
=
true
window
.
count
=
0
// hyper parameters
...
...
@@ -85,7 +88,6 @@
log
(
`
${
lossType
}
:
${
faceapi
.
round
(
currentLoss
[
lossType
])}
(avg:
${
faceapi
.
round
(
currentLoss
[
lossType
]
/
detectionFilenames
.
length
)}
) (delta:
${
currentLoss
[
lossType
]
-
prevLoss
[
lossType
]}
)`
)
}
window
.
count
=
0
function
onBatchProcessed
(
dataIdx
,
inputSize
)
{
window
.
count
++
...
...
tools/train/tinyYolov2/train.js
View file @
4f45297b
...
...
@@ -47,35 +47,6 @@ function minimize(groundTruthBoxes, batchInput, inputSize, batch, { reshapedImgD
},
true
)
}
function
imageToSquare
(
img
)
{
const
scale
=
608
/
Math
.
max
(
img
.
height
,
img
.
width
)
const
width
=
scale
*
img
.
width
const
height
=
scale
*
img
.
height
const
canvas1
=
faceapi
.
createCanvasFromMedia
(
img
)
const
targetCanvas
=
faceapi
.
createCanvas
({
width
:
608
,
height
:
608
})
targetCanvas
.
getContext
(
'2d'
).
putImageData
(
canvas1
.
getContext
(
'2d'
).
getImageData
(
0
,
0
,
width
,
height
),
0
,
0
)
return
targetCanvas
}
function
getPaddingsAndReshapedSize
(
img
,
inputSize
)
{
const
[
h
,
w
]
=
[
img
.
height
,
img
.
width
]
const
maxDim
=
Math
.
max
(
h
,
w
)
const
f
=
inputSize
/
maxDim
const
reshapedImgDims
=
{
height
:
Math
.
floor
(
h
*
f
),
width
:
Math
.
floor
(
w
*
f
)
}
const
paddings
=
new
faceapi
.
Point
(
maxDim
/
img
.
width
,
maxDim
/
img
.
height
)
return
{
paddings
,
reshapedImgDims
}
}
async
function
trainStep
(
batchCreators
,
inputSizes
,
rescaleEveryNthBatch
,
onBatchProcessed
=
()
=>
{})
{
async
function
step
(
currentBatchCreators
)
{
...
...
tools/train/tinyYolov2/verify.html
View file @
4f45297b
...
...
@@ -34,11 +34,12 @@
<div
class=
"row side-by-side"
>
<div
class=
"row input-field"
style=
"margin-right: 20px;"
>
<select
id=
"sizeType"
>
<option
value=
""
disabled
selected
>
Input Size:
</option>
<option
value=
"xs"
>
XS: 224 x 224
</option>
<option
value=
"sm"
>
SM: 320 x 320
</option>
<option
value=
"md"
>
MD: 416 x 416
</option>
<option
value=
"lg"
>
LG: 608 x 608
</option>
<option
value=
"128"
>
128 x 128
</option>
<option
value=
"160"
>
160 x 160
</option>
<option
value=
"224"
>
224 x 224
</option>
<option
value=
"320"
>
320 x 320
</option>
<option
value=
"416"
>
416 x 416
</option>
<option
value=
"608"
>
608 x 608
</option>
</select>
<label>
Input Size
</label>
</div>
...
...
@@ -67,7 +68,7 @@
<script>
let
scoreThreshold
=
0.5
let
sizeType
=
'sm'
let
sizeType
=
608
function
onKeyDown
(
e
)
{
e
.
target
.
value
=
(
...
...
@@ -113,7 +114,7 @@
canvas
.
height
=
height
const
forwardParams
=
{
inputSize
:
sizeType
,
inputSize
:
parseInt
(
sizeType
)
,
scoreThreshold
}
...
...
@@ -145,7 +146,7 @@
const
startIdx608
=
16520
//const weightsUrl = `/tmp/tmp__224_${startIdx224}__320_${startIdx320}__416_${startIdx416}__608_${startIdx608}.weights`
const
weightsUrl
=
`/tmp/
overfit_count_15
00.weights`
const
weightsUrl
=
`/tmp/
tmp_multiscale_count_42
00.weights`
const
weights
=
await
loadNetWeights
(
weightsUrl
)
window
.
net
=
new
faceapi
.
TinyYolov2
(
true
)
...
...
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