aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/api/api/.gitignore3
-rw-r--r--backend/api/api/Controllers/AuthController.cs1
-rw-r--r--backend/api/api/Controllers/DatasetController.cs43
-rw-r--r--backend/api/api/Controllers/FileUploadController.cs47
-rw-r--r--backend/api/api/Controllers/UserController.cs33
-rw-r--r--backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs1
-rw-r--r--backend/api/api/Models/Dataset.cs21
-rw-r--r--backend/api/api/Services/DatasetService.cs40
-rw-r--r--backend/api/api/Services/IDatasetService.cs13
-rw-r--r--backend/api/api/Services/IUserService.cs1
-rw-r--r--backend/api/api/Services/UserService.cs19
-rw-r--r--backend/api/api/api.csproj4
-rw-r--r--backend/api/api/appsettings.json6
-rw-r--r--backend/microservice/cuvanjemodela.ipynb168
-rw-r--r--backend/microservice/gradientDescent.ipynb355
15 files changed, 745 insertions, 10 deletions
diff --git a/backend/api/api/.gitignore b/backend/api/api/.gitignore
index 8afdcb63..242abea5 100644
--- a/backend/api/api/.gitignore
+++ b/backend/api/api/.gitignore
@@ -3,6 +3,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+##Ignore contents for UploadedFiles Folder
+UploadedFiles/*
+
# User-specific files
*.rsuser
*.suo
diff --git a/backend/api/api/Controllers/AuthController.cs b/backend/api/api/Controllers/AuthController.cs
index c74c579d..e1601815 100644
--- a/backend/api/api/Controllers/AuthController.cs
+++ b/backend/api/api/Controllers/AuthController.cs
@@ -38,5 +38,6 @@ namespace api.Controllers
}
+
}
}
diff --git a/backend/api/api/Controllers/DatasetController.cs b/backend/api/api/Controllers/DatasetController.cs
new file mode 100644
index 00000000..e1b888a1
--- /dev/null
+++ b/backend/api/api/Controllers/DatasetController.cs
@@ -0,0 +1,43 @@
+using Microsoft.AspNetCore.Mvc;
+
+// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
+
+namespace api.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class DatasetController : ControllerBase
+ {
+ // GET: api/<DatasetController>
+ [HttpGet]
+ public IEnumerable<string> Get()
+ {
+ return new string[] { "value1", "value2" };
+ }
+
+ // GET api/<DatasetController>/5
+ [HttpGet("{id}")]
+ public string Get(int id)
+ {
+ return "value";
+ }
+
+ // POST api/<DatasetController>
+ [HttpPost]
+ public void Post([FromBody] string value)
+ {
+ }
+
+ // PUT api/<DatasetController>/5
+ [HttpPut("{id}")]
+ public void Put(int id, [FromBody] string value)
+ {
+ }
+
+ // DELETE api/<DatasetController>/5
+ [HttpDelete("{id}")]
+ public void Delete(int id)
+ {
+ }
+ }
+}
diff --git a/backend/api/api/Controllers/FileUploadController.cs b/backend/api/api/Controllers/FileUploadController.cs
new file mode 100644
index 00000000..46e7f4f9
--- /dev/null
+++ b/backend/api/api/Controllers/FileUploadController.cs
@@ -0,0 +1,47 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+namespace api.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class FileUploadController : ControllerBase
+ {
+ private string[] permittedExtensions = { ".csv" };
+
+
+ [HttpPost("Csv")]
+ [Authorize(Roles = "User")]
+ public async Task<ActionResult<string>> CsvUpload([FromForm]IFormFile file,[FromForm]string username)//???Umesto username poslati jwt odakle se moze preuzeti username radi sigurnosti
+ {
+ var filename=file.FileName;
+ var ext=Path.GetExtension(filename).ToLowerInvariant();
+ var name = Path.GetFileNameWithoutExtension(filename).ToLowerInvariant();
+ if (string.IsNullOrEmpty(ext) || ! permittedExtensions.Contains(ext)) {
+ return BadRequest("Wrong file type");
+ }
+ var folderPath=Path.Combine(Directory.GetCurrentDirectory(),"UploadedFiles",username);
+ if (!Directory.Exists(folderPath))
+ {
+ Directory.CreateDirectory(folderPath);
+ }
+
+ var fullPath = Path.Combine(folderPath, filename);
+ int i=0;
+
+ while (System.IO.File.Exists(fullPath)) {
+ i++;
+ fullPath = Path.Combine(folderPath,name+i.ToString()+ext);
+ }
+
+
+
+ using (var stream=new FileStream(fullPath, FileMode.Create))
+ {
+ await file.CopyToAsync(stream);
+ }
+
+ return Ok();
+ }
+ }
+}
diff --git a/backend/api/api/Controllers/UserController.cs b/backend/api/api/Controllers/UserController.cs
index b1544477..caf78d9c 100644
--- a/backend/api/api/Controllers/UserController.cs
+++ b/backend/api/api/Controllers/UserController.cs
@@ -38,16 +38,36 @@ namespace api.Controllers
return user;
}
+ // GET api/<UserController>/5
+ //potrebno za profile page
+ [HttpGet("{id}")]
+ public ActionResult<User> GetUserUsername(string username)
+ {
+ var user = userService.GetUserUsername(username);
+
+ if (user == null)
+ return NotFound($"User with Id = {username} not found");
+
+ return user;
+ }
+
// POST api/<UserController>
[HttpPost]
public ActionResult<User> Post([FromBody] User user)
{
- userService.Create(user);
+
+ var existingUser = userService.GetUserUsername(user.Username);
- //Debug.WriteLine("\nTest.\n");
+ if (existingUser != null)
+ return NotFound($"User with username = {user.Username} exisits");
+ else
+ {
+ userService.Create(user);
- return CreatedAtAction(nameof(Get), new { id = user._id }, user);
+ //Debug.WriteLine("\nTest.\n");
+ return CreatedAtAction(nameof(Get), new { id = user._id }, user);
+ }
}
// PUT api/<UserController>/5
@@ -56,10 +76,11 @@ namespace api.Controllers
{
var existingUser = userService.Get(id);
+ //ne mora da se proverava
if(existingUser == null)
return NotFound($"User with Id = {id} not found");
- userService.Update(id, existingUser);
+ userService.Update(id, user);
return NoContent();
}
@@ -79,9 +100,7 @@ namespace api.Controllers
}
/*
{
- "userId": {
- "$oid": "62276146c4a20eabc664abc3"
- },
+ "_id": "",
"username" : "ivan996sk",
"email" : "ivan996sk@gmail.com",
"password" : "proba",
diff --git a/backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs b/backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs
index 43fe9b3a..8d2a175f 100644
--- a/backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs
+++ b/backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs
@@ -5,5 +5,6 @@
string ConnectionString { get; set; }
string DatabaseName { get; set; }
string CollectionName { get; set; }
+ string DatasetCollectionName { get; set; }
}
}
diff --git a/backend/api/api/Models/Dataset.cs b/backend/api/api/Models/Dataset.cs
new file mode 100644
index 00000000..448a6aa9
--- /dev/null
+++ b/backend/api/api/Models/Dataset.cs
@@ -0,0 +1,21 @@
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace api.Models
+{
+ public class Dataset
+ {
+ internal string uploaderId;
+
+ [BsonId]
+ [BsonRepresentation(BsonType.ObjectId)]//mongo data type to .net
+ public string _id { get; set; }
+ [BsonElement("uploaderId")]
+ public string UploaderId { get; set; }
+ [BsonElement("extension")]
+ public string extension { get; set; }
+ [BsonElement("name")]
+ public string name { get; set; }
+
+ }
+}
diff --git a/backend/api/api/Services/DatasetService.cs b/backend/api/api/Services/DatasetService.cs
new file mode 100644
index 00000000..154c9438
--- /dev/null
+++ b/backend/api/api/Services/DatasetService.cs
@@ -0,0 +1,40 @@
+using api.Interfaces;
+using api.Models;
+using MongoDB.Driver;
+
+namespace api.Services
+{
+ public class DatasetService : IDatasetService
+ {
+ private readonly IMongoCollection<Dataset> _dataset;
+
+ public DatasetService(IUserStoreDatabaseSettings settings, IMongoClient mongoClient)
+ {
+ var database = mongoClient.GetDatabase(settings.DatabaseName);
+ _dataset = database.GetCollection<Dataset>(settings.DatasetCollectionName);
+ }
+ //kreiranje dataseta
+ public Dataset Create(Dataset dataset)
+ {
+ _dataset.InsertOne(dataset);
+ return dataset;
+ }
+
+ //brisanje odredjenog name-a
+ public void Delete(string uploaderId, string name)
+ {
+ _dataset.DeleteOne(dataset => dataset.UploaderId == uploaderId && dataset.name == name); ;
+ }
+
+ public Dataset Get(string uploaderId)
+ {
+ return _dataset.Find(dataset => dataset.UploaderId == uploaderId).FirstOrDefault();
+ }
+
+ //ako je potrebno da se zameni name ili ekstenzija
+ public void Update(string uploaderId, Dataset dataset)
+ {
+ _dataset.ReplaceOne(dataset => dataset.UploaderId == uploaderId, dataset);
+ }
+ }
+}
diff --git a/backend/api/api/Services/IDatasetService.cs b/backend/api/api/Services/IDatasetService.cs
new file mode 100644
index 00000000..22633c3c
--- /dev/null
+++ b/backend/api/api/Services/IDatasetService.cs
@@ -0,0 +1,13 @@
+
+using api.Models;
+
+namespace api.Services
+{
+ public interface IDatasetService
+ {
+ Dataset Get(string uploaderId);
+ Dataset Create(Dataset dataset);
+ void Update(string uploaderId, Dataset dataset);
+ void Delete(string uploaderId, string name);
+ }
+}
diff --git a/backend/api/api/Services/IUserService.cs b/backend/api/api/Services/IUserService.cs
index e9f14c8b..b6725694 100644
--- a/backend/api/api/Services/IUserService.cs
+++ b/backend/api/api/Services/IUserService.cs
@@ -6,6 +6,7 @@ namespace api.Services
{
List<User> Get();// daje sve korisnike
User Get(string id); //daje korisnika po id-u
+ User GetUserUsername(string username); //daje korisnika po korisnickom imenu
User Create(User user); // kreira korisnika
void Update(string id, User user); //apdejruje korisnika po idu
void Delete(string id);//brise korisnika
diff --git a/backend/api/api/Services/UserService.cs b/backend/api/api/Services/UserService.cs
index e5d1bb32..c626889d 100644
--- a/backend/api/api/Services/UserService.cs
+++ b/backend/api/api/Services/UserService.cs
@@ -19,13 +19,16 @@ namespace api.Services
return user;
}
-
-
public List<User> Get()
{
return _users.Find(user => true).ToList();
}
+ public User GetUserUsername(string username)
+ {
+ return _users.Find(user => user.Username == username).FirstOrDefault();
+ }
+
public User Get(string id)
{
return _users.Find(user => user._id == id).FirstOrDefault();
@@ -51,4 +54,14 @@ namespace api.Services
"firstName" : "Ivan",
"lastName" : "Ljubisavljevic"
}
- */ \ No newline at end of file
+
+{
+ "_id": {
+ "$oid": "62291140d88e6bcf95c96a58"
+ },
+ "uploaderId":"",
+ "extension" : "",
+ "name" : ""
+}
+
+*/
diff --git a/backend/api/api/api.csproj b/backend/api/api/api.csproj
index 6081cd21..46842c3e 100644
--- a/backend/api/api/api.csproj
+++ b/backend/api/api/api.csproj
@@ -18,4 +18,8 @@
<PackageReference Include="MongoDB.Driver" Version="2.14.1" />
</ItemGroup>
+ <ItemGroup>
+ <Folder Include="UploadedFiles\" />
+ </ItemGroup>
+
</Project>
diff --git a/backend/api/api/appsettings.json b/backend/api/api/appsettings.json
index d2c95254..3661f171 100644
--- a/backend/api/api/appsettings.json
+++ b/backend/api/api/appsettings.json
@@ -10,8 +10,14 @@
},
"AllowedHosts": "*",
"UserStoreDatabaseSettings": {
+ /* LocalHost
"ConnectionString": "mongodb://127.0.0.1:27017/",
"DatabaseName": "si_project",
"CollectionName": "User"
+ */
+ "ConnectionString": "mongodb+srv://si_user:si_user@sidatabase.twtfm.mongodb.net/myFirstDatabase?retryWrites=true&w=majority",
+ "DatabaseName": "si_db",
+ "CollectionName": "users",
+ "DatasetCollectionName" : "Dataset"
}
}
diff --git a/backend/microservice/cuvanjemodela.ipynb b/backend/microservice/cuvanjemodela.ipynb
new file mode 100644
index 00000000..f24fcc41
--- /dev/null
+++ b/backend/microservice/cuvanjemodela.ipynb
@@ -0,0 +1,168 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Pre samog čuvanja modela, potrebno je kreirati i obučiti željeni model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "<keras.engine.functional.Functional object at 0x000001B0AA821550>\n"
+ ]
+ }
+ ],
+ "source": [
+ "import tensorflow as tf\n",
+ "\n",
+ "\n",
+ "datainput=tf.keras.Input(shape=(32,))\n",
+ "dataoutput=tf.keras.layers.Dense(1)(datainput)\n",
+ "\n",
+ "model=tf.keras.Model(datainput,dataoutput)\n",
+ "\n",
+ "model.compile(optimizer='adam',loss=\"mean_squared_error\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Nakon kreiranja, potrebno je izvršiti trening kreiranog modela"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Za trening će se koristiti nasumicno generisani skup brojeva"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x=np.random.random((128,32))\n",
+ "y=np.random.random((128,1))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Nakon generisanja, moguće je izvršiti trening "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4/4 [==============================] - 0s 3ms/step - loss: 0.6013\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "<keras.callbacks.History at 0x1b0a99bbf10>"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "model.fit(x,y)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Kreiranje h5 fajla se izvršava pozivanjem sledeceg koda:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "INFO:tensorflow:Assets written to: primer.onnx\\assets\n"
+ ]
+ }
+ ],
+ "source": [
+ "model.save(\"primer.h5\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Učitavanje postojećeg fajla može se izvršiti pozivanjem sledećeg koda:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "model2=tf.keras.models.load_model('primer.h5')"
+ ]
+ }
+ ],
+ "metadata": {
+ "interpreter": {
+ "hash": "aa60dac3a75d8da79a838f0110309d30613c15866a87f648d4b1206eac7c83af"
+ },
+ "kernelspec": {
+ "display_name": "Python 3.9.10 64-bit (windows store)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.10"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/backend/microservice/gradientDescent.ipynb b/backend/microservice/gradientDescent.ipynb
new file mode 100644
index 00000000..930f0784
--- /dev/null
+++ b/backend/microservice/gradientDescent.ipynb
@@ -0,0 +1,355 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "gradientDescent.ipynb",
+ "provenance": [],
+ "collapsed_sections": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Gradijentni spust"
+ ],
+ "metadata": {
+ "id": "ktt1djHu0cNl"
+ }
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "id": "ZQDusvq4z52M"
+ },
+ "outputs": [],
+ "source": [
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "def gradient_descent(f, gradient, x0, alpha, eps, iters):\n",
+ " result = {}\n",
+ " \n",
+ " x = x0\n",
+ " for i in range(iters):\n",
+ " x_new = x - alpha * gradient(x)\n",
+ "\n",
+ " if abs(f(x_new) - f(x)) < eps:\n",
+ " result['converged'] = True\n",
+ " break\n",
+ "\n",
+ " x = x_new\n",
+ " else:\n",
+ " result['converged'] = False\n",
+ " \n",
+ "\n",
+ " result['num_iters'] = i\n",
+ " result['x'] = x_new\n",
+ " \n",
+ " return result"
+ ],
+ "metadata": {
+ "id": "SRYg9QtE0Dcf"
+ },
+ "execution_count": 1,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "x[0] = x\n",
+ "\n",
+ "x[1] = y"
+ ],
+ "metadata": {
+ "id": "XewBwwG71oqK"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "def f(x):\n",
+ " return 0.5 * (x[0]**2 + 10*x[1]**2)"
+ ],
+ "metadata": {
+ "id": "Mbtzh4hx0DZf"
+ },
+ "execution_count": 3,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "def gradient(x):\n",
+ " return np.array([x[0], 10*x[1]])"
+ ],
+ "metadata": {
+ "id": "vwmWa-qQ0DXD"
+ },
+ "execution_count": 4,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "x0 = np.array([3,5])\n",
+ "eps = 0.00001\n",
+ "iters = 10\n",
+ "alpha = 0.1\n",
+ "\n",
+ "gradient_descent(f, gradient, x0, alpha, eps, iters)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "62OBHamq0DUI",
+ "outputId": "2fecd164-6feb-439c-8cc6-079085f20cba"
+ },
+ "execution_count": 5,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'converged': False, 'num_iters': 9, 'x': array([1.04603532, 0. ])}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 5
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Sada se posmatraju gradijent i inercija.\n",
+ "\n",
+ "d - za cuvanje prethodnih gradijenata\n",
+ "\n",
+ "beta*d - koliko znacaja se daje inerciji\n",
+ "\n",
+ "Prvo racuna gradijent pa se tek onda pomera po inerciji."
+ ],
+ "metadata": {
+ "id": "ul28Spkz3bY7"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "def momentum(f, gradient, x0, alpha, eps, iters, beta):\n",
+ " result = {}\n",
+ " \n",
+ " x = x0\n",
+ " d = 0\n",
+ " \n",
+ " for i in range(iters):\n",
+ " d = beta * d + alpha * gradient(x)\n",
+ " x_new = x - d\n",
+ " \n",
+ " if abs(f(x_new) - f(x)) < eps:\n",
+ " result['converged'] = True\n",
+ " break\n",
+ " x = x_new\n",
+ " else:\n",
+ " result['converged'] = False\n",
+ " result['num_iters'] = i\n",
+ " result['x'] = x_new\n",
+ " \n",
+ " return result "
+ ],
+ "metadata": {
+ "id": "SSzc08Rf0DRg"
+ },
+ "execution_count": 6,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "momentum(f, gradient, x0, alpha, eps, iters, beta=0.5)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "eEfVIiS86DjY",
+ "outputId": "312e9a41-ae2f-4182-85c5-3ea5bf855a05"
+ },
+ "execution_count": 7,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'converged': False, 'num_iters': 9, 'x': array([0.19952216, 0.16601562])}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 7
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Racuna gradijent u tacki nakon inercije. Prvo se pomera po inerciji pa tek onda rcauna gradijent."
+ ],
+ "metadata": {
+ "id": "n1bl2N5l8Cf4"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "def nesterov(f, gradient, x0, alpha, eps, iters, beta):\n",
+ " result = {}\n",
+ " \n",
+ " x = x0\n",
+ " d = 0\n",
+ " \n",
+ " for i in range(iters):\n",
+ " d = beta * d + alpha * gradient(x - beta*d)\n",
+ " x_new = x - d\n",
+ " \n",
+ " if abs(f(x_new) - f(x)) < eps:\n",
+ " result['converged'] = True\n",
+ " break\n",
+ " x = x_new\n",
+ " else:\n",
+ " result['converged'] = False\n",
+ " \n",
+ " result['num_iters'] = i\n",
+ " result['x'] = x_new\n",
+ " \n",
+ " return result "
+ ],
+ "metadata": {
+ "id": "EVAuWKXH6JNi"
+ },
+ "execution_count": 8,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "nesterov(f, gradient, x0, alpha, eps, iters, beta=0.5)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "Gldkp1lH6M1P",
+ "outputId": "74bfb0ca-63cc-44ee-a7b9-65400eca3e33"
+ },
+ "execution_count": 9,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'converged': False, 'num_iters': 9, 'x': array([0.31974124, 0. ])}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 9
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "ADAM (Adaptive Moment Estimation)\n",
+ "\n",
+ "Pokusava da aproksimira prvi i drugi momenat (statistika).\n",
+ "\n",
+ "E(X^k) - k-ti momenat\n",
+ "\n",
+ "m - ocena prvog momenta (akumulira gradijente, povecava korak), m je proporcionalno velicini koraka\n",
+ "\n",
+ "v - ocena drugog momenta (gleda promene gradijenta, kvadrat gradijenta), v je obrnuto proporcionalno velicini koraka\n"
+ ],
+ "metadata": {
+ "id": "uq3aN31j-pHD"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "def adam(f, gradient, x0, alpha, eps, iters, beta1, beta2, delta):\n",
+ " result = {}\n",
+ " \n",
+ " x = x0\n",
+ " m = 0\n",
+ " v = 0\n",
+ " \n",
+ " for i in range(1, iters+1):\n",
+ " grad = gradient(x)\n",
+ " m = beta1 * m + (1 - beta1) * grad\n",
+ " v = beta2 * v + (1 - beta2) * grad**2\n",
+ " \n",
+ " m_hat = m / (1 - beta1**i)\n",
+ " v_hat = v / (1 - beta2**i)\n",
+ " \n",
+ " x_new = x - alpha * m_hat / (np.sqrt(v_hat) + delta)\n",
+ " \n",
+ " if abs(f(x_new) - f(x)) < eps:\n",
+ " result['converged'] = True\n",
+ " break\n",
+ " \n",
+ " x = x_new\n",
+ " else:\n",
+ " result['converged'] = False\n",
+ " \n",
+ " result['num_iters'] = i\n",
+ " result['x'] = x_new\n",
+ " \n",
+ " return result "
+ ],
+ "metadata": {
+ "id": "mEe_3317-Ko2"
+ },
+ "execution_count": 10,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "adam(f, gradient, x0, alpha, eps, iters, 0.9, 0.999, 1e-7)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "hjCIJjRv-UkZ",
+ "outputId": "afdb0882-8934-44b7-c1a3-a4b8864a07ec"
+ },
+ "execution_count": 11,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "{'converged': False, 'num_iters': 10, 'x': array([2.01418844, 4.00760162])}"
+ ]
+ },
+ "metadata": {},
+ "execution_count": 11
+ }
+ ]
+ }
+ ]
+} \ No newline at end of file