aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanijel Andjelkovic <adanijel99@gmail.com>2022-03-29 12:24:38 +0200
committerDanijel Andjelkovic <adanijel99@gmail.com>2022-03-29 12:24:38 +0200
commit98d580ca1ba501bc059ff417dd1794e0f6a68407 (patch)
treebc0680bda42355ba42ca5aae5b5bf0d6861a34fe
parent2833bcde639d0c8e36971b5e899488dc828a0779 (diff)
Povezao treniranje modela.
-rw-r--r--.gitignore4
-rw-r--r--backend/api/api/Controllers/ModelController.cs12
-rw-r--r--backend/api/api/Models/Model.cs7
-rw-r--r--backend/api/api/Services/DatasetService.cs5
-rw-r--r--backend/api/api/Services/IDatasetService.cs1
-rw-r--r--backend/api/api/Services/IMlConnectionService.cs2
-rw-r--r--backend/api/api/Services/IModelService.cs1
-rw-r--r--backend/api/api/Services/MlConnectionService.cs18
-rw-r--r--backend/api/api/Services/ModelService.cs5
-rw-r--r--backend/microservice/PythonServer/project/socket_example/socket/client.py (renamed from backend/microservice/PythonServer/project/api/socket/client.py)0
-rw-r--r--backend/microservice/PythonServer/project/socket_example/socket/server.py (renamed from backend/microservice/PythonServer/project/api/socket/server.py)0
-rw-r--r--backend/microservice/PythonServer/project/socket_example/socket2/client.py (renamed from backend/microservice/PythonServer/project/api/socket2/client.py)0
-rw-r--r--backend/microservice/PythonServer/project/socket_example/socket2/server.py (renamed from backend/microservice/PythonServer/project/api/socket2/server.py)0
-rw-r--r--backend/microservice/api/controller.py42
-rw-r--r--backend/microservice/api/ml_service.py155
-rw-r--r--backend/microservice/api/ml_socket.py (renamed from backend/microservice/ml_socket.py)13
-rw-r--r--frontend/src/app/_data/Model.ts13
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.html69
-rw-r--r--frontend/src/app/_pages/add-model/add-model.component.ts32
-rw-r--r--frontend/src/app/_services/models.service.ts14
-rw-r--r--frontend/src/app/_services/web-socket.service.ts6
21 files changed, 313 insertions, 86 deletions
diff --git a/.gitignore b/.gitignore
index d094e2e2..25a7cdac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,6 @@ sandbox/test-projekat-danijel/backend/.vs/
sandbox/testAppSonja/MiniApkSonja/MiniApkSonja/bin/
sandbox/testAppSonja/MiniApkSonja/MiniApkSonja/obj/
sandbox/TestTamara/TestTamara/TestTamara/obj/
-sandbox/TestTamara/TestTamara/TestTamara/bin/ \ No newline at end of file
+sandbox/TestTamara/TestTamara/TestTamara/bin/
+backend/microservice/temp/
+backend/microservice/api/__pycache__/
diff --git a/backend/api/api/Controllers/ModelController.cs b/backend/api/api/Controllers/ModelController.cs
index b997efa3..4bc094cd 100644
--- a/backend/api/api/Controllers/ModelController.cs
+++ b/backend/api/api/Controllers/ModelController.cs
@@ -14,22 +14,28 @@ namespace api.Controllers
{
private IMlConnectionService _mlService;
+ private readonly IDatasetService _datasetService;
+ private readonly IFileService _fileService;
private readonly IModelService _modelService;
private JwtToken jwtToken;
- public ModelController(IMlConnectionService mlService, IModelService modelService, IConfiguration configuration)
+ public ModelController(IMlConnectionService mlService, IModelService modelService, IDatasetService datasetService, IFileService fileService, IConfiguration configuration)
{
_mlService = mlService;
_modelService = modelService;
+ _datasetService = datasetService;
+ _fileService = fileService;
jwtToken = new JwtToken(configuration);
}
[HttpPost("sendModel")]
[Authorize(Roles = "User")]
- public async Task<ActionResult<string>> Test([FromBody] object model)
+ public async Task<ActionResult<string>> Test([FromBody] Model model)
{
- var result = await _mlService.SendModelAsync(model);
+ var dataset = _datasetService.GetOneDataset(model.datasetId);
+ var filepath = _fileService.GetFilePath(dataset.fileId, dataset.username);
+ var result = await _mlService.SendModelAsync(model, filepath);
return Ok(result);
}
diff --git a/backend/api/api/Models/Model.cs b/backend/api/api/Models/Model.cs
index 5678daaf..2baab1c0 100644
--- a/backend/api/api/Models/Model.cs
+++ b/backend/api/api/Models/Model.cs
@@ -38,10 +38,13 @@ namespace api.Models
public int batchSize { get; set; }
// na izlazu je moguce da bude vise neurona (klasifikacioni problem sa vise od 2 klase)
public int outputNeurons { get; set; }
- public string inputLayerActivationFunction { get; set; }
- public string hiddenLayerActivationFunction { get; set; }
+ public string[] hiddenLayerActivationFunctions { get; set; }
public string outputLayerActivationFunction { get; set; }
+ public string[] metrics { get; set; }
+ public int epochs { get; set; }
+ public string nullValues { get; set; }
+ public string[] nullValuesReplacers { get; set; }
}
}
diff --git a/backend/api/api/Services/DatasetService.cs b/backend/api/api/Services/DatasetService.cs
index 5e708d11..45ed18a9 100644
--- a/backend/api/api/Services/DatasetService.cs
+++ b/backend/api/api/Services/DatasetService.cs
@@ -61,6 +61,11 @@ namespace api.Services
}
//odraditi za pretragu getOne
+ public Dataset GetOneDataset(string id)
+ {
+ return _dataset.Find(dataset => dataset._id == id).FirstOrDefault();
+ }
+
//ako je potrebno da se zameni name ili ekstenzija
public void Update(string username, string name, Dataset dataset)
{
diff --git a/backend/api/api/Services/IDatasetService.cs b/backend/api/api/Services/IDatasetService.cs
index be56f5cb..dbe43321 100644
--- a/backend/api/api/Services/IDatasetService.cs
+++ b/backend/api/api/Services/IDatasetService.cs
@@ -6,6 +6,7 @@ namespace api.Services
public interface IDatasetService
{
Dataset GetOneDataset(string username, string name);
+ Dataset GetOneDataset(string id);
List<Dataset> SearchDatasets(string name, string username);
List<Dataset> GetMyDatasets(string username);
List<Dataset> SortDatasets(string username, bool ascdsc, int latest);
diff --git a/backend/api/api/Services/IMlConnectionService.cs b/backend/api/api/Services/IMlConnectionService.cs
index f38fb50a..ee839d28 100644
--- a/backend/api/api/Services/IMlConnectionService.cs
+++ b/backend/api/api/Services/IMlConnectionService.cs
@@ -3,6 +3,6 @@ namespace api.Services
{
public interface IMlConnectionService
{
- Task<string> SendModelAsync(object model);
+ Task<string> SendModelAsync(object model, object dataset);
}
} \ No newline at end of file
diff --git a/backend/api/api/Services/IModelService.cs b/backend/api/api/Services/IModelService.cs
index ee5c279f..637d09a3 100644
--- a/backend/api/api/Services/IModelService.cs
+++ b/backend/api/api/Services/IModelService.cs
@@ -6,6 +6,7 @@ namespace api.Services
public interface IModelService
{
Model GetOneModel(string username, string name);
+ Model GetOneModel(string id);
List<Model> GetMyModels(string username);
List<Model> GetLatestModels(string username);
//List<Model> GetPublicModels();
diff --git a/backend/api/api/Services/MlConnectionService.cs b/backend/api/api/Services/MlConnectionService.cs
index 9b167537..9c3b3fd8 100644
--- a/backend/api/api/Services/MlConnectionService.cs
+++ b/backend/api/api/Services/MlConnectionService.cs
@@ -6,13 +6,19 @@ namespace api.Services
{
public class MlConnectionService : IMlConnectionService
{
- public async Task<string> SendModelAsync(object model)
+ private RestClient client;
+
+ public MlConnectionService()
+ {
+ this.client = new RestClient("http://127.0.0.1:5543");
+ }
+
+ public async Task<string> SendModelAsync(object model, object dataset)
{
- RestClient client = new RestClient("http://localhost:5000");
- var request = new RestRequest("data", Method.Post);
- request.AddJsonBody(model);
- var result = await client.ExecuteAsync(request);
- return result.Content;//Response od ML microservisa
+ var request = new RestRequest("train", Method.Post);
+ request.AddJsonBody(new { model, dataset});
+ var result = await this.client.ExecuteAsync(request);
+ return result.Content; //Response od ML microservisa
}
}
}
diff --git a/backend/api/api/Services/ModelService.cs b/backend/api/api/Services/ModelService.cs
index f42219f5..eae8c78b 100644
--- a/backend/api/api/Services/ModelService.cs
+++ b/backend/api/api/Services/ModelService.cs
@@ -50,6 +50,11 @@ namespace api.Services
return _model.Find(model => model.username == username && model.name == name).FirstOrDefault();
}
+ public Model GetOneModel(string id)
+ {
+ return _model.Find(model => model._id == id).FirstOrDefault();
+ }
+
public void Update(string username, string name, Model model)
{
_model.ReplaceOne(model => model.username == username && model.name == name, model);
diff --git a/backend/microservice/PythonServer/project/api/socket/client.py b/backend/microservice/PythonServer/project/socket_example/socket/client.py
index d5740e25..d5740e25 100644
--- a/backend/microservice/PythonServer/project/api/socket/client.py
+++ b/backend/microservice/PythonServer/project/socket_example/socket/client.py
diff --git a/backend/microservice/PythonServer/project/api/socket/server.py b/backend/microservice/PythonServer/project/socket_example/socket/server.py
index d6ff3f7c..d6ff3f7c 100644
--- a/backend/microservice/PythonServer/project/api/socket/server.py
+++ b/backend/microservice/PythonServer/project/socket_example/socket/server.py
diff --git a/backend/microservice/PythonServer/project/api/socket2/client.py b/backend/microservice/PythonServer/project/socket_example/socket2/client.py
index 65e76b55..65e76b55 100644
--- a/backend/microservice/PythonServer/project/api/socket2/client.py
+++ b/backend/microservice/PythonServer/project/socket_example/socket2/client.py
diff --git a/backend/microservice/PythonServer/project/api/socket2/server.py b/backend/microservice/PythonServer/project/socket_example/socket2/server.py
index c65dae78..c65dae78 100644
--- a/backend/microservice/PythonServer/project/api/socket2/server.py
+++ b/backend/microservice/PythonServer/project/socket_example/socket2/server.py
diff --git a/backend/microservice/api/controller.py b/backend/microservice/api/controller.py
new file mode 100644
index 00000000..ceed02ad
--- /dev/null
+++ b/backend/microservice/api/controller.py
@@ -0,0 +1,42 @@
+import flask
+from flask import request, jsonify
+import ml_socket
+import ml_service
+import tensorflow as tf
+import pandas as pd
+
+app = flask.Flask(__name__)
+app.config["DEBUG"] = True
+app.config["SERVER_NAME"] = "127.0.0.1:5543"
+
+class train_callback(tf.keras.callbacks.Callback):
+ def __init__(self, x_test, y_test):
+ self.x_test = x_test
+ self.y_test = y_test
+ #
+ def on_epoch_end(self, epoch, logs=None):
+ print(epoch)
+ #print('Evaluation: ', self.model.evaluate(self.x_test,self.y_test),"\n") #broj parametara zavisi od izabranih metrika loss je default
+
+@app.route('/train', methods = ['POST'])
+def train():
+ print("******************************TRAIN*************************************************")
+ f = request.json["dataset"]
+ dataset = pd.read_csv(f)
+ #
+ result = ml_service.train(dataset, request.json["model"], train_callback)
+ print(result)
+ return jsonify(result)
+
+@app.route('/predict', methods = ['POST'])
+def predict():
+ f = request.json['filepath']
+ dataset = pd.read_csv(f)
+ m = request.json['modelpath']
+ #model = tf.keras.models.load_model(m)
+ #
+ #model.predict?
+
+print("App loaded.")
+ml_socket.start()
+app.run() \ No newline at end of file
diff --git a/backend/microservice/api/ml_service.py b/backend/microservice/api/ml_service.py
new file mode 100644
index 00000000..efd24fdc
--- /dev/null
+++ b/backend/microservice/api/ml_service.py
@@ -0,0 +1,155 @@
+import pandas as pd
+import tensorflow as tf
+import keras
+import numpy as np
+import csv
+import json
+import h5py
+import sklearn.metrics as sm
+from statistics import mode
+from typing_extensions import Self
+from copyreg import constructor
+from flask import request, jsonify, render_template
+from sklearn.preprocessing import LabelEncoder
+from sklearn.preprocessing import StandardScaler
+from sklearn.model_selection import train_test_split
+from dataclasses import dataclass
+
+@dataclass
+class TrainingResult:
+ accuracy: float
+ precision: float
+ recall: float
+ tn: float
+ fp: float
+ fn: float
+ tp: float
+ specificity: float
+ f1: float
+ mse: float
+ mae: float
+ mape: float
+ rmse: float
+ fpr: float
+ tpr: float
+
+def train(dataset, params, callback):
+ data = pd.DataFrame()
+ for col in params["inputColumns"]:
+ data[col]=dataset[col]
+ output_column = params["columnToPredict"]
+ data[output_column] = dataset[output_column]
+ #
+ # Brisanje null kolona / redova / zamena
+ #nullreplace=[
+ # {"column":"Embarked","value":"C","deleteRow":false,"deleteCol":true},
+ # {"column": "Cabin","value":"C123","deleteRow":"0","deleteCol":"0"}]
+
+ null_value_options = params["nullValues"]
+ null_values_replacers = params["nullValuesReplacers"]
+
+ if(null_value_options=='replace'):
+ print("replace null") # TODO
+ elif(null_value_options=='delete_rows'):
+ data=data.dropna()
+ elif(null_value_options=='delete_columns'):
+ data=data.dropna()
+ #
+ #print(data.isnull().any())
+ #
+ # Brisanje kolona koje ne uticu na rezultat
+ #
+ num_rows=data.shape[0]
+ for col in data.columns:
+ if((data[col].nunique()==(num_rows)) and (data[col].dtype==np.object_)):
+ data.pop(col)
+ #
+ # Enkodiranje
+ #
+ encoding=params["encoding"]
+ if(encoding=='label'):
+ encoder=LabelEncoder()
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ data[col]=encoder.fit_transform(data[col])
+ elif(encoding=='onehot'):
+ category_columns=[]
+ for col in data.columns:
+ if(data[col].dtype==np.object_):
+ category_columns.append(col)
+ data=pd.get_dummies(data, columns=category_columns, prefix=category_columns)
+ #
+ # Input - output
+ #
+ x_columns = []
+ for col in data.columns:
+ if(col!=output_column):
+ x_columns.append(col)
+ x = data[x_columns].values
+ y = data[output_column].values
+ #
+ # Podela na test i trening skupove
+ #
+ test=params["randomTestSetDistribution"]
+ randomOrder = params["randomOrder"]
+ if(randomOrder):
+ random=50
+ else:
+ random=0
+ x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=test, random_state=random)
+ #
+ # Skaliranje vrednosti
+ #
+ scaler=StandardScaler()
+ scaler.fit(x_train)
+ x_test=scaler.transform(x_test)
+ x_train=scaler.transform(x_train)
+ #
+ # Treniranje modela
+ #
+ classifier=tf.keras.Sequential()
+ hidden_layer_neurons = params["hiddenLayerNeurons"]
+ for func in params["hiddenLayerActivationFunctions"]:
+ classifier.add(tf.keras.layers.Dense(units=hidden_layer_neurons,activation=func))
+ output_func = params["outputLayerActivationFunction"]
+ classifier.add(tf.keras.layers.Dense(units=1,activation=output_func))
+ optimizer = params["optimizer"]
+ metrics=params['metrics']
+ loss_func=params["lossFunction"]
+ classifier.compile(optimizer=optimizer, loss=loss_func,metrics=metrics)
+ batch_size = params["batchSize"]
+ epochs = params["epochs"]
+ history=classifier.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, callbacks=callback(x_test, y_test), validation_split=0.2) # TODO params["validationSplit"]
+ #
+ # Test
+ #
+ y_pred=classifier.predict(x_test)
+ y_pred=(y_pred>=0.5).astype('int')
+ #y_pred=(y_pred * 100).astype('int')
+ y_pred=y_pred.flatten()
+ result=pd.DataFrame({"Actual":y_test,"Predicted":y_pred})
+ model_name = params['_id']
+ classifier.save("temp/"+model_name, save_format='h5')
+ #
+ # Metrike
+ #
+ print("HELLO???")
+ print(result)
+ print("HELLO???")
+ accuracy = float(sm.accuracy_score(y_test,y_pred))
+ precision = float(sm.precision_score(y_test,y_pred))
+ recall = float(sm.recall_score(y_test,y_pred))
+ tn, fp, fn, tp = sm.confusion_matrix(y_test,y_pred).ravel()
+ specificity = float(tn / (tn+fp))
+ f1 = float(sm.f1_score(y_test,y_pred))
+ mse = float(sm.mean_squared_error(y_test,y_pred))
+ mae = float(sm.mean_absolute_error(y_test,y_pred))
+ mape = float(sm.mean_absolute_percentage_error(y_test,y_pred))
+ rmse = float(np.sqrt(sm.mean_squared_error(y_test,y_pred)))
+ fpr, tpr, _ = sm.roc_curve(y_test,y_pred)
+ # TODO upload trenirani model nazad na backend
+ return TrainingResult(accuracy, precision, recall, float(tn), float(fp), float(fn), float(tp), specificity, f1, mse, mae, mape, rmse, fpr.tolist(), tpr.tolist())
+
+
+
+
diff --git a/backend/microservice/ml_socket.py b/backend/microservice/api/ml_socket.py
index 5489b787..65dd7321 100644
--- a/backend/microservice/ml_socket.py
+++ b/backend/microservice/api/ml_socket.py
@@ -14,12 +14,15 @@ def get_or_create_eventloop():
# create handler for each connection
async def handler(websocket, path):
#data = json.loads(await websocket.recv())
- #reply = f"Data recieved as: {data}!"
#print(data['test'])
msg = await websocket.recv()
- await websocket.send("[" + msg + "]")
+ print(msg)
-start_server = websockets.serve(handler, "localhost", 5027)
+async def start():
+ start_server = websockets.serve(handler, "localhost", 5027)
+ print('Websocket starting...')
+ get_or_create_eventloop().run_until_complete(start_server)
+ get_or_create_eventloop().run_forever()
-get_or_create_eventloop().run_until_complete(start_server)
-get_or_create_eventloop().run_forever() \ No newline at end of file
+async def send(msg):
+ await websocket.send(msg) \ No newline at end of file
diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts
index 48418d51..32247bbd 100644
--- a/frontend/src/app/_data/Model.ts
+++ b/frontend/src/app/_data/Model.ts
@@ -23,12 +23,14 @@ export default class Model {
public hiddenLayerNeurons: number = 1,
public hiddenLayers: number = 1,
public batchSize: number = 5,
- public hiddenLayerActivationFunction = [],
+ public hiddenLayerActivationFunctions: string[] = ['sigmoid'],
//public inputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid,
public outputLayerActivationFunction: ActivationFunction = ActivationFunction.Sigmoid,
public username: string = '',
public nullValues: NullValueOptions = NullValueOptions.DeleteRows,
- public nullValuesReplacers = []
+ public nullValuesReplacers = [],
+ public metrics: Metric[] = [], // TODO add to add-model form
+ public epochs: number = 5 // TODO add to add-model form
) { }
}
@@ -111,4 +113,11 @@ export enum ReplaceWith {
None = 'Popuni...',
Mean = 'Srednja vrednost',
Median = 'Medijana'
+}
+
+export enum Metric {
+ MSE = 'mse',
+ MAE = 'mae',
+ RMSE = 'rmse'
+ //...
} \ No newline at end of file
diff --git a/frontend/src/app/_pages/add-model/add-model.component.html b/frontend/src/app/_pages/add-model/add-model.component.html
index 9dde9afe..38b3ed47 100644
--- a/frontend/src/app/_pages/add-model/add-model.component.html
+++ b/frontend/src/app/_pages/add-model/add-model.component.html
@@ -71,7 +71,8 @@
<br>
<div *ngFor="let item of selectedDataset.header; let i = index">
<input class="form-check-input" type="checkbox" value="{{item}}" id="cb_{{item}}"
- name="cbsNew" [checked] = "this.selectedOutputColumnVal != item" [disabled]="this.selectedOutputColumnVal == item">&nbsp;
+ name="cbsNew" [checked]="this.selectedOutputColumnVal != item"
+ [disabled]="this.selectedOutputColumnVal == item">&nbsp;
<label class="form-check-label" for="cb_{{item}}">
{{item}}
</label>
@@ -163,7 +164,8 @@
</div>
<div class="col-2">
<select id=typeOptions class="form-control" name="type" [(ngModel)]="newModel.type">
- <option *ngFor="let option of Object.keys(ProblemType); let optionName of Object.values(ProblemType)"
+ <option
+ *ngFor="let option of Object.keys(ProblemType); let optionName of Object.values(ProblemType)"
[value]="option">
{{ optionName }}
</option>
@@ -176,7 +178,8 @@
</div>
<div class="col-1">
<input type="number" min="1" class="form-control" name="hiddenLayers"
- [(ngModel)]="newModel.hiddenLayers">
+ [(ngModel)]="newModel.hiddenLayers"
+ (change)="newModel.hiddenLayerActivationFunctions = [].constructor(newModel.hiddenLayers).fill(newModel.hiddenLayerActivationFunctions[0])">
</div>
</div>
@@ -258,56 +261,36 @@
</div>
<div class="row p-2">
-
- <!-- <div class="col-1">
- </div>
+ <div class="col-3"></div>
<div class="col-3">
- <label for="inputLayerActivationFunction" class="col-form-label">Funkcija aktivacije ulaznog
- sloja:</label>
+ <label for="hiddenLayerActivationFunction" class="col-form-label">Funkcija aktivacije skrivenih
+ slojeva:</label>
</div>
-
- <div class="col-2">
- <select id=inputLayerActivationFunctionOptions class="form-control"
- name="inputLayerActivationFunction" [(ngModel)]="newModel.inputLayerActivationFunction">
- <option
- *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
- [value]="option">
- {{ optionName }}
- </option>
- </select>
+ <div class="col-3">
+ <div *ngFor="let item of [].constructor(newModel.hiddenLayers); let i = index">
+ <select [id]="'hiddenLayerActivationFunctionOption_'+i" class="form-control"
+ [(ngModel)]="newModel.hiddenLayerActivationFunctions[i]">
+ <option
+ *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
+ [value]="option">
+ {{ optionName }}
+ </option>
+ </select>
+ </div>
</div>
+ <div class="col-3"></div>
+ </div>
+
+ <div class="row p-2">
<div class="col-1">
</div>
- -->
-
- <div class="col-5">
+ <div class="col-3">
<label for="splitYesNo" class="form-check-label">Podela test skupa:&nbsp;&nbsp;
<input id="splitYesNo" class="form-check-input" type="checkbox"
[checked]="newModel.randomTestSet"
(change)="newModel.randomTestSet = !newModel.randomTestSet">
</label>
</div>
- <div class="col">
- </div>
- </div>
-
- <div class="row p-2">
- <div class="col-1">
- </div>
- <div class="col-3">
- <label for="hiddenLayerActivationFunction" class="col-form-label">Funkcija aktivacije skrivenih
- slojeva:</label>
- </div>
- <div class="col-2">
- <select id=hiddenLayerActivationFunctionOptions class="form-control"
- name="hiddenLayerActivationFunction" [(ngModel)]="newModel.hiddenLayerActivationFunction">
- <option
- *ngFor="let option of Object.keys(ActivationFunction); let optionName of Object.values(ActivationFunction)"
- [value]="option">
- {{ optionName }}
- </option>
- </select>
- </div>
<div class="col-1">
</div>
<div class="col-2">
@@ -357,7 +340,7 @@
<button class="btn btn-lg col-4" style="background-color:#003459; color:white;"
(click)="addModel();">Sačuvaj model</button>
<div class="col"></div>
- <button class="btn btn-lg col-4 disabled" style="background-color:#003459; color:white;"
+ <button class="btn btn-lg col-4" style="background-color:#003459; color:white;"
(click)="trainModel();">Treniraj model</button>
<div class="col"></div>
</div>
diff --git a/frontend/src/app/_pages/add-model/add-model.component.ts b/frontend/src/app/_pages/add-model/add-model.component.ts
index 37672d0a..4270a2db 100644
--- a/frontend/src/app/_pages/add-model/add-model.component.ts
+++ b/frontend/src/app/_pages/add-model/add-model.component.ts
@@ -76,19 +76,28 @@ export class AddModelComponent implements OnInit {
addModel() {
if (!this.showMyDatasets)
- this.saveModelWithNewDataset();
+ this.saveModelWithNewDataset(_ => { console.log('MODEL ADDED (with new dataset).') });
else
- this.saveModelWithExistingDataset();
+ this.saveModelWithExistingDataset(_ => { console.log('MODEL ADDED (with existing dataset).') });
}
trainModel() {
- this.saveModelWithNewDataset().subscribe((modelId: any) => {
- if (modelId)
- this.models.trainModel(modelId);
- }); //privremeno cuvanje modela => vraca id sacuvanog modela koji cemo da treniramo sad
+ let saveFunc;
+
+ if (!this.showMyDatasets)
+ saveFunc = (x: (arg0: any) => void) => { this.saveModelWithNewDataset(x) };
+ else
+ saveFunc = (x: (arg0: any) => void) => { this.saveModelWithExistingDataset(x) };
+
+ saveFunc(((model: any) => {
+ console.log('Saved, training model...', model);
+ this.models.trainModel(model).subscribe(response => {
+ console.log('Train model complete!', response);
+ });
+ })); //privremeno cuvanje modela => vraca id sacuvanog modela koji cemo da treniramo sad
}
- saveModelWithNewDataset(): any {
+ saveModelWithNewDataset(callback: ((arg0: any) => void)) {
this.getCheckedInputCols();
this.getCheckedOutputCol();
@@ -117,7 +126,7 @@ export class AddModelComponent implements OnInit {
this.newModel.username = shared.username;
this.models.addModel(this.newModel).subscribe((response) => {
- console.log('ADD MODEL: DONE! REPLY:\n', response);
+ callback(response);
}, (error) => {
alert("Model sa unetim nazivom već postoji u Vašoj kolekciji.\nPromenite naziv modela i nastavite sa kreiranim datasetom.");
}); //kraj addModel subscribe
@@ -133,8 +142,7 @@ export class AddModelComponent implements OnInit {
} //kraj prvog ifa
}
- saveModelWithExistingDataset(): any {
-
+ saveModelWithExistingDataset(callback: ((arg0: any) => void)): any {
if (this.selectedDataset) { //dataset je izabran
this.getCheckedInputCols();
this.getCheckedOutputCol();
@@ -147,7 +155,7 @@ export class AddModelComponent implements OnInit {
this.newModel.username = shared.username;
this.models.addModel(this.newModel).subscribe((response) => {
- console.log('ADD MODEL: DONE! REPLY:\n', response);
+ callback(response);
}, (error) => {
alert("Model sa unetim nazivom već postoji u Vašoj kolekciji.\nPromenite naziv modela i nastavite sa kreiranim datasetom.");
});
@@ -226,7 +234,7 @@ export class AddModelComponent implements OnInit {
for (let i = this.datasetFile.length - 1; i >= 0; i--) { //moguce da je vise redova na kraju fajla prazno i sl.
if (this.datasetFile[i].length != this.datasetFile[0].length)
this.datasetFile[i].pop();
- else
+ else
break; //nema potrebe dalje
}
console.log(this.datasetFile);
diff --git a/frontend/src/app/_services/models.service.ts b/frontend/src/app/_services/models.service.ts
index 58ddb2e6..6ea4310c 100644
--- a/frontend/src/app/_services/models.service.ts
+++ b/frontend/src/app/_services/models.service.ts
@@ -35,25 +35,23 @@ export class ModelsService {
addDataset(dataset: Dataset): Observable<any> {
return this.http.post(`${API_SETTINGS.apiURL}/dataset/add`, dataset, { headers: this.authService.authHeader() });
}
- trainModel(modelId: string): Observable<any> {
- return this.http.post(`${API_SETTINGS.apiURL}/model/train`, modelId, { headers: this.authService.authHeader() });
+ trainModel(model: Model): Observable<any> {
+ return this.http.post(`${API_SETTINGS.apiURL}/model/sendmodel`, model, { headers: this.authService.authHeader(), responseType: 'text' });
}
getMyDatasets(): Observable<Dataset[]> {
return this.http.get<Dataset[]>(`${API_SETTINGS.apiURL}/dataset/mydatasets`, { headers: this.authService.authHeader() });
}
-
+
getMyModels(): Observable<Model[]> {
return this.http.get<Model[]>(`${API_SETTINGS.apiURL}/model/mymodels`, { headers: this.authService.authHeader() });
}
- editModel(model:Model) : Observable<Model>
- {
+ editModel(model: Model): Observable<Model> {
return this.http.put<Model>(`${API_SETTINGS.apiURL}/model/`, model, { headers: this.authService.authHeader() });
}
- deleteModel(model:Model) : Observable<any>
- {
- return this.http.delete(`${API_SETTINGS.apiURL}/model/`+model.name, { headers: this.authService.authHeader() });
+ deleteModel(model: Model): Observable<any> {
+ return this.http.delete(`${API_SETTINGS.apiURL}/model/` + model.name, { headers: this.authService.authHeader() });
}
}
diff --git a/frontend/src/app/_services/web-socket.service.ts b/frontend/src/app/_services/web-socket.service.ts
index 890ada6b..1a7efa87 100644
--- a/frontend/src/app/_services/web-socket.service.ts
+++ b/frontend/src/app/_services/web-socket.service.ts
@@ -13,15 +13,15 @@ export class WebSocketService {
constructor() {
this.ws = new WebsocketBuilder(API_SETTINGS.apiWSUrl)
- .withBackoff(new ConstantBackoff(30000))
- .onOpen((i, e) => { console.log('WS: Connected to ' + API_SETTINGS.apiWSUrl) })
+ .withBackoff(new ConstantBackoff(120000))
+ .onOpen((i, e) => { /*console.log('WS: Connected to ' + API_SETTINGS.apiWSUrl)*/ })
.onMessage((i, e) => {
console.log('WS MESSAGE: ', e.data);
this.handlers.forEach(handler => {
handler(e.data);
})
})
- .onClose((i, e) => { console.log('WS: Connection closed!') })
+ .onClose((i, e) => { /*console.log('WS: Connection closed!')*/ })
.build();
}