aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanijel Anđelković <adanijel99@gmail.com>2022-06-04 01:17:55 +0200
committerDanijel Anđelković <adanijel99@gmail.com>2022-06-04 01:17:55 +0200
commit60782001174dc7f6f8f5670bff5aaca54667b734 (patch)
tree3839d149476115cbf7b954867a7c3bf2006c23f7
parent854e21f08d1c876cf62c7a360bd5bd142675d705 (diff)
Dodao poredjenje modela/prediktora nad eksperimentom. Popravio bug sa dodavanjem novog prediktora.
-rw-r--r--backend/api/api/Controllers/PredictorController.cs22
-rw-r--r--backend/microservice/api/controller.py5
-rw-r--r--frontend/src/app/_elements/_charts/line-chart/line-chart.component.css2
-rw-r--r--frontend/src/app/_elements/_charts/line-chart/line-chart.component.html15
-rw-r--r--frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts23
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.css30
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.html19
-rw-r--r--frontend/src/app/_pages/experiment/experiment.component.ts71
8 files changed, 154 insertions, 33 deletions
diff --git a/backend/api/api/Controllers/PredictorController.cs b/backend/api/api/Controllers/PredictorController.cs
index 6ff7746a..56095553 100644
--- a/backend/api/api/Controllers/PredictorController.cs
+++ b/backend/api/api/Controllers/PredictorController.cs
@@ -21,7 +21,7 @@ namespace api.Controllers
private readonly IHubContext<ChatHub> _ichat;
private readonly IModelService _modelService;
- public PredictorController(IPredictorService predictorService, IConfiguration configuration, IJwtToken Token, IMlConnectionService mlConnectionService, IExperimentService experimentService,IUserService userService, IHubContext<ChatHub> ichat,IModelService modelService)
+ public PredictorController(IPredictorService predictorService, IConfiguration configuration, IJwtToken Token, IMlConnectionService mlConnectionService, IExperimentService experimentService, IUserService userService, IHubContext<ChatHub> ichat, IModelService modelService)
{
_predictorService = predictorService;
jwtToken = Token;
@@ -78,7 +78,7 @@ namespace api.Controllers
//public ActionResult<List<Predictor>> Search(string name)
//{
// string username = getUsername();
-
+
// if (username == null)
// return BadRequest();
@@ -138,7 +138,7 @@ namespace api.Controllers
List<Predictor> lista = _predictorService.SortPredictors(userId, ascdsc, latest);
- if(latest == 0)
+ if (latest == 0)
return lista;
else
{
@@ -155,19 +155,23 @@ namespace api.Controllers
[HttpPost("add")]
public async Task<ActionResult<Predictor>> Post([FromBody] Predictor predictor)
{
- var user=_userService.GetUserById(predictor.uploaderId);
+ var user = _userService.GetUserById(predictor.uploaderId);
predictor.dateCreated = DateTime.Now.ToUniversalTime();
var model = _modelService.GetOneModel(predictor.modelId);
- if (model == null || user==null)
+ if (model == null || user == null)
return BadRequest("Model not found or user doesnt exist");
- Predictor p=_predictorService.Exists(predictor.modelId, predictor.experimentId);
- if (p == null)
+ Predictor p = _predictorService.Exists(predictor.modelId, predictor.experimentId);
+
+ if (p == null) {
_predictorService.Create(predictor);
- else
+ }
+ else {
+ predictor._id = p._id;
_predictorService.Update(p._id, predictor);
+ }
if (ChatHub.CheckUser(user._id))
foreach(var connection in ChatHub.getAllConnectionsOfUser(user._id))
- await _ichat.Clients.Client(connection).SendAsync("NotifyPredictor", predictor._id,model.name);
+ await _ichat.Clients.Client(connection).SendAsync("NotifyPredictor", predictor._id, model._id);
return CreatedAtAction(nameof(Get), new { id = predictor._id }, predictor);
}
diff --git a/backend/microservice/api/controller.py b/backend/microservice/api/controller.py
index c82634a2..bc8c17a0 100644
--- a/backend/microservice/api/controller.py
+++ b/backend/microservice/api/controller.py
@@ -1,3 +1,4 @@
+from asyncio.windows_events import NULL
from cmath import log
from dataclasses import dataclass
from distutils.command.upload import upload
@@ -112,12 +113,12 @@ def train():
"metricsMse":histMetrics[6],
"metricsValMse":histMetrics[7]
}
- #print(predictor)
+ print(predictor)
url = config.api_url + "/Predictor/add"
r = requests.post(url, json=predictor).text
- #print(r)
+ print(r)
return r
@app.route('/predict', methods = ['POST'])
diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css
index 9694119d..862a86e1 100644
--- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css
+++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.css
@@ -4,7 +4,7 @@
}
.bottom {
- height: 10%;
+ height: 30px;
}
canvas {
diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html
index a81f9dc4..cc1c0121 100644
--- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html
+++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.html
@@ -1,28 +1,29 @@
-<div #wrapper class="position-relative" style="width:100%;height:95%;">
+<div #wrapper class="position-relative" style="width:100%;height:95%; border: 1px solid var(--ns-accent); background-color: var(--ns-bg-dark-100); border-radius: 15px;">
<div class="d-flex flex-column align-items-stretch" [ngClass]="{'hide':experiment.type != ProblemType.Regression}" style="width: 100%; height: 90%;">
<div class="canvas-container">
- <canvas id="myChartmae" #canvas>
+ <canvas #myChartmae>
</canvas>
</div>
<div class="canvas-container">
- <canvas id="myChartmse" #canvas>
+ <canvas #myChartmse>
</canvas>
</div>
</div>
<div class="ns-row" [ngClass]="{'hide':experiment.type == ProblemType.Regression}">
<div class="ns-col">
- <canvas id="myChartloss" #canvas>
+ <canvas #myChartloss>
</canvas>
</div>
<div class="ns-col">
- <canvas id="myChartacc" #canvas>
+ <canvas #myChartacc>
</canvas>
</div>
</div>
- <div class="bottom d-flex flex-row align-items-center">
- <button *ngIf="predictor" class="btn-clear dl-button d-flex flex-row" (click)="downloadFile();" style="display: inline-block;" matTooltip="Preuzmi H5" matTooltipPosition="above">
+ <div class="bottom d-flex flex-row" style="justify-content: space-between; align-items: center;">
+ <h3 class="mt-5 mx-2"><span *ngIf="modelName.length > 0 && predictor">Model treniran za konfiguraciju: {{modelName}}</span><span *ngIf="modelName.length > 0 && !predictor">Model se trenira za konfiguraciju: {{modelName}}</span></h3>
+ <button *ngIf="predictor" class="mt-5 mx-2 btn-clear dl-button d-flex flex-row" (click)="downloadFile();" style="display: inline-block;" matTooltip="Preuzmi H5" matTooltipPosition="above">
<mat-icon>download</mat-icon> <div>H5</div>
</button>
</div>
diff --git a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts
index ceff02bd..b2eec377 100644
--- a/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts
+++ b/frontend/src/app/_elements/_charts/line-chart/line-chart.component.ts
@@ -26,8 +26,12 @@ export class LineChartComponent implements AfterViewInit {
@ViewChild('wrapper')
wrapper!: ElementRef;
- @ViewChildren('canvas')
- canvas!: QueryList<ElementRef>;
+
+ @ViewChild('myChartacc') myChartacc!: ElementRef;
+ @ViewChild('myChartloss') myChartloss!: ElementRef;
+ @ViewChild('myChartmse') myChartmse!: ElementRef;
+ @ViewChild('myChartmae') myChartmae!: ElementRef;
+
@Input() experiment!: Experiment;
@Input() predictor?: Predictor;
@@ -149,7 +153,7 @@ export class LineChartComponent implements AfterViewInit {
window.addEventListener('resize', () => { this.resize() });
this.resize();
- this.myChartAcc = new Chart("myChartacc",
+ this.myChartAcc = new Chart(this.myChartacc.nativeElement,
{
type: 'line',
data: {
@@ -222,7 +226,7 @@ export class LineChartComponent implements AfterViewInit {
);
if (this.experiment.type == ProblemType.BinaryClassification || this.experiment.type == ProblemType.MultiClassification) { }
- this.myChartLoss = new Chart("myChartloss",
+ this.myChartLoss = new Chart(this.myChartloss.nativeElement,
{
type: 'line',
data: {
@@ -294,7 +298,7 @@ export class LineChartComponent implements AfterViewInit {
},
);
- this.myChartMse = new Chart("myChartmse",
+ this.myChartMse = new Chart(this.myChartmse.nativeElement,
{
type: 'line',
data: {
@@ -366,7 +370,7 @@ export class LineChartComponent implements AfterViewInit {
},
);
- this.myChartMae = new Chart("myChartmae",
+ this.myChartMae = new Chart(this.myChartmae.nativeElement,
{
type: 'line',
data: {
@@ -440,5 +444,12 @@ export class LineChartComponent implements AfterViewInit {
);
}
+
+ modelName: string = '';
+
+ setName(name: string) {
+ this.modelName = name;
+ this.predictor = undefined;
+ }
}
diff --git a/frontend/src/app/_pages/experiment/experiment.component.css b/frontend/src/app/_pages/experiment/experiment.component.css
index 59e004e9..37edd3c2 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.css
+++ b/frontend/src/app/_pages/experiment/experiment.component.css
@@ -74,4 +74,34 @@ mat-stepper {
.text-overflow-experiment-name {
overflow-wrap: break-word;
+}
+
+#compareButton {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+}
+
+.side-by-side {
+ display: flex;
+ flex-direction: row;
+ width: 100%;
+ height: 100%;
+}
+
+
+/* one item */
+
+.side-by-side>*:first-child:nth-last-child(1) {
+ /* -or- li:only-child { */
+ width: 100%;
+}
+
+
+/* two items */
+
+.side-by-side>*:first-child:nth-last-child(2),
+.side-by-side>*:first-child:nth-last-child(2)~li {
+ width: 50%;
+ margin: 5px;
} \ No newline at end of file
diff --git a/frontend/src/app/_pages/experiment/experiment.component.html b/frontend/src/app/_pages/experiment/experiment.component.html
index 2e5a269c..a0ed26ef 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.html
+++ b/frontend/src/app/_pages/experiment/experiment.component.html
@@ -25,10 +25,10 @@
<ng-template matStepLabel>
<span class="label addedElement text-overflow" *ngIf="experiment._id!=''">Predvideti:{{experiment.outputColumn}}</span>
<span *ngIf="!this.step1" class="align-middle"><mat-icon>lock</mat-icon></span>
- <span class="label text-overflow" *ngIf="experiment._id==''">Odabir kolona </span>
+ <span class="label text-overflow" *ngIf="experiment._id==''">Priprema podataka </span>
</ng-template>
<ng-template matStepContent>
- <p class="text-left text-overflow">Pripremite podatke i izaberite izlazne kolone</p>
+ <p class="text-left text-overflow">Pripremite podatke i odaberite ulazne i izlaznu kolonu</p>
</ng-template>
</mat-step>
<mat-step [completed]="this.step3">
@@ -62,12 +62,23 @@
</div>
<div #steps id="step_3" class="step-content" *ngIf="step2">
<div class="step-content-inside">
- <app-folder #folderModel [type]="FolderType.Model" [forExperiment]="experiment" [startingTab]="TabType.NewFile" [tabsToShow]="[TabType.MyModels]" (okPressed)="goToPage(3); trainModel();" (selectedFileChanged)="setModel($event)"></app-folder>
+ <div id="compareButton">
+ <button mat-raised-button color="accent" *ngIf="!comparing" (click)="toggleCompare()"><mat-icon>compare</mat-icon> Dodaj konfiguraciju za upoređivanje</button>
+ <button mat-raised-button *ngIf="comparing" (click)="toggleCompare()"><mat-icon>not_interested</mat-icon> Prekini upoređivanje</button>
+ </div>
+ <div class="side-by-side">
+ <app-folder #folderModel [type]="FolderType.Model" [forExperiment]="experiment" [startingTab]="TabType.NewFile" [tabsToShow]="[TabType.MyModels]" (okPressed)="goToPage(3); trainModel();" (selectedFileChanged)="setModel($event);"></app-folder>
+ <app-folder #folderModelCompare [type]="FolderType.Model" [forExperiment]="experiment" [startingTab]="TabType.MyModels" [tabsToShow]="[TabType.MyModels]" (okPressed)="goToPage(3); trainModelCmp();" (selectedFileChanged)="setModelCmp($event);" style="width: 50%;"
+ *ngIf="comparing"></app-folder>
+ </div>
</div>
</div>
<div #steps id="step_4" class="step-content" *ngIf="step3">
<div class="step-content-inside">
- <app-line-chart [experiment]="experiment" [predictor]="predictor!"></app-line-chart>
+ <div class="side-by-side">
+ <app-line-chart #linechart [experiment]="experiment" [predictor]="predictor!"></app-line-chart>
+ <app-line-chart #linechartCompare [experiment]="experiment" style="width: 50%;" *ngIf="comparing"></app-line-chart>
+ </div>
</div>
</div>
<!--
diff --git a/frontend/src/app/_pages/experiment/experiment.component.ts b/frontend/src/app/_pages/experiment/experiment.component.ts
index 4ceb9a03..5822eedf 100644
--- a/frontend/src/app/_pages/experiment/experiment.component.ts
+++ b/frontend/src/app/_pages/experiment/experiment.component.ts
@@ -37,13 +37,27 @@ export class ExperimentComponent implements AfterViewInit {
@ViewChild("folderDataset") folderDataset!: FolderComponent;
@ViewChild(ColumnTableComponent) columnTable!: ColumnTableComponent;
@ViewChild("folderModel") folderModel!: FolderComponent;
- @ViewChild(LineChartComponent) linechartComponent!: LineChartComponent;
+ @ViewChild("folderModelCompare") folderModelCmp!: FolderComponent;
+ @ViewChild("linechart") linechartComponent!: LineChartComponent;
+ @ViewChild("linechartCompare") linechartComponentCmp!: LineChartComponent;
step1: boolean = false;
step2: boolean = false;
step3: boolean = false;
step4: boolean = false;
+ comparing: boolean = false;
+
+ toggleCompare() {
+ this.comparing = !this.comparing;
+ setTimeout(() => {
+ if (this.folderModel.formModel)
+ this.folderModel.formModel.graph.resize();
+ if (this.folderModel.formNewModel)
+ this.folderModel.formNewModel.graph.resize();
+ });
+ }
+
constructor(private experimentsService: ExperimentsService, private modelsService: ModelsService, private datasetsService: DatasetsService, private predictorsService: PredictorsService, private signalRService: SignalRService, private route: ActivatedRoute) {
this.experiment = new Experiment("exp1");
}
@@ -65,6 +79,15 @@ export class ExperimentComponent implements AfterViewInit {
}
}
+ trainModelCmp() {
+ if (!this.modelToTrainCmp) {
+ Shared.openDialog('Greška', 'Morate odabrati konfiguraciju neuronske mreže');
+ } else {
+ this.modelsService.trainModel(this.modelToTrainCmp._id, this.experiment._id).subscribe(() => { console.log("pocelo treniranje") });
+ this.step4 = true;
+ }
+ }
+
stepHeight = this.calcStepHeight();
calcStepHeight() {
@@ -87,16 +110,48 @@ export class ExperimentComponent implements AfterViewInit {
if (this.signalRService.hubConnection) {
this.signalRService.hubConnection.on("NotifyEpoch", (mName: string, mId: string, stat: string, totalEpochs: number, currentEpoch: number) => {
- if (currentEpoch == 0) {
- this.history = [];
- }
+
if (this.modelToTrain?._id == mId) {
+ if (currentEpoch == 0) {
+ this.linechartComponent.setName(mName);
+ this.history = [];
+ }
+
stat = stat.replace(/'/g, '"');
this.history.push(JSON.parse(stat));
+
this.linechartComponent.updateAll(this.history, this.modelToTrain.epochs);
}
+
+ if (this.modelToTrainCmp?._id == mId) {
+ if (currentEpoch == 0) {
+ this.linechartComponentCmp.setName(mName);
+ this.historyCmp = [];
+ }
+
+ stat = stat.replace(/'/g, '"');
+
+ this.historyCmp.push(JSON.parse(stat));
+ this.linechartComponentCmp.updateAll(this.historyCmp, this.modelToTrainCmp.epochs);
+ }
});
+ this.signalRService.hubConnection.on("NotifyPredictor", (pId: string, mId: string) => {
+ console.log("Predictor trained: ", pId, "for model:", mId);
+
+ if (this.modelToTrain && mId == this.modelToTrain._id) {
+ this.predictorsService.getPredictor(pId).subscribe((predictor) => {
+ this.linechartComponent.predictor = predictor;
+ });
+ }
+
+ if (this.modelToTrainCmp && mId == this.modelToTrainCmp._id) {
+ this.predictorsService.getPredictor(pId).subscribe((predictor) => {
+ this.linechartComponentCmp.predictor = predictor;
+ });
+ }
+ })
+
}
this.route.queryParams.subscribe(params => {
@@ -142,6 +197,7 @@ export class ExperimentComponent implements AfterViewInit {
}
history: any[] = [];
+ historyCmp: any[] = [];
updatePageIfScrolled() {
if (this.scrolling) return;
@@ -227,10 +283,17 @@ export class ExperimentComponent implements AfterViewInit {
}
modelToTrain?: Model;
+ modelToTrainCmp?: Model;
setModel(model: FolderFile) {
const m = <Model>model;
this.modelToTrain = m;
this.step3 = true;
}
+
+ setModelCmp(model: FolderFile) {
+ const m = <Model>model;
+ this.modelToTrainCmp = m;
+ this.step3 = true;
+ }
}