From ec6816d0d9a737f9fe70ec8d77f15afcd4720354 Mon Sep 17 00:00:00 2001 From: TAMARA JERINIC Date: Thu, 26 May 2022 00:58:36 +0200 Subject: Ispravljen raspored prikaza metrika, svaka vrednost i odgovarajuća vrednost na validacionom skupu se prikazuju na pojedinačnom grafiku. Metrike su filtrirane u zavisnosti od tipa problema. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/microservice/api/newmlservice.py | 13 +- .../_charts/line-chart/line-chart.component.css | 12 +- .../_charts/line-chart/line-chart.component.html | 26 ++- .../_charts/line-chart/line-chart.component.ts | 249 +++++++++++++++++++-- .../metric-view/metric-view.component.html | 21 +- .../_pages/experiment/experiment.component.html | 7 +- .../app/_pages/experiment/experiment.component.ts | 7 +- 7 files changed, 285 insertions(+), 50 deletions(-) diff --git a/backend/microservice/api/newmlservice.py b/backend/microservice/api/newmlservice.py index 99e3cae5..943e18a1 100644 --- a/backend/microservice/api/newmlservice.py +++ b/backend/microservice/api/newmlservice.py @@ -1,3 +1,4 @@ +from cmath import nan from enum import unique from itertools import count import os @@ -374,13 +375,15 @@ def train(dataset, paramsModel,paramsExperiment,paramsDataset,callback): - classifier.compile(loss =paramsModel["lossFunction"] , optimizer =opt, metrics = ['accuracy','mae','mse']) + classifier.compile(loss =paramsModel["lossFunction"] , optimizer =opt, metrics = ['accuracy']) history=classifier.fit( x=x_train, y=y_train, epochs = paramsModel['epochs'],batch_size=int(paramsModel['batchSize']),callbacks=callback(x_test, y_test,paramsModel['_id']),validation_data=(x_val, y_val)) hist=history.history #plt.plot(hist['accuracy']) - #plt.show() + plt.plot(history.history['loss']) + plt.plot(history.history['val_loss']) + plt.show() y_pred=classifier.predict(x_test) y_pred=np.argmax(y_pred,axis=1) @@ -410,7 +413,7 @@ def train(dataset, paramsModel,paramsExperiment,paramsDataset,callback): #from ann_visualizer.visualize import ann_viz; #ann_viz(classifier, title="My neural network") - return filepath,[hist['loss'],hist['val_loss'],hist['accuracy'],hist['val_accuracy'],hist['mae'],hist['val_mae'],hist['mse'],hist['val_mse']] + return filepath,[hist['loss'],hist['val_loss'],hist['accuracy'],hist['val_accuracy'],[],[],[],[]] elif(problem_type=='binarni-klasifikacioni'): #print('*************************************************************************binarni') @@ -444,7 +447,7 @@ def train(dataset, paramsModel,paramsExperiment,paramsDataset,callback): classifier.add(tf.keras.layers.Dense(units=1, activation=paramsModel['outputLayerActivationFunction']))#izlazni sloj - classifier.compile(loss =paramsModel["lossFunction"] , optimizer =opt , metrics = ['accuracy','mae','mse']) + classifier.compile(loss =paramsModel["lossFunction"] , optimizer =opt , metrics = ['accuracy']) history=classifier.fit( x=x_train, y=y_train, epochs = paramsModel['epochs'],batch_size=int(paramsModel['batchSize']),callbacks=callback(x_test, y_test,paramsModel['_id']),validation_data=(x_val, y_val)) hist=history.history @@ -468,7 +471,7 @@ def train(dataset, paramsModel,paramsExperiment,paramsDataset,callback): logloss = float(sm.log_loss(y_test, y_pred)) """ - return filepath,[hist['loss'],hist['val_loss'],hist['accuracy'],hist['val_accuracy'],hist['mae'],hist['val_mae'],hist['mse'],hist['val_mse']] + return filepath,[hist['loss'],hist['val_loss'],hist['accuracy'],hist['val_accuracy'],[],[],[],[]] elif(problem_type=='regresioni'): reg=paramsModel['layers'][0]['regularisation'] 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 2eea561e..ea150b0f 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 @@ -1,11 +1,17 @@ canvas{ width:100% !important; - height:90% !important; + height:100% !important; border: 1px solid var(--ns-primary); background-color: var(--ns-bg-dark-100); border-radius: 5px; - margin: 10px; + margin: 0; font-size: 11 !important; + padding: 10px; } - \ No newline at end of file +.ns-col{ + margin: 5px; +} +.hide{ + display: none; +} 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 1c711562..e36d0dcf 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,4 +1,24 @@ -
- - +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+ +
+
\ No newline at end of file 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 7d21129c..acba7201 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 @@ -1,5 +1,7 @@ -import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core'; +import { Component, AfterViewInit, ElementRef, ViewChild, Input } from '@angular/core'; import { Chart } from 'chart.js'; +import Experiment from 'src/app/_data/Experiment'; +import Model, { ProblemType } from 'src/app/_data/Model'; @Component({ selector: 'app-line-chart', @@ -23,14 +25,18 @@ export class LineChartComponent implements AfterViewInit { wrapper!: ElementRef; @ViewChild('canvas') canvas!: ElementRef; - + @Input() experiment!:Experiment; constructor() { } width = 700; height = 400; - - myChart!: Chart; + history: any[] = []; + myChartAcc!: Chart; + myChartMae!: Chart; + myChartMse!: Chart; + myChartLoss!: Chart; + ProblemType=ProblemType; resize() { this.width = this.wrapper.nativeElement.offsetWidth; this.height = this.wrapper.nativeElement.offsetHeight; @@ -69,14 +75,69 @@ export class LineChartComponent implements AfterViewInit { this.dataValMSE.length = 0; this.dataValMSE.push(...myValMse); - this.myChart.update(); + this.myChartAcc.update(); + this.myChartLoss.update(); + this.myChartMae.update(); + this.myChartMse.update(); } + updateAll(history: any[],totalEpochs:number) { + const myAcc: number[] = []; + const myMae: number[] = []; + const myMse: number[] = []; + const myLoss: number[] = []; + const myValLoss: number[] = []; + const myValAcc: number[] = []; + const myValMAE: number[] = []; + const myValMSE: number[] = []; + + const myEpochs: number[] = []; + this.history = history; + this.history.forEach((metrics, epoch) => { + if(totalEpochs>100) + { + let epochEstimate=epoch*Math.round(Math.sqrt(totalEpochs)) + if(epochEstimate>totalEpochs) + epochEstimate=totalEpochs; + myEpochs.push(epochEstimate); + } + else + myEpochs.push(epoch + 1); + for (let key in metrics) { + let value = metrics[key]; + if (key === 'accuracy') { + myAcc.push(parseFloat(value)); + } + else if (key === 'loss') { + myLoss.push(parseFloat(value)); + } + else if (key === 'mae') { + myMae.push(parseFloat(value)); + } + else if (key === 'mse') { + myMse.push(parseFloat(value)); + } + else if (key === 'val_acc') { + myValAcc.push(parseFloat(value)); + } + else if (key === 'val_loss') { + myValLoss.push(parseFloat(value)); + } + else if (key === 'val_mae') { + myValMAE.push(parseFloat(value)); + } + else if (key === 'val_mse') { + myValMSE.push(parseFloat(value)); + } + } + }); + this.update(myEpochs, myAcc, myLoss, myMae, myMse, myValAcc,myValLoss,myValMAE,myValMSE); + } ngAfterViewInit(): void { window.addEventListener('resize', () => { this.resize() }); this.resize(); - this.myChart = new Chart("myChart", + this.myChartAcc = new Chart("myChartacc", { type: 'line', data: { @@ -92,7 +153,59 @@ export class LineChartComponent implements AfterViewInit { label: 'Val_Accuracy', data: this.dataValAcc, borderWidth: 1 + } + ] + }, + options: { + responsive: true, + maintainAspectRatio: true, + + plugins: { + legend: { + labels: { + // This more specific font property overrides the global property + color:'white', + font: { + size: 10 + } + } + } + }, + scales: { + x: { + ticks: { + color: 'white' + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + }, + }, + y: { + beginAtZero: true, + ticks: { + color: 'white' + + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + } + } + }, + animation: { + duration: 0 + } + + } + }, + + ); + this.myChartLoss = new Chart("myChartloss", + { + type: 'line', + data: { + labels: this.dataEpoch, + datasets: [ { label: 'Loss', data: this.dataLOSS, @@ -103,16 +216,58 @@ export class LineChartComponent implements AfterViewInit { data: this.dataValLoss, borderWidth: 1 }, - { - label: 'MAE', - data: this.dataMAE, - borderWidth: 1 + ] + }, + options: { + responsive: true, + maintainAspectRatio: true, + + plugins: { + legend: { + labels: { + // This more specific font property overrides the global property + color:'white', + font: { + size: 10 + } + } + } }, - { - label: 'Val_MAE', - data: this.dataValMAE, - borderWidth: 1 + scales: { + x: { + ticks: { + color: 'white' + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + }, + }, + y: { + beginAtZero: true, + ticks: { + color: 'white' + + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + } + } + }, + animation: { + duration: 0 + } + + } + }, + + ); + this.myChartMse = new Chart("myChartmse", + { + type: 'line', + data: { + labels: this.dataEpoch, + datasets: [ { label: 'MSE', data: this.dataMSE, @@ -166,8 +321,72 @@ export class LineChartComponent implements AfterViewInit { } } - } + }, + ); + this.myChartMae = new Chart("myChartmae", + { + type: 'line', + data: { + labels: this.dataEpoch, + datasets: [ + { + label: 'MAE', + data: this.dataMAE, + borderWidth: 1 + }, + { + label: 'Val_MAE', + data: this.dataValMAE, + borderWidth: 1 + }, + ] + }, + options: { + responsive: true, + maintainAspectRatio: true, + + plugins: { + legend: { + labels: { + // This more specific font property overrides the global property + color:'white', + font: { + size: 10 + } + } + } + }, + scales: { + x: { + ticks: { + color: 'white' + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + }, + }, + y: { + beginAtZero: true, + ticks: { + color: 'white' + + }, + grid: { + color: "rgba(0, 99, 171, 0.5)" + } + } + + }, + animation: { + duration: 0 + } + + } + }, + + ); + } } diff --git a/frontend/src/app/_elements/metric-view/metric-view.component.html b/frontend/src/app/_elements/metric-view/metric-view.component.html index 2ab0a425..139597f9 100644 --- a/frontend/src/app/_elements/metric-view/metric-view.component.html +++ b/frontend/src/app/_elements/metric-view/metric-view.component.html @@ -1,21 +1,2 @@ - - - + diff --git a/frontend/src/app/_pages/experiment/experiment.component.html b/frontend/src/app/_pages/experiment/experiment.component.html index 17a6539d..b11729a7 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.html +++ b/frontend/src/app/_pages/experiment/experiment.component.html @@ -67,7 +67,12 @@
- + +
+
+
+
+
diff --git a/frontend/src/app/_pages/experiment/experiment.component.ts b/frontend/src/app/_pages/experiment/experiment.component.ts index ec4275fa..ff17500a 100644 --- a/frontend/src/app/_pages/experiment/experiment.component.ts +++ b/frontend/src/app/_pages/experiment/experiment.component.ts @@ -15,6 +15,7 @@ import { MetricViewComponent } from 'src/app/_elements/metric-view/metric-view.c import { ActivatedRoute, Router } from '@angular/router'; import { DatasetsService } from 'src/app/_services/datasets.service'; import { PredictorsService } from 'src/app/_services/predictors.service'; +import { LineChartComponent } from 'src/app/_elements/_charts/line-chart/line-chart.component'; @Component({ selector: 'app-experiment', @@ -33,7 +34,7 @@ export class ExperimentComponent implements AfterViewInit { @ViewChild("folderDataset") folderDataset!: FolderComponent; @ViewChild(ColumnTableComponent) columnTable!: ColumnTableComponent; @ViewChild("folderModel") folderModel!: FolderComponent; - @ViewChild("metricView") metricView!: MetricViewComponent; + @ViewChild(LineChartComponent) linechartComponent!: LineChartComponent; step1: boolean = false; step2: boolean = false; @@ -89,7 +90,7 @@ export class ExperimentComponent implements AfterViewInit { if (this.modelToTrain?._id == mId) { stat = stat.replace(/'/g, '"'); this.history.push(JSON.parse(stat)); - this.metricView.update(this.history,this.modelToTrain.epochs); + this.linechartComponent.updateAll(this.history,this.modelToTrain.epochs); } }); @@ -115,7 +116,7 @@ export class ExperimentComponent implements AfterViewInit { this.step3 = true; let numOfEpochsArray = Array.from({length: model.epochs}, (_, i) => i + 1); setTimeout(() => { - this.metricView.linechartComponent.update(numOfEpochsArray, predictor.metricsAcc, predictor.metricsLoss, predictor.metricsMae, predictor.metricsMse, predictor.metricsValAcc, predictor.metricsValLoss, predictor.metricsValMae, predictor.metricsValMse); + this.linechartComponent.update(numOfEpochsArray, predictor.metricsAcc, predictor.metricsLoss, predictor.metricsMae, predictor.metricsMse, predictor.metricsValAcc, predictor.metricsValLoss, predictor.metricsValMae, predictor.metricsValMse); }) }); }); -- cgit v1.2.3