Commit 734f8e31 authored by Kruyff,D.L.W. (Dylan)'s avatar Kruyff,D.L.W. (Dylan)
Browse files

Add table labeling

parent f1c33054
......@@ -12,7 +12,7 @@ export interface LshData {
average_distances: number[];
samples: number[];
distances: number[][][];
hash_functions: number[][][][];
hash_functions: number[][];
parameters?: number[];
}
......@@ -64,14 +64,14 @@ export class ApiService {
return await response.json();
}
async getWeights(query: number[][], labels: {[index: number]: boolean}, weights: number[]): Promise<number[]> {
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}) ], { type: 'text/plain' } )
body: new Blob( [ JSON.stringify({query, labels, weights, hash_functions}) ], { type: 'text/plain' } )
});
return await response.json();
}
......
......@@ -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,
......
<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>
import { Component, OnInit } from '@angular/core';
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {StateService} from '../state.service';
@Component({
......@@ -11,6 +11,7 @@ export class LabelingWindowComponent implements OnInit {
public subplots = [];
public labels: boolean[] = [];
private k = 5;
@Output() labelsOutput = new EventEmitter<boolean[]>();
constructor(private state: StateService) { }
......@@ -18,37 +19,24 @@ export class LabelingWindowComponent implements OnInit {
this.state.onNewLshData.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(Object.assign({}, this.labels));
}
async updateQuery() {
this.state.labels = Object.assign({}, this.state.labels, this.labels);
await this.state.getQueryWindow(this.state.labels);
}
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() {
// const allowedCandidates = this.state.lshData.average_candidates.filter((candidate) => this.state.labels[candidate] !== true);
// this.topk = allowedCandidates.slice(0, this.k);
// for (let i = 0; i < this.k; i++) {
// this.topk.push(allowedCandidates[Math.floor(Math.random() * allowedCandidates.length)]);
// }
this.labels = [];
this.topk = this.state.lshData.samples;
......@@ -115,8 +103,4 @@ export class LabelingWindowComponent implements OnInit {
this.subplots.push(plot);
}
}
public get show() {
return !!this.state.lshData;
}
}
......@@ -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-table-overview></app-table-overview>
<app-labeling-window></app-labeling-window>
<app-training-window></app-training-window>
</mat-tab>
<mat-tab label="Labeled data">
<app-labels></app-labels>
......
......@@ -259,6 +259,9 @@ export class OverviewWindowComponent implements OnInit {
const index = 6713;
await this.state.getQueryWindow(index);
await this.state.lshInitial();
const temp = {};
temp[index] = true;
this.state.labels = temp;
}
zoom(p) {
......
......@@ -74,8 +74,8 @@ export class StateService {
this.createTable();
}
async update(labels): Promise<void> {
this._weights = await this.api.getWeights(this._queryWindow, labels, this._weights);
async update(labels, hashFunctions): Promise<void> {
this._weights = await this.api.getWeights(this._queryWindow, labels, this._weights, hashFunctions);
console.log(this._weights);
this.lshData = await this.api.lshUpdate(this._queryWindow, this._weights, this._lshParameters);
this.createTable();
......
......@@ -23,3 +23,15 @@
.button-holder {
z-index: 5;
}
.label-button {
width: 40px;
}
.correct-selected {
background-color: #4caf50
}
.neutral-selected { background-color: #ffa300
}
.incorrect-selected { background-color: #f44336 }
<div class="window">
<div class="plots">
<div class="subplot" *ngFor="let subplot of subplots">
<div class="button-holder">
<button class="correct-button label-button" [class.correct-selected]="labels[subplot.index]" (click)="labelCorrect(subplot.index)">&#10004;</button>
<button class="neutral-button label-button" [class.neutral-selected]="labels[subplot.index] == undefined" (click)="labelUndefined(subplot.index)">&#8226;</button>
</div>
<plotly-plot [data]="subplot.data" [layout]="subplot.layout"></plotly-plot>
</div>
</div>
<div class="plots">
<div class="subplot" *ngFor="let subplot of averages">
<plotly-plot class="plotly-plot" [data]="subplot" [layout]="layout"></plotly-plot>
<!-- <div class="button-holder">-->
<!-- <button class="query-button" (click)="setQuery(subplot.data)">&#x21c4;</button>-->
<!-- </div>-->
</div>
</div>
</div>
import { Component, OnInit } from '@angular/core';
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {StateService} from '../state.service';
@Component({
......@@ -7,9 +7,11 @@ import {StateService} from '../state.service';
styleUrls: ['./table-overview.component.css']
})
export class TableOverviewComponent implements OnInit {
@Output() labelsOutput = new EventEmitter<boolean[]>();
public subplots;
public averages;
public layout;
public labels: boolean[];
constructor(private state: StateService) { }
ngOnInit(): void {
......@@ -19,6 +21,18 @@ export class TableOverviewComponent implements OnInit {
});
}
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);
}
}
async createPrototypes(): Promise<void> {
const representatives: number[][] = [];
this.state.lshData.candidates.forEach((grouphash) => {
......@@ -114,6 +128,7 @@ export class TableOverviewComponent implements OnInit {
}
async createHistograms() {
this.labels = [];
console.log('creating table histograms');
this.subplots = [];
this.averages = [];
......@@ -123,6 +138,7 @@ export class TableOverviewComponent implements OnInit {
console.log(index);
this.subplots.push(
{
index,
data: [{
x: Object.keys(table),
y: Object.values(table).map((values: number[]) => values.length), // / (this.service.rawValues.length - this.service.windowSize)),
......
<app-table-overview (labelsOutput)="hashFunctionLabels = $event"></app-table-overview>
<app-labeling-window (labelsOutput)="labels = $event"></app-labeling-window>
<div class="button-holder">
<button *ngIf="show" (click)="train()" class="train-button">Train</button>
</div>
import { Component, OnInit } from '@angular/core';
import {StateService} from '../state.service';
@Component({
selector: 'app-training-window',
templateUrl: './training-window.component.html',
styleUrls: ['./training-window.component.css']
})
export class TrainingWindowComponent implements OnInit {
public labels: boolean[] = [];
public hashFunctionLabels: boolean[] = [];
constructor(private state: StateService) { }
ngOnInit(): void {
}
async train() {
this.state.labels = Object.assign({}, this.state.labels, this.labels);
await this.state.getQueryWindow(this.state.labels);
console.log(this.hashFunctionLabels);
const hashFunctions: number[][] = [];
this.hashFunctionLabels.forEach((label, index) => {
if (label) {
hashFunctions.push(this.state.lshData.hash_functions[index]);
}
});
console.log(hashFunctions);
await this.state.update(Object.assign({}, this.labels), hashFunctions);
}
public get show() {
return !!this.state.lshData;
}
}
......@@ -25,14 +25,7 @@
<change beforePath="$PROJECT_DIR$/../AngularApp/prototype/src/app/overview-window/overview-window.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../AngularApp/prototype/src/app/overview-window/overview-window.component.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../AngularApp/prototype/src/app/state.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../AngularApp/prototype/src/app/state.service.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/_lsh.cpython-38-x86_64-linux-gnu.so" beforeDir="false" afterPath="$PROJECT_DIR$/_lsh.cpython-38-x86_64-linux-gnu.so" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so" beforeDir="false" afterPath="$PROJECT_DIR$/build/lib.linux-x86_64-3.8/_lsh.cpython-38-x86_64-linux-gnu.so" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/_lsh.o" beforeDir="false" afterPath="$PROJECT_DIR$/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/_lsh.o" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/lsh.o" beforeDir="false" afterPath="$PROJECT_DIR$/build/temp.linux-x86_64-3.8/locality-sensitive-hashing-visual-analytics/lsh-fast/lsh.o" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/processed-data.npy" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../experiments/.ipynb_checkpoints/EEG data test-checkpoint.ipynb" beforeDir="false" afterPath="$PROJECT_DIR$/../experiments/.ipynb_checkpoints/EEG data test-checkpoint.ipynb" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../experiments/EEG data test.ipynb" beforeDir="false" afterPath="$PROJECT_DIR$/../experiments/EEG data test.ipynb" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
......
......@@ -217,7 +217,7 @@ def initialize():
response = {
"hash_functions": hf.tolist(),
"hash_functions": hf.reshape((len(candidates) * len(candidates[0]), len(query[0]))).tolist(),
"candidates": candidates,
"tables": tables,
"distances": distances.tolist(),
......@@ -235,37 +235,46 @@ def weights():
alpha = 0.2
raw_data = orjson.loads(request.data)
labels = raw_data["labels"]
hash_functions = raw_data["hash_functions"]
query = raw_data["query"]
old_weights = raw_data["weights"]
data = np.load('processed-data.npy')
all_good_windows = data[[[int(index) for index, value in labels.items() if value is True]]]
all_bad_windows = data[[[int(index) for index, value in labels.items() if value is False]]]
good_distances = np.zeros(len(query))
for window in all_good_windows:
for i in range(len(all_good_windows[0])):
good_distances[i] += _ucrdtw.ucrdtw(query[i], window[i], 0.05, False)[1]
if len(all_good_windows) != 0:
good_distances = np.square(good_distances)
good_distances /= np.sum(good_distances)
good_distances = np.ones(len(query)) - good_distances
good_distances /= np.sum(good_distances)
good_distances *= len(all_good_windows[0])
good_distances = np.sqrt(good_distances)
good_distances = alpha * np.array(old_weights) + (1-alpha) * good_distances
# bad_distances = np.zeros(len(query))
# for window in all_bad_windows:
# for i in range(len(all_bad_windows[0])):
# bad_distances[i] += _ucrdtw.ucrdtw(query[i], window[i], 0.05, False)[1]
# if len(all_bad_windows) != 0:
# bad_distances /= np.sum(bad_distances)
# bad_distances = np.ones(len(query)) - bad_distances
print(good_distances)
if len(hash_functions) != 0:
summed_hash_functions = np.sum(hash_functions, axis=0)
summed_hash_functions = np.square(summed_hash_functions)
normalized_hash_functions = summed_hash_functions / np.sum(summed_hash_functions)
normalized_hash_functions *= len(hash_functions[0])
if len(hash_functions) + len(all_good_windows) == 0:
print("no update")
new_weights = old_weights
elif len(hash_functions) == 0:
print("only windows")
new_weights = alpha * np.array(old_weights) + (1 - alpha) * good_distances
elif len(all_good_windows) == 0:
print("only tables")
new_weights = alpha * np.array(old_weights) + (1 - alpha) * normalized_hash_functions
else:
print("tables & windows")
new_weights = alpha * np.array(old_weights) + 0.5 * (1-alpha) * good_distances + 0.5 * (1-alpha) * normalized_hash_functions
# Caculate weights
print(new_weights)
response = orjson.dumps(good_distances.tolist())
response = orjson.dumps(new_weights.tolist())
return response
......@@ -310,7 +319,7 @@ def update():
samples = np.array(list(filter(lambda x: x in samples_set, average_candidates))).tolist()
response = {
"hash_functions": hf.tolist(),
"hash_functions": hf.reshape((len(candidates) * len(candidates[0]), len(query[0]))).tolist(),
"candidates": candidates,
"tables": tables,
"samples": list(samples),
......
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