Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
vig
Sublinear Algorithms for VA
pseudo
Commits
649da5a6
Commit
649da5a6
authored
Nov 29, 2020
by
Kruyff,D.L.W. (Dylan)
Browse files
Merge mts to master
Former-commit-id:
58b61c74
parents
ecd7e693
5b836d45
Changes
77
Hide whitespace changes
Inline
Side-by-side
AngularApp/prototype/src/app/api.service.ts
View file @
649da5a6
import
{
Injectable
}
from
'
@angular/core
'
;
export
interface
RawData
{
index
:
string
[];
values
:
number
[];
index
:
string
[]
[]
;
values
:
number
[]
[]
;
}
export
interface
LshData
{
candidates
:
number
[];
distances
:
number
[];
hash_functions
:
number
[];
// number[][][][];
candidates
:
number
[][][];
distances
:
number
[][][];
average_candidates
:
number
[];
average_distances
:
number
[];
tables
:
{[
bucket
:
string
]:
number
[]}[];
average_table
:
{[
bucket
:
string
]:
number
[]};
samples
:
number
[];
hash_functions
:
number
[][];
parameters
?:
number
[];
}
export
interface
TableInfoData
{
prototypes
:
{
average
:
number
[];
min
:
number
[];
max
:
number
[];
average
:
number
[]
[]
;
min
:
number
[]
[]
;
max
:
number
[]
[]
;
}[];
distances
:
number
[][];
}
export
interface
Parameters
{
windowsize
:
number
;
hashsize
:
number
;
tablesize
:
number
;
stepsize
:
number
;
}
@
Injectable
({
providedIn
:
'
root
'
})
/**
* This service acts as the interface between the client and server side.
*/
export
class
ApiService
{
constructor
()
{
}
// Read input data
async
readFile
():
Promise
<
RawData
>
{
/**
* Read input data. The format is a list of channels, where each channel is an object of type RawData
*/
async
readFile
():
Promise
<
RawData
[]
>
{
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/read-data
'
);
return
await
response
.
json
();
}
// Split data into windows and normalize
async
createWindows
(
parameters
):
Promise
<
any
>
{
/**
* Split the data into windows (server side)
*/
async
createWindows
(
parameters
:
Parameters
):
Promise
<
any
>
{
const
postData
=
{
parameters
};
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/create-windows
'
,
{
await
fetch
(
'
http://127.0.0.1:5000/create-windows
'
,
{
method
:
'
POST
'
,
headers
:
{
'
Accept
'
:
'
application/json
'
,
...
...
@@ -47,8 +66,25 @@ export class ApiService {
});
}
// Calculate parameters for LSH + find candidates using LSH
async
lshInitial
(
query
):
Promise
<
LshData
>
{
/**
* Get weights which will be applied to the LSH hash functions
*/
async
getWeights
(
query
:
number
[][],
labels
:
{[
index
:
number
]:
boolean
},
weights
:
number
[],
hash_functions
:
number
[][]):
Promise
<
number
[]
>
{
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/weights
'
,
{
method
:
'
POST
'
,
headers
:
{
'
Accept
'
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
},
body
:
new
Blob
(
[
JSON
.
stringify
({
query
,
labels
,
weights
,
hash_functions
})
],
{
type
:
'
text/plain
'
}
)
});
return
await
response
.
json
();
}
/**
* Do the first iteration of LSH and return important information
*/
async
lshInitial
(
query
:
number
[][]):
Promise
<
LshData
>
{
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/initialize
'
,
{
method
:
'
POST
'
,
headers
:
{
...
...
@@ -60,7 +96,9 @@ export class ApiService {
return
await
response
.
json
();
}
// Find candidates using LSH with weights
/**
* Do another iteration of LSH, with weights, and return important information
*/
async
lshUpdate
(
query
,
weights
,
parameters
):
Promise
<
LshData
>
{
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/update
'
,
{
method
:
'
POST
'
,
...
...
@@ -73,21 +111,25 @@ export class ApiService {
return
await
response
.
json
();
}
// Get query window based on windows labeled correct
async
getQueryWindow
(
window
):
Promise
<
number
[]
>
{
/**
* Get query window based on windows labeled correct
*/
async
getQueryWindow
(
indices
:
number
|
{[
index
:
number
]:
boolean
}):
Promise
<
number
[][]
>
{
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/query
'
,
{
method
:
'
POST
'
,
headers
:
{
'
Accept
'
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
},
body
:
JSON
.
stringify
({
w
ind
ow
})
body
:
JSON
.
stringify
({
ind
ices
})
});
return
await
response
.
json
();
}
// Get data of a window by indices
async
getWindowByIndices
(
indices
:
number
[]):
Promise
<
number
[][]
>
{
/**
* Get data of a window by indices
*/
async
getWindowByIndices
(
indices
:
number
[]):
Promise
<
number
[][][]
>
{
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/window
'
,
{
method
:
'
POST
'
,
headers
:
{
...
...
@@ -99,14 +141,17 @@ export class ApiService {
return
await
response
.
json
();
}
async
getTableInfo
(
windows
):
Promise
<
TableInfoData
>
{
/**
* Get additional information for a given table
*/
async
getTableInfo
(
table
:
number
[][]):
Promise
<
TableInfoData
>
{
const
response
=
await
fetch
(
'
http://127.0.0.1:5000/table-info
'
,
{
method
:
'
POST
'
,
headers
:
{
'
Accept
'
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
},
body
:
JSON
.
stringify
({
windows
})
body
:
JSON
.
stringify
({
table
})
});
return
await
response
.
json
();
}
...
...
AngularApp/prototype/src/app/app.module.ts
View file @
649da5a6
...
...
@@ -19,6 +19,7 @@ import { ProgressViewComponent } from './progress-view/progress-view.component';
import
{
MainComponent
}
from
'
./main/main.component
'
;
import
{
MatProgressBarModule
}
from
'
@angular/material/progress-bar
'
;
import
{
MatSliderModule
}
from
'
@angular/material/slider
'
;
import
{
TrainingWindowComponent
}
from
'
./training-window/training-window.component
'
;
PlotlyModule
.
plotlyjs
=
PlotlyJS
;
...
...
@@ -33,6 +34,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
QueryWindowComponent
,
ProgressViewComponent
,
MainComponent
,
TrainingWindowComponent
,
],
imports
:
[
BrowserModule
,
...
...
AngularApp/prototype/src/app/labeling-window/labeling-window.component.css
View file @
649da5a6
...
...
@@ -2,11 +2,12 @@
margin-right
:
20px
;
display
:
flex
;
justify-content
:
center
;
border-right
:
1px
solid
;
border-bottom
:
1px
solid
;
}
.subplot-container
{
display
:
flex
;
flex-wrap
:
wrap
;
overflow-x
:
scroll
;
width
:
95%
;
}
...
...
AngularApp/prototype/src/app/labeling-window/labeling-window.component.html
View file @
649da5a6
<div
class=
"container"
>
<div
*ngIf=
"show"
class=
"subplot-container"
>
<div
class=
"subplot-container"
>
<div
class=
"subplot"
*ngFor=
"let subplot of subplots"
>
<plotly-plot
[data]=
"subplot.data"
[layout]=
"subplot.layout"
></plotly-plot>
<div
class=
"button-holder"
>
...
...
@@ -9,10 +9,6 @@
</div>
</div>
</div>
<div
class=
"button-holder"
>
<!-- <button *ngIf="show" (click)="updateQuery()" class="train-button">Query</button>-->
<button
*ngIf=
"show"
(click)=
"train()"
class=
"train-button"
>
Train
</button>
</div>
</div>
AngularApp/prototype/src/app/labeling-window/labeling-window.component.ts
View file @
649da5a6
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
Component
,
EventEmitter
,
OnInit
,
Output
}
from
'
@angular/core
'
;
import
{
StateService
}
from
'
../state.service
'
;
@
Component
({
...
...
@@ -10,86 +10,97 @@ export class LabelingWindowComponent implements OnInit {
public
topk
:
number
[];
public
subplots
=
[];
public
labels
:
boolean
[]
=
[];
private
k
=
12
;
private
k
=
5
;
@
Output
()
labelsOutput
=
new
EventEmitter
<
boolean
[]
>
();
constructor
(
private
state
:
StateService
)
{
}
ngOnInit
():
void
{
this
.
state
.
onNewTable
.
subscribe
(()
=>
this
.
showSamples
());
}
async
train
()
{
this
.
state
.
labels
=
Object
.
assign
({},
this
.
state
.
labels
,
this
.
labels
);
await
this
.
state
.
getQueryWindow
(
this
.
state
.
labels
);
await
this
.
state
.
update
();
}
async
updateQuery
()
{
this
.
state
.
labels
=
Object
.
assign
({},
this
.
state
.
labels
,
this
.
labels
);
await
this
.
state
.
getQueryWindow
(
this
.
state
.
labels
);
this
.
state
.
onNewLshData
.
subscribe
(()
=>
this
.
showSamples
());
}
public
labelCorrect
(
index
:
number
)
{
this
.
labels
[
index
]
=
true
;
this
.
labelsOutput
.
emit
(
this
.
labels
);
}
public
labelUndefined
(
index
:
number
)
{
if
(
this
.
labels
[
index
]
!==
undefined
)
{
delete
this
.
labels
[
index
];
this
.
labelsOutput
.
emit
(
this
.
labels
);
}
}
public
labelIncorrect
(
index
:
number
)
{
this
.
labels
[
index
]
=
false
;
this
.
labelsOutput
.
emit
(
this
.
labels
);
}
async
showSamples
()
{
this
.
topk
=
this
.
state
.
lshData
.
candidates
.
filter
((
candidate
)
=
>
this
.
state
.
l
abels
[
candidate
]
!==
true
)
.
slice
(
0
,
this
.
k
);
this
.
labels
=
[];
this
.
topk
=
this
.
state
.
l
shData
.
samples
;
this
.
subplots
=
[];
const
values
=
await
this
.
state
.
getWindow
(
this
.
topk
);
this
.
topk
.
forEach
((
index
,
i
)
=>
{
this
.
subplots
.
push
(
{
index
,
data
:
[{
x
:
[...
Array
(
values
[
i
].
length
).
keys
()],
y
:
values
[
i
],
type
:
'
line
'
}],
layout
:
{
title
:
`Index:
${
index
.
toString
()}
`
,
hovermode
:
'
closest
'
,
autosize
:
true
,
margin
:
{
l
:
30
,
r
:
30
,
t
:
30
,
b
:
0
,
pad
:
4
},
height
:
150
,
width
:
300
,
titlefont
:
{
size
:
9
},
xaxis
:
{
showgrid
:
false
,
zeroline
:
false
,
showticklabels
:
false
,
},
yaxis
:
{
zeroline
:
false
,
showticklabels
:
false
,
}
const
values
:
number
[][][]
=
await
this
.
state
.
getWindow
(
this
.
topk
);
for
(
const
idx
in
this
.
topk
)
{
const
window
=
values
[
idx
];
const
data
=
[];
window
.
forEach
((
channel
:
number
[],
index
:
number
)
=>
{
data
.
push
({
x
:
[...
Array
(
channel
.
length
).
keys
()],
y
:
channel
,
type
:
'
line
'
,
xaxis
:
'
x
'
,
yaxis
:
`y
${
index
+
2
}
`
,
});
});
const
subplots
=
[];
window
.
forEach
((
channel
:
number
[],
index
:
number
)
=>
{
subplots
.
push
([
`xy
${
index
+
2
}
`
]);
});
const
plot
=
{
index
:
this
.
topk
[
idx
],
data
:
data
,
layout
:
{
grid
:
{
rows
:
this
.
state
.
queryWindow
.
length
,
columns
:
1
,
subplots
:
subplots
,
},
showlegend
:
false
,
title
:
`Index:
${
this
.
topk
[
idx
].
toString
()}
`
,
hovermode
:
'
closest
'
,
autosize
:
true
,
margin
:
{
l
:
30
,
r
:
30
,
t
:
30
,
b
:
0
,
pad
:
4
},
height
:
100
*
values
[
0
].
length
,
width
:
300
,
titlefont
:
{
size
:
9
},
xaxis
:
{
showgrid
:
false
,
zeroline
:
false
,
showticklabels
:
false
,
},
yaxis
:
{
zeroline
:
false
,
showticklabels
:
false
,
}
}
);
});
}
public
get
show
()
{
return
!!
this
.
state
.
lshData
;
};
window
.
forEach
((
channel
:
number
[],
index
:
number
)
=>
{
plot
.
layout
[
`yaxis
${
index
+
2
}
`
]
=
{
zeroline
:
false
,
showticklabels
:
false
,
};
});
this
.
subplots
.
push
(
plot
);
}
}
}
AngularApp/prototype/src/app/labels/labels.component.ts
View file @
649da5a6
...
...
@@ -20,7 +20,7 @@ export class LabelsComponent implements OnInit {
async
createSubplots
()
{
this
.
goodLabels
=
[];
this
.
badLabels
=
[];
const
labelWindows
:
number
[][]
=
await
this
.
state
.
getWindow
(
Object
.
keys
(
this
.
state
.
labels
).
map
(
Number
));
const
labelWindows
:
number
[][]
[]
=
await
this
.
state
.
getWindow
(
Object
.
keys
(
this
.
state
.
labels
).
map
(
Number
));
Object
.
keys
(
this
.
state
.
labels
).
forEach
((
key
,
i
)
=>
{
const
index
=
Number
(
key
);
const
plot
=
...
...
AngularApp/prototype/src/app/main/main.component.html
View file @
649da5a6
...
...
@@ -3,8 +3,7 @@
<app-overview-window
style=
"z-index: 10"
></app-overview-window>
<mat-tab-group
animationDuration=
"0ms"
(selectedTabChange)=
"changeTab($event)"
>
<mat-tab
label=
"Training"
>
<app-labeling-window></app-labeling-window>
<app-table-overview></app-table-overview>
<app-training-window></app-training-window>
</mat-tab>
<mat-tab
label=
"Labeled data"
>
<app-labels></app-labels>
...
...
AngularApp/prototype/src/app/overview-window/overview-window.component.html
View file @
649da5a6
<zingchart-angular
[id]=
"id"
[config]=
"config"
(mousewheel)=
"zoom($event)"
(click)=
"clicked($event)"
[height]=
"
15
0"
></zingchart-angular>
<zingchart-angular
#chart
[id]=
"id"
[config]=
"config"
(mousewheel)=
"zoom($event)"
(click)=
"clicked($event)"
[height]=
"
30
0"
></zingchart-angular>
AngularApp/prototype/src/app/overview-window/overview-window.component.ts
View file @
649da5a6
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
Component
,
OnInit
,
ViewChild
}
from
'
@angular/core
'
;
import
{
StateService
}
from
'
../state.service
'
;
import
zingchart
from
'
zingchart/es6
'
;
...
...
@@ -8,12 +8,15 @@ import zingchart from 'zingchart/es6';
styleUrls
:
[
'
./overview-window.component.css
'
]
})
export
class
OverviewWindowComponent
implements
OnInit
{
@
ViewChild
(
'
chart
'
)
chart
;
public
config
;
public
graphset
=
[];
public
id
=
'
overview
'
;
public
markers
=
[];
public
series
=
[];
public
goodLabels
=
[];
public
badLabels
=
[];
public
candidateLabels
=
[];
public
data
;
public
layout
;
...
...
@@ -23,98 +26,181 @@ export class OverviewWindowComponent implements OnInit {
async
ngOnInit
():
Promise
<
void
>
{
this
.
state
.
onNewData
.
subscribe
(()
=>
this
.
initializePlot
());
this
.
state
.
onNewTable
.
subscribe
(()
=>
this
.
updatePlot
());
//
this.state.onNewTable.subscribe(() => this.updatePlot());
}
async
initializePlot
()
{
this
.
state
.
queryWindow
=
undefined
;
// this.debugClicked();
this
.
data
=
[];
for
(
let
i
=
0
;
i
<
this
.
state
.
rawData
.
values
.
length
;
i
++
)
{
this
.
data
.
push
([
this
.
state
.
rawData
.
index
[
i
],
this
.
state
.
rawData
.
values
[
i
]]);
}
this
.
series
=
[
{
type
:
'
line
'
,
values
:
this
.
data
,
text
:
'
Raw Values
'
,
zIndex
:
5
,
marker
:
{
alpha
:
0.0
,
zIndex
:
10
}
},
{
type
:
'
scatter
'
,
values
:
[],
text
:
'
Good labels
'
,
marker
:
{
backgroundColor
:
'
#4caf50
'
},
zIndex
:
20
,
},
{
type
:
'
scatter
'
,
values
:
[],
text
:
'
Bad labels
'
,
marker
:
{
backgroundColor
:
'
#f44336
'
},
zIndex
:
20
,
}];
this
.
config
=
{
type
:
'
mixed
'
,
preview
:
{
height
:
'
30px
'
,
position
:
'
0% 100%
'
,
'
auto-fit
'
:
true
},
plotarea
:
{
'
margin-top
'
:
'
10px
'
,
'
margin-bottom
'
:
'
50%
'
},
this
.
graphset
.
push
({
id
:
'
preview
'
,
type
:
"
scatter
"
,
x
:
0
,
y
:
0
,
scaleX
:
{
zooming
:
true
,
minValue
:
0
,
maxValue
:
this
.
state
.
rawData
[
0
].
values
.
length
,
zoomTo
:
[
0
,
this
.
state
.
windowSize
],
'
auto-fit
'
:
true
,
markers
:
this
.
markers
visible
:
false
,
guide
:
{
visible
:
false
}
},
height
:
'
30px
'
,
scaleY
:
{
maxValue
:
1
,
minValue
:
-
1
,
visible
:
false
,
guide
:
{
visible
:
false
}
},
'
scale-y
'
:
{
'
auto-fit
'
:
true
preview
:
{
x
:
50
,
y
:
10
,
height
:
'
30px
'
,
},
series
:
this
.
series
series
:
[
{
type
:
'
scatter
'
,
values
:
[],
text
:
'
Good labels
'
,
marker
:
{
backgroundColor
:
'
#4caf50
'
},
zIndex
:
3
,
},
{
type
:
'
scatter
'
,
values
:
[],
text
:
'
Bad labels
'
,
marker
:
{
backgroundColor
:
'
#f44336
'
},
zIndex
:
2
,
},
{
type
:
'
scatter
'
,
values
:
[],
text
:
'
Candidates
'
,
marker
:
{
backgroundColor
:
'
#b1a343
'
},
zIndex
:
1
,
}
]
});
// Initialize channels
this
.
state
.
rawData
.
forEach
((
channel
,
index
)
=>
{
const
data
=
[];
for
(
let
i
=
0
;
i
<
channel
.
values
.
length
;
i
++
)
{
data
.
push
([
i
,
channel
.
values
[
i
]]);
}
this
.
graphset
.
push
({
id
:
index
,
x
:
0
,
y
:
`
${
75
*
index
+
50
}
px`
,
type
:
'
line
'
,
height
:
'
50px
'
,
scaleX
:
{
zooming
:
true
,
zoomTo
:
[
0
,
this
.
state
.
windowSize
],
markers
:
[]
},
'
scale-y
'
:
{
zooming
:
false
,
'
auto-fit
'
:
true
},
plotarea
:
{
height
:
'
50px
'
,
'
margin-top
'
:
'
0px
'
,
'
margin-bot
'
:
'
0px
'
},
series
:
[{
type
:
'
line
'
,
values
:
data
,
text
:
'
Raw Values
'
,
zIndex
:
5
,
marker
:
{
alpha
:
0.0
,
zIndex
:
10
}
}]
});
});
zingchart
.
bind
(
'
zingchart-ng-1
'
,
'
zoom
'
,
(
e
)
=>
{
if
(
e
.
graphid
!==
`zingchart-ng-1-graph-preview`
)
{