diff options
Diffstat (limited to 'backend')
22 files changed, 2902 insertions, 4 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 new file mode 100644 index 00000000..01354f87 --- /dev/null +++ b/backend/api/api/Controllers/AuthController.cs @@ -0,0 +1,36 @@ +using api.Models.Users; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using api.Services; +using Microsoft.AspNetCore.Authorization; + +namespace api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class AuthController : ControllerBase + { + private IAuthService _auth; + public AuthController(IAuthService auth) + { + _auth = auth; + } + + [HttpPost("register")] + public async Task<ActionResult<string>> Register(RegisterRequest user) + { + + return Ok(_auth.Register(user)); + } + + [HttpPost("login")] + public async Task<ActionResult<string>> Login(AuthRequest user) + { + + return Ok(_auth.Login(user)); + } + + + + } +} 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 new file mode 100644 index 00000000..85f8218d --- /dev/null +++ b/backend/api/api/Controllers/UserController.cs @@ -0,0 +1,108 @@ +using api.Models; +using api.Services; +using Microsoft.AspNetCore.Mvc; +using System.Diagnostics; + +// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 +//dovrsi kontroler +namespace api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class UserController : ControllerBase + { + private readonly IUserService userService; + + public UserController(IUserService userService) + { + this.userService = userService; + } + + // GET: api/<UserController> + [HttpGet] + public ActionResult<List<User>> Get() + { + return userService.Get(); + } + + // GET api/<UserController>/5 + //potrebno za profile page + [HttpGet("{id}")] + public ActionResult<User> Get(string id) + { + var user = userService.Get(id); + + if (user == null) + return NotFound($"User with Id = {id} not found"); + + 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) + { + + var existingUser = userService.GetUserUsername(user.Username); + + if (existingUser != null) + return NotFound($"User with username = {user.Username} exisits"); + else + { + userService.Create(user); + + //Debug.WriteLine("\nTest.\n"); + + return CreatedAtAction(nameof(Get), new { id = user._id }, user); + } + } + + // PUT api/<UserController>/5 + [HttpPut("{id}")] + public ActionResult Put(string id, [FromBody] User user) + { + var existingUser = userService.Get(id); + + //ne mora da se proverava + if(existingUser == null) + return NotFound($"User with Id = {id} not found"); + + userService.Update(id, user); + return NoContent(); + } + + // DELETE api/<UserController>/5 + [HttpDelete("{id}")] + public ActionResult Delete(string id) + { + var user = userService.Get(id); + + if (user == null) + return NotFound($"User with Id = {id} not found"); + + userService.Delete(user._id); + return Ok($"Student with Id = {id} deleted"); + } + } +} +/* +{ + "_id": "", + "username" : "ivan996sk", + "email" : "ivan996sk@gmail.com", + "password" : "proba", + "firstName" : "Ivan", + "lastName" : "Ljubisavljevic" +} +*/
\ No newline at end of file diff --git a/backend/api/api/Data/UserStoreDatabaseSettings.cs b/backend/api/api/Data/UserStoreDatabaseSettings.cs new file mode 100644 index 00000000..0efd2895 --- /dev/null +++ b/backend/api/api/Data/UserStoreDatabaseSettings.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; +using MongoDB.Driver; +using api.Interfaces; + +namespace api.Data +{ + public class UserStoreDatabaseSettings : IUserStoreDatabaseSettings + { + public string ConnectionString { get; set; } = String.Empty; + public string DatabaseName { get; set; } = String.Empty; + public string CollectionName { get; set; } = String.Empty; + } +} diff --git a/backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs b/backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs new file mode 100644 index 00000000..43fe9b3a --- /dev/null +++ b/backend/api/api/Interfaces/IUserStoreDatabaseSettings.cs @@ -0,0 +1,9 @@ +namespace api.Interfaces +{ + public interface IUserStoreDatabaseSettings + { + string ConnectionString { get; set; } + string DatabaseName { get; set; } + string CollectionName { get; set; } + } +} diff --git a/backend/api/api/Models/JwtToken.cs b/backend/api/api/Models/JwtToken.cs new file mode 100644 index 00000000..23307185 --- /dev/null +++ b/backend/api/api/Models/JwtToken.cs @@ -0,0 +1,37 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using api.Models.Users; +using Microsoft.IdentityModel.Tokens; + +namespace api.Models +{ + public class JwtToken + { + private readonly IConfiguration _configuration; + + public JwtToken(IConfiguration configuration) + { + _configuration = configuration; + } + + public string GenToken(AuthRequest user) + { + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.ASCII.GetBytes(_configuration.GetSection("AppSettings:JwtToken").Value); + var tokenDescriptor = new SecurityTokenDescriptor + { + Subject = new ClaimsIdentity(new[] { new Claim("name", user.UserName), + new Claim("role", "User")}), + Expires = DateTime.UtcNow.AddDays(1), + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) + }; + var token = tokenHandler.CreateToken(tokenDescriptor); + return tokenHandler.WriteToken(token); + + } + + + + } +} diff --git a/backend/api/api/Models/PasswordCrypt.cs b/backend/api/api/Models/PasswordCrypt.cs new file mode 100644 index 00000000..016fde51 --- /dev/null +++ b/backend/api/api/Models/PasswordCrypt.cs @@ -0,0 +1,27 @@ +namespace api.Models +{ + public class PasswordCrypt + { + private static int difficulty = 10; + + public static String hashPassword(String password) + { + String salt = BCrypt.Net.BCrypt.GenerateSalt(difficulty); + String passwordHash = BCrypt.Net.BCrypt.HashPassword(password, salt); + + return passwordHash; + } + public static Boolean checkPassword(String plainText,String hash) + { + Boolean verified = false; + + if (hash == null || !hash.StartsWith("$2a$")) + throw new ArgumentException("invalid hash"); + + verified=BCrypt.Net.BCrypt.Verify(plainText, hash); + + return verified; + + } + } +} diff --git a/backend/api/api/Models/User.cs b/backend/api/api/Models/User.cs new file mode 100644 index 00000000..46db50ab --- /dev/null +++ b/backend/api/api/Models/User.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + + +namespace api.Models +{ + [BsonIgnoreExtraElements]//ignorise visak elemenata iz baze --moze da se obrise jer nemamo viska + public class User + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)]//mongo data type to .net + public string _id { get; set; } + [BsonElement("username")] + public string Username { get; set; } + [BsonElement("email")] + public string Email { get; set; } + [BsonElement("password")] + public string Password { get; set; } + + + [BsonElement("firstName")] + public string FirstName { get; set; } + [BsonElement("lastName")] + public string LastName { get; set; } + + } +} diff --git a/backend/api/api/Models/Users/AuthRequest.cs b/backend/api/api/Models/Users/AuthRequest.cs new file mode 100644 index 00000000..fbf2412d --- /dev/null +++ b/backend/api/api/Models/Users/AuthRequest.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace api.Models.Users +{ + public class AuthRequest + { + [Required] + public string UserName { get; set; } + [Required] + public string Password { get; set; } + + } +} diff --git a/backend/api/api/Models/Users/RegisterRequest.cs b/backend/api/api/Models/Users/RegisterRequest.cs new file mode 100644 index 00000000..675d571d --- /dev/null +++ b/backend/api/api/Models/Users/RegisterRequest.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.DataAnnotations; + +namespace api.Models.Users +{ + public class RegisterRequest + { + [Required] + public string firstName { get; set; } + + [Required] + public string lastName { get; set; } + + [Required] + public string username { get; set; } + + [Required] + public string email { get; set; } + + [Required] + public string password { get; set; } + + } +} diff --git a/backend/api/api/Program.cs b/backend/api/api/Program.cs index 478b7052..550f6ce1 100644 --- a/backend/api/api/Program.cs +++ b/backend/api/api/Program.cs @@ -1,13 +1,64 @@ +using System.Text; +using api.Data; +using api.Interfaces; +using api.Services; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using MongoDB.Driver; + var builder = WebApplication.CreateBuilder(args); -// Add services to the container. +//Add Cors +builder.Services.AddCors(); + +// Add services to the container +//dodajemo dep inj + +builder.Services.Configure<UserStoreDatabaseSettings>( + builder.Configuration.GetSection(nameof(UserStoreDatabaseSettings))); + +builder.Services.AddSingleton<IUserStoreDatabaseSettings>(sp => + sp.GetRequiredService<IOptions<UserStoreDatabaseSettings>>().Value); + +builder.Services.AddSingleton<IMongoClient>(s => + new MongoClient(builder.Configuration.GetValue<string>("UserStoreDatabaseSettings:ConnectionString"))); + +//Inject Dependencies +builder.Services.AddScoped<IUserService, UserService>(); +builder.Services.AddScoped<IAuthService, AuthService>(); + +//Add Authentication +builder.Services.AddAuthentication( + JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration.GetSection("AppSettings:JwtToken").Value)), + ValidateIssuer=false, + ValidateAudience=false + }; + + }); + builder.Services.AddControllers(); var app = builder.Build(); + +//Add Cors +app.UseCors( + x=>x.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader() + ); + // Configure the HTTP request pipeline. +//Add Authentication +app.UseAuthentication(); + app.UseAuthorization(); app.MapControllers(); diff --git a/backend/api/api/Services/AuthService.cs b/backend/api/api/Services/AuthService.cs new file mode 100644 index 00000000..015fdac7 --- /dev/null +++ b/backend/api/api/Services/AuthService.cs @@ -0,0 +1,49 @@ +using api.Interfaces; +using api.Models; +using api.Models.Users; +using MongoDB.Driver; + +namespace api.Services +{ + public class AuthService : IAuthService + { + private JwtToken _jwt; + private readonly IConfiguration _configuration; + private readonly IMongoCollection<User> _users; + public AuthService(IConfiguration configuration, IUserStoreDatabaseSettings settings, IMongoClient mongoClient) + { + _configuration = configuration; + _jwt = new JwtToken(_configuration); + var database = mongoClient.GetDatabase(settings.DatabaseName); + _users = database.GetCollection<User>(settings.CollectionName); + } + public string Login(AuthRequest user) + { + User u = _users.Find(x => x.Username == user.UserName).FirstOrDefault(); + if (u == null) + return "Username doesn't exist"; + if (!PasswordCrypt.checkPassword(user.Password, u.Password)) + return "Wrong password"; + return _jwt.GenToken(user); + + } + public string Register(RegisterRequest user) + { + User u = new User(); + u.Username = user.username; + u.Email = user.email; + u.Password = PasswordCrypt.hashPassword(user.password); + u.FirstName = user.firstName; + u.LastName = user.lastName; + if (_users.Find(user => user.Username == u.Username).FirstOrDefault() != null) + return "Username Already Exists"; + if (_users.Find(user => user.Email == u.Email).FirstOrDefault() != null) + return "Email Already Exists"; + + _users.InsertOne(u); + return "User added"; + } + + + } +} diff --git a/backend/api/api/Services/IAuthService.cs b/backend/api/api/Services/IAuthService.cs new file mode 100644 index 00000000..79085f8c --- /dev/null +++ b/backend/api/api/Services/IAuthService.cs @@ -0,0 +1,10 @@ +using api.Models.Users; + +namespace api.Services +{ + public interface IAuthService + { + string Login(AuthRequest user); + string Register(RegisterRequest user); + } +}
\ No newline at end of file diff --git a/backend/api/api/Services/IUserService.cs b/backend/api/api/Services/IUserService.cs new file mode 100644 index 00000000..b6725694 --- /dev/null +++ b/backend/api/api/Services/IUserService.cs @@ -0,0 +1,14 @@ +using api.Models; + +namespace api.Services +{ + public interface IUserService + { + 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 new file mode 100644 index 00000000..e1d1e8b7 --- /dev/null +++ b/backend/api/api/Services/UserService.cs @@ -0,0 +1,56 @@ +using api.Interfaces; +using api.Models; +using MongoDB.Driver; + +namespace api.Services +{ + public class UserService : IUserService + { + private readonly IMongoCollection<User> _users; + + public UserService(IUserStoreDatabaseSettings settings, IMongoClient mongoClient) + { + var database = mongoClient.GetDatabase(settings.DatabaseName); + _users = database.GetCollection<User>(settings.CollectionName); + } + public User Create(User user) + { + _users.InsertOne(user); + 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(); + } + + public void Delete(string id) + { + _users.DeleteOne(user => user._id == id); + + } + public void Update(string id, User user) + { + _users.ReplaceOne(user => user._id == id, user); + } + } +} +/* + { + "_id": "", + "username" : "ivan996sk", + "email" : "ivan996sk@gmail.com", + "password" : "proba", + "firstName" : "Ivan", + "lastName" : "Ljubisavljevic" +} + */
\ No newline at end of file diff --git a/backend/api/api/api.csproj b/backend/api/api/api.csproj index f278c90a..46842c3e 100644 --- a/backend/api/api/api.csproj +++ b/backend/api/api/api.csproj @@ -1,4 +1,4 @@ -<Project Sdk="Microsoft.NET.Sdk.Web"> +<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> @@ -7,7 +7,19 @@ </PropertyGroup> <ItemGroup> - <Folder Include="Controllers\" /> + <PackageReference Include="BCrypt.Net-Next" Version="4.0.3" /> + <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.3" /> + <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.16.0" /> + <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.16.0" /> + </ItemGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" /> + <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 10f68b8c..204eba33 100644 --- a/backend/api/api/appsettings.json +++ b/backend/api/api/appsettings.json @@ -1,9 +1,24 @@ { + "AppSettings": { + "JwtToken": "2mnttqPtRb4GIWHFtagm" + }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "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" + + } } diff --git a/backend/microservice/classificationCNN.ipynb b/backend/microservice/classificationCNN.ipynb new file mode 100644 index 00000000..b79577e1 --- /dev/null +++ b/backend/microservice/classificationCNN.ipynb @@ -0,0 +1,683 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "classificationCNN.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "0g9hqhtBez9M" + }, + "outputs": [], + "source": [ + "from keras.datasets import mnist" + ] + }, + { + "cell_type": "code", + "source": [ + "(X_train, y_train), (X_test, y_test) = mnist.load_data()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "mnHLMwq5fFYN", + "outputId": "6d82dea4-9ae0-4ef7-bc88-fbd3a933965a" + }, + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n", + "11493376/11490434 [==============================] - 0s 0us/step\n", + "11501568/11490434 [==============================] - 0s 0us/step\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_train.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "88HYktIFfFTd", + "outputId": "65562967-3667-4adb-a239-1b4dde68cb61" + }, + "execution_count": 3, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(60000, 28, 28)" + ] + }, + "metadata": {}, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "source": [ + "import keras.backend as K" + ], + "metadata": { + "id": "iAkFNG3wfFPD" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# (60000, 1, 28, 28)\n", + "# (60000, 28, 28, 1)\n", + "img_size = X_train.shape[1]\n", + "if K.image_data_format() == 'channels_first':\n", + " X_train = X_train.reshape(X_train.shape[0], 1, img_size, img_size)\n", + " X_test = X_test.reshape(X_test.shape[0], 1, img_size, img_size)\n", + "else:\n", + " X_train = X_train.reshape(X_train.shape[0], img_size, img_size, 1)\n", + " X_test = X_test.reshape(X_test.shape[0], img_size, img_size, 1)" + ], + "metadata": { + "id": "QBL_5PO7fFMa" + }, + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "X_train.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "oirq1wVlfFJ5", + "outputId": "60d7801c-98ed-48c0-ee57-67afbf800fe3" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(60000, 28, 28, 1)" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_train = X_train / 255" + ], + "metadata": { + "id": "FO4wGXXDfFHm" + }, + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "X_test = X_test / 255" + ], + "metadata": { + "id": "9w3bEQ4gfFFS" + }, + "execution_count": 8, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "y_train.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "OjdLctDtfFCO", + "outputId": "17b5ad38-f66e-41a5-8935-d0de7481652c" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(60000,)" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "source": [ + "y_train[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "EhodYEHRfFAN", + "outputId": "f45d6cee-c132-4674-d179-d661872b7e2a" + }, + "execution_count": 10, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "5" + ] + }, + "metadata": {}, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.utils import to_categorical" + ], + "metadata": { + "id": "j8ssc39YfE97" + }, + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "num_classes = 10\n", + "y_train = to_categorical(y_train, num_classes)\n", + "y_test = to_categorical(y_test, num_classes)" + ], + "metadata": { + "id": "F0KAsy7SfE7k" + }, + "execution_count": 12, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "y_train.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "jz5cSWzvfE4z", + "outputId": "2dddc1bb-759c-47d9-fc2e-7175105fd7ad" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(60000, 10)" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "y_train[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "fhKVJUBQfE2a", + "outputId": "9178a8a4-fff6-498a-80f7-fa87f21e70a3" + }, + "execution_count": 14, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], dtype=float32)" + ] + }, + "metadata": {}, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout" + ], + "metadata": { + "id": "rvdolRvLfEzg" + }, + "execution_count": 15, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "input_shape = X_train.shape[1:]\n", + "input_shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Q4e_AIYxfEw_", + "outputId": "6d92e152-2a60-4b5e-c1e7-de84a9ffdca1" + }, + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(28, 28, 1)" + ] + }, + "metadata": {}, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model = Sequential()\n", + "model.add(Conv2D(32, kernel_size=(3,3), strides=(1,1), padding='same', activation='relu', input_shape=input_shape))\n", + "model.add(MaxPooling2D(pool_size=(2,2)))\n", + "model.add(Conv2D(64, kernel_size=(3,3), strides=(1,1), padding='same', activation='relu'))\n", + "model.add(MaxPooling2D(pool_size=(2,2)))\n", + "#\n", + "model.add(Dropout(0.2))\n", + "model.add(Flatten())\n", + "model.add(Dense(units=64, activation='relu'))\n", + "#\n", + "model.add(Dropout(0.5))\n", + "model.add(Dense(units=num_classes, activation='softmax'))\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-mYbag3yfhsZ", + "outputId": "8641dd4a-424e-48eb-c21e-1c7f3906dc4b" + }, + "execution_count": 17, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"sequential\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " conv2d (Conv2D) (None, 28, 28, 32) 320 \n", + " \n", + " max_pooling2d (MaxPooling2D (None, 14, 14, 32) 0 \n", + " ) \n", + " \n", + " conv2d_1 (Conv2D) (None, 14, 14, 64) 18496 \n", + " \n", + " max_pooling2d_1 (MaxPooling (None, 7, 7, 64) 0 \n", + " 2D) \n", + " \n", + " dropout (Dropout) (None, 7, 7, 64) 0 \n", + " \n", + " flatten (Flatten) (None, 3136) 0 \n", + " \n", + " dense (Dense) (None, 64) 200768 \n", + " \n", + " dropout_1 (Dropout) (None, 64) 0 \n", + " \n", + " dense_1 (Dense) (None, 10) 650 \n", + " \n", + "=================================================================\n", + "Total params: 220,234\n", + "Trainable params: 220,234\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])" + ], + "metadata": { + "id": "9hbTVxflfhoG" + }, + "execution_count": 18, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "history = model.fit(X_train, y_train, batch_size=128, epochs=10, validation_split=0.2)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "g8ZGgOkYfhkA", + "outputId": "97821855-ca96-4f67-fe78-b6cf8220361e" + }, + "execution_count": 19, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/10\n", + "375/375 [==============================] - 15s 12ms/step - loss: 0.4360 - accuracy: 0.8645 - val_loss: 0.0841 - val_accuracy: 0.9750\n", + "Epoch 2/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.1489 - accuracy: 0.9557 - val_loss: 0.0564 - val_accuracy: 0.9842\n", + "Epoch 3/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.1126 - accuracy: 0.9669 - val_loss: 0.0462 - val_accuracy: 0.9863\n", + "Epoch 4/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.0923 - accuracy: 0.9732 - val_loss: 0.0424 - val_accuracy: 0.9877\n", + "Epoch 5/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.0776 - accuracy: 0.9761 - val_loss: 0.0384 - val_accuracy: 0.9891\n", + "Epoch 6/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.0724 - accuracy: 0.9785 - val_loss: 0.0417 - val_accuracy: 0.9883\n", + "Epoch 7/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.0640 - accuracy: 0.9803 - val_loss: 0.0365 - val_accuracy: 0.9895\n", + "Epoch 8/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.0593 - accuracy: 0.9827 - val_loss: 0.0380 - val_accuracy: 0.9898\n", + "Epoch 9/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.0523 - accuracy: 0.9837 - val_loss: 0.0353 - val_accuracy: 0.9899\n", + "Epoch 10/10\n", + "375/375 [==============================] - 4s 10ms/step - loss: 0.0502 - accuracy: 0.9850 - val_loss: 0.0425 - val_accuracy: 0.9889\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from matplotlib import pyplot as plt" + ], + "metadata": { + "id": "WlhMk7cWfhhD" + }, + "execution_count": 20, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "plt.plot(history.epoch, history.history['loss'])\n", + "plt.plot(history.epoch, history.history['val_loss'])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 284 + }, + "id": "E3ZNW5o8fpXH", + "outputId": "8d517369-aa8b-4963-9310-ad4555996786" + }, + "execution_count": 21, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x7f2c402cc8d0>]" + ] + }, + "metadata": {}, + "execution_count": 21 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD5CAYAAAAp8/5SAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de3Sc9X3n8fdXMxrdb4NlA5LsEWAu5maDJNKwkARoYtouzrbpKaTpsr0shy1s2U32tKTNSfeQzTlp0s0JZ5duy1LSJk3KpjTb9aY0JOXSNNkAlsEQbOMgG9uSMbZsXSzrfvnuH88jaSRL9sga+xnNfF7nzNFznflKx/78nvk9l5+5OyIikr+Koi5ARETOLQW9iEieU9CLiOQ5Bb2ISJ5T0IuI5DkFvYhInotnspGZbQYeBWLAE+7+hUW2+yXgaaDV3dvNLAXsBvaEm7zk7vef7rNWrVrlqVQqo+JFRCSwffv2Y+5ev9C6Mwa9mcWAx4CfBbqAbWa21d13zduuCngIeHneW+x1942ZFptKpWhvb890cxERAczswGLrMum6aQM63H2fu48BTwFbFtjuc8AfASNnVaWIiJwTmQR9A9CZNt8VLpthZjcATe7+9wvs32xmr5nZP5nZLQt9gJndZ2btZtbe3d2dae0iIpKBZZ+MNbMi4MvApxZYfRhY6+6bgE8C3zSz6vkbufvj7t7i7i319Qt2MYmIyFnKJOgPAU1p843hsmlVwDXAi2a2H3gfsNXMWtx91N2PA7j7dmAvcHk2ChcRkcxkEvTbgPVm1mxmCeBuYOv0Snfvd/dV7p5y9xTwEnBXeNVNfXgyFzO7BFgP7Mv6byEiIos641U37j5hZg8CzxJcXvmku+80s0eAdnffeprdbwUeMbNxYAq43917slG4iIhkxnLtMcUtLS2uyytFRJbGzLa7e8tC6/Lmzti+oTEe/ce3efNQf9SliIjklIzujF0JYkXGo8/9lCl3rmmoibocEZGckTdH9FWlxVx1UTXb9usUgIhIurwJeoDWVJLXDvYxPjkVdSkiIjkjr4K+rTnJ8Pik+ulFRNLkVdC3ppIA6r4REUmTV0FfX1VC86oKXnmnN+pSRERyRl4FPUBrqo5t+3uYmsqt+wNERKKSd0Hf1nwB/cPjvH30ZNSliIjkhPwL+rCf/hX104uIAHkY9E3JMtZUl7DtHQW9iAjkYdCbGa2pJNv295Brz/EREYlC3gU9BNfTH+4foat3OOpSREQil5dBr+vpRURm5WXQX7GmiurSOK+on15EJD+DvqjIaEkldeWNiAgZBr2ZbTazPWbWYWYPn2a7XzIzN7OWtGWfDvfbY2YfyUbRmWhrTrKve5BjJ0fP10eKiOSkMwZ9OObrY8CdwAbgHjPbsMB2VcBDwMtpyzYQjDF7NbAZ+JPpMWTPtel++nYd1YtIgcvkiL4N6HD3fe4+BjwFbFlgu88BfwSMpC3bAjzl7qPu/g7QEb7fOXdtQw2lxUV67o2IFLxMgr4B6Eyb7wqXzTCzG4Amd//7pe4b7n+fmbWbWXt3d3dGhZ9JIl7ExqZaXXkjIgVv2SdjzawI+DLwqbN9D3d/3N1b3L2lvr5+uSXNaEsl2fluPydHJ7L2niIiK00mQX8IaEqbbwyXTasCrgFeNLP9wPuAreEJ2TPte061NieZcnj1gLpvRKRwZRL024D1ZtZsZgmCk6tbp1e6e7+7r3L3lLungJeAu9y9PdzubjMrMbNmYD3wStZ/i0XcsLaOWJHpenoRKWjxM23g7hNm9iDwLBADnnT3nWb2CNDu7ltPs+9OM/sWsAuYAB5w98ks1X5GFSVxrr64WtfTi0hBO2PQA7j7M8Az85Z9dpFtPzhv/vPA58+yvmVrSyX52ksHGJ2YpCR+Xq7sFBHJKXl5Z2y61uYkYxNT/KRLA4aLSGHK/6DXQCQiUuDyPuiTFQkuW12pgUhEpGDlfdBDcFTffqCXSQ0YLiIFqCCCvq25joGRCfa8NxB1KSIi511BBP1MP/07xyOuRETk/CuIoG+sK+fimlK27dcdsiJSeAoi6CF4Pv0rGjBcRApQwQR9a3OS7oFRDhwfiroUEZHzqmCCvk3X04tIgSqYoL9sdSV15cW6nl5ECk7BBL1ZMGC4BiIRkUJTMEEPQffN/uNDHD0xcuaNRUTyREEFfWuz+ulFpPAUVNBffXE1ZcUx9dOLSEEpqKAvjhVx47o6XtGNUyJSQDIKejPbbGZ7zKzDzB5eYP39ZvYTM9thZj80sw3h8pSZDYfLd5jZn2b7F1iq1lSSt947Qf/weNSliIicF2cMejOLAY8BdwIbgHumgzzNN939WnffCHwR+HLaur3uvjF83Z+tws9Wa3MdrgHDRaSAZHJE3wZ0uPs+dx8DngK2pG/g7ifSZiuAnH3OwKamOopjphOyIlIwMgn6BqAzbb4rXDaHmT1gZnsJjuh/J21Vs5m9Zmb/ZGa3LPQBZnafmbWbWXt3d/cSyl+6skSMaxpqdEJWRApG1k7Guvtj7n4p8HvAZ8LFh4G17r4J+CTwTTOrXmDfx929xd1b6uvrs1XSotpSSd7o6mdkfPKcf5aISNQyCfpDQFPafGO4bDFPAR8FcPdRdz8eTm8H9gKXn12p2dOaSjI2OcWOzr6oSxEROecyCfptwHozazazBHA3sDV9AzNbnzb788Db4fL68GQuZnYJsB7Yl43Cl6MlVQeg7hsRKQjxM23g7hNm9iDwLBADnnT3nWb2CNDu7luBB83sDmAc6AXuDXe/FXjEzMaBKeB+d488XWvLE1x5YZVOyIpIQThj0AO4+zPAM/OWfTZt+qFF9vtb4G+XU+C50ppK8u1Xu5iYnCIeK6j7xkSkwBRswrU2Jxkcm2T3YQ0YLiL5rWCDXgORiEihKNigv7CmlKZkmU7IikjeK9igh6CffpsGDBeRPFfQQd+WSnJ8cIy93YNRlyIics4UdNBPD0Si4QVFJJ8VdNBfsqqCVZUJ9dOLSF4r6KA3M1pTSV15IyJ5raCDHoITsl29wxzuH466FBGRc6Lgg75tesBwdd+ISJ4q+KC/6qJqKkviOiErInmr4IM+VmTcsK6Obe9oaEERyU8FH/QAbak69hwZoHdwLOpSRESyTkFPcEIWoF0DhotIHlLQA9c31ZKIFamfXkTyUkZBb2abzWyPmXWY2cMLrL/fzH5iZjvM7IdmtiFt3afD/faY2UeyWXy2lBbHuL6pRlfeiEheOmPQh0MBPgbcCWwA7kkP8tA33f1ad98IfBH4crjvBoKhB68GNgN/Mj20YK5pTSV581A/Q2MTUZciIpJVmRzRtwEd7r7P3ccIBv/ekr6Bu59Im60Aph8HuQV4Khwk/B2gI3y/nNPanGRiytlxUAOGi0h+ySToG4DOtPmucNkcZvaAme0lOKL/nSXue5+ZtZtZe3d3d6a1Z9WN6+ow00AkIpJ/snYy1t0fc/dLgd8DPrPEfR939xZ3b6mvr89WSUtSXVrMVRdWq59eRPJOJkF/CGhKm28Mly3mKeCjZ7lvpNqak7x2sI/xyamoSxERyZpMgn4bsN7Mms0sQXBydWv6Bma2Pm3254G3w+mtwN1mVmJmzcB64JXll31utKaSDI9P8uah/qhLERHJmviZNnD3CTN7EHgWiAFPuvtOM3sEaHf3rcCDZnYHMA70AveG++40s28Bu4AJ4AF3nzxHv8uytTbXAcFAJJvW1kVcjYhIdliujZfa0tLi7e3tkX3+h/74RS6tr+SJe1siq0FEZKnMbLu7LxhcujN2ntZUHe0Hepiayq0GUETkbCno52lNJekbGqej+2TUpYiIZIWCfh4NRCIi+UZBP8/aZDmrq0oU9CKSNxT085gZrc1Jtu3vIddOVIuInA0F/QJuak5yuH+Erl4NGC4iK5+CfgHTA5Ho+fQikg8U9Au4Yk0V1aUaMFxE8oOCfgFFRUZLKqkTsiKSFxT0i2hNJdnbPcjxk6NRlyIisiwK+kW0zTz3RgOGi8jKpqBfxLUNtZTEi9R9IyIrnoJ+EYl4ERubanVCVkRWPAX9adzUnGTnu/2cHNWA4SKycinoT6O1OcmUw6sH1E8vIiuXgv40blhbR6zI1H0jIitaRkFvZpvNbI+ZdZjZwwus/6SZ7TKzN8zsOTNbl7Zu0sx2hK+t8/fNZRUlca6+WAOGi8jKdsagN7MY8BhwJ7ABuMfMNszb7DWgxd2vA54Gvpi2btjdN4avu7JU93nTmkqyo7OP0YmcHQFRROS0MjmibwM63H2fu48BTwFb0jdw9xfcfSicfQlozG6Z0WlNJRmdmNKA4SKyYmUS9A1AZ9p8V7hsMb8J/EPafKmZtZvZS2b20YV2MLP7wm3au7u7Myjp/GlNBTdOvazuGxFZobJ6MtbMPgG0AF9KW7wuHLD248BXzOzS+fu5++Pu3uLuLfX19dksadkuqCzh0voKtinoRWSFyiToDwFNafON4bI5zOwO4A+Au9x95gEx7n4o/LkPeBHYtIx6I9HWfAHtB3qZ1IDhIrICZRL024D1ZtZsZgngbmDO1TNmtgn4M4KQP5q2vM7MSsLpVcDNwK5sFX++tDXXMTAywZ73BqIuRURkyc4Y9O4+ATwIPAvsBr7l7jvN7BEzm76K5ktAJfA38y6jvApoN7PXgReAL7j7igt6DUQiIitZPJON3P0Z4Jl5yz6bNn3HIvv9P+Da5RSYCxrryrm4ppRX9vdw7/tTUZcjIrIkujM2Q63NSba9owHDRWTlUdBnqDWV5OjAKAd7hs68sYhIDlHQZ6itOein1/X0IrLSKOgzdFl9JbXlxbqeXkRWHAV9hoqKjNZUUlfeiMiKo6BfgrZUkv3Hhzg6MBJ1KSIiGVPQL0Fr2E+/7R0NRCIiK4eCfgmuvriasuKYum9EZEVR0C9BcayIG9bVaiASEVlRFPRL1JpKsvu9E5wYGY+6FBGRjCjol6gtlcQdtu9XP72IrAwK+iXatLaOeJHxivrpRWSFUNAvUVkixrWNNbpxSkRWDAX9WWhLJXmjq5+RcQ0YLiK5T0F/FlpTScYmp3i9sy/qUkREzkhBfxZawgHDdT29iKwEGQW9mW02sz1m1mFmDy+w/pNmtsvM3jCz58xsXdq6e83s7fB1bzaLj0pteYIr1lTxiq68EZEV4IxBb2Yx4DHgTmADcI+ZbZi32WtAi7tfBzwNfDHcNwn8IXAT0Ab8oZnVZa/86LQ217F9fw8Tk1NRlyIiclqZHNG3AR3uvs/dx4CngC3pG7j7C+4+PSLHS0BjOP0R4Pvu3uPuvcD3gc3ZKT1arakkg2OT7D6sAcNFJLdlEvQNQGfafFe4bDG/CfzDUvY1s/vMrN3M2ru7uzMoKXrTA5HoenoRyXVZPRlrZp8AWoAvLWU/d3/c3VvcvaW+vj6bJZ0zF9WU0ZQs0/X0IpLzMgn6Q0BT2nxjuGwOM7sD+APgLncfXcq+K9X0QCQaMFxEclkmQb8NWG9mzWaWAO4GtqZvYGabgD8jCPmjaaueBT5sZnXhSdgPh8vyQlsqyfHBMfYdG4y6FBGRRZ0x6N19AniQIKB3A99y951m9oiZ3RVu9iWgEvgbM9thZlvDfXuAzxE0FtuAR8JleWF2IJK8+ZVEJA/FM9nI3Z8Bnpm37LNp03ecZt8ngSfPtsBcdsmqClZVJnhlfw93t62NuhwRkQXpzthlMDNa1iU1EImI5DQF/TK1Nifp6h3mcP9w1KWIiCxIQb9Mbanwenod1YtIjlLQL9NVF1VRWRLXA85EJGcp6JcpHivihnV1bHtHDzgTkdykoM+CtlQde44M0Dc0FnUpIiKnUNBnQWvYT9+uxxaLSA5S0GfB9U21JGJF6qcXkZykoM+C0uIY1zXW8LKuvBGRHKSgz5LW5iRvHupnaGwi6lJEROZQ0GdJWyrJxJSz46AGDBeR3KKgz5IbU3WYaSASEck9CvosqS4t5qoLq3VCVkRyjoI+i9qak7x6oI9xDRguIjlEQZ9Frakkw+OT7Hz3RNSliIjMyCjozWyzme0xsw4ze3iB9bea2atmNmFmH5u3bjIcjGRmQJJ81dpcB2ggEhHJLWcMejOLAY8BdwIbgHvMbMO8zQ4C/wb45gJvMezuG8PXXQuszxurq0pJXVCu6+lFJKdkckTfBnS4+z53HwOeArakb+Du+939DaDgO6dbU0naD/QwNaUBw0UkN2QS9A1AZ9p8V7gsU6Vm1m5mL5nZRxfawMzuC7dp7+7uXsJb557W5iR9Q+P86Q/2MjI+GXU5IiLn5WTsOndvAT4OfMXMLp2/gbs/7u4t7t5SX19/Hko6d37u2ou4Zf0qvvjdPdz2xy/yrfZOJnQVjohEKJOgPwQ0pc03hssy4u6Hwp/7gBeBTUuob8WpLInz9d+8iW/81k3UV5Xwu0+/wUe+8gO+++Zh3NWdIyLnXyZBvw1Yb2bNZpYA7gYyunrGzOrMrCScXgXcDOw622JXkpsvW8XfPXAzf/qJGzAz7v+rV/noYz/iRx3Hoi5NRArMGYPe3SeAB4Fngd3At9x9p5k9YmZ3AZhZq5l1Ab8M/JmZ7Qx3vwpoN7PXgReAL7h7QQQ9gJmx+ZqL+O5Dt/DFj11H98Aov/rEy/zqEy/xeqeeiSMi54flWndCS0uLt7e3R13GOTEyPsk3Xj7IYy900DM4xp3XXMinPnwFl62ujLo0EVnhzGx7eD701HUK+vPv5OgET/zzPv7nD/YxPD7Jx25s5KE7Lqehtizq0kRkhVLQ56jjJ0f5kxf38vUfHwDg135mHb/9wUu5oLIk4spEZKVR0Oe4Q33DPPqPP+Xp7V2UFcf4t7dewm/dcgmVJfGoSxORFUJBv0J0HB3gv37vp/zDm++RrEjwwIcu41dvWktpcSzq0kQkxynoV5jXO/v40rN7+GHHMRpqy3jojvX84qYG4jE9bFREFna6oFdy5KDrm2r5q98KbrpaVZnQTVcisiwK+hymm65EJBsU9DlON12JyHKpj36F0U1XIrIQnYzNQ7rpSkTSKejzmG66EhFQ0BcE3XQlUtgU9AUk/aarqtI4H7xiNbdfuZoPXF5PXUUi6vJE5BxR0Beg1zv7+PpLB3jhraMcHxyjyODGdXV86MrV3H7lGi5fU4mZRV2miGSJgr6ATU05bxzq5/ndR3juraPsfPcEAA21Zdx+1Wo+dOVqfuaSC/SYBZEVTkEvM97rH+GFPUd5bvdRftRxjOHxScqKY9x82aog+K9YzYU1pVGXKSJLtOygN7PNwKNADHjC3b8wb/2twFeA64C73f3ptHX3Ap8JZ/+Lu//l6T5LQX/+jIxP8tK+4zz/VhD8h/qGAbj64mpuv3I1t121husaaigqUhePSK5bVtCbWQz4KfCzQBfBGLL3pA8JaGYpoBr4T8DW6aA3syTQDrQADmwHbnT33sU+T0EfDXfn7aMneW73UZ5/6wjbD/Qy5bCqMjFzQvdfrF9FVWlx1KWKyAJOF/SZXHvXBnS4+77wzZ4CtpA2yLe77w/XTc3b9yPA9929J1z/fWAz8NdL/B3kHDMzLl9TxeVrqvh3H7yU3sExfvB2N8/tPsr3dr7H09u7KI4Zbc1JbrtyDbdfuZrUqoqoyxaRDGQS9A1AZ9p8F3BThu+/0L4N8zcys/uA+wDWrl2b4VvLuVRXkWDLxga2bGxgYnKKVw/28dxbR3h+91E+951dfO47u7ikvoLbrljNbVetpjWVpFiPURbJSTlxN427Pw48DkHXTcTlyDzxWBFtzUnampN8+s6r6OwZCvr13zrK1358gCd++A5VJXFuvaKe265YzQevqNeduSI5JJOgPwQ0pc03hssycQj44Lx9X8xwX8lRTcly7n1/invfn2JwdIIfdhzjhTD4//6Nw5jBpqZabrtyNbdduYarLqrSNfsiEcrkZGyc4GTs7QTBvQ34uLvvXGDbvwC+M+9k7HbghnCTVwlOxvYs9nk6GbtyTU05O989wfNvBSd0X+/qB6C+qoSNTbVsbKplU1Mt1zXV6tEMIlmWjcsrf47g8skY8KS7f97MHgHa3X2rmbUC/xuoA0aA99z96nDf3wB+P3yrz7v7V0/3WQr6/HF0YIQX3+rmpX3H2dHZx75jgwCYwfrVlWH417GxqZbL11RqqESRZdANU5IT+obGeL2rnx0H+9jR2cuOzj56h8YBKCuOcW1jDZvCI/+Na2u5qEaPXBbJ1HIvr1w5Jschpuu8c1VteYIPXF7PBy6vB4Jr9w/2DLGjs4/XDvaxo7OPr/5oP2OTwVW6a6pL5hz1X9dYQ4W6fESWLH/+14wOwH+7EdZ/GFp+HS6+IegjkJxlZqy7oIJ1F1SwZWNw1e3oxCS73j3Bjs6+mdezO48AUGRw+ZoqNq2tnWkALltdSUx37oqcVv503Zw8Cs9/Dn7yNIwPwYXXQctvwLUfg5Kq7Bcq503P4Bivd/bxWhj8r3f20T8cdPlUJGJc1xh09Uyf7F1drWf1SOEprD76kX5441uw/S/gyJuQqIRrfzk4yr/o+qzVKdFxd945NjjnqH/XuyeYmAr+LV9cUzoT/Bub6ri2oYayhJ7OKfmtsIJ+mjt0tUP7k7Dz2zAxEnTntPwGXPOLkNDt+/lkZHySnXO6fHrp7Ake0hYrMq5YU8Ul9RUkKxLUlidIlhdTV5Ggrjx8VRRTV56gPBHTNf+yIhVm0Kcb7oXX/xds/yp0vwUl1XDdrwRH+Wuuzu5nSc44dnKU19OO+rt6h+kdGqMvvNJnIYl4EXXlQegnK+Y2AvOng0ajmMqSuBoHiZyCfpo7HHwpOMrf9X9gchQa24Kj/Ks/CsW6nK8QTE45/cPj9AyO0Tc0Rs/gGL1DY/QOjdMbTvcMjgfrwoahb2iMqUX+qxTHLPyWkNYQVCRmGoz0RiFZkWBNdakGepGsU9AvZKgHdnwzOMo/3gGltXD9PcFRfv0V5/7zZUWZmnJOjIyHjcJsgzC/gegdHJ+zfHKR1mFVZYKGunIaa8toqCujobaMxrrZaT0OWpZKQX867rD/h8FR/u7/C1PjsPb9wVH+hrsgrodzydmZmnIGRifmNAo9g+O81z9MV+8wh/qGOdQ7TFffMGMTc5/wXV0ap7GufE4j0FhXRkNtsKyuvFjdRTKHgj5TJ7thxzeCK3Z634GyJGz8ONz467Dqsmhqkrw3NeUcGxzlUHr4z5keYnBscs4+5YkYDWnfBhrqyoKGIWwU6itLNDJYgVHQL9XUFLzzT8FR/p5nYGoCUrcE3TpX/kuIJ6KtTwqKe3BOoeuUhmBoZr533gnmRKyIi2tLZxuC2vI5XUMX1ZTq2UJ5RkG/HANH4LWvw6t/CX0HoXwVbPoE3HgvJC+JujoRAAZHJ+Z0BXX1Ds35hnB0YHTO9kUG1WXF1JYVU1OeoCacri0PflaXFVNbngjXF8/8rCkrpiSuE8m5SEGfDVOTsPeF4Cj/p98Fn4RLPhQc5V/xc3rGjuS0kfFJDvePhOE/xKG+EfqmrygaHqd/eJz+obGZ6dPFQllxjNow9GvCxqEmbBjmzJclZrcrL6ZKl6GeUwr6bDvxLrwaHuWfOASVa2DTrwVH+bUaClFWtumTyP1D4/QNj9E/PD7TIJwYHl+ggZjdbmR8/rDRs2JFRnVpfKZBqCkrpq68mDXVpayuLmVNdQlrqktZU1XK6uoSXYK6RAr6c2VqEt7+fnCU//b3gmWX3QE3/GtouBGqLoIi9YNK4RgZn5xpGPqnG4WZBiJoEKbXTd/LcHRg9JSrjgBqyopnwn91VVpDUF0SNgyl1FeWkIjr/xgo6M+Pvk549WvB6+R7wbLickheGlyxc8G8V1lttPWK5Ijpk81HToxy5MQIR06McHRgdvrIiVGOhssmFrgv4YKKxOw3gqq5DcF047CqsiTvn3KajRGmNgOPEoww9YS7f2He+hLga8CNwHHgV9x9v5mlgN3AnnDTl9z9/tN91ooN+mmTE3Dwx3BsDxzfG9yMdbwDeg8E/frTylcFgT+/EUheomv3RRYwNeX0DI3NaQDSG4IjA8H0sZOjp5xjKLJgSMvFvh0kyxOUFscoiReRiBdREi+ipDhGIlZEccxWxLmFZQW9mcUIxoz9WaCLYMzYe9x9V9o2vw1c5+73m9ndwL9y918Jg/477n5NpsWu+KBfzMQY9O4Pg//t8GfYEJw8MrudFUFN02zwr1oPF1waTFc3qitI5AwmJqc4djKtQRgIG4K0xuHowCg9g2MZvZ8ZQfDHY7ONQLyIRDyWNh2sLymeXV8Sn9dwpO9fHM7H0qbjRVSXxrmkvvKsfu/ljjDVBnS4+77wzZ4CtgC70rbZAvzncPpp4L/bSmgCz6d4AuovD17zjfSHob93bkPQ+TKMnUx7j9KgK2g6+Fetn20QypPn73cRyWHxWBEX1pRyYc3pxyUYnZike2CUIyeC0B+bmGJ0YjL8OX96amb96PjsstGJSUYnphgYmeDYxNjcfcYnGZsMpjPtId/YVMvfPXBzFv4Kc2US9A1AZ9p8F3DTYtu4+4SZ9QMXhOuazew14ATwGXf/5/kfYGb3AfcBrF1bgFetlNZAww3BK517cLR/7O3ZLqDjHXB01+yNXNPKkmldQJcGjUDtuuC9S6qDwVd0o5fIjJJ4jMa6chrrys/p57g745MehP745KkNR9p0eeLcDPp3rocSPAysdffjZnYj8HdmdrW7n0jfyN0fBx6HoOvmHNe0cphB1YXBq/mWuesmx4MbuOY3AvtegNe/ufD7xUqCwC8Ng3+6ATjltdDytGXxUg3TKJIhMyMRNxLxIiojGvM4k089BDSlzTeGyxbapsvM4kANcNyDEwCjAO6+3cz2ApcDedgJf57FisMunEtPXTd6Enr2Bg3B6ED4OpE2nfbq75ydHjkRPNTtTIqKz9AoLLC8tDpYNv0No7RaJ51Fxkdg4HDwOvFucBB11S9k/WMyCfptwHozayYI9LuBj8/bZitwL/Bj4GPA8+7uZlYP9Lj7pJldAqwH9mWtellYSWUwbOLZDJ04MRoE/oINwyKNxeiJoIvpeMfssonhM39WrCStAUj/WbPI8gXWF5/j8WGnpoIxiMcGg/MlYyfD6cG506MDacsHF9huen4oqBirtd8AAAWjSURBVLn8gqC7rXz6lT4/PX1BMF9aq5PwK407DB0PwnsmyA/DwLvhzzDYh3vm7nfR9dEEfdjn/iDwLMHllU+6+04zewRod/etwJ8DXzezDqCHoDEAuBV4xMzGgSngfnfvOfVTJGfES6CyPngtx+T43IZguvGY+dl/6vxI2GBML0s/Eb2YWGKRBqHm1OVYGLanCeXReWE+Ppj572yxoJFNTL8qgld1w+x0oiJoOIaOw1BvcAK+a1swn37OZc77FgVhf0ojULd4A1FWB7FouglO4R78bpNjwb+LyfFgemo8uOkwXhoM+lNcHvz7y/VuwflH4aeE+Lsw8F7wO85hUFEP1RcFV9Y1tUHVxcF81UVQfXHw8xzQDVOSu6YmF2kkFmssFvg5NrDwexfFZwO5JC2UE/OnT7NuZr/wZyxx9iHlHjSKwz2zjcDQ8bT5noXXTYws/p4lNYt8Ywi/JcDC4Ts9nb58ciwtrMeC+0VmpsfD/ebvk/aeGbMg8KeDv7jsNNPpP0tPs26B/RZ6NtX8o/BTfoYhPtx76r7F5WlhfeHc4J7+WXXhOX0m1nIvrxSJRlEsODItqzv795ianP1Wgc0Gc65dgWQWfOsorYa6VOb7jQ2d2iDMNAo9s+tOHoGjbwXzp/uWEksEr6L47HQsvvDyRDnEak+/faw4OKczPR0rnrvcioLGamIk+KYzPhy+hub9HIaRviBwx4eCo+rp9UtqSEJF8bmNwNRUcEf76Y7Ca9fC2psWPgovrcnpbyIKeslvRbHgcRP5+siJRHnwqm0687bTJkZhuC8I2ZngTQR/qxwOq0VNji/QQKRNT5ym8Ziehtkj8fN4FH6+KOhFCk28BKrWRF1F9kx/UyitjrqSnKVT+SIieU5BLyKS5xT0IiJ5TkEvIpLnFPQiInlOQS8ikucU9CIieU5BLyKS53LuWTdm1g0cWMZbrAKOZamclU5/i7n095hLf49Z+fC3WOfuCz6NMOeCfrnMrH2xB/sUGv0t5tLfYy79PWbl+99CXTciInlOQS8ikufyMegfj7qAHKK/xVz6e8ylv8esvP5b5F0fvYiIzJWPR/QiIpJGQS8ikufyJujNbLOZ7TGzDjN7OOp6omRmTWb2gpntMrOdZvZQ1DVFzcxiZvaamX0n6lqiZma1Zva0mb1lZrvN7GeirilKZvYfw/8nb5rZX5tZadQ1ZVteBL2ZxYDHgDuBDcA9ZrYh2qoiNQF8yt03AO8DHijwvwfAQ8DuqIvIEY8C33X3K4HrKeC/i5k1AL8DtLj7NUAMuDvaqrIvL4IeaAM63H2fu48BTwFbIq4pMu5+2N1fDacHCP4jN0RbVXTMrBH4eeCJqGuJmpnVALcCfw7g7mPu3hdtVZGLA2VmFgfKgXcjrifr8iXoG4DOtPkuCjjY0plZCtgEvBxtJZH6CvC7wFTUheSAZqAb+GrYlfWEmVVEXVRU3P0Q8MfAQeAw0O/u34u2quzLl6CXBZhZJfC3wH9w9xNR1xMFM/sF4Ki7b4+6lhwRB24A/oe7bwIGgYI9p2VmdQTf/puBi4EKM/tEtFVlX74E/SGgKW2+MVxWsMysmCDkv+Hu3466ngjdDNxlZvsJuvRuM7O/irakSHUBXe4+/Q3vaYLgL1R3AO+4e7e7jwPfBt4fcU1Zly9Bvw1Yb2bNZpYgOJmyNeKaImNmRtAHu9vdvxx1PVFy90+7e6O7pwj+XTzv7nl3xJYpd38P6DSzK8JFtwO7IiwpageB95lZefj/5nby8OR0POoCssHdJ8zsQeBZgrPmT7r7zojLitLNwK8BPzGzHeGy33f3ZyKsSXLHvwe+ER4U7QN+PeJ6IuPuL5vZ08CrBFervUYePg5Bj0AQEclz+dJ1IyIii1DQi4jkOQW9iEieU9CLiOQ5Bb2ISJ5T0IuI5DkFvYhInvv/6DI6sAOzFEIAAAAASUVORK5CYII=\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "plt.plot(history.epoch, history.history['accuracy'])\n", + "plt.plot(history.epoch, history.history['val_accuracy'])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 283 + }, + "id": "25zeWoN6fpTt", + "outputId": "028d6a2f-eb96-4fd7-e3fb-5e08813c14b9" + }, + "execution_count": 22, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x7f2bd51797d0>]" + ] + }, + "metadata": {}, + "execution_count": 22 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de3SddZ3v8fc393svufSWNi3YAgUKSCggYpmiiOiAoI6gMIN6hLUUbwPLAzOznFm4HGadg4pr5DhWZBD1iEyP4zDHKiAtMnoQknK19EIpvaSlbZq0TZMm2bl8zx/Ps5Od3bTZJbvdez/781prr/3s55L89m7zyS+/5/c8X3N3REQkugoy3QARETmxFPQiIhGnoBcRiTgFvYhIxCnoRUQirijTDUhWV1fn8+fPz3QzRERyytq1a/e5e/1427Iu6OfPn09ra2ummyEiklPMbNvRtmnoRkQk4hT0IiIRp6AXEYk4Bb2ISMQp6EVEIk5BLyIScQp6EZGIy7p59CKSpdxheAh8KOl5+MjXR902BMPDY1/7cNLDx1l3PNvfxj5WACWV4aMqeC6uGF1OXF9UCmaZ/tc4Lgp6iS53GOiFvoPQdyB4XVwe/AAXlwePwuJMt/Ltc4fBfujvgr4u6D8YPncd/Xlk+RAMDxwZukcL4+EhQLUrALDCpF8AlUd5XTHOtqMsF1dCwYkbYFHQS3Zzh1hPENS9BxKeD46zbpznodixv35B0djgH1l+G+uKjrGtoPDI9zVwOCmID46G8LhhffDI9cMDE3+GJdVQVgOlNcFzRS1Ma4LCkiC0CgrC58KgZ5u4XFCY8DoN68fsk/x9Ex82zroTuM/wUPDvEesJH93HsRwe170nYVsPxA4Ffy2kqrgC5i6Fv/yP1I9JkYJeTjz3ILyOFch9B4++bXjwGF/cgvAqmwrlU4PnmlljX5dPhbIpQagM9AY/0AO9ScsJz4N9wXJP+5H7x3p4Wz3bwtLR0B/sC0LahyY4yEbDOf5cNRPqFkFpddK2KUfuW1oT7Jf8S0aOVFAYfqbV6fua8b+4jucXR/XM9H3/BAp6mdjwcPCfsO/g6CPewxzzODDOunC/Y4WaFQZBlRjMU+eOE9bjPJfWnNA/eY/gHvyVMNEvi5Ft4+xTVJpaSJdUndz3JullBsVlwaOyNqNNUdDng+Hh4M/II0I4xUd/18R/ghZXBoEVf1TNhLrTRl/He9XjhnV17pzcMguCuqgUyqdlujUiKVHQ5yp3ONwJ3bvh0FtwKPE5fHTvHQ3qiYYbSqrDIA57mDWzoeGMseE93qM0PCaXT2qKRJyCPtu4B0Mgh5IDfM/YIO/ePf6JxrKpUD0rGOurPTV4PWFY10Ch/iuIRJV+uk8W96BnPW5wJzx37wlO1iUrnRKEd/VMaLo4XJ419rlqRnCyT0QybmjY6e4bpKtvgK6+AQ71DdLVGz4nvT7UP0BX7yDzaiv4x2vPTntbFPTpdnAnvPYfcLBtNLjjQT5w+Mj9S6pGw3ru0tHlqhkJQT4zmGsrIieFu9M7MDQSxl3jhfM4AZ4Y4t39x5otFqgoKaS6rIjqsmJqyoooKjgx56oU9OngDtufhee+D+v/M5hhUlQeTPOrngWzzoVFs8bphc9I73QukTw2NOz0xAY53D9Ed/8gh2NB2B7uH6InNkhP/9Douli4T/8gPbEhuhN61YfCoB4cPvZ5raICo6a8mOqyImrKgucFdZWjwV0+GuDx58T9q8qKKC48ObOqFPSTMdALr66E578Pu18Nxrsv/hw0fxqmLcidmSQiGTA07Ow/HKOnfzR8e/qDQA6COXFdEMhjnhO3xwbpG0j94qTy4kIqSwupLC2ioqSIqtJCGqrLeEd9ckgXh8EdhHTNSKgXU1ZcgOXIz7iC/u04sANafwhrfwS9ndCwGD50Hyz5Cw2xiAADQ8Ps6epjT1cfbx3sY/fBxOde9nT1s6erb8JeMwQ958rSIqpKi6goKaSiNAjm6ZUVI+uqwsAeDe/RdVWlRVSUFlIZbq8oKaLwBA2RZCsFfarcYdsf4Ll/gQ2/CtaddhVceCvMv1S9d8kbfQNDo8Hd1ctbB/vYM/I6eN7X3Y8nZXh5cSGzppQxc0oZF54ynVlTymioLqOqtIjK0tGQrixJCOrSQkqLdGXvZKUU9GZ2JfAdoBB4wN3/KWl7E/AgUA90Aje6e1u47X8AHyS4JfKTwJfck/8LZLHYYXj134Lx973rgotk3vUFuOC/wdR5mW6dSFod6hsY6YWP7YmHgd7Vx/7DR95fp6asiFlTypk5pYzFs2qYUVM2Eurx9TVlRTkz1BE1Ewa9mRUC9wPvA9qAFjN7zN1fS9jtXuBhd/+RmS0H7gFuMrN3AZcAS8L9fg8sA55O31s4QfZvg5YH4IWHg3ntM86Cq/8ZzvpocFc6kRzh7nT1DdLR3U9nT4x93TE6evqP6IXvPtg37kyR2soSZk4po3FaOc3zpwXBHQb5jCllzKwpo7JUgwPZLJV/naXAZnffAmBmjwDXAIlBvxj463B5DfDLcNmBMqAEMKAY2DP5Zp8g7vDmM/D8Cti4CjA440Ow9FZoepeGZyQruDs9sSE6u2Ps6+mnoztGZ08/+7pjdPbE6Ojup6MnRkcY6J09MQaGjvwjusCgoTrodS9sqOLShXXMrBnthc+aUkZDTamGTiIglaCfA+xIeN0GXJi0z8vAdQTDO9cC1WZW6+7Pmtka4C2CoP+uu69P/gZmdgtwC8C8eRkYDon1wCs/h+dWQPt6KJ8Ol3wZLvgMTGk8+e2RvNMbG6JjJLRj7At73x2Jy92jId4/OP4Mk8qSQqZXlVBbWcrsqWWcNaeG2qpSaitLqA3XT68soa6qlLqqEopO0vQ+yax0/b11B/BdM7sZeAbYCQyZ2TuAM4B4Wj5pZpe6+38lHuzuK4AVAM3NzSdv/H7/Vnj+B/Dij4N7wsxcAtfcD2d9RFeYyqS5O509sYTx7t6RE5Ud3TH29QQ98Y7uGIdj49/ds6SogPqqIJxrq0pYNKM6DOySkcCurQqWaytLKS9R71uOlErQ7wTmJrxuDNeNcPddBD16zKwK+Ii7HzCzzwJ/dPfucNuvgYuBMUF/UrnDlqfD4ZlfB4UHFl8dDM/Mu0jDM5KS4WGn83CM3Qf72HWgd2Sc+60DvWPGvWNJPe/CAqOuqoTplUGPekFtBdMrg7COr6+tKqGuspTpVSVUlhTqBKZMWipB3wIsNLMFBAF/PfCJxB3MrA7odPdh4C6CGTgA24HPmtk9BEM3y4D70tT249PfDa88EvTg2zdARR28547g4qaa2RlpkmSn4WGnoycM8YO9IzNP3gp75LvDR2xobIgXF9rIbJMljVN5/5nBcjD7pJzZU8qorSrNuzncknkTBr27D5rZbcDjBNMrH3T3dWZ2N9Dq7o8BlwH3mJkTDN18Pjx8JbAceJXgxOxv3P0/0/82jqHjjWD2zIs/DUq1zToXPvwvcOa1QUEAySvDw86+nv6wJx4Op3T18daBcCphVy97DvaPG+Izp5Qxq6acc+dOZdbZZcyqCQN8anACs66ylAKFuGQhy7Yp7c3Nzd7a2jq5LzI8DFvWBHPfX38iKBO2+MPBxU2NF2h4JuIOHI6xreMw2zoPs72jZ2R514Fe9nT1HTEDpaSwgJkjc75HZ5zMnFLG7HAOeG1liUJcspqZrXX35vG2RWvya/8heOlnwfh7x+tQ2QDLvgrnfyq4wZhEwvCws+dQH9s6DrO94zDbOoMw3955mG0dhznYO/aCnvrqUpqmV9DcNI1ZU8uPCPPayhKNg0ukRSfoO96A7y8LSubNOR+uXQFnfjgo+SY5p39wiLb9vUGQd/SEvfOgZ76j8/CY6YVFBcacaeXMm17Bn58zi6bplcyrraCptoJ50yuoKInOf3ORtyM6PwHTT4HmT8Hia6Bx3L9eJMsc6hsY0xPf1jHaM991sHfMvVIqSgqZN72CU+srWX56A/OmB0HeNL2S2VPLNB9c5BiiE/RmcMXXM90KSdLdP8j6t7rCYZagZx4P886esaUQaytLmFdbwQXzpzGvtpH5I73ySuqqNLwi8nZFJ+gla2zr6GH1hr2s3rCXP27pGDn5WWAwe2o5TbUVvP/MmWGPvCIcZqmkSvdLETkh9JMlkzYwNMzabftHwn3z3m4ATq2v5FOXLODiU2qZX1fJnKnllBRpiEXkZFPQy9uyvyfG7za189SGvfxu4166+gYpLjQuOqWWT144j+WnN9BUqyIsItlAQS8pcXc27enmqQ17WL1+Ly9s38+wQ11VKe8/cyaXn9HAuxfWa/hFJAvpp1KOqm9giGe3dLBmw16eWr+XnQd6AThrTg23LV/I5ac3cPacKbqQSCTLKehljN0H+1izMQj2P2zeR+/AEOXFhbx7YR1fWP4O/uz0BmbU6NYRIrlEQZ/nhoedV3YeZPX6PTy1YS/rdnUBMGdqOR9rbmT56Q1cdEotZcW6/a1IrlLQ56FDfQP8/vV9rN6wlzUb97KvO0aBwflN0/jvV57O5Wc0sLChSvPWRSJCQZ8ntnX08NT6YPrjc28Gc9tryopYdloDl5/ewLJF9UyrLMl0M0XkBFDQR9TQsPP8m52s3rCH1Rv28kZ7DwDvaKji05csYPnpDZzfNE23DhDJAwr6iHF3Hl+3m28+sYnX93ZTUljAhadM58aLmjS3XSRPKegjwt353aZ2vvnEJl7deZBT6iu57+Pn8t7FMzS3XSTPKQEi4LktHdz7xEZatu6ncVo5//OjS7j2vDkalhERQEGf017ecYB7n9jIf72+j4bqUr5+zZl8/IJ5up+MiIyhoM9BG3Z38a0nNvHEa3uYVlHM31x1OjddNJ/yEs11F5EjKehzyNZ9PXz7t5t47OVdVJUU8ZX3LuLT755PdVlxppsmIllMQZ8Ddh7o5Z+fep1/W9tGcaFx63tO5db3nKJ57yKSEgV9Fms/1M/9azbzv5/bDsBNFzXxuT87lYZq3WtGRFKXUtCb2ZXAd4BC4AF3/6ek7U3Ag0A90Anc6O5t4bZ5wAPAXMCBq9x9a7reQBQdOBzj+89s4aE/bCU2NMxH39nIF9+7kDlTyzPdNBHJQRMGvZkVAvcD7wPagBYze8zdX0vY7V7gYXf/kZktB+4Bbgq3PQx8w92fNLMqYDit7yBCuvsHefD3b/KDZ7bQHRvkz5fM5ivvW8SCOl3kJCJvXyo9+qXAZnffAmBmjwDXAIlBvxj463B5DfDLcN/FQJG7Pwng7t1panek9A0M8eNnt/G9371BZ0+M9y2ewe1XLOL0mTWZbpqIREAqQT8H2JHwug24MGmfl4HrCIZ3rgWqzawWWAQcMLNfAAuA3wJ3uvtQ4sFmdgtwC8C8efPextvITbHBYX7euoPvrn6dPV39XLqwjtuvOI1z507NdNNEJELSdTL2DuC7ZnYz8AywExgKv/6lwHnAduDnwM3ADxMPdvcVwAqA5uZmT1ObstbQsPPvL+7kvt9uom1/L81N0/jO9edx0Sm1mW6aiERQKkG/k+BEalxjuG6Eu+8i6NETjsN/xN0PmFkb8FLCsM8vgYtICvp8MTzs/PpPu/nWkxt5o72Hs+bU8PUPn8Vli+p173cROWFSCfoWYKGZLSAI+OuBTyTuYGZ1QKe7DwN3EczAiR871czq3b0dWA60pqvxucLdWbNxL/c+vonX3upiYUMV3/vkO7nyrJkKeBE54SYMencfNLPbgMcJplc+6O7rzOxuoNXdHwMuA+4xMycYuvl8eOyQmd0BPGVBoq0FfnBi3kp2+n9v7OPexzfywvYDzJtewbc/fg5XnzOHQhXUFpGTxNyza0i8ubnZW1tzv9P/4vb93PvERv6wuYOZNWV88fKFfKy5kWLdUVJETgAzW+vuzeNt05WxaXY4NsiXHnmJJ1/bQ21lCX/3wTO48aImFdcWkYxR0KfZb/60mydf28MXl7+DW5edSqWKfohIhimF0qxlayc1ZUV8+b2LKNA4vIhkAQ0Yp1nL1v00z5+ukBeRrKGgT6POnhib93bTPH9appsiIjJCQZ9Ga7ftB+CC+dMz3BIRkVEK+jRq2dpJSWEBZ8+ZkummiIiMUNCnUcvWTs6ZO0VTKUUkqyjo06Q3NsSfdh6kWcM2IpJlFPRp8nLbAQaGnAt0IlZEsoyCPk1at3YCcP489ehFJLso6NPk+a37OW1GNVMqijPdFBGRMRT0aTA07LywbT8XLNCwjYhkHwV9GmzY3UV3/6Dmz4tIVlLQp0Hr1uBCKc24EZFspKBPg+e3djJ7ShlzppZnuikiIkdQ0E+Su9O6tZMLFqg3LyLZSUE/SW37e9nT1a9hGxHJWgr6SWoJ58/rQikRyVYK+kmKFxpZ1FCd6aaIiIxLQT9JKjQiItlOQT8JKjQiIrlAQT8JKjQiIrkgpaA3syvNbKOZbTazO8fZ3mRmT5nZK2b2tJk1Jm2vMbM2M/tuuhqeDVpVaEREcsCEQW9mhcD9wAeAxcANZrY4abd7gYfdfQlwN3BP0vavA89MvrnZ5fmtnSxpVKEREcluqfTolwKb3X2Lu8eAR4BrkvZZDKwOl9ckbjez84EZwBOTb272iBca0YVSIpLtUgn6OcCOhNdt4bpELwPXhcvXAtVmVmtmBcA3gTuO9Q3M7BYzazWz1vb29tRanmEqNCIiuSJdJ2PvAJaZ2YvAMmAnMAR8Dljl7m3HOtjdV7h7s7s319fXp6lJJ5YKjYhIrihKYZ+dwNyE143huhHuvouwR29mVcBH3P2AmV0MXGpmnwOqgBIz63b3I07o5hoVGhGRXJFK0LcAC81sAUHAXw98InEHM6sDOt19GLgLeBDA3T+ZsM/NQHMUQj5eaOTD583OdFNERCY04dCNuw8CtwGPA+uBR919nZndbWZXh7tdBmw0s00EJ16/cYLamxVUaEREckkqPXrcfRWwKmnd1xKWVwIrJ/gaDwEPHXcLs5AKjYhILtGVsW9DiwqNiEgOUdAfJ3enZWunevMikjMU9McpXmhEF0qJSK5Q0B8nFRoRkVyjoD9OLVv3U61CIyKSQxT0x6llayfNTdNUaEREcoaC/jjEC41ofF5EcomC/jio0IiI5CIF/XFQoRERyUUK+uPQokIjIpKDFPQp6hsY4tWdB3WhlIjkHAV9il7aERQaWbpA8+dFJLco6FOkQiMikqsU9ClqUaEREclRCvoUxAuNNOu2ByKSgxT0Kdiwu4tD/YMs1YVSIpKDFPQpUKEREcllCvoUqNCIiOQyBf0EVGhERHKdgn4CI4VGdCJWRHKUgn4CI4VGdCJWRHKUgn4CKjQiIrkupaA3syvNbKOZbTazO8fZ3mRmT5nZK2b2tJk1huvPNbNnzWxduO3j6X4DJ1qrCo2ISI6bMOjNrBC4H/gAsBi4wcwWJ+12L/Cwuy8B7gbuCdcfBv7S3c8ErgTuM7Op6Wr8iba/J8bre7t1IlZEcloqPfqlwGZ33+LuMeAR4JqkfRYDq8PlNfHt7r7J3V8Pl3cBe4H6dDT8ZGgNC43oQikRyWWpBP0cYEfC67ZwXaKXgevC5WuBajOrTdzBzJYCJcAbyd/AzG4xs1Yza21vb0+17SecCo2ISBSk62TsHcAyM3sRWAbsBIbiG81sFvBj4FPuPpx8sLuvcPdmd2+ur8+eDr8KjYhIFKQS9DuBuQmvG8N1I9x9l7tf5+7nAX8brjsAYGY1wK+Av3X3P6al1SeBCo2ISFSkEvQtwEIzW2BmJcD1wGOJO5hZnZnFv9ZdwIPh+hLg3wlO1K5MX7NPvHihEV0oJSK5bsKgd/dB4DbgcWA98Ki7rzOzu83s6nC3y4CNZrYJmAF8I1z/F8B7gJvN7KXwcW6638SJEC800tykHr2I5LaiVHZy91XAqqR1X0tYXgkc0WN3958AP5lkGzNChUZEJCp0Zew4VGhERKJEQT+OeKGRC3QiVkQiQEE/jnihEd3ITESiQEE/DhUaEZEoUdAnUaEREYkaBX0SFRoRkahR0CeJFxpRj15EokJBnyReaOS0GSo0IiLRoKBPokIjIhI1CvoEKjQiIlGkoE8QLzSiC6VEJEoU9AnihUaWNKrQiIhEh4I+gQqNiEgUKehDKjQiIlGloA+p0IiIRJWCPhQvNHJ+k4JeRKJFQR+KFxqZWlGS6aaIiKSVgh4VGhGRaFPQo0IjIhJtCnpGC42oRy8iUaSgZ7TQSOO0ikw3RUQk7fI+6FVoRESiLu+DXoVGRCTqUgp6M7vSzDaa2WYzu3Oc7U1m9pSZvWJmT5tZY8K2vzKz18PHX6Wz8emgQiMiEnUTBr2ZFQL3Ax8AFgM3mNnipN3uBR529yXA3cA94bHTgb8HLgSWAn9vZlnVdY4XGlmkQiMiElGp9OiXApvdfYu7x4BHgGuS9lkMrA6X1yRsfz/wpLt3uvt+4Engysk3O33ihUYKVWhERCIqlaCfA+xIeN0Wrkv0MnBduHwtUG1mtSkei5ndYmatZtba3t6eatsnTYVGRCQfpOtk7B3AMjN7EVgG7ASGUj3Y3Ve4e7O7N9fX16epSRNToRERyQdFKeyzE5ib8LoxXDfC3XcR9ujNrAr4iLsfMLOdwGVJxz49ifamlQqNiEg+SKVH3wIsNLMFZlYCXA88lriDmdWZWfxr3QU8GC4/DlxhZtPCk7BXhOuyggqNiEg+mDDo3X0QuI0goNcDj7r7OjO728yuDne7DNhoZpuAGcA3wmM7ga8T/LJoAe4O12WcCo2ISL5IZegGd18FrEpa97WE5ZXAyqMc+yCjPfys8bIKjYhInsjbK2NbVGhERPJEHgf9fhbNqFKhERGJvLwM+nihEU2rFJF8kJdBv3H3IRUaEZG8kZdBP3ojM43Pi0j05W3Qz5pSxpyp5ZluiojICZd3QR8vNHLB/OmY6UZmIhJ9eRf0KjQiIvkm74JehUZEJN/kYdCr0IiI5Je8C/rWrZ2cr0IjIpJH8iro44VGNH9eRPJJXgX9WhUaEZE8lFdB36JCIyKSh/Iu6M9WoRERyTN5E/TxQiMathGRfJM3Qa9CIyKSr/Im6FVoRETyVR4FvQqNiEh+yougjxca0W0PRCQf5UXQxwuNLFXQi0geyougb92mQiMikr9SCnozu9LMNprZZjO7c5zt88xsjZm9aGavmNlV4fpiM/uRmb1qZuvN7K50v4FUPP+mCo2ISP6aMOjNrBC4H/gAsBi4wcwWJ+32d8Cj7n4ecD3wv8L1HwNK3f1s4HzgVjObn56mpyZeaKRZhUZEJE+l0qNfCmx29y3uHgMeAa5J2seBmnB5CrArYX2lmRUB5UAM6Jp0q49DvNDIUg3biEieSiXo5wA7El63hesS/QNwo5m1AauAL4TrVwI9wFvAduBed+9M/gZmdouZtZpZa3t7+/G9gwmMjs/rRKyI5Kd0nYy9AXjI3RuBq4Afm1kBwV8DQ8BsYAFwu5mdknywu69w92Z3b66vr09TkwLPv6lCIyKS31IJ+p3A3ITXjeG6RJ8BHgVw92eBMqAO+ATwG3cfcPe9wB+A5sk2+nio0IiI5LtUgr4FWGhmC8yshOBk62NJ+2wHLgcwszMIgr49XL88XF8JXARsSE/TJ6ZCIyIiKQS9uw8CtwGPA+sJZtesM7O7zezqcLfbgc+a2cvAz4Cb3d0JZutUmdk6gl8Y/+rur5yINzIeFRoREYGiVHZy91UEJ1kT130tYfk14JJxjusmmGKZES3bVGhERCTSV8a2vKlCIyIikQ36eKER3fZARPJdZIM+XmhENzITkXwX2aBvDU/EqtCIiOS7yAb98292qtCIiAgRDXoVGhERGRXJoI8XGlEhcBGRiAZ9/EZmulBKRCSiQa9CIyIioyIX9Co0IiIyVuSCPl5oROPzIiKByAW9xudFRMaKXNC3bFWhERGRRNEL+jdVaEREJFGkgl6FRkREjhSpoI8XGmnW/W1EREZEKujjhUbOmTs1000REcka0Qp6FRoRETlCZIJehUZERMYXmaDv6hvgqrNnsWxhfaabIiKSVVIqDp4LGqrL+M7152W6GSIiWScyPXoRERmfgl5EJOJSCnozu9LMNprZZjO7c5zt88xsjZm9aGavmNlVCduWmNmzZrbOzF41s7J0vgERETm2CcfozawQuB94H9AGtJjZY+7+WsJufwc86u7fM7PFwCpgvpkVAT8BbnL3l82sFhhI+7sQEZGjSqVHvxTY7O5b3D0GPAJck7SPAzXh8hRgV7h8BfCKu78M4O4d7j40+WaLiEiqUgn6OcCOhNdt4bpE/wDcaGZtBL35L4TrFwFuZo+b2Qtm9tXxvoGZ3WJmrWbW2t7eflxvQEREji1dJ2NvAB5y90bgKuDHZlZAMDT0buCT4fO1ZnZ58sHuvsLdm929ub5e8+BFRNIplaDfCcxNeN0Yrkv0GeBRAHd/FigD6gh6/8+4+z53P0zQ23/nZBstIiKpS+WCqRZgoZktIAj464FPJO2zHbgceMjMziAI+nbgceCrZlYBxIBlwLeP9c3Wrl27z8y2Hde7GKsO2DeJ46NEn8VY+jzG0ucxKgqfRdPRNkwY9O4+aGa3EYR2IfCgu68zs7uBVnd/DLgd+IGZfYXgxOzN7u7AfjP7FsEvCwdWufuvJvh+kxq7MbNWd2+ezNeICn0WY+nzGEufx6iofxYW5HF0RP0f7HjosxhLn8dY+jxGRf2z0JWxIiIRF8WgX5HpBmQRfRZj6fMYS5/HqEh/FpEbuhERkbGi2KMXEZEECnoRkYiLTNBPdIfNfGJmc8O7ib4W3jX0S5luU6aZWWF4d9X/m+m2ZJqZTTWzlWa2wczWm9nFmW5TJpnZV8Kfkz+Z2c+ieIfdSAR9wh02PwAsBm4I76KZrwaB2919MXAR8Pk8/zwAvgSsz3QjssR3gN+4++nAOeTx52Jmc4AvAs3ufhbBtULXZ7ZV6ReJoCe1O2zmDXd/y91fCJcPEfwgJ9+ILm+YWSPwQeCBTLcl08xsCvAe4IcA7h5z9wOZbVXGFQHl4W3VKxi9+25kRCXoU7nDZl4ys/nAecBzmW1JRt0HfBUYznRDssACgtuT/Gs4lPWAmVVmulGZ4u47gXsJbuPyFnDQ3Z/IbJYv6KoAAAFGSURBVKvSLypBL+Mwsyrg/wBfdveuTLcnE8zsQ8Bed1+b6bZkiSKCGwt+z93PA3qAvD2nZWbTCP76XwDMBirN7MbMtir9ohL0qdxhM6+YWTFByP/U3X+R6fZk0CXA1Wa2lWBIb7mZ/SSzTcqoNqDN3eN/4a0kv+8o+17gTXdvd/cB4BfAuzLcprSLStCP3GHTzEoITqY8luE2ZYyZGcEY7Hp3/1am25NJ7n6Xuze6+3yC/xer3T1yPbZUuftuYIeZnRauuhx47RiHRN124CIzqwh/bi4ngienU7lNcdY72h02M9ysTLoEuAl41cxeCtf9jbuvymCbJHt8Afhp2CnaAnwqw+3JGHd/zsxWAi8QzFZ7kQjeDkG3QBARibioDN2IiMhRKOhFRCJOQS8iEnEKehGRiFPQi4hEnIJeRCTiFPQiIhH3/wEkgvEhlvaZDAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.evaluate(X_test, y_test)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "NSNK9zcwfpQc", + "outputId": "47ccee65-0885-4c7e-86bc-05cf390f69bd" + }, + "execution_count": 23, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "313/313 [==============================] - 1s 4ms/step - loss: 0.0326 - accuracy: 0.9894\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0.032551269978284836, 0.9894000291824341]" + ] + }, + "metadata": {}, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.metrics import confusion_matrix, classification_report\n", + "import numpy as np" + ], + "metadata": { + "id": "DRxul_2efpL3" + }, + "execution_count": 24, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "y_test.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "RnzBynjHfvNj", + "outputId": "820fc2b7-28d5-4e3f-906e-bf5b3502f06d" + }, + "execution_count": 25, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(10000, 10)" + ] + }, + "metadata": {}, + "execution_count": 25 + } + ] + }, + { + "cell_type": "code", + "source": [ + "y_true = np.argmax(y_test, axis=1)\n", + "y_pred = np.argmax(model.predict(X_test), axis=1)\n", + "\n", + "confusion_matrix(y_true, y_pred)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "fqD4k5PPfvHT", + "outputId": "d67d6653-cc41-4fbc-98f7-19bec5c78a93" + }, + "execution_count": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 977, 1, 0, 0, 0, 0, 0, 1, 1, 0],\n", + " [ 0, 1134, 1, 0, 0, 0, 0, 0, 0, 0],\n", + " [ 3, 1, 1023, 0, 0, 0, 0, 5, 0, 0],\n", + " [ 0, 0, 1, 1001, 0, 4, 0, 2, 2, 0],\n", + " [ 0, 0, 0, 0, 981, 0, 0, 0, 0, 1],\n", + " [ 2, 1, 0, 3, 0, 883, 1, 1, 0, 1],\n", + " [ 7, 3, 0, 0, 1, 5, 941, 0, 1, 0],\n", + " [ 0, 2, 2, 0, 0, 0, 0, 1020, 1, 3],\n", + " [ 8, 1, 4, 1, 3, 1, 1, 4, 946, 5],\n", + " [ 0, 2, 0, 0, 8, 3, 0, 8, 0, 988]])" + ] + }, + "metadata": {}, + "execution_count": 26 + } + ] + }, + { + "cell_type": "code", + "source": [ + "print(classification_report(y_true, y_pred))" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "k_ywfr01fvAv", + "outputId": "386065f9-6fac-4fea-c76f-f6dfc49718b6" + }, + "execution_count": 27, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.98 1.00 0.99 980\n", + " 1 0.99 1.00 0.99 1135\n", + " 2 0.99 0.99 0.99 1032\n", + " 3 1.00 0.99 0.99 1010\n", + " 4 0.99 1.00 0.99 982\n", + " 5 0.99 0.99 0.99 892\n", + " 6 1.00 0.98 0.99 958\n", + " 7 0.98 0.99 0.99 1028\n", + " 8 0.99 0.97 0.98 974\n", + " 9 0.99 0.98 0.98 1009\n", + "\n", + " accuracy 0.99 10000\n", + " macro avg 0.99 0.99 0.99 10000\n", + "weighted avg 0.99 0.99 0.99 10000\n", + "\n" + ] + } + ] + } + ] +}
\ No newline at end of file diff --git a/backend/microservice/classificationFCNN.ipynb b/backend/microservice/classificationFCNN.ipynb new file mode 100644 index 00000000..2f95f5e5 --- /dev/null +++ b/backend/microservice/classificationFCNN.ipynb @@ -0,0 +1,714 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "classificationFCNN.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "Dataset - Breast Cancer" + ], + "metadata": { + "id": "MDfw3VTykAm8" + } + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "f2CQaXKPjGwq" + }, + "outputs": [], + "source": [ + "from sklearn import datasets" + ] + }, + { + "cell_type": "code", + "source": [ + "data = datasets.load_breast_cancer()" + ], + "metadata": { + "id": "4Hy86U_XjO9p" + }, + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "data.data" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "sCnT365mjO6u", + "outputId": "3776c3de-94a4-4878-8a29-7b9310c76e3b" + }, + "execution_count": 3, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[1.799e+01, 1.038e+01, 1.228e+02, ..., 2.654e-01, 4.601e-01,\n", + " 1.189e-01],\n", + " [2.057e+01, 1.777e+01, 1.329e+02, ..., 1.860e-01, 2.750e-01,\n", + " 8.902e-02],\n", + " [1.969e+01, 2.125e+01, 1.300e+02, ..., 2.430e-01, 3.613e-01,\n", + " 8.758e-02],\n", + " ...,\n", + " [1.660e+01, 2.808e+01, 1.083e+02, ..., 1.418e-01, 2.218e-01,\n", + " 7.820e-02],\n", + " [2.060e+01, 2.933e+01, 1.401e+02, ..., 2.650e-01, 4.087e-01,\n", + " 1.240e-01],\n", + " [7.760e+00, 2.454e+01, 4.792e+01, ..., 0.000e+00, 2.871e-01,\n", + " 7.039e-02]])" + ] + }, + "metadata": {}, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "source": [ + "data.feature_names" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "YXPHkptgjO4b", + "outputId": "a277fb4a-c86e-402e-ae90-e303c34383e5" + }, + "execution_count": 4, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array(['mean radius', 'mean texture', 'mean perimeter', 'mean area',\n", + " 'mean smoothness', 'mean compactness', 'mean concavity',\n", + " 'mean concave points', 'mean symmetry', 'mean fractal dimension',\n", + " 'radius error', 'texture error', 'perimeter error', 'area error',\n", + " 'smoothness error', 'compactness error', 'concavity error',\n", + " 'concave points error', 'symmetry error',\n", + " 'fractal dimension error', 'worst radius', 'worst texture',\n", + " 'worst perimeter', 'worst area', 'worst smoothness',\n", + " 'worst compactness', 'worst concavity', 'worst concave points',\n", + " 'worst symmetry', 'worst fractal dimension'], dtype='<U23')" + ] + }, + "metadata": {}, + "execution_count": 4 + } + ] + }, + { + "cell_type": "code", + "source": [ + "data.data.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "53bpRNwijO2M", + "outputId": "c381ac0f-c5aa-4511-e03f-b825958be773" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(569, 30)" + ] + }, + "metadata": {}, + "execution_count": 5 + } + ] + }, + { + "cell_type": "code", + "source": [ + "len(data.feature_names)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "hTxes9kZjOz6", + "outputId": "9be7b161-a4d2-496b-d752-be21df20bbc6" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "30" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "source": [ + "data.target" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "XNxyf8vEjOxu", + "outputId": "08889df8-e11b-4d9f-8adf-69e97f0dd528" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0,\n", + " 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0,\n", + " 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1,\n", + " 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0,\n", + " 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,\n", + " 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1,\n", + " 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0,\n", + " 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0,\n", + " 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1,\n", + " 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1,\n", + " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1,\n", + " 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0,\n", + " 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,\n", + " 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,\n", + " 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1,\n", + " 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0,\n", + " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1,\n", + " 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,\n", + " 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,\n", + " 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1,\n", + " 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,\n", + " 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n", + " 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1])" + ] + }, + "metadata": {}, + "execution_count": 7 + } + ] + }, + { + "cell_type": "code", + "source": [ + "data.target.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "kDkRm9LTjOus", + "outputId": "ff8fbb76-c1da-4373-9abb-f73aae730d4a" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(569,)" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "source": [ + "X = data.data" + ], + "metadata": { + "id": "jh9xnFMpjOsi" + }, + "execution_count": 9, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "y = data.target" + ], + "metadata": { + "id": "7A1vI92IjOqZ" + }, + "execution_count": 10, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.model_selection import train_test_split" + ], + "metadata": { + "id": "-4a_vt_3jOoL" + }, + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=456, stratify=y)" + ], + "metadata": { + "id": "VUlV9t2GjOl1" + }, + "execution_count": 12, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "X_train.shape " + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "TiTqB9fyjOjh", + "outputId": "17e67972-9c23-4d05-ca6c-6a7ffeadb254" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(398, 30)" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_test.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "2SDafnC6jOgz", + "outputId": "02ff0cc0-ad64-4aa2-d30e-af3eba319e8a" + }, + "execution_count": 14, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(171, 30)" + ] + }, + "metadata": {}, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_train[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "hziBgpkPjOeM", + "outputId": "e67a0810-9f03-4c14-fb61-e9c05947a42d" + }, + "execution_count": 15, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([1.613e+01, 1.788e+01, 1.070e+02, 8.072e+02, 1.040e-01, 1.559e-01,\n", + " 1.354e-01, 7.752e-02, 1.998e-01, 6.515e-02, 3.340e-01, 6.857e-01,\n", + " 2.183e+00, 3.503e+01, 4.185e-03, 2.868e-02, 2.664e-02, 9.067e-03,\n", + " 1.703e-02, 3.817e-03, 2.021e+01, 2.726e+01, 1.327e+02, 1.261e+03,\n", + " 1.446e-01, 5.804e-01, 5.274e-01, 1.864e-01, 4.270e-01, 1.233e-01])" + ] + }, + "metadata": {}, + "execution_count": 15 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.preprocessing import StandardScaler" + ], + "metadata": { + "id": "tk64ph2VjObZ" + }, + "execution_count": 16, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "scaler = StandardScaler()\n", + "scaler.fit(X_train)\n", + "X_train = scaler.transform(X_train)\n", + "\n", + "X_test = scaler.transform(X_test)" + ], + "metadata": { + "id": "uZjD8KKCjOYj" + }, + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "X_train[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ESDQ_bqujOT5", + "outputId": "4205c1f2-4847-4424-8b27-c18aa11eb7dc" + }, + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 0.53569949, -0.32144709, 0.58344649, 0.40671395, 0.53185623,\n", + " 0.87858605, 0.52298087, 0.68280034, 0.67148343, 0.26905974,\n", + " -0.26699658, -0.95260858, -0.35390298, -0.11690941, -0.92389033,\n", + " 0.12784915, -0.20007137, -0.47113407, -0.42159193, -0.03806135,\n", + " 0.80695644, 0.27222786, 0.73958519, 0.67132174, 0.53767841,\n", + " 2.01780444, 1.17757981, 1.06284667, 2.20643957, 2.08111864])" + ] + }, + "metadata": {}, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Dense" + ], + "metadata": { + "id": "VgPyh0tmjlx0" + }, + "execution_count": 19, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "model = Sequential()\n", + "model.add(Dense(input_dim=X_train.shape[1], units=100, activation='relu'))\n", + "model.add(Dense(units=40, activation='relu'))\n", + "model.add(Dense(units=1, activation='sigmoid'))\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-WLXRER0jlvJ", + "outputId": "fdbee282-4e75-43cd-ea35-97fe6645e348" + }, + "execution_count": 20, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"sequential\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " dense (Dense) (None, 100) 3100 \n", + " \n", + " dense_1 (Dense) (None, 40) 4040 \n", + " \n", + " dense_2 (Dense) (None, 1) 41 \n", + " \n", + "=================================================================\n", + "Total params: 7,181\n", + "Trainable params: 7,181\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])" + ], + "metadata": { + "id": "tKVEZIc4jlrp" + }, + "execution_count": 21, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "history = model.fit(X_train, y_train, batch_size=64, epochs=20, validation_split=0.2)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-t53nj1YkUsN", + "outputId": "cb058b99-7ec4-4b6c-d12f-429c20524329" + }, + "execution_count": 23, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/20\n", + "5/5 [==============================] - 6s 64ms/step - loss: 0.5247 - accuracy: 0.7767 - val_loss: 0.4173 - val_accuracy: 0.9125\n", + "Epoch 2/20\n", + "5/5 [==============================] - 0s 11ms/step - loss: 0.3352 - accuracy: 0.9182 - val_loss: 0.3011 - val_accuracy: 0.9125\n", + "Epoch 3/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.2399 - accuracy: 0.9308 - val_loss: 0.2249 - val_accuracy: 0.9625\n", + "Epoch 4/20\n", + "5/5 [==============================] - 0s 13ms/step - loss: 0.1867 - accuracy: 0.9434 - val_loss: 0.1765 - val_accuracy: 0.9625\n", + "Epoch 5/20\n", + "5/5 [==============================] - 0s 15ms/step - loss: 0.1526 - accuracy: 0.9434 - val_loss: 0.1470 - val_accuracy: 0.9750\n", + "Epoch 6/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.1290 - accuracy: 0.9591 - val_loss: 0.1270 - val_accuracy: 0.9875\n", + "Epoch 7/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.1136 - accuracy: 0.9686 - val_loss: 0.1137 - val_accuracy: 0.9875\n", + "Epoch 8/20\n", + "5/5 [==============================] - 0s 11ms/step - loss: 0.1028 - accuracy: 0.9717 - val_loss: 0.1044 - val_accuracy: 0.9875\n", + "Epoch 9/20\n", + "5/5 [==============================] - 0s 11ms/step - loss: 0.0939 - accuracy: 0.9748 - val_loss: 0.0978 - val_accuracy: 0.9875\n", + "Epoch 10/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.0875 - accuracy: 0.9811 - val_loss: 0.0929 - val_accuracy: 0.9875\n", + "Epoch 11/20\n", + "5/5 [==============================] - 0s 17ms/step - loss: 0.0826 - accuracy: 0.9811 - val_loss: 0.0902 - val_accuracy: 0.9875\n", + "Epoch 12/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.0786 - accuracy: 0.9811 - val_loss: 0.0884 - val_accuracy: 0.9875\n", + "Epoch 13/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.0743 - accuracy: 0.9811 - val_loss: 0.0866 - val_accuracy: 0.9875\n", + "Epoch 14/20\n", + "5/5 [==============================] - 0s 13ms/step - loss: 0.0708 - accuracy: 0.9780 - val_loss: 0.0849 - val_accuracy: 0.9875\n", + "Epoch 15/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.0679 - accuracy: 0.9780 - val_loss: 0.0836 - val_accuracy: 0.9875\n", + "Epoch 16/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.0654 - accuracy: 0.9780 - val_loss: 0.0830 - val_accuracy: 0.9875\n", + "Epoch 17/20\n", + "5/5 [==============================] - 0s 13ms/step - loss: 0.0629 - accuracy: 0.9780 - val_loss: 0.0824 - val_accuracy: 0.9875\n", + "Epoch 18/20\n", + "5/5 [==============================] - 0s 13ms/step - loss: 0.0607 - accuracy: 0.9780 - val_loss: 0.0830 - val_accuracy: 0.9875\n", + "Epoch 19/20\n", + "5/5 [==============================] - 0s 12ms/step - loss: 0.0583 - accuracy: 0.9811 - val_loss: 0.0840 - val_accuracy: 0.9875\n", + "Epoch 20/20\n", + "5/5 [==============================] - 0s 13ms/step - loss: 0.0565 - accuracy: 0.9843 - val_loss: 0.0854 - val_accuracy: 0.9875\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "history.epoch" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "LqibdjMNjvJA", + "outputId": "6cb16230-6a15-4445-893d-5b544be5a75b" + }, + "execution_count": 24, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" + ] + }, + "metadata": {}, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from matplotlib import pyplot as plt" + ], + "metadata": { + "id": "rkC3nOHPjlo-" + }, + "execution_count": 25, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "epochs = history.epoch\n", + "plt.plot(epochs, history.history['loss'])\n", + "plt.plot(epochs, history.history['val_loss'])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 283 + }, + "id": "H1eJqmMyj4Yr", + "outputId": "8d611dd0-f0d7-49f2-8c37-834f7d667fa7" + }, + "execution_count": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x7f6720060410>]" + ] + }, + "metadata": {}, + "execution_count": 26 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "plt.plot(epochs, history.history['accuracy'])\n", + "plt.plot(epochs, history.history['val_accuracy'])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 283 + }, + "id": "kZxs-3kyj4UC", + "outputId": "5af03c64-2d39-466a-c526-88de3e862ef8" + }, + "execution_count": 27, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x7f67200d00d0>]" + ] + }, + "metadata": {}, + "execution_count": 27 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.evaluate(X_test, y_test, batch_size=64)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "3_3CjReGj4K5", + "outputId": "4408ca17-bb23-4454-a0e4-67210a16fe09" + }, + "execution_count": 28, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "3/3 [==============================] - 0s 8ms/step - loss: 0.0708 - accuracy: 0.9766\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0.07082781940698624, 0.9766082167625427]" + ] + }, + "metadata": {}, + "execution_count": 28 + } + ] + } + ] +}
\ No newline at end of file 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 diff --git a/backend/microservice/regressionFCNN.ipynb b/backend/microservice/regressionFCNN.ipynb new file mode 100644 index 00000000..470a9831 --- /dev/null +++ b/backend/microservice/regressionFCNN.ipynb @@ -0,0 +1,595 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "regressionFCNN.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "Dataset - Boston Housing" + ], + "metadata": { + "id": "8vzWlOHFi6el" + } + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "OnfiK4W-g9NC" + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.datasets import boston_housing" + ], + "metadata": { + "id": "f_siGNjyhNG4" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "(X_train, y_train), (X_test, y_test) = boston_housing.load_data()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "v6rzMZSahNEp", + "outputId": "b6f076c9-e69a-42b6-b1ca-d2c942efb684" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/boston_housing.npz\n", + "57344/57026 [==============================] - 0s 0us/step\n", + "65536/57026 [==================================] - 0s 0us/step\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_train.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "wJDkN70phNB5", + "outputId": "fef03e1d-595f-4e0c-9e48-cac1b7cf0c66" + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(404, 13)" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_test.shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "sZCvrECthM--", + "outputId": "c1b12abe-13d5-4b46-a67e-90aa7b613b4f" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(102, 13)" + ] + }, + "metadata": {}, + "execution_count": 7 + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_train[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9i8Ix3ZkhM8U", + "outputId": "1be03f2d-faf3-4856-9eb7-bc550d77c91e" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 1.23247, 0. , 8.14 , 0. , 0.538 , 6.142 ,\n", + " 91.7 , 3.9769 , 4. , 307. , 21. , 396.9 ,\n", + " 18.72 ])" + ] + }, + "metadata": {}, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "source": [ + "y_test" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "1a-jNd6KhM5a", + "outputId": "a54ce6e6-6462-4a0f-99c1-c13ebc47844a" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([ 7.2, 18.8, 19. , 27. , 22.2, 24.5, 31.2, 22.9, 20.5, 23.2, 18.6,\n", + " 14.5, 17.8, 50. , 20.8, 24.3, 24.2, 19.8, 19.1, 22.7, 12. , 10.2,\n", + " 20. , 18.5, 20.9, 23. , 27.5, 30.1, 9.5, 22. , 21.2, 14.1, 33.1,\n", + " 23.4, 20.1, 7.4, 15.4, 23.8, 20.1, 24.5, 33. , 28.4, 14.1, 46.7,\n", + " 32.5, 29.6, 28.4, 19.8, 20.2, 25. , 35.4, 20.3, 9.7, 14.5, 34.9,\n", + " 26.6, 7.2, 50. , 32.4, 21.6, 29.8, 13.1, 27.5, 21.2, 23.1, 21.9,\n", + " 13. , 23.2, 8.1, 5.6, 21.7, 29.6, 19.6, 7. , 26.4, 18.9, 20.9,\n", + " 28.1, 35.4, 10.2, 24.3, 43.1, 17.6, 15.4, 16.2, 27.1, 21.4, 21.5,\n", + " 22.4, 25. , 16.6, 18.6, 22. , 42.8, 35.1, 21.5, 36. , 21.9, 24.1,\n", + " 50. , 26.7, 25. ])" + ] + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from sklearn.preprocessing import StandardScaler" + ], + "metadata": { + "id": "c9ETzZu-hMzb" + }, + "execution_count": 10, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "scaler = StandardScaler()\n", + "scaler.fit(X_train)\n", + "X_train = scaler.transform(X_train)\n", + "X_test = scaler.transform(X_test)" + ], + "metadata": { + "id": "VUb0qQR7hepF" + }, + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "X_train[0]" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "Qhjccz_whemx", + "outputId": "083f4f0b-1295-43c9-b6ac-2160f909dc50" + }, + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([-0.27224633, -0.48361547, -0.43576161, -0.25683275, -0.1652266 ,\n", + " -0.1764426 , 0.81306188, 0.1166983 , -0.62624905, -0.59517003,\n", + " 1.14850044, 0.44807713, 0.8252202 ])" + ] + }, + "metadata": {}, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_test" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "lQcbYns7hejc", + "outputId": "32eccf17-3220-44f8-bfa7-ae6300a3f41e" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[ 1.55369355, -0.48361547, 1.0283258 , ..., 0.78447637,\n", + " -3.48459553, 2.25092074],\n", + " [-0.39242675, -0.48361547, -0.16087773, ..., -0.30759583,\n", + " 0.42733126, 0.47880119],\n", + " [-0.39982927, -0.48361547, -0.86940196, ..., 0.78447637,\n", + " 0.44807713, -0.41415936],\n", + " ...,\n", + " [-0.20709507, -0.48361547, 1.24588095, ..., -1.71818909,\n", + " 0.37051949, -1.49344089],\n", + " [-0.36698601, -0.48361547, -0.72093526, ..., -0.48960787,\n", + " 0.39275481, -0.41829982],\n", + " [-0.0889679 , -0.48361547, 1.24588095, ..., -1.71818909,\n", + " -1.21946544, -0.40449827]])" + ] + }, + "metadata": {}, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.models import Sequential\n", + "from tensorflow.keras.layers import Dense" + ], + "metadata": { + "id": "WbQA9y9BioPi" + }, + "execution_count": 15, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "model = Sequential()\n", + "model.add(Dense(input_dim=X_train.shape[1], units=100, activation='relu'))\n", + "# model.add(Dense(input_dim=X_train.shape[1], units=50, activation='relu'))\n", + "model.add(Dense(units=1))\n", + "model.summary()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "eiH9Y1P8heg4", + "outputId": "62018b2b-f765-43a9-f487-6e3fd733e6e7" + }, + "execution_count": 16, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Model: \"sequential\"\n", + "_________________________________________________________________\n", + " Layer (type) Output Shape Param # \n", + "=================================================================\n", + " dense (Dense) (None, 100) 1400 \n", + " \n", + " dense_1 (Dense) (None, 1) 101 \n", + " \n", + "=================================================================\n", + "Total params: 1,501\n", + "Trainable params: 1,501\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.compile(optimizer='adam', loss='mse', metrics=['mae'])" + ], + "metadata": { + "id": "lr0HPSnyhedp" + }, + "execution_count": 17, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "history = model.fit(X_train, y_train, batch_size=32, epochs=20, validation_split=0.2)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "DmNuBukshp9P", + "outputId": "804ec2d0-ba5c-4f29-d0ce-ea9ce7ca5a6a" + }, + "execution_count": 18, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/20\n", + "11/11 [==============================] - 3s 22ms/step - loss: 557.1730 - mae: 21.9147 - val_loss: 609.2063 - val_mae: 23.0475\n", + "Epoch 2/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 532.9012 - mae: 21.3854 - val_loss: 585.1005 - val_mae: 22.5338\n", + "Epoch 3/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 509.3247 - mae: 20.8655 - val_loss: 560.5905 - val_mae: 22.0077\n", + "Epoch 4/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 486.2475 - mae: 20.3399 - val_loss: 535.8640 - val_mae: 21.4625\n", + "Epoch 5/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 461.9990 - mae: 19.7867 - val_loss: 509.6354 - val_mae: 20.8769\n", + "Epoch 6/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 436.3251 - mae: 19.1894 - val_loss: 481.8866 - val_mae: 20.2395\n", + "Epoch 7/20\n", + "11/11 [==============================] - 0s 8ms/step - loss: 410.0367 - mae: 18.5537 - val_loss: 453.0820 - val_mae: 19.5479\n", + "Epoch 8/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 382.7516 - mae: 17.8715 - val_loss: 423.8254 - val_mae: 18.8088\n", + "Epoch 9/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 354.5889 - mae: 17.1212 - val_loss: 392.0852 - val_mae: 17.9759\n", + "Epoch 10/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 325.2735 - mae: 16.2985 - val_loss: 360.8828 - val_mae: 17.1014\n", + "Epoch 11/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 295.4146 - mae: 15.4205 - val_loss: 329.8161 - val_mae: 16.1668\n", + "Epoch 12/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 266.6942 - mae: 14.5040 - val_loss: 299.9690 - val_mae: 15.2050\n", + "Epoch 13/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 238.4964 - mae: 13.5476 - val_loss: 270.8452 - val_mae: 14.2164\n", + "Epoch 14/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 211.5596 - mae: 12.5503 - val_loss: 243.2032 - val_mae: 13.1773\n", + "Epoch 15/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 186.9801 - mae: 11.5573 - val_loss: 217.9993 - val_mae: 12.1424\n", + "Epoch 16/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 165.2683 - mae: 10.6563 - val_loss: 195.9235 - val_mae: 11.2217\n", + "Epoch 17/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 145.9631 - mae: 9.8479 - val_loss: 176.3322 - val_mae: 10.4139\n", + "Epoch 18/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 129.5782 - mae: 9.1388 - val_loss: 159.7129 - val_mae: 9.7597\n", + "Epoch 19/20\n", + "11/11 [==============================] - 0s 6ms/step - loss: 115.6311 - mae: 8.5268 - val_loss: 144.8544 - val_mae: 9.1716\n", + "Epoch 20/20\n", + "11/11 [==============================] - 0s 7ms/step - loss: 103.5382 - mae: 7.9529 - val_loss: 131.3257 - val_mae: 8.6467\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from matplotlib import pyplot as plt" + ], + "metadata": { + "id": "8nhJUJKLiyVW" + }, + "execution_count": 20, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "plt.plot(history.epoch, history.history['loss'])\n", + "plt.plot(history.epoch, history.history['val_loss'])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 283 + }, + "id": "dfYbEqEahs7a", + "outputId": "ae03afb2-ce90-4d04-8ae1-6d08dd6c4d54" + }, + "execution_count": 21, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x7f54e056a4d0>]" + ] + }, + "metadata": {}, + "execution_count": 21 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "plt.plot(history.epoch, history.history['mae'])\n", + "plt.plot(history.epoch, history.history['val_mae'])" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 283 + }, + "id": "rr6zjCGFhtu4", + "outputId": "8deb985f-28fa-4f87-c55c-25c577247769" + }, + "execution_count": 22, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x7f54e0132d50>]" + ] + }, + "metadata": {}, + "execution_count": 22 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.evaluate(X_test, y_test)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "-MmP-D5phwcq", + "outputId": "9c1fbb91-1614-47d8-ccff-a34fbf56e949" + }, + "execution_count": 23, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "4/4 [==============================] - 0s 4ms/step - loss: 113.3174 - mae: 8.8532\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[113.3174057006836, 8.853187561035156]" + ] + }, + "metadata": {}, + "execution_count": 23 + } + ] + }, + { + "cell_type": "code", + "source": [ + "model.save('models/boston.hdf5')\n", + "# model.save_weight()" + ], + "metadata": { + "id": "OAySS7O0hy4-" + }, + "execution_count": 24, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.models import load_model" + ], + "metadata": { + "id": "xQmG2F0Ph08v" + }, + "execution_count": 25, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "old_model = load_model('models/boston.hdf5')" + ], + "metadata": { + "id": "Qp_jE9Fxh3cl" + }, + "execution_count": 26, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "x_new = np.random.rand(X_train.shape[1])\n", + "x_new = x_new.reshape(1, -1)\n", + "x_new.shape\n", + "# Za nove podatke koristi se predict tako da se dobije predvidjena vrednost za y\n", + "old_model.predict(x_new)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "yOyueyFmh4CJ", + "outputId": "d56f0b37-cedc-4456-a527-499b9ff68d7d" + }, + "execution_count": 27, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "array([[5.2812877]], dtype=float32)" + ] + }, + "metadata": {}, + "execution_count": 27 + } + ] + } + ] +}
\ No newline at end of file |