├── Bayes.jl ├── LICENSE ├── README.md ├── neuronal ├── Boltzmann.jl ├── DAM.jl ├── Hopfield.jl ├── HopfieldAsc.jl ├── RNN.jl ├── XOR.jl ├── autoencoder.jl ├── conv.jl ├── feedforward │ ├── feedforward.jl │ └── perceptron.jl ├── image │ └── u_net.jl └── variational.jl ├── optimization ├── SA.jl ├── amoeba.jl ├── ants.jl ├── genetic.jl └── swarm.jl ├── reinforced ├── A2C.jl ├── A2C │ └── main.cpp ├── DDPG.jl ├── PPO.jl ├── Q.f90 ├── Q.jl ├── REINFORCE.jl ├── REINFORCE │ ├── Gaussian.cpp │ └── Softmax.cpp ├── SARSA.f90 ├── SARSA.jl ├── SARSA.py ├── conjgrad.jl ├── deepQ.jl ├── deepQ │ ├── makefile │ └── source │ │ ├── activ.f90 │ │ ├── deepQ.f90 │ │ ├── layer.f90 │ │ ├── loss.f90 │ │ └── neural.f90 └── regret.py ├── statistics └── KDE.jl ├── supervised ├── classification │ ├── forest.jl │ ├── knn.jl │ ├── logistic.jl │ ├── logistic.py │ ├── tree.jl │ └── tree.py └── regression │ ├── Anscombe.py │ ├── Gaussian.jl │ ├── LARS.jl │ ├── LARS.py │ ├── LM.jl │ ├── LM.py │ ├── Simpson.py │ ├── linear.jl │ ├── linear.py │ ├── mlinear.jl │ ├── mlinear.py │ └── stagewise.py └── unsupervised ├── clustering ├── AGNES.jl ├── DBSCAN.jl ├── DIANA.jl ├── PAM.jl ├── dbscan.py ├── imgKMeans.jl ├── kmeans.f90 ├── kmeans.jl ├── kmeans.py ├── kmedoids.f90 ├── kmedoids.py └── spectral.jl ├── dimensionality ├── ICA.jl ├── KPCA.jl └── PCA.jl └── vector ├── LVQ.jl ├── SOM.jl ├── SOM.py ├── gas.jl ├── gas.py └── growing_gas.jl /Bayes.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | function muvar(M) 4 | N, = size(M) 5 | x1 = [] 6 | x2 = [] 7 | y1 = [] 8 | y2 = [] 9 | 10 | # First pass: mean 11 | μₚʸ = 0 12 | μₚⁿ = 0 13 | μᵥʸ = 0 14 | μᵥⁿ = 0 15 | n = 0 16 | 17 | for i in 1:N 18 | if (M[i,3] == 1) 19 | push!(x1,M[i,1]) 20 | push!(x2,M[i,2]) 21 | 22 | μₚʸ += M[i,1] 23 | μᵥʸ += M[i,2] 24 | n += 1 25 | else 26 | push!(y1,M[i,1]) 27 | push!(y2,M[i,2]) 28 | 29 | μₚⁿ += M[i,1] 30 | μᵥⁿ += M[i,2] 31 | end 32 | end 33 | 34 | μₚʸ /= n 35 | μₚⁿ /= (N-n) 36 | μᵥʸ /= n 37 | μᵥⁿ /= (N-n) 38 | 39 | # Second pass: variance 40 | σ²ₚʸ = 0 41 | σ²ₚⁿ = 0 42 | σ²ᵥʸ = 0 43 | σ²ᵥⁿ = 0 44 | 45 | for i in 1:N 46 | if (M[i,3] == 1) 47 | σ²ₚʸ += (M[i,1] - μₚʸ)^2 48 | σ²ᵥʸ += (M[i,2] - μᵥʸ)^2 49 | else 50 | σ²ₚⁿ += (M[i,1] - μₚⁿ)^2 51 | σ²ᵥⁿ += (M[i,2] - μᵥⁿ)^2 52 | end 53 | end 54 | 55 | σ²ₚʸ /= (n-1) 56 | σ²ₚⁿ /= (N-n-1) 57 | σ²ᵥʸ /= (n-1) 58 | σ²ᵥⁿ /= (N-n-1) 59 | 60 | return [μₚʸ,μₚⁿ,μᵥʸ,μᵥⁿ,σ²ₚʸ,σ²ₚⁿ,σ²ᵥʸ,σ²ᵥⁿ] 61 | end 62 | 63 | function Gaussian(x,μ,σ²) 64 | return exp(-(x-μ)^2/(2σ²))/sqrt(2π*σ²) 65 | end 66 | 67 | function Classifier(price,volume,p) 68 | μₚʸ,μₚⁿ,μᵥʸ,μᵥⁿ,σ²ₚʸ,σ²ₚⁿ,σ²ᵥʸ,σ²ᵥⁿ = p 69 | 70 | P_buy = Gaussian(price,μₚʸ,σ²ₚʸ)*Gaussian(volume,μᵥʸ,σ²ᵥʸ) 71 | P_not = Gaussian(price,μₚⁿ,σ²ₚⁿ)*Gaussian(volume,μᵥⁿ,σ²ᵥⁿ) 72 | 73 | if P_buy > P_not 74 | return 1 75 | else 76 | return 0 77 | end 78 | end 79 | 80 | M = [10.3 100 0; 81 | 9.5 50 1; 82 | 11.5 90 0; 83 | 5.5 30 1; 84 | 7.5 120 1; 85 | 12.2 40 0; 86 | 7.1 80 1; 87 | 10.5 65 0] 88 | 89 | N, = size(M) 90 | x1 = [] 91 | x2 = [] 92 | y1 = [] 93 | y2 = [] 94 | 95 | for i in 1:N 96 | if (M[i,3] == 1) 97 | push!(x1,M[i,1]) 98 | push!(x2,M[i,2]) 99 | else 100 | push!(y1,M[i,1]) 101 | push!(y2,M[i,2]) 102 | end 103 | end 104 | 105 | par = muvar(M) 106 | 107 | p_sp = LinRange(5.2,12.5,100) 108 | v_sp = LinRange(25.6,124.4,100) 109 | K = zeros(100,100) 110 | 111 | for i in 1:100 112 | p = p_sp[i] 113 | for j in 1:100 114 | v = v_sp[j] 115 | K[j,i] = Classifier(p,v,par) 116 | end 117 | end 118 | 119 | contourf(p_sp,v_sp,K,alpha=0.5) 120 | 121 | # plotting 122 | #println("Buy") 123 | #println(" mu_p: ",μₚʸ,", var_p: ",σ²ₚʸ,", mu_v: ",μᵥʸ,", var_v: ",σ²ᵥʸ) 124 | #println("Don't") 125 | #println(" mu_p: ",μₚⁿ,", var_p: ",σ²ₚⁿ,", mu_v: ",μᵥⁿ,", var_v: ",σ²ᵥⁿ) 126 | 127 | plot(x1,x2,"s",color="blue") 128 | plot(y1,y2,"o",color="orange") 129 | xlabel("Price") 130 | ylabel("Volume") 131 | show() 132 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Carlo R. da Cunha 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MachineLearning 2 | 3 | 4 | 5 | The collection of Julia scripts for the book: C. R. da Cunha, "Machine Learning for the Physical Sciences: Fundamentals and Prototyping with Julia" (2023) CRC Press. 6 | 7 | 8 | 9 | [![Generic badge](https://img.shields.io/badge/GitHub-StxGuy/MachineLearning-.svg)](https://github.com/StxGuy/MachineLearning) 10 | 11 | 12 | ## Credits 13 | 14 | @book{daCunha2021, 15 | title = "Machine Learning for the Physical Sciences: Fundamentals and Prototyping with Julia", 16 | author = "da Cunha, Carlo R.", 17 | year = 2023, 18 | publisher = "CRC Press", 19 | address = "Boca Raton, FL", 20 | url = {https://github.com/StxGuy/MachineLearning} 21 | } 22 | 23 | ## License 24 | 25 | Copyright (c) 2022 - Carlo R. da Cunha. \ 26 | 27 | -------------------------------------------------------------------------------- /neuronal/Boltzmann.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using PyPlot 3 | 4 | p0 = [1 1 1; 5 | 1 0 1; 6 | 1 0 1; 7 | 1 0 1; 8 | 1 1 1] 9 | p0 = reshape(p0,15,1) 10 | 11 | p1 = [0 0 1; 12 | 0 1 1; 13 | 0 0 1; 14 | 0 0 1; 15 | 0 0 1] 16 | p1 = reshape(p1,15,1) 17 | 18 | p2 = [1 1 1; 19 | 0 0 1; 20 | 0 1 0; 21 | 1 0 0; 22 | 1 1 1] 23 | p2 = reshape(p2,15,1) 24 | 25 | p3 = [1 1 1; 26 | 0 0 1; 27 | 0 1 1; 28 | 0 0 1; 29 | 1 1 1] 30 | p3 = reshape(p3,15,1) 31 | 32 | p4 = [1 0 1; 33 | 1 0 1; 34 | 1 1 1; 35 | 0 0 1; 36 | 0 0 1] 37 | p4 = reshape(p4,15,1) 38 | 39 | p5 = [1 1 1; 40 | 1 0 0; 41 | 1 1 1; 42 | 0 0 1; 43 | 1 1 1] 44 | p5 = reshape(p5,15,1) 45 | 46 | p6 = [1 0 0; 47 | 1 0 0; 48 | 1 1 1; 49 | 1 0 1; 50 | 1 1 1] 51 | p6 = reshape(p6,15,1) 52 | 53 | p7 = [1 1 1; 54 | 0 0 1; 55 | 0 1 0; 56 | 0 1 0; 57 | 0 1 0] 58 | p7 = reshape(p7,15,1) 59 | 60 | p8 = [1 1 1; 61 | 1 0 1; 62 | 0 1 0; 63 | 1 0 1; 64 | 1 1 1] 65 | p8 = reshape(p8,15,1) 66 | 67 | p9 = [1 1 1; 68 | 1 0 1; 69 | 1 1 1; 70 | 0 0 1 71 | 0 0 1] 72 | p9 = reshape(p9,15,1) 73 | 74 | training_set = [p0 p1 p2 p3 p4 p5 p6 p7 p8 p9] 75 | 76 | 77 | function σ(x) 78 | return 1/(1+exp(-x)) 79 | end 80 | 81 | # Training 82 | function train(b,c,W,tset) 83 | η = 1E-3 84 | N = size(W,1) 85 | h = zeros(N,1) 86 | x = zeros(N,1) 87 | 88 | ε = 0 89 | for s in eachcol(tset) 90 | # Set hidden layer 91 | for i in 1:N 92 | p = σ(c[i] + W[i,:]·s) 93 | if (rand() < p) 94 | h[i] = 1 95 | else 96 | h[i] = 0 97 | end 98 | end 99 | 100 | # Reconstruct visible layer 101 | for i in 1:N 102 | p = σ(b[i] + h·W[:,i]) 103 | if (rand() < p) 104 | x[i] = 1 105 | else 106 | x[i] = 0 107 | end 108 | end 109 | 110 | # Estimate gradients 111 | y0 = σ.(c + W*s) 112 | y1 = σ.(c + W*x) 113 | 114 | ∇b = s - x 115 | ∇c = y0 - y1 116 | ∇W = s*transpose(y0) - x*transpose(y1) 117 | 118 | # Improve parameters 119 | b += η*∇b 120 | c += η*∇c 121 | W += η*transpose(∇W) 122 | 123 | # Calculate error 124 | ε += -b·s - c·h - h·(W*s) 125 | end 126 | 127 | ε /= size(tset,2) 128 | 129 | return b,c,W,ε 130 | end 131 | 132 | N = 15 133 | c = zeros(N,1) 134 | b = zeros(N,1) 135 | W = randn(N,N) 136 | 137 | for it in 1:100000 138 | global b,c,W,ε = train(b,c,W,training_set) 139 | println(ε) 140 | end 141 | 142 | s = [1 1 0; 143 | 0 0 1; 144 | 0 1 0; 145 | 1 1 0; 146 | 0 1 1] 147 | 148 | s = reshape(s,15,1) 149 | x = reshape(s,5,3) 150 | imshow(x) 151 | show() 152 | 153 | h = σ.(W*s + b) 154 | s = σ.(transpose(W)*h + c) 155 | x = reshape(s,5,3) 156 | imshow(x) 157 | show() 158 | 159 | 160 | -------------------------------------------------------------------------------- /neuronal/DAM.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using PyPlot 3 | 4 | p0 = [1 1 1; 5 | 1 0 1; 6 | 1 0 1; 7 | 1 0 1; 8 | 1 1 1] 9 | p0 = reshape(2*(p0 .- 0.5),15,1) 10 | 11 | p1 = [0 0 1; 12 | 0 1 1; 13 | 0 0 1; 14 | 0 0 1; 15 | 0 0 1] 16 | p1 = reshape(2*(p1 .- 0.5),15,1) 17 | 18 | p2 = [1 1 1; 19 | 0 0 1; 20 | 0 1 0; 21 | 1 0 0; 22 | 1 1 1] 23 | p2 = reshape(2*(p2 .- 0.5),15,1) 24 | 25 | p3 = [1 1 1; 26 | 0 0 1; 27 | 0 1 1; 28 | 0 0 1; 29 | 1 1 1] 30 | p3 = reshape(2*(p3 .- 0.5),15,1) 31 | 32 | p4 = [1 0 1; 33 | 1 0 1; 34 | 1 1 1; 35 | 0 0 1; 36 | 0 0 1] 37 | p4 = reshape(2*(p4 .- 0.5),15,1) 38 | 39 | p5 = [1 1 1; 40 | 1 0 0; 41 | 1 1 1; 42 | 0 0 1; 43 | 1 1 1] 44 | p5 = reshape(2*(p5 .- 0.5),15,1) 45 | 46 | p6 = [1 0 0; 47 | 1 0 0; 48 | 1 1 1; 49 | 1 0 1; 50 | 1 1 1] 51 | p6 = reshape(2*(p6 .- 0.5),15,1) 52 | 53 | p7 = [1 1 1; 54 | 0 0 1; 55 | 0 1 0; 56 | 0 1 0; 57 | 0 1 0] 58 | p7 = reshape(2*(p7 .- 0.5),15,1) 59 | 60 | p8 = [1 1 1; 61 | 1 0 1; 62 | 0 1 0; 63 | 1 0 1; 64 | 1 1 1] 65 | p8 = reshape(2*(p8 .- 0.5),15,1) 66 | 67 | p9 = [1 1 1; 68 | 1 0 1; 69 | 1 1 1; 70 | 0 0 1 71 | 0 0 1] 72 | p9 = reshape(2*(p9 .- 0.5),15,1) 73 | 74 | W = transpose([p0 p1 p2 p3 p4 p5 p6 p7 p8 p9]) 75 | 76 | function sgn(x) 77 | if (x > 0) 78 | return 1 79 | else 80 | return -1 81 | end 82 | end 83 | 84 | function softmax(x) 85 | m = maximum(x) 86 | 87 | S = 0 88 | for xi in x 89 | S += exp(xi-m) 90 | end 91 | 92 | return exp.(x .- m)/S 93 | end 94 | 95 | 96 | # Output 97 | s = [1 1 0; 98 | 0 0 1; 99 | 0 1 0; 100 | 1 1 0; 101 | 0 1 1] 102 | s = reshape(2*(s .- 0.5),15,1) 103 | 104 | β = 0.9 105 | for it in 1:8 106 | x = reshape(s,5,3) 107 | imshow(x) 108 | show() 109 | 110 | h = β*W*s 111 | global s = (transpose(W)*softmax(h)) 112 | end 113 | 114 | 115 | -------------------------------------------------------------------------------- /neuronal/Hopfield.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using PyPlot 3 | 4 | p0 = [1 1 1; 5 | 1 0 1; 6 | 1 0 1; 7 | 1 0 1; 8 | 1 1 1] 9 | p0 = reshape(2*(p0 .- 0.5),15,1) 10 | 11 | p1 = [0 0 1; 12 | 0 1 1; 13 | 0 0 1; 14 | 0 0 1; 15 | 0 0 1] 16 | p1 = reshape(2*(p1 .- 0.5),15,1) 17 | 18 | p2 = [1 1 1; 19 | 0 0 1; 20 | 0 1 0; 21 | 1 0 0; 22 | 1 1 1] 23 | p2 = reshape(2*(p2 .- 0.5),15,1) 24 | 25 | p3 = [1 1 1; 26 | 0 0 1; 27 | 0 1 1; 28 | 0 0 1; 29 | 1 1 1] 30 | p3 = reshape(2*(p3 .- 0.5),15,1) 31 | 32 | p4 = [1 0 1; 33 | 1 0 1; 34 | 1 1 1; 35 | 0 0 1; 36 | 0 0 1] 37 | p4 = reshape(2*(p4 .- 0.5),15,1) 38 | 39 | p5 = [1 1 1; 40 | 1 0 0; 41 | 1 1 1; 42 | 0 0 1; 43 | 1 1 1] 44 | p5 = reshape(2*(p5 .- 0.5),15,1) 45 | 46 | p6 = [1 0 0; 47 | 1 0 0; 48 | 1 1 1; 49 | 1 0 1; 50 | 1 1 1] 51 | p6 = reshape(2*(p6 .- 0.5),15,1) 52 | 53 | p7 = [1 1 1; 54 | 0 0 1; 55 | 0 1 0; 56 | 0 1 0; 57 | 0 1 0] 58 | p7 = reshape(2*(p7 .- 0.5),15,1) 59 | 60 | p8 = [1 1 1; 61 | 1 0 1; 62 | 0 1 0; 63 | 1 0 1; 64 | 1 1 1] 65 | p8 = reshape(2*(p8 .- 0.5),15,1) 66 | 67 | p9 = [1 1 1; 68 | 1 0 1; 69 | 1 1 1; 70 | 0 0 1 71 | 0 0 1] 72 | p9 = reshape(2*(p9 .- 0.5),15,1) 73 | 74 | patterns = [p0 p1 p2]# p3 p4 p5 p6 p7 p8 p9] 75 | 76 | function sgn(x) 77 | if (x > 0) 78 | return 1 79 | else 80 | return -1 81 | end 82 | end 83 | 84 | # Training 85 | W = zeros(15,15) 86 | for x in eachcol(patterns) 87 | global W += (x*transpose(x) - I) 88 | end 89 | W /= size(patterns,1) 90 | 91 | # Output 92 | s = [1 1 0; 93 | 0 0 1; 94 | 0 1 0; 95 | 1 1 0; 96 | 0 1 1] 97 | s = reshape(2*(s .- 0.5),15,1) 98 | 99 | for it in 1:5 100 | x = reshape(s,5,3) 101 | imshow(x) 102 | show() 103 | global s = sgn.(W*s) 104 | end 105 | 106 | 107 | -------------------------------------------------------------------------------- /neuronal/HopfieldAsc.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using PyPlot 3 | 4 | p0 = [1 1 1; 5 | 1 0 1; 6 | 1 0 1; 7 | 1 0 1; 8 | 1 1 1] 9 | p0 = reshape(2*(p0 .- 0.5),15,1) 10 | 11 | p1 = [0 0 1; 12 | 0 1 1; 13 | 0 0 1; 14 | 0 0 1; 15 | 0 0 1] 16 | p1 = reshape(2*(p1 .- 0.5),15,1) 17 | 18 | p2 = [1 1 1; 19 | 0 0 1; 20 | 0 1 0; 21 | 1 0 0; 22 | 1 1 1] 23 | p2 = reshape(2*(p2 .- 0.5),15,1) 24 | 25 | p3 = [1 1 1; 26 | 0 0 1; 27 | 0 1 1; 28 | 0 0 1; 29 | 1 1 1] 30 | p3 = reshape(2*(p3 .- 0.5),15,1) 31 | 32 | p4 = [1 0 1; 33 | 1 0 1; 34 | 1 1 1; 35 | 0 0 1; 36 | 0 0 1] 37 | p4 = reshape(2*(p4 .- 0.5),15,1) 38 | 39 | p5 = [1 1 1; 40 | 1 0 0; 41 | 1 1 1; 42 | 0 0 1; 43 | 1 1 1] 44 | p5 = reshape(2*(p5 .- 0.5),15,1) 45 | 46 | p6 = [1 0 0; 47 | 1 0 0; 48 | 1 1 1; 49 | 1 0 1; 50 | 1 1 1] 51 | p6 = reshape(2*(p6 .- 0.5),15,1) 52 | 53 | p7 = [1 1 1; 54 | 0 0 1; 55 | 0 1 0; 56 | 0 1 0; 57 | 0 1 0] 58 | p7 = reshape(2*(p7 .- 0.5),15,1) 59 | 60 | p8 = [1 1 1; 61 | 1 0 1; 62 | 0 1 0; 63 | 1 0 1; 64 | 1 1 1] 65 | p8 = reshape(2*(p8 .- 0.5),15,1) 66 | 67 | p9 = [1 1 1; 68 | 1 0 1; 69 | 1 1 1; 70 | 0 0 1 71 | 0 0 1] 72 | p9 = reshape(2*(p9 .- 0.5),15,1) 73 | 74 | patterns = [p0 p1 p2]# p3 p4 p5 p6 p7 p8 p9] 75 | 76 | function sgn(x) 77 | if (x > 0) 78 | return 1 79 | else 80 | return -1 81 | end 82 | end 83 | 84 | # Training 85 | W = zeros(15,15) 86 | for x in eachcol(patterns) 87 | global W += (x*transpose(x) - I) 88 | end 89 | W /= size(patterns,1) 90 | 91 | # Output 92 | s = [1 1 0; 93 | 0 0 1; 94 | 0 1 0; 95 | 1 1 0; 96 | 0 1 1] 97 | s = reshape(2*(s .- 0.5),15,1) 98 | 99 | Energy1 = (-0.5*s'*W*s)[1] 100 | 101 | while(Energy1 > -8) 102 | println(Energy1) 103 | 104 | x = reshape(s,5,3) 105 | imshow(x) 106 | show() 107 | 108 | p = rand(1:15) 109 | t = copy(s) 110 | t[p] = -t[p] 111 | Energy2 = (-0.5*t'*W*t)[1] 112 | 113 | if (Energy2 < Energy1) 114 | global s = copy(t) 115 | global Energy1 = Energy2 116 | end 117 | end 118 | 119 | 120 | -------------------------------------------------------------------------------- /neuronal/RNN.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using PyPlot 3 | 4 | #---------------------------# 5 | # MODEL # 6 | #---------------------------# 7 | # Dense Layer 8 | mutable struct ElmanLayer 9 | Wh :: Matrix 10 | Uh :: Matrix 11 | bh :: Matrix 12 | 13 | Wy :: Matrix 14 | by :: Matrix 15 | 16 | act :: String 17 | 18 | is :: Int 19 | os :: Int 20 | hs :: Int 21 | end 22 | 23 | 24 | # Architecture 25 | mutable struct NeuralNetwork 26 | Layers :: Vector{ElmanLayer} 27 | loss :: String 28 | end 29 | 30 | #-------------------------# 31 | # Dense Layer Initializer # 32 | #-------------------------# 33 | function Elman(in_size,out_size,act) 34 | h_size = (in_size + out_size)÷2 35 | 36 | Wh = (rand(h_size,in_size).-0.5)./h_size 37 | Uh = (rand(h_size,h_size).-0.5)./h_size 38 | bh = zeros(h_size,1) 39 | 40 | Wy = (rand(out_size,h_size).-0.5)./out_size 41 | by = zeros(out_size,1) 42 | 43 | x = zeros(in_size,1) 44 | h1 = zeros(h_size,1) 45 | 46 | return ElmanLayer(Wh,Uh,bh,Wy,by,act,in_size,out_size,h_size) 47 | end 48 | 49 | #-----------------------------------# 50 | # Activation/deActivation Functions # 51 | #-----------------------------------# 52 | function sigmoid(x) 53 | return 1.0/(1.0 + exp(-x)) 54 | end 55 | 56 | # Activate # 57 | function σ(y,act) 58 | if (act == "tanh") 59 | z = tanh.(y) 60 | end 61 | if (act == "sig") 62 | z = sigmoid.(y) 63 | end 64 | 65 | return z 66 | end 67 | 68 | # Softmax # 69 | function softmax(y) 70 | ymax = maximum(y) 71 | s = sum(exp.(y.-ymax)) 72 | z = exp.(y.-ymax)/s 73 | 74 | return z 75 | end 76 | 77 | # Deactivate # 78 | function dσ(z,act) 79 | if (act == "tanh") 80 | D = 1.0 .- z.^2 81 | end 82 | if (act == "sig") 83 | D = z .* (1.0 .- z) 84 | end 85 | 86 | return Diagonal(D[:,1]) 87 | end 88 | 89 | #-------------------------# 90 | # FeedForward Dense Layer # 91 | #-------------------------# 92 | function forwardElman!(x,h1,layer :: ElmanLayer) 93 | k = layer.Wh*x + layer.Uh*h1 + layer.bh 94 | h = σ(k,layer.act) 95 | 96 | y = layer.Wy*h + layer.by 97 | 98 | return h,k,y 99 | end 100 | 101 | function decode(x) 102 | p = argmax(x) 103 | 104 | if (p[1] == 4) 105 | s = "F" 106 | elseif (p[1] == 3) 107 | s = "=" 108 | elseif (p[1] == 2) 109 | s = "m" 110 | else 111 | s = "a" 112 | end 113 | end 114 | 115 | function feedForward(input_vector,layer :: ElmanLayer,print) 116 | z_vector = [] 117 | k_vector = [] 118 | x_vector = [] 119 | h = zeros(layer.hs,1) 120 | for row in eachrow(input_vector) 121 | x = convert(Matrix,reshape(row,layer.is,1)) 122 | h,k,y = forwardElman!(x,h,layer) 123 | z = softmax(y) 124 | 125 | push!(x_vector,x) 126 | push!(z_vector,z) 127 | push!(k_vector,k) 128 | if (print) 129 | println(decode(x)," -> ",decode(z)) 130 | end 131 | end 132 | 133 | return z_vector,k_vector,x_vector 134 | end 135 | 136 | function BPTT(ẑv,zv,kv,xv,layer :: ElmanLayer) 137 | τ = length(ẑv) 138 | 139 | ∂L∂by = zeros(1,layer.os) 140 | ∂L∂Wy = zeros(layer.hs,layer.os) 141 | ∂L∂h = zeros(1,layer.hs) 142 | ∂L∂bh = zeros(1,layer.hs) 143 | ∂L∂Wh = zeros(layer.hs,layer.is) 144 | ∂L∂Uh = zeros(layer.hs,layer.hs) 145 | 146 | for t in τ:-1:1 147 | ∂L∂y = reshape(ẑv[t]-zv[t,:],1,layer.os) 148 | 149 | # y-layer 150 | ∂L∂by += ∂L∂y 151 | ∂L∂Wy += σ(kv[t],layer.act)*∂L∂y 152 | 153 | # h-layer 154 | if (t < τ) 155 | k1 = kv[t+1] 156 | else 157 | k1 = zeros(layer.hs,1) 158 | end 159 | 160 | dς = dσ(k1,layer.act) 161 | ∂L∂h = ∂L∂h*dς*layer.Uh + ∂L∂y*layer.Wy 162 | ∂L∂k = ∂L∂h*dς 163 | ∂L∂bh += ∂L∂k 164 | ∂L∂Wh += xv[t]*∂L∂k 165 | if (t > 1) 166 | ∂L∂Uh += σ(kv[t-1],layer.act)*∂L∂k 167 | end 168 | end 169 | 170 | η = 0.0001 171 | 172 | setfield!(layer, :Wh, layer.Wh - η*∂L∂Wh'/τ) 173 | setfield!(layer, :Uh, layer.Uh - η*∂L∂Uh'/τ) 174 | setfield!(layer, :bh, layer.bh - η*∂L∂bh'/τ) 175 | setfield!(layer, :Wy, layer.Wy - η*∂L∂Wy'/τ) 176 | setfield!(layer, :by, layer.by - η*∂L∂by'/τ) 177 | end 178 | 179 | # Loss 180 | function loss(ẑv,zv) 181 | τ = length(ẑv) 182 | 183 | L = 0 184 | for t in 1:τ 185 | L += sum((ẑv[t]-zv[t,:]).^2) 186 | end 187 | 188 | return L/τ 189 | end 190 | 191 | 192 | RNN = Elman(4,4,"tanh") 193 | 194 | x = [0 0 0 1;0 0 1 0; 0 1 0 0; 1 0 0 0] 195 | zv = [0 0 1 0;0 1 0 0; 1 0 0 0; 0 0 0 1] 196 | 197 | ε = 1 198 | while(ε > 0.6) 199 | ẑv,kv,xv = feedForward(x,RNN,false) 200 | global ε = loss(ẑv,zv) 201 | println(ε) 202 | BPTT(ẑv,zv,kv,xv,RNN) 203 | end 204 | feedForward(x,RNN,true) 205 | 206 | 207 | -------------------------------------------------------------------------------- /neuronal/XOR.jl: -------------------------------------------------------------------------------- 1 | using Flux 2 | using IterTools: ncycle 3 | 4 | # Neural network architecture 5 | function SetNet(inputChannels,outputChannels) 6 | m = Chain( 7 | Dense(2,32,tanh; init = Flux.glorot_normal()), 8 | Dense(32,1,sigmoid; init = Flux.glorot_normal()) 9 | ) 10 | 11 | return m 12 | end 13 | 14 | # An approximator for the neural network with an optimiser 15 | mutable struct NNApprox 16 | model :: Chain 17 | optimiser :: Flux.Optimiser 18 | end 19 | 20 | # Returns an approximator 21 | function SetAppr(η) 22 | model = SetNet(2,1) 23 | op = Flux.Optimiser(ClipValue(1E-1),Flux.Optimise.ADAM(η)) 24 | 25 | return NNApprox(model,op) 26 | end 27 | 28 | # Creates a dataset 29 | function buildDataSet(N) 30 | x_set = Float64[0;0] 31 | y_set = Float64[0] 32 | 33 | for it in 1:N 34 | for (x1,x2,y) in zip([0 0 1 1],[0 1 0 1],[0 1 1 0]) 35 | r1 = (rand()-0.5)/10 36 | r2 = (rand()-0.5)/10 37 | x_set = hcat(x_set,[x1+r1;x2+r2]) 38 | y_set = hcat(y_set,y) 39 | end 40 | end 41 | 42 | return x_set,y_set 43 | end 44 | 45 | # Train the approximator with a dataset 46 | function train!(ap :: NNApprox, x :: Matrix{Float64}, y :: Matrix{Float64}, batch_size, epochs) 47 | train_data = Flux.Data.DataLoader((x,y),batchsize=batch_size,shuffle=true) 48 | train_data = ncycle(train_data,epochs) 49 | 50 | for (a,b) in train_data 51 | ∇ = Flux.gradient(params(ap.model)) do 52 | loss = Flux.Losses.mse(ap.model(a),b) 53 | end 54 | Flux.Optimise.update!(ap.optimiser,Flux.params(ap.model),∇) 55 | end 56 | end 57 | 58 | # Evaluate the trained approximator 59 | function evaluate(ap :: NNApprox, M :: Matrix{Float64}) 60 | for x in eachcol(M) 61 | ŷ = ap.model(x) 62 | 63 | println(x," = ",ŷ) 64 | end 65 | end 66 | 67 | #================================================================# 68 | # MAIN CODE 69 | #================================================================# 70 | A = SetAppr(1E-3) 71 | 72 | x,y = buildDataSet(200) 73 | train!(A,x,y,20,100) 74 | 75 | x = Float64[0 0 1 1;0 1 0 1] 76 | evaluate(A,x) 77 | -------------------------------------------------------------------------------- /neuronal/autoencoder.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | #---------------------------# 4 | # MODEL # 5 | #---------------------------# 6 | # Dense Layer 7 | mutable struct DenseLayer 8 | x :: Matrix 9 | W :: Matrix 10 | b :: Matrix 11 | z :: Matrix 12 | activation :: String 13 | ∂L∂W :: Matrix 14 | ∂L∂b :: Matrix 15 | 16 | # Adam 17 | ∂L∂Wm :: Matrix 18 | ∂L∂bm :: Matrix 19 | ∂L∂Wv :: Matrix 20 | ∂L∂bv :: Matrix 21 | end 22 | 23 | 24 | # Architecture 25 | mutable struct NeuralNetwork 26 | Layers :: Vector{DenseLayer} 27 | loss :: String 28 | optimizer :: String 29 | end 30 | 31 | #-------------------------# 32 | # Dense Layer Initializer # 33 | #-------------------------# 34 | function Dense(input_size,output_size,act) 35 | x = zeros(input_size,1) 36 | W = (rand(output_size,input_size) .- 0.5) ./ output_size 37 | b = (rand(output_size,1) .- 0.5) 38 | z = zeros(output_size,1) 39 | dW = zeros(input_size,output_size) 40 | db = zeros(1,output_size) 41 | 42 | return DenseLayer(x,W,b,z,act,dW,db,dW,db,dW,db) 43 | end 44 | 45 | #----------------------# 46 | # Activation Functions # 47 | #----------------------# 48 | function sigmoid(x) 49 | return 1.0/(1.0 + exp(-x)) 50 | end 51 | 52 | function relu(x) 53 | if (x > 0) 54 | return x 55 | else 56 | return 0 57 | end 58 | end 59 | 60 | function Heaviside(x) 61 | if (x > 0) 62 | return 1.0 63 | else 64 | return 0.0 65 | end 66 | end 67 | 68 | #-------------------------# 69 | # FeedForward Dense Layer # 70 | #-------------------------# 71 | function forwardDense!(x,layer :: DenseLayer) 72 | setfield!(layer,:x,x) 73 | y = layer.W*x + layer.b 74 | 75 | if (layer.activation == "tanh") 76 | z = tanh.(y) 77 | end 78 | if (layer.activation == "sig") 79 | z = sigmoid.(y) 80 | end 81 | if (layer.activation == "relu") 82 | z = relu.(y) 83 | end 84 | 85 | setfield!(layer,:z,z) 86 | 87 | return z 88 | end 89 | 90 | #----------------# 91 | # ADAM Optimizer # 92 | #----------------# 93 | function Adam(m,v,g,n) 94 | β1 = 0.9 95 | β2 = 0.999 96 | ε = 1E-8 97 | 98 | m = β1*m + (1-β1)*g 99 | v = β2*v + (1-β2)*(g.*g) 100 | 101 | mh = m ./ (1-β1^n) 102 | vh = v ./ (1-β2^n) 103 | 104 | Δ = mh ./ (sqrt.(vh) .+ ε) 105 | 106 | return m,v,-Δ 107 | end 108 | 109 | #---------------------------# 110 | # BackPropagate Dense Layer # 111 | #---------------------------# 112 | function backDense!(∂L∂z,layer :: DenseLayer,opt,n) 113 | if (layer.activation == "tanh") 114 | D = 1.0 .- layer.z'.^2 115 | end 116 | if (layer.activation == "sig") 117 | D = (layer.z .* (1.0 .- layer.z))' 118 | end 119 | if (layer.activation == "relu") 120 | D = Heaviside.(layer.z') 121 | end 122 | 123 | ∂L∂y = ∂L∂z.*D 124 | ξ = layer.x*∂L∂y 125 | 126 | if (opt == "Grad") 127 | g1 = ∂L∂y 128 | g2 = ξ 129 | elseif (opt == "Adam") 130 | m,v,g1 = Adam(layer.∂L∂bm,layer.∂L∂bv,∂L∂y,n) 131 | setfield!(layer,:∂L∂bm,m) 132 | setfield!(layer,:∂L∂bv,v) 133 | 134 | m,v,g2 = Adam(layer.∂L∂Wm,layer.∂L∂Wv,ξ,n) 135 | setfield!(layer,:∂L∂Wm,m) 136 | setfield!(layer,:∂L∂Wv,v) 137 | end 138 | 139 | setfield!(layer,:∂L∂b,layer.∂L∂b + g1) 140 | setfield!(layer,:∂L∂W,layer.∂L∂W + g2) 141 | 142 | ∂L∂x = ∂L∂y*layer.W 143 | 144 | return ∂L∂x 145 | end 146 | 147 | #------------------# 148 | # Gradient Descend # 149 | #------------------# 150 | function Gradient!(layer :: DenseLayer, η) 151 | setfield!(layer,:W, layer.W - η*layer.∂L∂W') 152 | setfield!(layer,:b, layer.b - η*layer.∂L∂b') 153 | 154 | i,j = size(layer.∂L∂W) 155 | z = zeros(i,j) 156 | setfield!(layer,:∂L∂W,z) 157 | setfield!(layer,:∂L∂Wm,z) 158 | setfield!(layer,:∂L∂Wv,z) 159 | 160 | i,j = size(layer.∂L∂b) 161 | z = zeros(i,j) 162 | setfield!(layer,:∂L∂b,z) 163 | setfield!(layer,:∂L∂bm,z) 164 | setfield!(layer,:∂L∂bv,z) 165 | 166 | return nothing 167 | end 168 | 169 | #==================# 170 | # Architecture # 171 | #==================# 172 | # Initialize Neural Network 173 | function SetNeuralNetwork(ni,no,loss,opt) 174 | Layer1 = Dense(ni,4,"tanh") 175 | Layer2 = Dense(4,8,"tanh") 176 | Layer3 = Dense(8,4,"tanh") 177 | Layer4 = Dense(4,no,"tanh") 178 | 179 | Layers = [Layer1, Layer2, Layer3, Layer4] 180 | 181 | return NeuralNetwork(Layers,loss,opt) 182 | end 183 | 184 | # Feedforward Neural Network 185 | function FeedForward!(x, nn :: NeuralNetwork) 186 | z = x 187 | for L in nn.Layers 188 | z = forwardDense!(z,L) 189 | end 190 | 191 | return z 192 | end 193 | 194 | # Backpropagate Neural Network 195 | function BackPropagate(∂L, nn :: NeuralNetwork,step) 196 | D = ∂L 197 | for L in nn.Layers[end:-1:1] 198 | D = backDense!(D,L,nn.optimizer,step) 199 | end 200 | 201 | return D 202 | end 203 | 204 | # Apply gradients to Neural Network 205 | function SetGradients!(η, nn :: NeuralNetwork) 206 | for L in nn.Layers 207 | Gradient!(L,η) 208 | end 209 | 210 | return nothing 211 | end 212 | 213 | # Loss 214 | function Loss(y, nn :: NeuralNetwork) 215 | L = nn.Layers[end] 216 | ŷ = L.z 217 | ωo² = 1 218 | λ = 0.8 219 | 220 | if (nn.loss == "L2") 221 | lossm = sum((ŷ-y).^2)/length(y) 222 | Dm = 2*transpose(ŷ-y)/length(y) 223 | 224 | ε_true = 0.5*y[2]^2 - ωo²*cos(y[1]) 225 | ε_predicted = 0.5*ŷ[2]^2 -ωo²*cos(ŷ[1]) 226 | loss_physics = (ε_predicted - ε_true)^2 227 | Dp = 2(ε_predicted - ε_true)*reshape([ωo²*sin(ŷ[1]) ŷ[2]],1,2) 228 | end 229 | 230 | loss = (1-λ)*lossm + λ*loss_physics 231 | D = (1-λ)*Dm + λ*Dp 232 | 233 | #println("::",lossm," ",loss_physics) 234 | 235 | return loss,D 236 | end 237 | 238 | # Train a neural network 239 | function TrainNeuralNetwork!(nn :: NeuralNetwork,sample,η) 240 | ny,nx = size(sample) 241 | 242 | loss_y = [] 243 | loss = 1.0 244 | it = 1 245 | while(loss > 1E-5) 246 | loss = 0 247 | for epoch in 1:ny 248 | # Generate data 249 | r = rand(1:ny) 250 | x = reshape(sample[r,1:2],2,1) 251 | y = reshape(sample[r,3:4],2,1) 252 | 253 | # Feedforward 254 | ŷ = FeedForward!(x,nn) 255 | 256 | # Compute loss and its gradient 257 | l,D = Loss(y,nn) 258 | loss += l 259 | 260 | # Backpropagate 261 | D1 = BackPropagate(D,nn,it) 262 | end 263 | it += 1 264 | loss /= ny 265 | push!(loss_y,loss) 266 | println(loss) 267 | 268 | # Apply gradient descend 269 | SetGradients!(η, nn) 270 | end 271 | 272 | return loss_y 273 | end 274 | 275 | #====================================================# 276 | # MAIN # 277 | #====================================================# 278 | function f(r) 279 | ωo² = 1 280 | θ = r[1] 281 | φ = r[2] 282 | return [φ,-ωo²*sin(θ)] 283 | end 284 | 285 | # Setup autoencoder 286 | nn = SetNeuralNetwork(2,2,"L2","Grad") 287 | 288 | # Create training set 289 | training_set = zeros(1000,4) 290 | Δ = 0.1 291 | 292 | ac = 0 293 | #for zo in [2π/3,π/2,π/4] 294 | x = [] 295 | y = [] 296 | for zo in [π/2]# 2π/3 π/4] 297 | z = [zo,0] 298 | 299 | for it in 1:1000 300 | global ac += 1 301 | 302 | # Runge-Kutta 303 | training_set[ac,1] = z[1]/π + (rand()-0.5)/100 304 | training_set[ac,2] = z[2]/π + (rand()-0.5)/100 305 | 306 | k1 = f(z) 307 | k2 = f(z + 0.5*Δ*k1) 308 | k3 = f(z + 0.5*Δ*k2) 309 | k4 = f(z + Δ*k3) 310 | 311 | z += (k1 + 2k2 + 2k3 + k4)*Δ/6 312 | 313 | training_set[ac,3] = z[1]/π 314 | training_set[ac,4] = z[2]/π 315 | 316 | push!(x,z[1]/π) 317 | push!(y,z[2]/π) 318 | end 319 | end 320 | plot(x,y) 321 | 322 | # Train autoencoder 323 | l = TrainNeuralNetwork!(nn,training_set,0.0001) 324 | 325 | # Print results 326 | z = [0.5,0] 327 | x = [] 328 | y = [] 329 | for it in 1:10000 330 | global z = FeedForward!(reshape(z,2,1),nn) 331 | push!(x,z[1]) 332 | push!(y,z[2]) 333 | end 334 | 335 | #plot(x) 336 | #plot(y) 337 | plot(x,y,color="orange") 338 | show() 339 | 340 | -------------------------------------------------------------------------------- /neuronal/conv.jl: -------------------------------------------------------------------------------- 1 | using Statistics 2 | using MLDatasets 3 | 4 | using Flux 5 | using Flux: onehotbatch, onecold, flatten 6 | using Flux.Data: DataLoader 7 | using Flux.Optimise: Optimiser 8 | using Flux.Losses: logitcrossentropy 9 | 10 | 11 | # Get MNIST data and create minibatch 12 | # Y. LeCun, L. Bottou, Y. Bengio, and P. Haffner 13 | # "Gradient-based learning applied to document recognition." 14 | # In: Proceedings of the IEEE, 86-11 (1998) 2278-2324. 15 | 16 | function get_data(bsize = 128) 17 | xtrain, ytrain = MLDatasets.MNIST(:train)[:] 18 | xtest, ytest = MLDatasets.MNIST(:test)[:] 19 | 20 | xtrain = reshape(xtrain, 28, 28, 1, :) 21 | xtest = reshape(xtest, 28, 28, 1, :) 22 | 23 | ytrain, ytest = onehotbatch(ytrain, 0:9), onehotbatch(ytest, 0:9) 24 | 25 | train_loader = DataLoader((xtrain, ytrain), batchsize=bsize, shuffle=true) 26 | test_loader = DataLoader((xtest, ytest), batchsize=bsize) 27 | 28 | return train_loader, test_loader 29 | end 30 | 31 | # Build a convolutional model 32 | function build_model() 33 | model = Chain( 34 | Conv((3, 3), 1=>16, pad=(1,1), relu), 35 | MaxPool((2,2)), 36 | 37 | Conv((3, 3), 16=>32, pad=(1,1), relu), 38 | MaxPool((2,2)), 39 | 40 | Conv((3, 3), 32=>32,pad=(1,1), relu), 41 | MaxPool((2,2)), 42 | 43 | flatten, 44 | Dense(288, 10), 45 | 46 | softmax, 47 | ) 48 | 49 | model = gpu(model); 50 | 51 | return model 52 | end 53 | 54 | # Loss and accuracy functions 55 | loss(ŷ, y) = logitcrossentropy(ŷ, y) 56 | accuracy(x,y,model) = mean(onecold(model(x)) .== onecold(y)) 57 | 58 | # Train model and make predictions 59 | function train() 60 | train_loader,test_loader = get_data() 61 | model = build_model() 62 | ps = Flux.params(model) 63 | opt = ADAM(0.001) 64 | 65 | # Train 66 | for epoch in 1:10 67 | for (x,y) in train_loader 68 | x,y = x |> gpu, y |> gpu 69 | gs = Flux.gradient(ps) do 70 | ŷ = model(x) 71 | loss(ŷ,y) 72 | end 73 | 74 | Flux.Optimise.update!(opt,ps,gs) 75 | end 76 | 77 | # Print accuracy 78 | ac = 0 79 | n = 0 80 | for (x,y) in train_loader 81 | x,y = x |> gpu, y |> gpu 82 | ac += accuracy(x,y,model) 83 | n += size(x)[end] 84 | end 85 | println(100*ac/n) 86 | end 87 | 88 | return model 89 | end 90 | 91 | # Make some predictions 92 | function predict(model) 93 | x,y = MLDatasets.MNIST(:test)[:] 94 | ŷ = zeros(10) 95 | 96 | for i in 1:5 97 | g = reshape(x[:,:,i],28,28,1,1) 98 | g = g |> gpu 99 | copyto!(ŷ,model(g)) 100 | println("Expected: ",y[i],", Obtained: ",argmax(ŷ)-1) 101 | end 102 | end 103 | 104 | #======================================# 105 | # MAIN # 106 | #======================================# 107 | model = train() 108 | predict(model) 109 | -------------------------------------------------------------------------------- /neuronal/feedforward/feedforward.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | #---------------------------# 4 | # MODEL # 5 | #---------------------------# 6 | # Dense Layer 7 | mutable struct DenseLayer 8 | x :: Matrix 9 | W :: Matrix 10 | b :: Matrix 11 | z :: Matrix 12 | activation :: String 13 | ∂L∂W :: Matrix 14 | ∂L∂b :: Matrix 15 | end 16 | 17 | 18 | # Architecture 19 | mutable struct NeuralNetwork 20 | Layers :: Vector{DenseLayer} 21 | loss :: String 22 | end 23 | 24 | #-------------------------# 25 | # Dense Layer Initializer # 26 | #-------------------------# 27 | function Dense(input_size,output_size,act) 28 | x = zeros(input_size,1) 29 | W = (rand(output_size,input_size) .- 0.5) ./ output_size 30 | b = (rand(output_size,1) .- 0.5) 31 | z = zeros(output_size,1) 32 | dW = zeros(input_size,output_size) 33 | db = zeros(1,output_size) 34 | 35 | return DenseLayer(x,W,b,z,act,dW,db) 36 | end 37 | 38 | #----------------------# 39 | # Activation Functions # 40 | #----------------------# 41 | function sigmoid(x) 42 | return 1.0/(1.0 + exp(-x)) 43 | end 44 | 45 | #-------------------------# 46 | # FeedForward Dense Layer # 47 | #-------------------------# 48 | function forwardDense!(x,layer :: DenseLayer) 49 | setfield!(layer,:x,x) 50 | y = layer.W*x + layer.b 51 | 52 | if (layer.activation == "tanh") 53 | z = tanh.(y) 54 | end 55 | if (layer.activation == "sig") 56 | z = sigmoid.(y) 57 | end 58 | 59 | setfield!(layer,:z,z) 60 | 61 | return z 62 | end 63 | 64 | #---------------------------# 65 | # BackPropagate Dense Layer # 66 | #---------------------------# 67 | function backDense!(∂L∂z,layer :: DenseLayer) 68 | if (layer.activation == "tanh") 69 | D = 1.0 .- layer.z'.^2 70 | end 71 | if (layer.activation == "sig") 72 | D = (layer.z .* (1.0 .- layer.z))' 73 | end 74 | 75 | ∂L∂y = ∂L∂z.*D 76 | setfield!(layer,:∂L∂b,layer.∂L∂b + ∂L∂y) 77 | setfield!(layer,:∂L∂W,layer.∂L∂W + layer.x*∂L∂y) 78 | ∂L∂x = ∂L∂y*layer.W 79 | 80 | return ∂L∂x 81 | end 82 | 83 | #------------------# 84 | # Gradient Descend # 85 | #------------------# 86 | function Gradient!(layer :: DenseLayer, η) 87 | setfield!(layer,:W, layer.W - η*layer.∂L∂W') 88 | setfield!(layer,:b, layer.b - η*layer.∂L∂b') 89 | 90 | i,j = size(layer.∂L∂W) 91 | z = zeros(i,j) 92 | setfield!(layer,:∂L∂W,z) 93 | 94 | i,j = size(layer.∂L∂b) 95 | z = zeros(i,j) 96 | setfield!(layer,:∂L∂b,z) 97 | 98 | return nothing 99 | end 100 | 101 | #==================# 102 | # Architecture # 103 | #==================# 104 | # Initialize Neural Network 105 | function SetNeuralNetwork(ni,no,act,loss) 106 | nh = floor(Int,(ni+no)/2)+1 107 | 108 | Layer1 = Dense(ni,nh,act) 109 | Layer2 = Dense(nh,no,act) 110 | 111 | Layers = [Layer1, Layer2] 112 | 113 | return NeuralNetwork(Layers,loss) 114 | end 115 | 116 | # Feedforward Neural Network 117 | function FeedForward!(x, nn :: NeuralNetwork) 118 | z = x 119 | for L in nn.Layers 120 | z = forwardDense!(z,L) 121 | end 122 | 123 | return z 124 | end 125 | 126 | # Backpropagate Neural Network 127 | function BackPropagate(∂L, nn :: NeuralNetwork) 128 | D = ∂L 129 | for L in nn.Layers[end:-1:1] 130 | D = backDense!(D,L) 131 | end 132 | 133 | return D 134 | end 135 | 136 | # Apply gradients to Neural Network 137 | function SetGradients!(η, nn :: NeuralNetwork) 138 | for L in nn.Layers 139 | Gradient!(L,η) 140 | end 141 | 142 | return nothing 143 | end 144 | 145 | # Loss 146 | function Loss(y, nn :: NeuralNetwork) 147 | L = nn.Layers[end] 148 | ŷ = L.z 149 | 150 | if (nn.loss == "L2") 151 | loss = sum((ŷ-y).^2)/length(y) 152 | D = 2*transpose(ŷ-y)/length(y) 153 | end 154 | 155 | return loss,D 156 | end 157 | 158 | # Train a neural network 159 | function TrainNeuralNetwork!(nn :: NeuralNetwork,sample,η) 160 | ny,nx = size(sample) 161 | 162 | loss_y = [] 163 | loss = 1.0 164 | while(loss > 1E-4) 165 | loss = 0 166 | for epoch in 1:ny 167 | # Generate data 168 | r = rand(1:4) 169 | x = reshape(sample[r,1:2],2,1) + 0.01*(rand(2) .- 0.5) 170 | y = reshape([sample[r,3]],1,1) 171 | 172 | # Feedforward 173 | ŷ = FeedForward!(x,nn) 174 | 175 | # Compute loss and its gradient 176 | l,D = Loss(y,nn) 177 | loss += l 178 | 179 | # Backpropagate 180 | D1 = BackPropagate(D,nn) 181 | end 182 | loss /= ny 183 | push!(loss_y,loss) 184 | println(loss) 185 | 186 | # Apply gradient descend 187 | SetGradients!(η, nn) 188 | end 189 | 190 | return loss_y 191 | end 192 | 193 | #====================================================# 194 | # MAIN # 195 | #====================================================# 196 | nn = SetNeuralNetwork(2,1,"sig","L2") 197 | 198 | training_set = [ 0 0 0; 199 | 0 1 1; 200 | 1 0 1; 201 | 1 1 0] 202 | 203 | l = TrainNeuralNetwork!(nn,training_set,0.01) 204 | 205 | # Print results 206 | for i in 1:4 207 | x = reshape(training_set[i,1:2],2,1) 208 | ŷ = FeedForward!(x,nn) 209 | println(x,": ",ŷ) 210 | end 211 | 212 | plot(l) 213 | show() 214 | 215 | -------------------------------------------------------------------------------- /neuronal/feedforward/perceptron.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | 3 | function Θ(x) 4 | if (x >= 0) 5 | return 1 6 | else 7 | return 0 8 | end 9 | end 10 | 11 | 12 | function train(w,b) 13 | example = [ 0 0 0; 14 | 0 1 1; 15 | 1 0 1; 16 | 1 1 1;] 17 | η = 0.001 18 | ε = 1 19 | while(ε > 0) 20 | ε = 0 21 | for epoch in 1:64 22 | r = rand(1:4) 23 | x = example[r,1:2] + rand(2)/150 24 | f = example[r,3] 25 | f_hat = Θ(w⋅x+b) 26 | 27 | # Update 28 | Δf = f_hat-f 29 | w = w - η*Δf*x 30 | b = b - η*Δf 31 | ε += abs(Δf) 32 | end 33 | ε /= 64 34 | 35 | println(ε) 36 | end 37 | 38 | return w,b 39 | end 40 | 41 | w,b = train(rand(2).-0.5,rand()-0.5) 42 | 43 | println("0 0 -> ", Θ(w⋅[0 0] + b)) 44 | println("0 1 -> ", Θ(w⋅[0 1] + b)) 45 | println("1 0 -> ", Θ(w⋅[1 0] + b)) 46 | println("1 1 -> ", Θ(w⋅[1 1] + b)) 47 | 48 | -------------------------------------------------------------------------------- /neuronal/image/u_net.jl: -------------------------------------------------------------------------------- 1 | function unet() 2 | model = Chain( 3 | Conv((3,3),1=>64,pad=SamePad(),relu), 4 | Conv((3,3),64=>64,pad=SamePad(),relu), 5 | 6 | SkipConnection( 7 | Chain( 8 | MaxPool((2,2)), 9 | Conv((3,3),64=>128,pad=SamePad(),relu), 10 | Conv((3,3),128=>128,pad=SamePad(),relu), 11 | 12 | SkipConnection( 13 | Chain( 14 | MaxPool((2,2)), 15 | Conv((3,3),128=>256,pad=SamePad(),relu), 16 | Conv((3,3),256=>256,pad=SamePad(),relu), 17 | 18 | SkipConnection( 19 | Chain( 20 | MaxPool((2,2)), 21 | Conv((3,3),256=>512,pad=SamePad(),relu), 22 | Conv((3,3),512=>512,pad=SamePad(),relu), 23 | 24 | SkipConnection( 25 | Chain( 26 | MaxPool((2,2)), 27 | Conv((3,3),512=>1024,pad=SamePad(),relu), 28 | Conv((3,3),1024=>1024,pad=SamePad(),relu), 29 | ConvTranspose((2,2),1024=>1024,pad=SamePad(),stride=2) 30 | ), 31 | (mx,x)->cat(mx,x,dims=3) 32 | ), 33 | 34 | Conv((3,3),1536=>512,pad=SamePad(),relu), 35 | Conv((3,3),512=>512,pad=SamePad(),relu), 36 | ConvTranspose((2,2),512=>512,pad=SamePad(),stride=2) 37 | ), 38 | (mx,x)->cat(mx,x,dims=3) 39 | ), 40 | 41 | Conv((3,3),768=>256,pad=SamePad(),relu), 42 | Conv((3,3),256=>256,pad=SamePad(),relu), 43 | ConvTranspose((2,2),256=>256,pad=SamePad(),stride=2) 44 | ), 45 | (mx,x)->cat(mx,x,dims=3) 46 | ), 47 | 48 | Conv((3,3),384=>128,pad=SamePad(),relu), 49 | Conv((3,3),128=>128,pad=SamePad(),relu), 50 | ConvTranspose((2,2),128=>128,pad=SamePad(),stride=2) 51 | ), 52 | (mx,x)->cat(mx,x,dims=3) 53 | ), 54 | 55 | Conv((3,3),192=>64,pad=SamePad(),relu), 56 | Conv((3,3),64=>64,pad=SamePad(),relu), 57 | Conv((3,3),64=>1,pad=SamePad(),relu) 58 | ) 59 | 60 | return model 61 | end 62 | -------------------------------------------------------------------------------- /neuronal/variational.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using LinearAlgebra 3 | 4 | #---------------------------# 5 | # MODEL # 6 | #---------------------------# 7 | # Dense Layer 8 | mutable struct DenseLayer 9 | x :: Matrix 10 | W :: Matrix 11 | b :: Matrix 12 | z :: Matrix 13 | activation :: String 14 | ∂L∂W :: Matrix 15 | ∂L∂b :: Matrix 16 | end 17 | 18 | # Architecture 19 | mutable struct NeuralNetwork 20 | Layers :: Vector{DenseLayer} 21 | end 22 | 23 | #-------------------------# 24 | # Dense Layer Initializer # 25 | #-------------------------# 26 | function Dense(input_size,output_size,act) 27 | x = zeros(input_size,1) 28 | W = (rand(output_size,input_size) .- 0.5) ./ output_size 29 | b = (rand(output_size,1) .- 0.5) 30 | z = zeros(output_size,1) 31 | dW = zeros(input_size,output_size) 32 | db = zeros(1,output_size) 33 | 34 | return DenseLayer(x,W,b,z,act,dW,db) 35 | end 36 | 37 | #----------------------# 38 | # Activation Functions # 39 | #----------------------# 40 | function sigmoid(x) 41 | return 1.0/(1.0 + exp(-x)) 42 | end 43 | 44 | function relu(x) 45 | if (x > 0) 46 | return x 47 | else 48 | return 0 49 | end 50 | end 51 | 52 | function Heaviside(x) 53 | if (x > 0) 54 | return 1.0 55 | else 56 | return 0.0 57 | end 58 | end 59 | 60 | #-------------------------# 61 | # FeedForward Dense Layer # 62 | #-------------------------# 63 | function forwardDense!(x,layer :: DenseLayer) 64 | setfield!(layer,:x,x) 65 | y = layer.W*x + layer.b 66 | 67 | if (layer.activation == "tanh") 68 | z = tanh.(y) 69 | end 70 | if (layer.activation == "sig") 71 | z = sigmoid.(y) 72 | end 73 | if (layer.activation == "relu") 74 | z = relu.(y) 75 | end 76 | 77 | setfield!(layer,:z,z) 78 | 79 | return z 80 | end 81 | 82 | #---------------------------# 83 | # BackPropagate Dense Layer # 84 | #---------------------------# 85 | function backDense!(∂L∂z,layer :: DenseLayer) 86 | if (layer.activation == "tanh") 87 | D = 1.0 .- layer.z'.^2 88 | end 89 | if (layer.activation == "sig") 90 | D = (layer.z .* (1.0 .- layer.z))' 91 | end 92 | if (layer.activation == "relu") 93 | D = Heaviside.(layer.z') 94 | end 95 | 96 | ∂L∂y = ∂L∂z.*D 97 | ξ = layer.x*∂L∂y 98 | g1 = ∂L∂y 99 | g2 = ξ 100 | 101 | setfield!(layer,:∂L∂b,layer.∂L∂b + g1) 102 | setfield!(layer,:∂L∂W,layer.∂L∂W + g2) 103 | 104 | ∂L∂x = ∂L∂y*layer.W 105 | 106 | return ∂L∂x 107 | end 108 | 109 | #------------------# 110 | # Gradient Descend # 111 | #------------------# 112 | function Gradient!(layer :: DenseLayer, η) 113 | setfield!(layer,:W, layer.W - η*layer.∂L∂W') 114 | setfield!(layer,:b, layer.b - η*layer.∂L∂b') 115 | 116 | i,j = size(layer.∂L∂W) 117 | z = zeros(i,j) 118 | setfield!(layer,:∂L∂W,z) 119 | 120 | i,j = size(layer.∂L∂b) 121 | z = zeros(i,j) 122 | setfield!(layer,:∂L∂b,z) 123 | 124 | return nothing 125 | end 126 | 127 | #==================# 128 | # Architecture # 129 | #==================# 130 | # Initialize Neural Network 131 | function SetNeuralNetwork(fans,acts) 132 | Layers = [] 133 | 134 | for i in 1:(length(fans)-1) 135 | Layer = Dense(fans[i],fans[i+1],acts[i]) 136 | push!(Layers,Layer) 137 | end 138 | 139 | return NeuralNetwork(Layers) 140 | end 141 | 142 | # Feedforward Neural Network 143 | function FeedForward!(x, nn :: NeuralNetwork) 144 | z = x 145 | for L in nn.Layers 146 | z = forwardDense!(z,L) 147 | end 148 | 149 | return z 150 | end 151 | 152 | # Backpropagate Neural Network 153 | function BackPropagate(∂L, nn :: NeuralNetwork) 154 | D = ∂L 155 | for L in nn.Layers[end:-1:1] 156 | D = backDense!(D,L) 157 | end 158 | 159 | return D 160 | end 161 | 162 | # Apply gradients to Neural Network 163 | function SetGradients!(η, nn :: NeuralNetwork) 164 | for L in nn.Layers 165 | Gradient!(L,η) 166 | end 167 | 168 | return nothing 169 | end 170 | 171 | # Loss 172 | function L2(ŷ,y) 173 | loss = sum((ŷ-y).^2)/length(y) 174 | grad = 2*transpose(ŷ-y)/length(y) 175 | return loss,grad 176 | end 177 | 178 | # Kullback-Leibler 179 | function Dkl(μ,Σ) 180 | loss = 0.5*(-log(det(Σ)) + tr(Σ) + dot(μ,μ) - length(μ)) 181 | grad = [transpose(μ), 0.5*(1 .- inv(Σ))] 182 | return loss,grad 183 | end 184 | 185 | #====================================================# 186 | # MAIN # 187 | #====================================================# 188 | # Parameters & Constants 189 | η = 0.001 190 | t = LinRange(0,2π,32) 191 | error = 10 192 | it = 0 193 | 194 | # Setup autoencoder 195 | sx = SetNeuralNetwork([32,8],["tanh"]) 196 | h = SetNeuralNetwork([8,1],["tanh"]) 197 | g = SetNeuralNetwork([8,1],["sig"]) 198 | f = SetNeuralNetwork([1,32],["tanh"]) 199 | 200 | # Train variational autoencoder 201 | while(error > 1E-2) 202 | θ = (0.1*rand(1:10)-0.5)*π # Finite sampling space 203 | x = reshape(sin.(t.+θ),32,1) 204 | 205 | # Feedforward 206 | s = FeedForward!(x,sx) 207 | μ = FeedForward!(s,h) 208 | σ² = FeedForward!(s,g) 209 | ξ = randn() 210 | z = μ + sqrt(σ²)*ξ 211 | xh = FeedForward!(z,f) 212 | 213 | # Losses 214 | Loss1,∂L1 = L2(xh,x) 215 | Loss2,∂L2 = Dkl(μ,σ²) 216 | global error = Loss1 217 | 218 | # Progress time 219 | println(Loss1," ",Loss2) 220 | r = it/1E8 221 | if (it ≤ 1E6) 222 | global it = it + 1 223 | end 224 | 225 | # Backpropagate 226 | ∂L∂z = BackPropagate(∂L1,f) 227 | ∂L∂μ = ∂L∂z + ∂L2[1]*r 228 | ∂L∂σ² = 0.5*∂L∂z*ξ/sqrt(σ²) + ∂L2[2]*r 229 | ∂L∂s1 = BackPropagate(∂L∂μ,h) 230 | ∂L∂s2 = BackPropagate(∂L∂σ²,g) 231 | ∂L∂s = BackPropagate(∂L∂s1 + ∂L∂s2,sx) 232 | 233 | # Apply gradients 234 | SetGradients!(η, sx) 235 | SetGradients!(η, h) 236 | SetGradients!(η, g) 237 | SetGradients!(η, f) 238 | end 239 | 240 | for it in 1:5 241 | # Make prediction 242 | θ = (0.1*rand(1:10)-0.5)*π 243 | x = reshape(sin.(t.+θ),32,1) 244 | 245 | s = FeedForward!(x,sx) 246 | μ = FeedForward!(s,h) 247 | σ = FeedForward!(s,g) 248 | ξ = randn() 249 | z = μ + σ*ξ 250 | xh = FeedForward!(z,f) 251 | 252 | # Plot 253 | plot(t/π,x) 254 | plot(t/π,xh) 255 | xlabel("θ/π") 256 | show() 257 | end 258 | -------------------------------------------------------------------------------- /optimization/SA.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | # Create some random function 4 | function random_walk() 5 | Y = [] 6 | 7 | y = 0 8 | for i in 1:200 9 | y += randn() 10 | 11 | push!(Y,y) 12 | end 13 | 14 | return Y 15 | end 16 | 17 | # Simulated annealing with Metropolis-Hastings 18 | function MH(f) 19 | β = 1E-3 20 | N = length(f) 21 | x = rand(1:N) 22 | 23 | for j = 1:1000 24 | for i = 1:(10*N) 25 | y = rand(max(1,x-3):min(x+3,N)) 26 | A = min(1,exp(β*(f[y]-f[x]))) 27 | 28 | if (rand() ≤ A) 29 | x = y 30 | end 31 | end 32 | 33 | β += 1E-3 34 | end 35 | 36 | return x 37 | end 38 | 39 | # Main function 40 | f = random_walk() 41 | println("Found: ", MH(f),", Should be: ",argmax(f)) 42 | plot(f) 43 | show() 44 | -------------------------------------------------------------------------------- /optimization/amoeba.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | mutable struct simplex 4 | x1 :: Vector 5 | x2 :: Vector 6 | x3 :: Vector 7 | 8 | f1 :: Float64 9 | f2 :: Float64 10 | f3 :: Float64 11 | 12 | α :: Float64 13 | γ :: Float64 14 | ρ :: Float64 15 | β :: Float64 16 | end 17 | 18 | function simplex(x1 :: Vector, x2 :: Vector, x3 :: Vector) 19 | return simplex(x1,x2,x3, 20 | 0.0, # f1 21 | 0.0, # f2 22 | 0.0, # f3 23 | 1.0, # α 24 | 2.0, # γ 25 | 0.5, # ρ 26 | 0.5) # β 27 | end 28 | 29 | function Rosen(r :: Vector) 30 | a = 1.0 31 | b = 100.0 32 | 33 | return (a-r[1])^2 + b*(r[2]-r[1]^2)^2 34 | end 35 | 36 | function order!(s :: simplex) 37 | f1 = Rosen(s.x1) 38 | f2 = Rosen(s.x2) 39 | f3 = Rosen(s.x3) 40 | 41 | f = [f1,f2,f3] 42 | x = [s.x1,s.x2,s.x3] 43 | 44 | index = sortperm(f) 45 | 46 | setfield!(s,:x1,x[index[1]]) 47 | setfield!(s,:x2,x[index[2]]) 48 | setfield!(s,:x3,x[index[3]]) 49 | 50 | setfield!(s,:f1,f[index[1]]) 51 | setfield!(s,:f2,f[index[2]]) 52 | setfield!(s,:f3,f[index[3]]) 53 | end 54 | 55 | function step!(s :: simplex) 56 | # Sort 57 | order!(s) 58 | 59 | # Find centroid 60 | xo = (s.x1 + s.x2)/2 61 | 62 | # Find reflection 63 | xr = xo + s.α*(xo - s.x3) 64 | fr = Rosen(xr) 65 | 66 | # Reflected better than best solution? 67 | if (fr < s.f1) 68 | # Try to expand 69 | xe = xo + s.γ*(xr - xo) 70 | fe = Rosen(xe) 71 | 72 | if (fr ≤ fe) # Reflected is still better 73 | setfield!(s,:x3,xr) 74 | setfield!(s,:f3,fr) 75 | else 76 | setfield!(s,:x3,xe) 77 | setfield!(s,:f3,fe) 78 | end 79 | elseif (s.f1 ≤ fr < s.f2) # Reflected worse than all but worst? 80 | setfield!(s,:x3,xr) 81 | setfield!(s,:f3,fr) 82 | else 83 | # Find contraction 84 | if (fr < s.f3) 85 | xc = xo + s.ρ*(xr - xo) 86 | else 87 | xc = xo + s.ρ*(s.x3 - xo) 88 | end 89 | fc = Rosen(xc) 90 | 91 | if (fc < s.f3) 92 | setfield!(s,:x3,xc) 93 | setfield!(s,:f3,fc) 94 | else 95 | shrink!(s) 96 | end 97 | end 98 | 99 | f1 = Rosen(s.x1) 100 | f3 = Rosen(s.x3) 101 | 102 | return f3#abs(f1-f3)/(f1+f3) 103 | end 104 | 105 | function shrink!(s :: simplex) 106 | x2 = s.x1 + s.β*(s.x2 - s.x1) 107 | x3 = s.x1 + s.β*(s.x3 - s.x1) 108 | 109 | setfield!(s,:x2, x2) 110 | setfield!(s,:x3, x3) 111 | end 112 | 113 | function main() 114 | x1 = [-0.532,1.012] 115 | x2 = [1.575,-1.565] 116 | x3 = [1.212,2.532] 117 | s = simplex(x1,x2,x3) 118 | 119 | x_space = LinRange(-2,2,300) 120 | y_space = LinRange(-1,3,300) 121 | R = zeros(300,300) 122 | for j in 1:300 123 | for i in 1:300 124 | R[j,i] = log(Rosen([x_space[i],y_space[j]])) 125 | end 126 | end 127 | #contourf(x_space,y_space,R,cmap="gray") 128 | 129 | ε = [] 130 | cnt = 0 131 | while(true) 132 | cnt += 1 133 | if (step!(s) < 1E-6) 134 | break 135 | end 136 | 137 | push!(ε,s.f3) 138 | 139 | if (mod(cnt-10,5) == 0) 140 | xx = [s.x1[1],s.x2[1],s.x3[1],s.x1[1]] 141 | yy = [s.x1[2],s.x2[2],s.x3[2],s.x1[2]] 142 | #plot(xx,yy,color="white") 143 | end 144 | end 145 | 146 | println(s.x1[1]," ",s.x1[2]) 147 | 148 | 149 | semilogy(ε,color="darkgray") 150 | #axis([-1.0,1.5,-1.0,2.0]) 151 | axis([0,66,1E-6,1E2]) 152 | xlabel("Step") 153 | ylabel("Log(error)") 154 | show() 155 | end 156 | 157 | main() 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /optimization/ants.jl: -------------------------------------------------------------------------------- 1 | #--------------------- 2 | # Ant-agent structure 3 | #--------------------- 4 | mutable struct antAgent 5 | node :: Int 6 | memory :: Vector 7 | end 8 | 9 | # Ant-agent Constructor 10 | function antAgent(node :: Int) 11 | return antAgent(node,[]) 12 | end 13 | 14 | #------------------ 15 | # Colony structure 16 | #------------------ 17 | mutable struct antColony 18 | number_of_ants :: Int # Number of ants 19 | target_node :: Int # Target node 20 | τ :: Matrix # Pheromone trail level 21 | A :: Matrix # Adjacency matrix 22 | ants :: Vector # Ants 23 | α :: Float64 # Importance of pheromone 24 | β :: Float64 # Importante of heuristic 25 | ρ :: Float64 # Evaporation rate 26 | Q :: Float64 # Amount of pheromone 27 | end 28 | 29 | # Colony constructor 30 | function build_colony(A :: Matrix, target_node :: Int, number_of_ants :: Int) 31 | N, = size(A) 32 | τ = zeros(N,N) 33 | 34 | # Place ants randomly in graph 35 | ants = [] 36 | for i in 1:number_of_ants 37 | push!(ants,antAgent(rand(1:N))) 38 | end 39 | 40 | return antColony(number_of_ants,target_node,τ,A,ants,1.0,1.0,0.01,10.0) 41 | end 42 | 43 | # Standard roulette selection 44 | function roulette_selection(fitness) 45 | if (sum(fitness) == 0) 46 | return rand(1:length(fitness)) 47 | else 48 | total_fitness = sum(fitness) 49 | r = rand()*total_fitness 50 | 51 | i = 0 52 | while(r ≥ 0) 53 | i += 1 54 | r -= fitness[i] 55 | end 56 | 57 | return i 58 | end 59 | end 60 | 61 | # Find neighbors given a node 62 | function find_neighbors(A,i) 63 | N, = size(A) 64 | 65 | k = [] 66 | for j in 1:N 67 | if (A[i,j] ≠ 0) 68 | push!(k,j) 69 | end 70 | end 71 | 72 | return k 73 | end 74 | 75 | # Construct solutions phase 76 | function construct_solutions(colony :: antColony) 77 | N, = size(colony.A) 78 | 79 | # Erase memory and start on a random location 80 | for ant in colony.ants 81 | setfield!(ant,:memory,[]) 82 | setfield!(ant,:node,rand(1:N)) 83 | end 84 | 85 | # Explore solution space until all ants find target node 86 | complete_tours = 0 87 | while(complete_tours < colony.number_of_ants) 88 | complete_tours = 0 89 | for ant in colony.ants 90 | neighbors = find_neighbors(colony.A,ant.node) 91 | neighbors = setdiff(neighbors,ant.memory) # Neighbors - memory 92 | 93 | if (isempty(neighbors) == false && ant.node ≠ colony.target_node) 94 | fitness = [] 95 | for j in neighbors 96 | η = 1/colony.A[ant.node,j] # Attractiveness 97 | p = (colony.τ[ant.node,j]^colony.α)*(η^colony.β) 98 | push!(fitness,p) 99 | end 100 | 101 | # Move to new node stochastically 102 | k = neighbors[roulette_selection(fitness)] 103 | setfield!(ant,:node,k) 104 | 105 | # Add node to memory 106 | memory = ant.memory ∪ k 107 | setfield!(ant,:memory,memory) 108 | else 109 | complete_tours += 1 110 | end 111 | end 112 | end 113 | end 114 | 115 | # Update pheromone levels 116 | function update_pheromone(colony :: antColony) 117 | N, = size(colony.A) 118 | 119 | for ant in colony.ants 120 | for i in 1:(N-1) 121 | p_from = findfirst(ant.memory .== i) 122 | for j in (i+1):N 123 | p_to = findfirst(ant.memory .== j) 124 | if (isnothing(p_from) == false && isnothing(p_to) == false) 125 | if (p_to - p_from == 1) 126 | Δ = colony.Q/length(ant.memory) 127 | else 128 | Δ = 0.0 129 | end 130 | else 131 | Δ = 0.0 132 | end 133 | 134 | colony.τ[i,j] = (1.0-colony.ρ)*colony.τ[i,j] + Δ 135 | setfield!(colony,:τ,colony.τ) 136 | end 137 | end 138 | end 139 | end 140 | 141 | #====================== MAIN =======================# 142 | A = [0 1 1 0 0; 143 | 1 0 1 0 0; 144 | 1 1 0 1 1; 145 | 0 0 1 0 1; 146 | 0 0 1 1 0] 147 | colony = build_colony(A,5,100) 148 | 149 | # Main loop 150 | for it in 1:10 151 | construct_solutions(colony) 152 | update_pheromone(colony) 153 | end 154 | 155 | # Print results 156 | for i in 1:5 157 | println(colony.τ[i,:]) 158 | end 159 | -------------------------------------------------------------------------------- /optimization/genetic.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using PyPlot 3 | 4 | # Structure for an individual 5 | # and its initialization 6 | mutable struct individual 7 | chromossome :: Vector{Float64} 8 | end 9 | 10 | function individual() 11 | x = [randn(),randn(),randn()] 12 | return individual(x) 13 | end 14 | 15 | # Computes the fitness of each member of the population. 16 | # In this case it is the norm of the difference between 17 | # each member's chromossome and the target 18 | function Fitness(pop,target) 19 | N = length(pop) 20 | r = [] 21 | av = 0 22 | for p in pop 23 | F = -norm(p.chromossome - target) 24 | av += F 25 | push!(r,F) 26 | end 27 | 28 | return r,av/N 29 | end 30 | 31 | # Elitist selection of N elements 32 | function Selection(pop,F,N) 33 | id = sortperm(F,rev=true) 34 | new_pop = [] 35 | 36 | for i in id[1:N] 37 | push!(new_pop,pop[i]) 38 | end 39 | 40 | return new_pop 41 | end 42 | 43 | # K-way tournment selecting n individuals 44 | function kway(Fitness,k,n) 45 | N = length(Fitness) 46 | 47 | selection = [] 48 | for i in 1:n 49 | idx = rand(1:N,k) 50 | p = argmax(Fitness[idx]) 51 | push!(selection,idx[p]) 52 | end 53 | 54 | return selection 55 | end 56 | 57 | # Crossover function 58 | function crossover(P1,P2) 59 | N = length(P1.chromossome) 60 | C = individual() 61 | 62 | for n in 1:N 63 | if (rand() < 0.5) 64 | x = P1.chromossome[n] 65 | else 66 | x = P2.chromossome[n] 67 | end 68 | C.chromossome[n] = x 69 | end 70 | 71 | return C 72 | end 73 | 74 | # Creates nchildren individuals using crossover 75 | # between pairs of individuals. 76 | function Reproduction(pop,nchildren) 77 | F,t = Fitness(pop,target) 78 | offspring = [] 79 | for i in 1:nchildren 80 | p1,p2 = kway(F,20,2) 81 | c = crossover(pop[p1],pop[p2]) 82 | push!(offspring,c) 83 | end 84 | 85 | return vcat(pop,offspring) 86 | end 87 | 88 | # Applies mutation to population 89 | function Mutation(pop,η) 90 | N = length(pop) 91 | L = length(pop[1].chromossome) 92 | #α = 1.0 93 | 94 | for p in 1:N 95 | for i in 1:L 96 | if (rand() < η) 97 | x = pop[p].chromossome[i] 98 | y = x + randn() 99 | pop[p].chromossome[i] = y 100 | end 101 | end 102 | end 103 | 104 | return pop 105 | end 106 | 107 | # Training function going over selection, reproduction and mutation 108 | function train(pop,target) 109 | K = length(pop) 110 | R = 50 111 | Fi = [] 112 | for it in 1:200 113 | F,a = Fitness(pop,target) 114 | pop = Selection(pop,F,(K-R)) 115 | pop = Reproduction(pop,R) 116 | pop = Mutation(pop,0.005) 117 | 118 | push!(Fi,a) 119 | end 120 | 121 | return pop,Fi 122 | end 123 | 124 | # Shows the average chromossome value of the population 125 | function showresult(pop) 126 | r = zeros(3) 127 | 128 | for p in pop 129 | r += p.chromossome 130 | end 131 | 132 | println(r/length(pop)) 133 | end 134 | 135 | #=============== MAIN ==================# 136 | NPop = 100 137 | population = [individual() for i in 1:NPop] 138 | target = [3.1423,2.3567,4.5442] 139 | population,y = train(population,target) 140 | showresult(population) 141 | 142 | plot(y) 143 | xlabel("Generation") 144 | ylabel("Average Fitness Value") 145 | show() 146 | 147 | 148 | -------------------------------------------------------------------------------- /optimization/swarm.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | # Agent structure 4 | mutable struct agent 5 | x :: Vector{Float64} # Position 6 | v :: Vector{Float64} # Velocity 7 | p :: Vector{Float64} # Best position 8 | F :: Float64 # Fitness 9 | Fbest :: Float64 # Best fitness 10 | end 11 | 12 | # Swarm structure 13 | mutable struct swarm 14 | a :: Vector{agent} # Agents 15 | p :: Vector{Float64} # Best position 16 | Fbest :: Float64 # Best swarm fitness 17 | xmin :: Vector{Float64} # Minimum position 18 | xmax :: Vector{Float64} # Maximum position 19 | vmin :: Vector{Float64} # Minimum velocity 20 | vmax :: Vector{Float64} # Maximum velocity 21 | c1 :: Float64 # Cognitive parameter 22 | c2 :: Float64 # Social parameter 23 | w :: Float64 # Inertia coefficient 24 | end 25 | 26 | # Non-convex test functions: Rosenbrock and Rastrigin 27 | function Rosenbrock(x :: Vector{Float64}) 28 | a = 1.0 29 | b = 100.0 30 | 31 | return (a-x[1])^2 + b*(x[2] - x[1]^2)^2 32 | end 33 | 34 | function Rastrigin(x :: Vector{Float64}) 35 | A = 10 36 | f = 2A 37 | for i in 1:2 38 | f += x[i]^2 - A*cos(2π*x[i]) 39 | end 40 | 41 | return f 42 | end 43 | 44 | # Initialization function for the swarm 45 | function swarm(xi :: Vector{Float64},xa :: Vector{Float64},vi :: Vector{Float64},va :: Vector{Float64},N :: Int) 46 | Fbest = 1E5 47 | a = [] 48 | p = xi + rand()*(xa - xi) 49 | 50 | for i in 1:N 51 | r1 = xi[1] + rand()*(xa[1] - xi[1]) 52 | r2 = xi[2] + rand()*(xa[2] - xi[2]) 53 | x = [r1,r2] 54 | 55 | r1 = vi[1] + rand()*(va[1] - vi[1]) 56 | r2 = vi[2] + rand()*(va[2] - vi[2]) 57 | v = [r1,r2] 58 | F = Rosenbrock(x) 59 | if (F < Fbest) 60 | Fbest = F 61 | p = x 62 | end 63 | t = agent(x,v,x,F,F) 64 | 65 | push!(a,t) 66 | end 67 | 68 | return swarm(a,p,Fbest,xi,xa,vi,va,1.5,0.8,0.8) 69 | end 70 | 71 | # Update position and velocity for each agent of the swarm 72 | function updateXV!(s :: swarm) 73 | for a in s.a 74 | r1 = rand() 75 | r2 = rand() 76 | 77 | setfield!(a, :v, s.w*a.v + s.c1*r1*(a.p - a.x) + s.c2*r2*(s.p - a.x)) 78 | setfield!(a, :x, a.x + a.v) 79 | end 80 | end 81 | 82 | # Get fitness function. In this case, how close it is from the zero 83 | # of the function. 84 | function getFitness!(s :: swarm) 85 | for a in s.a 86 | setfield!(a, :F, Rosenbrock(a.x)) 87 | end 88 | end 89 | 90 | # Find agent closest to the zero of the function and update best 91 | # position for each agent and for the swarm. 92 | function updateBest!(s :: swarm) 93 | for a in s.a 94 | if (a.F < a.Fbest) 95 | setfield!(a, :Fbest, a.F) 96 | setfield!(a, :p, a.x) 97 | end 98 | if (a.F < s.Fbest) 99 | setfield!(s, :Fbest, a.F) 100 | setfield!(s, :p, a.x) 101 | end 102 | end 103 | end 104 | 105 | # Train swarm. 106 | function train!(s :: swarm) 107 | # Main loop 108 | while(s.Fbest > 1E-2) 109 | updateBest!(s) 110 | updateXV!(s) 111 | getFitness!(s) 112 | end 113 | 114 | return s.p 115 | end 116 | 117 | # Show results 118 | function showParticles(s :: swarm) 119 | y_sp = LinRange(-5.12,5.12,100) 120 | x_sp = LinRange(-5.12,5.12,100) 121 | map = zeros(100,100) 122 | for y in 1:100 123 | for x in 1:100 124 | map[y,x] = Rosenbrock([x_sp[x],y_sp[y]]) 125 | end 126 | end 127 | 128 | contourf(x_sp,y_sp,map) 129 | 130 | for a in s.a 131 | plot(a.x[1],a.x[2],"o",color="orange") 132 | end 133 | 134 | show() 135 | end 136 | 137 | #=============== MAIN ==============# 138 | s = swarm([-5.12,-5.12],[5.12,5.12],[-1E-1,-1E-1],[1.0,1.0],25) 139 | sol = train!(s) 140 | showParticles(s) 141 | println(s.p,s.Fbest) 142 | -------------------------------------------------------------------------------- /reinforced/A2C.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using Flux 3 | 4 | 5 | # Initialize Neural Network 6 | function SetActorNetwork() 7 | m = Chain( 8 | Dense(4,32,σ), 9 | Dense(32,4), 10 | softmax, 11 | ) 12 | 13 | return m 14 | end 15 | 16 | function SetCriticNetwork() 17 | m = Chain( 18 | Dense(4,8,σ), 19 | Dense(8,1) 20 | ) 21 | 22 | return m 23 | end 24 | 25 | function roulette_selection(fitness) 26 | total_fitness = sum(fitness) 27 | r = rand()*total_fitness 28 | 29 | i = 0 30 | while(r ≥ 0) 31 | i += 1 32 | r -= fitness[i] 33 | end 34 | 35 | return i 36 | end 37 | 38 | function embedding(s) 39 | if (s == 1) 40 | state = reshape([1,0,0,0],4,1) 41 | elseif (s == 2) 42 | state = reshape([0,1,0,0],4,1) 43 | elseif (s == 3) 44 | state = reshape([0,0,1,0],4,1) 45 | else 46 | state = reshape([0,0,0,1],4,1) 47 | end 48 | 49 | return state 50 | end 51 | 52 | 53 | # Train a neural network 54 | function TrainNeuralNetwork!(actor,critic,RewardMatrix,StateTransitionMatrix) 55 | ηa = 1E-5 56 | ηc = 1E-3 57 | num_episodes = 100 58 | num_epochs = 1000 59 | γ = 0.99 60 | 61 | actor_optimizer = Flux.Optimise.ADAM(ηa) 62 | critic_optimizer = Flux.Optimise.ADAM(ηc) 63 | 64 | loss = [] 65 | 66 | for epoch in 1:num_epochs 67 | avR = 0 68 | avS = 0 69 | avA = 0 70 | for episode in 1:num_episodes 71 | s = rand([1,2,4]) 72 | R = 0 73 | steps = 0 74 | V = critic(embedding(s))[1,1] 75 | errorV = 0 76 | 77 | while(s ≠ 3 && steps < 5) 78 | # Sample {s,a} from actor(a|s) 79 | steps += 1 80 | actor_output = actor(embedding(s)) 81 | action = roulette_selection(actor_output) 82 | 83 | # Get reward and next state 84 | r = RewardMatrix[s,action] 85 | R += γ*r 86 | ns = StateTransitionMatrix[s,action] 87 | 88 | # Calculate advantage 89 | lastV = V 90 | V = critic(embedding(ns))[1,1] 91 | A = r + γ*V - lastV # TD Error 92 | avA += A 93 | 94 | # Update critic 95 | ∇c = Flux.gradient(params(critic)) do 96 | Flux.mse(critic(embedding(s)),r+γ*V) 97 | end 98 | Flux.Optimise.update!(critic_optimizer,params(critic),∇c) 99 | 100 | # Update actor 101 | ∇a = Flux.gradient(params(actor)) do 102 | -sum(log.(actor(embedding(s))).*Flux.onehot(action,1:4))*A 103 | end 104 | Flux.Optimise.update!(actor_optimizer,params(actor),∇a) 105 | 106 | # Update state 107 | s = ns 108 | end 109 | 110 | avR += R 111 | avS += steps 112 | end 113 | 114 | 115 | avR /= num_episodes 116 | avS /= num_episodes 117 | avA /= num_episodes 118 | 119 | push!(loss,avS) 120 | println("Epoch ",epoch,", average reward: ",avR,", average steps: ",avS, ", : ",avA) 121 | end 122 | 123 | return loss 124 | end 125 | 126 | function CheckPolicy(actor) 127 | for (s,t) in zip([1,2,4],["A","B","D"]) 128 | actor_output = actor(embedding(s)) 129 | x = argmax(actor_output[:,1]) 130 | 131 | if (x == 1) 132 | a = "up" 133 | end 134 | if (x == 2) 135 | a = "down" 136 | end 137 | if (x == 3) 138 | a = "left" 139 | end 140 | if (x == 4) 141 | a = "right" 142 | end 143 | 144 | println(t,": ",a) 145 | end 146 | end 147 | 148 | #====================================================# 149 | # MAIN # 150 | #====================================================# 151 | # States 152 | # A = [1 0 0 0] 153 | # B = [0 1 0 0] 154 | # C = [0 0 1 0] 155 | # D = [0 0 0 1] 156 | 157 | # Actions 158 | # up = [1 0 0 0] 159 | # down = [0 1 0 0] 160 | # left = [0 0 1 0] 161 | # right = [0 0 0 1] 162 | 163 | actor = SetActorNetwork() 164 | critic = SetCriticNetwork() 165 | 166 | # Reward matrix 167 | Rm = [-1 -1 -1 0; 168 | -1 0 0 -1; 169 | -1 -1 -1 0; 170 | 0 -1 100 -1] 171 | 172 | # Next state matrix 173 | M = [1 1 1 2; 174 | 2 4 1 2; 175 | 3 3 3 4; 176 | 2 4 3 4] 177 | 178 | R = TrainNeuralNetwork!(actor,critic,Rm,M) 179 | CheckPolicy(actor) 180 | plot(R) 181 | xlabel("Episode") 182 | ylabel("Steps") 183 | show() 184 | 185 | 186 | -------------------------------------------------------------------------------- /reinforced/A2C/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | /**************************************** 12 | * Choose an action based on the policy * 13 | * **************************************/ 14 | int choose(float pi[9]) { 15 | float cum[9]; 16 | int a; 17 | 18 | // Cumulative 19 | cum[0] = pi[0]; 20 | for(a = 1; a < 9; a ++) 21 | cum[a] = pi[a] + cum[a-1]; 22 | 23 | // Normalize 24 | for(a = 0; a < 9; a ++) 25 | cum[a] /= cum[8]; 26 | 27 | // Choose action 28 | float r = (float)rand()/RAND_MAX; 29 | a = 0; 30 | while(r > cum[a]) 31 | a ++; 32 | 33 | return a; 34 | } 35 | 36 | /********************* 37 | * Move to new state * 38 | * *******************/ 39 | void moveto(int a, int &x, int &y, int BoardSize) { 40 | switch(a) { 41 | case 0: 42 | x ++; 43 | y ++; 44 | break; 45 | case 1: 46 | x ++; 47 | break; 48 | case 2: 49 | x ++; 50 | y --; 51 | break; 52 | case 3: 53 | y ++; 54 | break; 55 | case 5: 56 | y --; 57 | break; 58 | case 6: 59 | x --; 60 | y ++; 61 | break; 62 | case 7: 63 | x --; 64 | break; 65 | case 8: 66 | x --; 67 | y --; 68 | break; 69 | } 70 | if (x >= BoardSize) 71 | x = 0; 72 | if (x < 0) 73 | x = BoardSize - 1; 74 | if (y >= BoardSize) 75 | y = 0; 76 | if (y < 0) 77 | y = BoardSize - 1; 78 | } 79 | 80 | /* *************** 81 | * MAIN FUNCTION * 82 | * ***************/ 83 | int main(void) { 84 | // Declaration of Constants 85 | const int BoardSize = 3; 86 | const int MaxSteps = 150; 87 | const unsigned int xo = 1; 88 | const unsigned int yo = 1; 89 | const float gamma = 0.8; 90 | const int N = 3; 91 | 92 | // Declaration of Variables 93 | bool active; 94 | int a,T; 95 | int t,k; 96 | float R,Loss; 97 | float reward[MaxSteps]; 98 | 99 | int x,y; 100 | 101 | // Neural net 102 | FeedForward Actor(2); 103 | FeedForward Critic(2); 104 | tensor pi(9,1); 105 | tensor g(1,9); 106 | tensor grad[MaxSteps]; 107 | tensor state[MaxSteps]; 108 | tensor input(2,1); 109 | tensor ga(1,9); 110 | tensor gc(1,1); 111 | 112 | ofstream myfile; 113 | 114 | //--------- Code ---------- 115 | myfile.open("out.dat"); 116 | 117 | // Setup feedforward neural network 118 | Actor.add_layer(4,"sigmoid"); 119 | Actor.add_layer(6,"sigmoid"); 120 | Actor.add_layer(9,"none"); 121 | 122 | Critic.add_layer(4,"sigmoid"); 123 | Critic.add_layer(3,"sigmoid"); 124 | Critic.add_layer(1,"none"); 125 | 126 | // Initialize tensors with proper size 127 | for(unsigned int i = 0; i < MaxSteps; i ++) { 128 | grad[i].set(1,9); 129 | state[i].set(2,1); 130 | } 131 | 132 | // Initialization 133 | srand(time(NULL)); 134 | 135 | // Main loop 136 | do { 137 | // Get an average loss 138 | Loss = 0; 139 | for(int avg = 0; avg < 10; avg ++) { 140 | //----------------------------------------------------------------------// 141 | // Sample trajectory 142 | //----------------------------------------------------------------------// 143 | t = 0; 144 | active = true; 145 | x = rand()%BoardSize; 146 | y = rand()%BoardSize; 147 | R = 0; 148 | do { 149 | // Run policy 150 | state[t] = {float(x),float(y)}; 151 | Actor.feedforward(state[t]); 152 | pi = Actor.output().softmax(); 153 | a = pi.choose(); 154 | 155 | // Store trajectory 156 | grad[t] = pi.REINFORCE_grad_loss(a); 157 | 158 | // Move to new state 159 | moveto(a,x,y,BoardSize); 160 | 161 | // Obtain reward 162 | reward[t] = (x == xo && y == yo) ? 100 : -1; 163 | 164 | t ++; 165 | if (t >= MaxSteps || (x == xo && y == yo)) 166 | active = false; 167 | 168 | } while(active); 169 | T = t; 170 | cout << "Ended episode after " << T << " steps" << endl; 171 | Loss += T; 172 | //----------------------------------------------------------------------// 173 | 174 | ga.zeros(); 175 | gc.zeros(); 176 | for(t = 0; t < T; t ++) { 177 | if (t+N >= T) { 178 | R = 0; 179 | } 180 | else { 181 | Critic.feedforward(state[t+N]); 182 | R = Critic.output()(0,0); 183 | } 184 | 185 | for(k = min(T-t,N)-1; k >= 0; k --) { 186 | R = reward[t+k] + gamma*R; 187 | } 188 | 189 | Critic.feedforward(state[t]); 190 | ga += grad[t]*(R-Critic.output()(0,0)); 191 | gc += Critic.output()(0,0)-R; 192 | } 193 | ga /= (float)T; 194 | gc /= (float)T; 195 | Actor.backpropagate(ga); 196 | Critic.backpropagate(gc); 197 | } 198 | Actor.applygrads(-0.001); 199 | Critic.applygrads(0.001); 200 | 201 | Loss /= 10; 202 | myfile << Loss << endl; 203 | } while(Loss > 1); 204 | 205 | myfile.close(); 206 | } 207 | -------------------------------------------------------------------------------- /reinforced/DDPG.jl: -------------------------------------------------------------------------------- 1 | using Flux 2 | using PyPlot 3 | using IterTools: ncycle 4 | 5 | # Neural network architecture 6 | function SetNet(inputChannels,outputChannels) 7 | m = Chain( 8 | Dense(inputChannels,32,tanh; init = Flux.glorot_normal()), 9 | Dense(32,outputChannels,sigmoid; init = Flux.glorot_normal()) 10 | ) 11 | 12 | return m 13 | end 14 | 15 | function SetJoined(nstates,nactions) 16 | m = Chain(x->vcat(x[1],x[2]), 17 | Dense(nstates+nactions,32,tanh; init = Flux.glorot_normal()), 18 | Dense(32,64,tanh; init = Flux.glorot_normal()), 19 | Dense(64,1;init = Flux.glorot_normal()) 20 | ) 21 | 22 | return m 23 | end 24 | 25 | # An approximator for the neural network with an optimiser 26 | mutable struct NNApprox 27 | model :: Chain 28 | target :: Chain 29 | optimiser :: Flux.Optimiser 30 | end 31 | 32 | # Returns an approximator 33 | function SetAppr(η) 34 | model = SetNet(1,2) 35 | target = SetNet(1,2) 36 | 37 | Flux.loadparams!(target,Flux.params(model)) 38 | 39 | op = Flux.Optimiser(ClipValue(1E-1),Flux.Optimise.ADAM(η)) 40 | 41 | return NNApprox(model,target,op) 42 | end 43 | 44 | function SetApprJ(η) 45 | model = SetJoined(1,2) 46 | target = SetJoined(1,2) 47 | 48 | Flux.loadparams!(target,Flux.params(model)) 49 | 50 | op = Flux.Optimiser(ClipValue(1E-1),Flux.Optimise.ADAM(η)) 51 | 52 | return NNApprox(model,target,op) 53 | end 54 | 55 | # Evaluate the trained approximator 56 | function evaluate(ap :: NNApprox, M :: Matrix{Float64}) 57 | 58 | for x in eachcol(M) 59 | ŷ = ap.model(x) 60 | 61 | println(x," = ",ŷ) 62 | end 63 | end 64 | 65 | #================================================================================# 66 | # REPLAY BUFFER 67 | #================================================================================# 68 | mutable struct ReplayBuffer 69 | buffer::Vector{Tuple} 70 | max_size::Int 71 | curr_size::Int 72 | end 73 | 74 | function ReplayBuffer(buffer_size::Int) 75 | return ReplayBuffer(Vector{Tuple}(), buffer_size, 0) 76 | end 77 | 78 | function store!(buffer::ReplayBuffer, item) 79 | if (buffer.curr_size ≥ buffer.max_size) 80 | popfirst!(buffer.buffer) 81 | else 82 | buffer.curr_size += 1 83 | end 84 | push!(buffer.buffer, item) 85 | end 86 | 87 | function sample(buffer::ReplayBuffer, batch_size::Int) 88 | indices = rand(1:length(buffer.buffer), min(batch_size,buffer.curr_size)) 89 | return [buffer.buffer[i] for i in indices] 90 | end 91 | 92 | #---------------------------- 93 | # REINFORCEMENT LEARNING 94 | #---------------------------- 95 | function ε_greedy(s,ε,Q) 96 | sz = length(Q) 97 | 98 | if (rand() < ε) # Exploration 99 | a = rand(1:sz) 100 | else # Exploitation 101 | a = argmax(Q) 102 | end 103 | 104 | return a 105 | end 106 | 107 | function train!(A::NNApprox,C::NNApprox,R::ReplayBuffer) 108 | γ = 0.95 109 | S = sample(R,100) 110 | 111 | for (s,a,r,s′,d) in S 112 | y = r + γ*(1-d)*C.target(([s′],A.target([s′])))[1] 113 | 114 | ∇c = Flux.gradient(params(C.model)) do 115 | loss = (y - C.model(([s],a))[1])^2 116 | end 117 | 118 | ∇a = Flux.gradient(params(A.model)) do 119 | loss = -C.model(([s],A.model([s])))[1] 120 | end 121 | 122 | Flux.Optimise.update!(C.optimiser,Flux.params(C.model),∇c) 123 | Flux.Optimise.update!(A.optimiser,Flux.params(A.model),∇a) 124 | end 125 | end 126 | 127 | 128 | # Replay buffer 129 | R = ReplayBuffer(40000) 130 | 131 | # Approximator for Q-value 132 | Actor = SetAppr(1E-3) 133 | Critic = SetApprJ(2E-3) 134 | 135 | γ = 0.95 136 | α = 0.1 137 | ζ = 1 # Exploration rate 138 | τ = 0.005 # Target update rate 139 | g = 9.8067 # [m/s²] 140 | m = 1 # [kg] 141 | 142 | y_plot = [] 143 | for tc in 1:200000 144 | # Begin 145 | s = 5*(rand()-0.5) 146 | totalReward = 0 147 | 148 | ti = 0 149 | while(abs(s - 3) > 1E-3 && ti < 10) 150 | ti += 1 151 | 152 | a = Actor.model([s]) 153 | 154 | # Environment 155 | θ = (a[1]*(1-ζ) + rand()*ζ)*π 156 | vo = (a[2]*(1-ζ) + rand()*ζ)*10 157 | 158 | t = (2*vo/g)*sin(θ) 159 | x = vo*t*cos(θ) 160 | s′ = s + x 161 | r = -abs(s′-3) 162 | totalReward += r 163 | 164 | d = false 165 | if (abs(s′-3) ≤ 1E-3 || ti ≥ 10) 166 | d = true 167 | end 168 | 169 | store!(R,(s,a,r,s′,d)) 170 | s = s′ 171 | 172 | # Reduce exploration 173 | global ζ = max(1E-6,ζ-1E-6) 174 | end 175 | 176 | if (tc % 100 == 0) 177 | push!(y_plot,totalReward) 178 | println("Reward: ",totalReward,", Exploration: ",ζ,", Steps: ",ti, ", Time: ",tc) 179 | end 180 | 181 | train!(Actor,Critic,R) 182 | Flux.loadparams!(Actor.target,τ.*Flux.params(Actor.model) .+ (1-τ).*Flux.params(Actor.model)) 183 | Flux.loadparams!(Critic.target,τ.*Flux.params(Critic.model) .+ (1-τ).*Flux.params(Critic.model)) 184 | end 185 | 186 | function showmat(M) 187 | for m in eachrow(M) 188 | println(m) 189 | end 190 | end 191 | 192 | #showmat(Q) 193 | for s in 1:4 194 | a = Actor.target([s]) 195 | θ = a[1]*π 196 | vo = a[2]*10 197 | 198 | t = (2*vo/(m*g))*sin(θ) 199 | x = s + vo*t*cos(θ) 200 | 201 | println("xo: ",s,", θ: ",θ*180/π,", vo: ",vo, ", x: ",x) 202 | end 203 | 204 | plot(y_plot) 205 | show() 206 | 207 | -------------------------------------------------------------------------------- /reinforced/PPO.jl: -------------------------------------------------------------------------------- 1 | using Flux 2 | using PyPlot 3 | using Statistics 4 | using LinearAlgebra 5 | 6 | 7 | # Actor estimates action given a state 8 | function SetActorNetwork() 9 | m = Chain( 10 | Dense(4,32,σ), 11 | Dense(32,5), 12 | softmax, 13 | ) 14 | 15 | return m 16 | end 17 | 18 | # Critic estimates value function given a state 19 | function SetCriticNetwork() 20 | m = Chain( 21 | Dense(4,8,σ), 22 | Dense(8,1) 23 | ) 24 | 25 | return m 26 | end 27 | 28 | # Roulette selection from fitness function 29 | function roulette_selection(fitness) 30 | total_fitness = sum(fitness) 31 | r = rand()*total_fitness 32 | 33 | i = 0 34 | while(r ≥ 0) 35 | i += 1 36 | r -= fitness[i] 37 | end 38 | 39 | return i 40 | end 41 | 42 | # Convert a scalar state into a vector 43 | function embedding(s) 44 | if (s == 1) 45 | state = reshape([1,0,0,0],4,1) 46 | elseif (s == 2) 47 | state = reshape([0,1,0,0],4,1) 48 | elseif (s == 3) 49 | state = reshape([0,0,1,0],4,1) 50 | else (s == 4) 51 | state = reshape([0,0,0,1],4,1) 52 | end 53 | 54 | return state 55 | end 56 | 57 | # Clip advantage 58 | function clip(A,ε,r) 59 | x = copy(r) 60 | if (A > 0) 61 | if (r ≥ 1+ε) 62 | x = 1+ε 63 | end 64 | else 65 | if (r < 1-ε) 66 | x = 1-ε 67 | end 68 | end 69 | 70 | return x*A 71 | end 72 | 73 | # Returns a zero gradient with appropriate dimensions 74 | function zerograd(network) 75 | p = params(network) 76 | t1,t2 = size(p[1]) 77 | x = zeros(t2,1) 78 | 79 | ∇ = Flux.gradient(p) do 80 | 0*Flux.mse(critic(x),0) 81 | end 82 | 83 | return ∇ 84 | end 85 | 86 | # Train a neural network 87 | function TrainNeuralNetwork!(actor,critic,RewardMatrix,StateTransitionMatrix) 88 | ηa = 1E-3 89 | ηc = 1E-3 90 | γ = 0.99 91 | ε = 0.2 92 | 93 | T = 5 94 | num_actors = 10 95 | num_interactions = 10000 96 | K = 10 97 | 98 | states = zeros(num_actors,T) 99 | rewards = zeros(num_actors,T) 100 | values = zeros(num_actors,T) 101 | advantages = zeros(num_actors,T) 102 | actions = zeros(num_actors,T) 103 | probs = zeros(num_actors,T) 104 | 105 | actor_optimizer = Flux.Optimise.ADAM(ηa) 106 | critic_optimizer = Flux.Optimise.ADAM(ηc) 107 | 108 | loss = [] 109 | 110 | for interaction in 1:num_interactions 111 | avR = 0 112 | avS = 0 113 | avA = 0 114 | for act in 1:num_actors # Run the policy for many actors in parallel 115 | # Run policy for T timesteps 116 | s = rand([1,2,4]) # Initial state 117 | R = 0 # Initial reward 118 | V = critic(embedding(s))[1,1] # Initial value 119 | 120 | steps = 0 # Steps counter 121 | for t in 1:T 122 | # Sample {s,a} from actor(a|s) 123 | steps += 1 124 | actor_output = actor(embedding(s)) 125 | action = roulette_selection(actor_output) 126 | 127 | # Get reward and next state 128 | r = RewardMatrix[s,action] 129 | R += γ*r 130 | ns = StateTransitionMatrix[s,action] 131 | 132 | # Calculate advantage 133 | lastV = V 134 | V = critic(embedding(ns))[1,1] 135 | A = r + γ*V - lastV # TD Error 136 | 137 | # Store values 138 | states[act,t] = s 139 | rewards[act,t] = r 140 | values[act,t] = V 141 | advantages[act,t] = A 142 | actions[act,t] = action 143 | probs[act,t] = actor_output⋅Flux.onehot(action,1:5) 144 | 145 | # Move to next state 146 | s = ns 147 | end 148 | end 149 | 150 | M = num_actors*T 151 | 152 | # Updates 153 | for epoch in 1:K 154 | ∇c = zerograd(critic) 155 | ∇a = zerograd(actor) 156 | 157 | for minibatch in 1:M 158 | act = rand(1:num_actors) 159 | t = rand(1:T) 160 | 161 | s = states[act,t] 162 | r = rewards[act,t] 163 | V = values[act,t] 164 | A = advantages[act,t] 165 | action = actions[act,t] 166 | πθo = probs[act,t] 167 | 168 | # critic gradient 169 | ∇c .+= Flux.gradient(params(critic)) do 170 | Flux.mse(critic(embedding(s)),r+γ*V) 171 | end 172 | 173 | # actor gradient 174 | ∇a .+= Flux.gradient(params(actor)) do 175 | πθ = actor(embedding(s))⋅Flux.onehot(action,1:5) 176 | r = exp(log(πθ) - log(πθo)) 177 | -clip(A,ε,r) 178 | end 179 | end 180 | 181 | Flux.Optimise.update!(critic_optimizer,params(critic),∇c./M) 182 | Flux.Optimise.update!(actor_optimizer,params(actor),∇a./M) 183 | end 184 | 185 | avR = mean(rewards) 186 | avS = mean(states) 187 | avA = mean(advantages) 188 | 189 | push!(loss,avR) 190 | println("Epoch ",interaction,", average reward: ",avR,", average steps: ",avS, ", : ",avA) 191 | end 192 | 193 | return loss 194 | end 195 | 196 | function CheckPolicy(actor) 197 | for (s,t) in zip(1:4,["A","B","C","D"]) 198 | actor_output = actor(embedding(s)) 199 | x = argmax(actor_output[:,1]) 200 | 201 | if (x == 1) 202 | a = "up" 203 | end 204 | if (x == 2) 205 | a = "down" 206 | end 207 | if (x == 3) 208 | a = "left" 209 | end 210 | if (x == 4) 211 | a = "right" 212 | end 213 | if (x == 5) 214 | a = "stay" 215 | end 216 | 217 | println(t,": ",a) 218 | end 219 | end 220 | 221 | #====================================================# 222 | # MAIN # 223 | #====================================================# 224 | # States 225 | # A = [1 0 0 0] 226 | # B = [0 1 0 0] 227 | # C = [0 0 1 0] 228 | # D = [0 0 0 1] 229 | 230 | # Actions 231 | # up = [1 0 0 0 0] 232 | # down = [0 1 0 0 0] 233 | # left = [0 0 1 0 0] 234 | # right = [0 0 0 1 0] 235 | # stay = [0 0 0 0 1] 236 | 237 | actor = SetActorNetwork() 238 | critic = SetCriticNetwork() 239 | 240 | # Reward matrix 241 | Rm = [-1 -1 -1 0 0; 242 | -1 0 0 -1 0; 243 | -1 -1 -1 0 10; 244 | 0 -1 100 -1 0] 245 | 246 | # Next state matrix 247 | M = [1 1 1 2 1; 248 | 2 4 1 2 2; 249 | 3 3 3 4 3; 250 | 2 4 3 4 4] 251 | 252 | R = TrainNeuralNetwork!(actor,critic,Rm,M) 253 | CheckPolicy(actor) 254 | plot(R) 255 | xlabel("Episode") 256 | ylabel("Rewards") 257 | show() 258 | 259 | 260 | -------------------------------------------------------------------------------- /reinforced/Q.f90: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #!/usr/bin/env python 3 | 4 | __author__ = """Prof. Carlo R. da Cunha, Ph.D. """ 5 | 6 | import os 7 | 8 | os.system('clear') 9 | 10 | print('.-------------------------------.') 11 | print('| Q-Learning |#') 12 | print('| By.: Prof. Carlo R. da Cunha |#') 13 | print('| |#') 14 | print('| 2021 |#') 15 | print('\'-------------------------------\'#') 16 | print(' ################################') 17 | print('') 18 | print('Importing Libraries:') 19 | 20 | import numpy as np 21 | import matplotlib.pyplot as pl 22 | 23 | #--------------# 24 | # Dictionaries # 25 | #--------------# 26 | 27 | action_space = { 28 | "up" : 0, 29 | "down" : 1, 30 | "left" : 2, 31 | "right" : 3 32 | } 33 | 34 | state_space = { 35 | "A" : 0, 36 | "B" : 1, 37 | "C" : 2, 38 | "D" : 3 39 | } 40 | 41 | #--------------------------# 42 | # Epsilon-greedy algorithm # 43 | #--------------------------# 44 | def egreedy(state,Q): 45 | r1 = np.random.rand() 46 | 47 | if (r1 < 0.1): 48 | if (state == state_space["A"]): 49 | action = action_space["right"] 50 | elif (state == state_space["B"]): 51 | r2 = np.random.rand() 52 | if (r2 < 0.5): 53 | action = action_space["left"] 54 | else: 55 | action = action_space["down"] 56 | elif (state == state_space["C"]): 57 | action = action_space["right"] 58 | elif (state == state_space["D"]): 59 | r2 = np.random.rand() 60 | if (r2 < 0.5): 61 | action = action_space["left"] 62 | else: 63 | action = action_space["up"] 64 | else: 65 | action = np.argmax(Q[state,:]) 66 | 67 | return action 68 | 69 | #-----------------# 70 | # Find next state # 71 | #-----------------# 72 | def next_state(state,action): 73 | nstate = state 74 | if (state == state_space["A"]): 75 | if (action == action_space["right"]): 76 | nstate = state_space["B"] 77 | elif (state == state_space["B"]): 78 | if (action == action_space["left"]): 79 | nstate = state_space["A"] 80 | elif (action == action_space["down"]): 81 | nstate = state_space["D"] 82 | elif (state == state_space["C"]): 83 | if (action == action_space["right"]): 84 | nstate = state_space["D"] 85 | elif (state == state_space["D"]): 86 | if (action == action_space["left"]): 87 | nstate = state_space["C"] 88 | elif (action == action_space["up"]): 89 | nstate = state_space["B"] 90 | 91 | return nstate 92 | 93 | #-------------------------# 94 | # Find reward for a state # 95 | #-------------------------# 96 | def reward(state): 97 | if (state == state_space["A"]): 98 | r = -1.0 99 | elif (state == state_space["B"]): 100 | r = -0.5 101 | elif (state == state_space["C"]): 102 | r = 10.0 103 | elif (state == state_space["D"]): 104 | r = -0.25 105 | 106 | return r 107 | 108 | #===============================================# 109 | # MAIN # 110 | #===============================================# 111 | alpha = 0.7 112 | gamma = 0.95 113 | Q = np.zeros((4,4)) 114 | y = [] 115 | 116 | for episode in range(100): 117 | s = state_space["C"] 118 | while (s == state_space["C"]): 119 | s = np.random.randint(4) 120 | 121 | R = 0 # Cumulated rewards 122 | while(s != state_space["C"]): 123 | a = egreedy(s,Q) 124 | sl = next_state(s,a) 125 | r = reward(sl) 126 | 127 | Q[s][a] = (1-alpha)*Q[s][a] + alpha*(r+gamma*max(Q[sl][:])) 128 | s = sl 129 | R = R + r 130 | R = R + reward(state_space["C"]) 131 | 132 | y.append(R) 133 | 134 | # Print and plot results 135 | print("Action-value function Q(s,a):") 136 | print(Q) 137 | print() 138 | 139 | pl.plot(y) 140 | pl.xlabel("Episode") 141 | pl.ylabel("Cumulated Rewards") 142 | pl.show() 143 | -------------------------------------------------------------------------------- /reinforced/Q.jl: -------------------------------------------------------------------------------- 1 | # ε-greedy algorithm for exploration/exploitation 2 | # returns action 3 | function ε_greedy(s,ε,Q) 4 | r = rand() 5 | 6 | if (r < ε) # Exploration 7 | a = rand(1:size(Q,2)) 8 | else # Exploitation 9 | a = argmax(Q[s,:]) 10 | end 11 | 12 | return a 13 | end 14 | 15 | # Q-learning algorithm 16 | function Q_Learning(reward,nstate,α,γ) 17 | ns,na = size(nstate) 18 | Q = rand(ns,na) 19 | 20 | for it in 1:500 21 | s = rand(1:ns) 22 | 23 | while(s ≠ 3) 24 | a = ε_greedy(s,0.1,Q) 25 | r = reward[s,a] 26 | sn = nstate[s,a] 27 | 28 | Q[s,a] = (1-α)*Q[s,a] + α*(r+γ*maximum(Q[sn,:])) 29 | s = sn 30 | end 31 | end 32 | 33 | return Q 34 | end 35 | 36 | # Simple function to display matrix 37 | function showmat(M) 38 | for m in eachrow(M) 39 | println(m) 40 | end 41 | end 42 | 43 | #====================================================# 44 | # Main 45 | #====================================================# 46 | # A = 1, B = 2, C = 3, D = 4 47 | # S = up, down, left, right 48 | 49 | # Reward matrix 50 | R = [-1 -1 -1 0; 51 | -1 0 0 -1; 52 | -1 -1 -1 0; 53 | 0 -1 100 -1] 54 | 55 | # Next state matrix 56 | M = [1 1 1 2; 57 | 2 4 1 2; 58 | 3 3 3 4; 59 | 2 4 3 4] 60 | 61 | Q = Q_Learning(R,M,0.7,0.95) 62 | showmat(Q) 63 | -------------------------------------------------------------------------------- /reinforced/REINFORCE.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | #---------------------------# 4 | # MODEL # 5 | #---------------------------# 6 | # Dense Layer 7 | mutable struct DenseLayer 8 | x :: Matrix 9 | W :: Matrix 10 | b :: Matrix 11 | z :: Matrix 12 | activation :: String 13 | ∂L∂W :: Matrix 14 | ∂L∂b :: Matrix 15 | end 16 | 17 | 18 | # Architecture 19 | mutable struct NeuralNetwork 20 | Layers :: Vector{DenseLayer} 21 | end 22 | 23 | #-------------------------# 24 | # Dense Layer Initializer # 25 | #-------------------------# 26 | function Dense(input_size,output_size,act) 27 | x = zeros(input_size,1) 28 | W = (rand(output_size,input_size) .- 0.5) ./ output_size 29 | b = (rand(output_size,1) .- 0.5) 30 | z = zeros(output_size,1) 31 | dW = zeros(input_size,output_size) 32 | db = zeros(1,output_size) 33 | 34 | return DenseLayer(x,W,b,z,act,dW,db) 35 | end 36 | 37 | #----------------------# 38 | # Activation Functions # 39 | #----------------------# 40 | function sigmoid(x) 41 | return 1.0/(1.0 + exp(-x)) 42 | end 43 | 44 | function softmax(v) 45 | ma = maximum(v) 46 | 47 | n = exp.(v .- ma) 48 | 49 | return n/sum(n) 50 | end 51 | 52 | 53 | #-------------------------# 54 | # FeedForward Dense Layer # 55 | #-------------------------# 56 | function forwardDense!(x,layer :: DenseLayer) 57 | setfield!(layer,:x,x) 58 | y = layer.W*x + layer.b 59 | 60 | if (layer.activation == "tanh") 61 | z = tanh.(y) 62 | end 63 | if (layer.activation == "sig") 64 | z = sigmoid.(y) 65 | end 66 | if (layer.activation == "none") 67 | z = copy(y) 68 | end 69 | 70 | setfield!(layer,:z,z) 71 | 72 | return z 73 | end 74 | 75 | #---------------------------# 76 | # BackPropagate Dense Layer # 77 | #---------------------------# 78 | function backDense!(∂L∂z,layer :: DenseLayer) 79 | if (layer.activation == "tanh") 80 | D = 1.0 .- layer.z'.^2 81 | ∂L∂y = ∂L∂z.*D 82 | end 83 | if (layer.activation == "sig") 84 | D = (layer.z .* (1.0 .- layer.z))' 85 | ∂L∂y = ∂L∂z.*D 86 | end 87 | if (layer.activation == "none") 88 | ∂L∂y = copy(∂L∂z) 89 | end 90 | 91 | setfield!(layer,:∂L∂b,layer.∂L∂b + ∂L∂y) 92 | setfield!(layer,:∂L∂W,layer.∂L∂W + layer.x*∂L∂y) 93 | ∂L∂x = ∂L∂y*layer.W 94 | 95 | return ∂L∂x 96 | end 97 | 98 | #------------------# 99 | # Gradient Descend # 100 | #------------------# 101 | function Gradient!(layer :: DenseLayer, η) 102 | setfield!(layer,:W, layer.W - η*layer.∂L∂W') 103 | setfield!(layer,:b, layer.b - η*layer.∂L∂b') 104 | 105 | i,j = size(layer.∂L∂W) 106 | z = zeros(i,j) 107 | setfield!(layer,:∂L∂W,z) 108 | 109 | i,j = size(layer.∂L∂b) 110 | z = zeros(i,j) 111 | setfield!(layer,:∂L∂b,z) 112 | 113 | return nothing 114 | end 115 | 116 | #==================# 117 | # Architecture # 118 | #==================# 119 | # Feedforward Neural Network 120 | function FeedForward!(x, nn :: NeuralNetwork) 121 | z = x 122 | for L in nn.Layers 123 | z = forwardDense!(z,L) 124 | end 125 | 126 | return z 127 | end 128 | 129 | # Backpropagate Neural Network 130 | function BackPropagate(∂L, nn :: NeuralNetwork) 131 | D = ∂L 132 | for L in nn.Layers[end:-1:1] 133 | D = backDense!(D,L) 134 | end 135 | 136 | return D 137 | end 138 | 139 | # Apply gradients to Neural Network 140 | function SetGradients!(η, nn :: NeuralNetwork) 141 | for L in nn.Layers 142 | Gradient!(L,η) 143 | end 144 | 145 | return nothing 146 | end 147 | 148 | 149 | 150 | #----------------------------------------------------------# 151 | # Initialize Neural Network 152 | function SetNeuralNetwork() 153 | Layer1 = Dense(4,120,"tanh") 154 | Layer2 = Dense(120,4,"none") 155 | 156 | Layers = [Layer1, Layer2] 157 | 158 | return NeuralNetwork(Layers) 159 | end 160 | 161 | function roulette_selection(fitness) 162 | total_fitness = sum(fitness) 163 | r = rand()*total_fitness 164 | 165 | i = 0 166 | while(r ≥ 0) 167 | i += 1 168 | r -= fitness[i] 169 | end 170 | 171 | return i 172 | end 173 | 174 | function embedding(s) 175 | if (s == 1) 176 | state = reshape([1,0,0,0],4,1) 177 | elseif (s == 2) 178 | state = reshape([0,1,0,0],4,1) 179 | elseif (s == 3) 180 | state = reshape([0,0,1,0],4,1) 181 | else 182 | state = reshape([0,0,0,1],4,1) 183 | end 184 | 185 | return state 186 | end 187 | 188 | # Train a neural network 189 | function TrainNeuralNetwork!(nn :: NeuralNetwork,RewardMatrix,StateTransitionMatrix) 190 | η = 1E-6 191 | num_episodes = 100 192 | 193 | loss = [] 194 | for epoch in 1:10000 195 | avR = 0 196 | avS = 0 197 | for episode in 1:num_episodes 198 | s = rand([1,2,4]) 199 | ∇ = zeros(1,4) 200 | R = 0 201 | steps = 0 202 | while(s ≠ 3 && steps < 5) 203 | steps += 1 204 | neural_output = FeedForward!(embedding(s),nn) 205 | action_probabilities = softmax(neural_output) 206 | action = roulette_selection(action_probabilities) 207 | 208 | R += RewardMatrix[s,action] 209 | 210 | z = zeros(1,4) 211 | z[1,action] = 1 212 | ∇ -= z - reshape(action_probabilities,1,4) 213 | 214 | s = StateTransitionMatrix[s,action] 215 | end 216 | 217 | ∇ *= R 218 | BackPropagate(∇,nn) 219 | 220 | avR += R 221 | avS += steps 222 | end 223 | 224 | avR /= num_episodes 225 | avS /= num_episodes 226 | 227 | SetGradients!(η,nn) 228 | push!(loss,avS) 229 | println("Epoch ",epoch,", average reward: ",avR,", average steps: ",avS) 230 | end 231 | 232 | 233 | return loss 234 | end 235 | 236 | function CheckPolicy(nn :: NeuralNetwork) 237 | for s in [1,2,4] 238 | neural_output = FeedForward!(embedding(s),nn) 239 | action_probabilities = softmax(neural_output) 240 | println(s,": ",action_probabilities) 241 | end 242 | end 243 | 244 | #====================================================# 245 | # MAIN # 246 | #====================================================# 247 | # States 248 | # A = [1 0 0 0] 249 | # B = [0 1 0 0] 250 | # C = [0 0 1 0] 251 | # D = [0 0 0 1] 252 | 253 | # Actions 254 | # up = [1 0 0 0] 255 | # down = [0 1 0 0] 256 | # left = [0 0 1 0] 257 | # right = [0 0 0 1] 258 | 259 | nn = SetNeuralNetwork() 260 | 261 | # Reward matrix 262 | Rm = [-1 -1 -1 0; 263 | -1 0 0 -1; 264 | -1 -1 -1 0; 265 | 0 -1 100 -1] 266 | 267 | # Next state matrix 268 | M = [1 1 1 2; 269 | 2 4 1 2; 270 | 3 3 3 4; 271 | 2 4 3 4] 272 | 273 | R = TrainNeuralNetwork!(nn,Rm,M) 274 | CheckPolicy(nn) 275 | plot(R) 276 | show() 277 | 278 | 279 | -------------------------------------------------------------------------------- /reinforced/REINFORCE/Gaussian.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | /**************************************** 9 | * Choose an action based on the policy * 10 | * **************************************/ 11 | int choose(float pi[9]) { 12 | float cum[9]; 13 | int a; 14 | 15 | // Cumulative 16 | cum[0] = pi[0]; 17 | for(a = 1; a < 9; a ++) 18 | cum[a] = pi[a] + cum[a-1]; 19 | 20 | // Normalize 21 | for(a = 0; a < 9; a ++) 22 | cum[a] /= cum[8]; 23 | 24 | // Choose action 25 | float r = (float)rand()/RAND_MAX; 26 | a = 0; 27 | while(r > cum[a]) 28 | a ++; 29 | 30 | return a; 31 | } 32 | 33 | /********************* 34 | * Move to new state * 35 | * *******************/ 36 | void moveto(int a, int &x, int &y, int BoardSize) { 37 | switch(a) { 38 | case 0: 39 | x ++; 40 | y ++; 41 | break; 42 | case 1: 43 | x ++; 44 | break; 45 | case 2: 46 | x ++; 47 | y --; 48 | break; 49 | case 3: 50 | y ++; 51 | break; 52 | case 5: 53 | y --; 54 | break; 55 | case 6: 56 | x --; 57 | y ++; 58 | break; 59 | case 7: 60 | x --; 61 | break; 62 | case 8: 63 | x --; 64 | y --; 65 | break; 66 | } 67 | if (x >= BoardSize) 68 | x = 0; 69 | if (x < 0) 70 | x = BoardSize - 1; 71 | if (y >= BoardSize) 72 | y = 0; 73 | if (y < 0) 74 | y = BoardSize - 1; 75 | } 76 | 77 | /* *************** 78 | * MAIN FUNCTION * 79 | * ***************/ 80 | int main(void) { 81 | // Declaration of Constants 82 | const int BoardSize = 3; 83 | const int MaxSteps = 150; 84 | const unsigned int xo = 1; 85 | const unsigned int yo = 1; 86 | const float gamma = 0.8; 87 | const float eta = 0.001; 88 | 89 | // Declaration of Variables 90 | bool active; 91 | int a,T; 92 | int t; 93 | float R,Loss; 94 | float reward; 95 | float delta; 96 | float pi[9]; 97 | float s1[MaxSteps],s2[MaxSteps]; 98 | int action[MaxSteps]; 99 | 100 | 101 | int x,y; 102 | float mu,w1,w2,w3; 103 | 104 | 105 | ofstream myfile; 106 | 107 | //--------- Code ---------- 108 | myfile.open("out.dat"); 109 | 110 | // Initialization 111 | srand(time(NULL)); 112 | w1 = (float)rand()/RAND_MAX-0.5; 113 | w2 = (float)rand()/RAND_MAX-0.5; 114 | w3 = (float)rand()/RAND_MAX-0.5; 115 | 116 | // Main loop 117 | do { 118 | // Get an average loss 119 | Loss = 0; 120 | for(int avg = 0; avg < 10; avg ++) { 121 | /*--------------------- 122 | * Sample trajectory 123 | * --------------------*/ 124 | t = 0; 125 | active = true; 126 | x = rand()%BoardSize; 127 | y = rand()%BoardSize; 128 | R = 0; 129 | do { 130 | // Run policy 131 | mu = w1*x + w2*y + w3; 132 | for(a = 0; a < 9; a ++) 133 | pi[a] = exp(-pow(a-mu,2)); 134 | 135 | a = choose(pi); 136 | 137 | // Store trajectory 138 | s1[t] = x; 139 | s2[t] = y; 140 | action[t] = a; 141 | 142 | // Move to new state 143 | moveto(a,x,y,BoardSize); 144 | 145 | // Obtain reward 146 | reward = (x == xo && y == yo) ? 100 : -1; 147 | R += pow(gamma,t)*reward; 148 | 149 | t ++; 150 | if (t >= MaxSteps || (x == xo && y == yo)) 151 | active = false; 152 | 153 | } while(active); 154 | T = t; 155 | cout << "Ended episode after " << T << " steps" << endl; 156 | Loss += T; 157 | 158 | // Gradient ascent 159 | for(t = 0; t < T; t ++) { 160 | delta = action[t] - w1*s1[t] - w2*s2[t] - w3; 161 | w1 += eta*delta*s1[t]*R/T; 162 | w2 += eta*delta*s2[t]*R/T; 163 | w3 += eta*delta*R/T; 164 | } 165 | } 166 | Loss /= 10; 167 | myfile << Loss << endl; 168 | } while(Loss > 1); 169 | 170 | myfile.close(); 171 | cout << "Model: " << w1 << "," << w2 << "," << w3 << endl; 172 | } 173 | 174 | 175 | -------------------------------------------------------------------------------- /reinforced/REINFORCE/Softmax.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | /**************************************** 12 | * Choose an action based on the policy * 13 | * **************************************/ 14 | int choose(float pi[9]) { 15 | float cum[9]; 16 | int a; 17 | 18 | // Cumulative 19 | cum[0] = pi[0]; 20 | for(a = 1; a < 9; a ++) 21 | cum[a] = pi[a] + cum[a-1]; 22 | 23 | // Normalize 24 | for(a = 0; a < 9; a ++) 25 | cum[a] /= cum[8]; 26 | 27 | // Choose action 28 | float r = (float)rand()/RAND_MAX; 29 | a = 0; 30 | while(r > cum[a]) 31 | a ++; 32 | 33 | return a; 34 | } 35 | 36 | /********************* 37 | * Move to new state * 38 | * *******************/ 39 | void moveto(int a, int &x, int &y, int BoardSize) { 40 | switch(a) { 41 | case 0: 42 | x ++; 43 | y ++; 44 | break; 45 | case 1: 46 | x ++; 47 | break; 48 | case 2: 49 | x ++; 50 | y --; 51 | break; 52 | case 3: 53 | y ++; 54 | break; 55 | case 5: 56 | y --; 57 | break; 58 | case 6: 59 | x --; 60 | y ++; 61 | break; 62 | case 7: 63 | x --; 64 | break; 65 | case 8: 66 | x --; 67 | y --; 68 | break; 69 | } 70 | if (x >= BoardSize) 71 | x = 0; 72 | if (x < 0) 73 | x = BoardSize - 1; 74 | if (y >= BoardSize) 75 | y = 0; 76 | if (y < 0) 77 | y = BoardSize - 1; 78 | } 79 | 80 | /* *************** 81 | * MAIN FUNCTION * 82 | * ***************/ 83 | int main(void) { 84 | // Declaration of Constants 85 | const int BoardSize = 3; 86 | const int MaxSteps = 150; 87 | const unsigned int xo = 1; 88 | const unsigned int yo = 1; 89 | const float gamma = 0.8; 90 | 91 | // Declaration of Variables 92 | bool active; 93 | int a,T; 94 | int t; 95 | float R,Loss; 96 | float reward; 97 | 98 | int x,y; 99 | 100 | // Neural net 101 | FeedForward Actor(2); 102 | tensor pi(9,1); 103 | tensor g(1,9), grad[MaxSteps]; 104 | tensor input(2,1); 105 | 106 | ofstream myfile; 107 | 108 | //--------- Code ---------- 109 | myfile.open("out.dat"); 110 | 111 | // Setup feedforward neural network 112 | Actor.add_layer(4,"sigmoid"); 113 | Actor.add_layer(6,"sigmoid"); 114 | Actor.add_layer(9,"none"); 115 | 116 | // Initialize tensors with proper size 117 | for(unsigned int i = 0; i < MaxSteps; i ++) 118 | grad[i].set(1,9); 119 | 120 | // Initialization 121 | srand(time(NULL)); 122 | 123 | // Main loop 124 | do { 125 | // Get an average loss 126 | Loss = 0; 127 | for(int avg = 0; avg < 10; avg ++) { 128 | /*--------------------- 129 | * Sample trajectory 130 | * --------------------*/ 131 | t = 0; 132 | active = true; 133 | x = rand()%BoardSize; 134 | y = rand()%BoardSize; 135 | R = 0; 136 | do { 137 | // Run policy 138 | input = {float(x),float(y)}; 139 | Actor.feedforward(input); 140 | pi = Actor.output().softmax(); 141 | a = pi.choose(); 142 | 143 | // Store trajectory 144 | grad[t] = pi.REINFORCE_grad_loss(a); 145 | 146 | // Move to new state 147 | moveto(a,x,y,BoardSize); 148 | 149 | // Obtain reward 150 | reward = (x == xo && y == yo) ? 100 : -1; 151 | R += pow(gamma,t)*reward; 152 | 153 | t ++; 154 | if (t >= MaxSteps || (x == xo && y == yo)) 155 | active = false; 156 | 157 | } while(active); 158 | T = t; 159 | cout << "Ended episode after " << T << " steps" << endl; 160 | Loss += T; 161 | 162 | // Gradient ascent 163 | g.zeros(); 164 | for(t = 0; t < T; t ++) { 165 | g += grad[t]*R; 166 | } 167 | Actor.backpropagate(g); 168 | } 169 | Actor.applygrads(-0.001); 170 | Loss /= 10; 171 | myfile << Loss << endl; 172 | } while(Loss > 1); 173 | 174 | myfile.close(); 175 | } 176 | 177 | 178 | -------------------------------------------------------------------------------- /reinforced/SARSA.f90: -------------------------------------------------------------------------------- 1 | ! SARSA 2 | ! By Prof. Carlo R. da Cunha, Ph.D. 3 | ! Last modification 02/12/2021 4 | ! creq@filosofisica.com 5 | 6 | module SARSA_Mod 7 | implicit none 8 | 9 | ! Action space 10 | integer,parameter :: go_up = 1 11 | integer,parameter :: go_down = 2 12 | integer,parameter :: go_left = 3 13 | integer,parameter :: go_right = 4 14 | 15 | ! State space 16 | integer,parameter :: state_A = 1 17 | integer,parameter :: state_B = 2 18 | integer,parameter :: state_C = 3 19 | integer,parameter :: state_D = 4 20 | 21 | ! epsilon parameter 22 | real,parameter :: eps = 0.1 23 | 24 | ! Game Class 25 | type,public :: game 26 | real :: Q(4,4) 27 | real :: alpha,gama 28 | 29 | contains 30 | 31 | procedure,private :: egreedy 32 | procedure :: play_episode 33 | end type 34 | 35 | interface game 36 | procedure :: game_constructor 37 | end interface 38 | 39 | contains 40 | 41 | !----------------------------! 42 | ! Constructor for class game ! 43 | !----------------------------! 44 | function game_constructor(alpha,gama) result(self) 45 | implicit none 46 | 47 | real,intent(in) :: alpha,gama 48 | type(game) :: self 49 | 50 | self%alpha = alpha 51 | self%gama = gama 52 | self%Q = 0.0 53 | end function 54 | 55 | !--------------------------! 56 | ! Epsilon-greedy algorithm ! 57 | !--------------------------! 58 | function egreedy(self,state) result(action) 59 | implicit none 60 | 61 | class(game),intent(in) :: self 62 | integer,intent(in) :: state 63 | integer :: action 64 | 65 | real :: r1,r2 66 | integer :: n(1) 67 | 68 | call random_number(r1) 69 | call random_number(r2) 70 | 71 | if (r1 < eps) then 72 | select case(state) 73 | case(state_A) 74 | action = go_right 75 | case(state_B) 76 | if (r2 < 0.5) then 77 | action = go_left 78 | else 79 | action = go_down 80 | end if 81 | case(state_C) 82 | action = go_right 83 | case(state_D) 84 | if (r2 < 0.5) then 85 | action = go_left 86 | else 87 | action = go_up 88 | end if 89 | end select 90 | else 91 | n = maxloc(self%Q(state,:)) 92 | action = n(1) 93 | end if 94 | end function 95 | 96 | !----------------------------------------------! 97 | ! Play full episode until reach terminal state ! 98 | !----------------------------------------------! 99 | function play_episode(self) result(cR) 100 | implicit none 101 | 102 | class(game),intent(inout) :: self 103 | real :: cR 104 | 105 | real :: r 106 | integer :: i,s,a,sl,al 107 | 108 | ! Choose random initial state s 109 | call random_number(r) 110 | i = floor(r*3) 111 | select case(i) 112 | case(0) 113 | s = state_A 114 | case(1) 115 | s = state_B 116 | case(2) 117 | s = state_D 118 | end select 119 | 120 | ! Find corresponding a epsilon-greedy 121 | a = self%egreedy(s) 122 | 123 | ! Run policy until terminal state 124 | cR = 0.0 125 | do while(s .ne. state_C) 126 | r = reward(s) 127 | sl = next_state(s,a) 128 | al = self%egreedy(sl) 129 | 130 | self%Q(s,a) = (1-self%alpha)*self%Q(s,a) + self%alpha*(r+self%gama*self%Q(sl,al)) 131 | s = sl 132 | a = al 133 | cR = cR + r 134 | end do 135 | cR = cR + reward(state_C) 136 | end function 137 | 138 | !-----------------! 139 | ! Find next state ! 140 | !-----------------! 141 | function next_state(state,action) result(nstate) 142 | implicit none 143 | 144 | integer,intent(in) :: state 145 | integer,intent(in) :: action 146 | integer :: nstate 147 | 148 | nstate = state 149 | select case(state) 150 | case(state_A) 151 | if (action .eq. go_right) then 152 | nstate = state_B 153 | end if 154 | case(state_B) 155 | if (action .eq. go_left) then 156 | nstate = state_A 157 | elseif (action .eq. go_down) then 158 | nstate = state_D 159 | end if 160 | case(state_C) 161 | if (action .eq. go_right) then 162 | nstate = state_D 163 | end if 164 | case(state_D) 165 | if (action .eq. go_left) then 166 | nstate = state_C 167 | elseif (action .eq. go_up) then 168 | nstate = state_B 169 | end if 170 | end select 171 | end function 172 | 173 | !-------------------------! 174 | ! Find reward for a state ! 175 | !-------------------------! 176 | function reward(state) result(r) 177 | implicit none 178 | 179 | integer,intent(in) :: state 180 | real :: r 181 | 182 | select case(state) 183 | case(state_A) 184 | r = -1.0 185 | case(state_B) 186 | r = -0.5 187 | case(state_C) 188 | r = 10.0 189 | case(state_D) 190 | r = -0.25 191 | end select 192 | end function 193 | 194 | end module 195 | 196 | !===============================================! 197 | ! MAIN ! 198 | !===============================================! 199 | program test 200 | use SARSA_Mod 201 | implicit none 202 | 203 | type(Game) :: G 204 | integer :: i 205 | 206 | G = Game(0.70,0.95) 207 | 208 | do i = 1,30 209 | write(*,*) G%play_episode() 210 | end do 211 | 212 | end program 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /reinforced/SARSA.jl: -------------------------------------------------------------------------------- 1 | # ε-greedy algorithm for exploration/exploitation 2 | # returns action 3 | function ε_greedy(s,ε,Q) 4 | r = rand() 5 | 6 | if (r < ε) # Exploration 7 | a = rand(1:size(Q,2)) 8 | else # Exploitation 9 | a = argmax(Q[s,:]) 10 | end 11 | 12 | return a 13 | end 14 | 15 | # SARSA algorithm 16 | function SARSA(reward,nstate,α,γ) 17 | ns,na = size(nstate) 18 | Q = rand(ns,na) 19 | 20 | for it in 1:500 21 | s = rand(1:ns) 22 | a = ε_greedy(s,0.1,Q) 23 | 24 | while(s ≠ 3) 25 | r = reward[s,a] 26 | sn = nstate[s,a] 27 | an = ε_greedy(s,0.1,Q) 28 | 29 | Q[s,a] = (1-α)*Q[s,a] + α*(r+γ*Q[sn,an]) 30 | s = sn 31 | a = an 32 | end 33 | end 34 | 35 | return Q 36 | end 37 | 38 | # Simple function to display matrix 39 | function showmat(M) 40 | for m in eachrow(M) 41 | println(m) 42 | end 43 | end 44 | 45 | #====================================================# 46 | # Main 47 | #====================================================# 48 | # A = 1, B = 2, C = 3, D = 4 49 | # S = up, down, left, right 50 | 51 | # Reward matrix 52 | R = [-1 -1 -1 0; 53 | -1 0 0 -1; 54 | -1 -1 -1 0; 55 | 0 -1 100 -1] 56 | 57 | # Next state matrix 58 | M = [1 1 1 2; 59 | 2 4 1 2; 60 | 3 3 3 4; 61 | 2 4 3 4] 62 | 63 | Q = SARSA(R,M,0.7,0.95) 64 | showmat(Q) 65 | -------------------------------------------------------------------------------- /reinforced/SARSA.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #!/usr/bin/env python 3 | 4 | __author__ = """Prof. Carlo R. da Cunha, Ph.D. """ 5 | 6 | import os 7 | 8 | os.system('clear') 9 | 10 | print('.-------------------------------.') 11 | print('| SARSA |#') 12 | print('| By.: Prof. Carlo R. da Cunha |#') 13 | print('| |#') 14 | print('| 2021 |#') 15 | print('\'-------------------------------\'#') 16 | print(' ################################') 17 | print('') 18 | print('Importing Libraries:') 19 | 20 | import numpy as np 21 | import matplotlib.pyplot as pl 22 | 23 | #--------------# 24 | # Dictionaries # 25 | #--------------# 26 | 27 | action_space = { 28 | "up" : 0, 29 | "down" : 1, 30 | "left" : 2, 31 | "right" : 3 32 | } 33 | 34 | state_space = { 35 | "A" : 0, 36 | "B" : 1, 37 | "C" : 2, 38 | "D" : 3 39 | } 40 | 41 | #--------------------------# 42 | # Epsilon-greedy algorithm # 43 | #--------------------------# 44 | def egreedy(state,Q): 45 | r1 = np.random.rand() 46 | 47 | if (r1 < 0.1): 48 | if (state == state_space["A"]): 49 | action = action_space["right"] 50 | elif (state == state_space["B"]): 51 | r2 = np.random.rand() 52 | if (r2 < 0.5): 53 | action = action_space["left"] 54 | else: 55 | action = action_space["down"] 56 | elif (state == state_space["C"]): 57 | action = action_space["right"] 58 | elif (state == state_space["D"]): 59 | r2 = np.random.rand() 60 | if (r2 < 0.5): 61 | action = action_space["left"] 62 | else: 63 | action = action_space["up"] 64 | else: 65 | action = np.argmax(Q[state,:]) 66 | 67 | return action 68 | 69 | #-----------------# 70 | # Find next state # 71 | #-----------------# 72 | def next_state(state,action): 73 | nstate = state 74 | if (state == state_space["A"]): 75 | if (action == action_space["right"]): 76 | nstate = state_space["B"] 77 | elif (state == state_space["B"]): 78 | if (action == action_space["left"]): 79 | nstate = state_space["A"] 80 | elif (action == action_space["down"]): 81 | nstate = state_space["D"] 82 | elif (state == state_space["C"]): 83 | if (action == action_space["right"]): 84 | nstate = state_space["D"] 85 | elif (state == state_space["D"]): 86 | if (action == action_space["left"]): 87 | nstate = state_space["C"] 88 | elif (action == action_space["up"]): 89 | nstate = state_space["B"] 90 | 91 | return nstate 92 | 93 | #-------------------------# 94 | # Find reward for a state # 95 | #-------------------------# 96 | def reward(state): 97 | if (state == state_space["A"]): 98 | r = -1.0 99 | elif (state == state_space["B"]): 100 | r = -0.5 101 | elif (state == state_space["C"]): 102 | r = 10.0 103 | elif (state == state_space["D"]): 104 | r = -0.25 105 | 106 | return r 107 | 108 | #===============================================# 109 | # MAIN # 110 | #===============================================# 111 | alpha = 0.7 112 | gamma = 0.95 113 | Q = np.zeros((4,4)) 114 | y = [] 115 | 116 | for episode in range(100): 117 | s = state_space["C"] 118 | while (s == state_space["C"]): 119 | s = np.random.randint(4) 120 | a = egreedy(s,Q) 121 | 122 | R = 0 # Cumulated rewards 123 | while(s != state_space["C"]): 124 | r = reward(s) 125 | sl = next_state(s,a) 126 | al = egreedy(sl,Q) 127 | 128 | Q[s][a] = (1-alpha)*Q[s][a] + alpha*(r+gamma*Q[sl][al]) 129 | s = sl 130 | a = al 131 | R = R + r 132 | R = R + reward(state_space["C"]) 133 | 134 | y.append(R) 135 | 136 | # Print and plot results 137 | print("Action-value function Q(s,a):") 138 | print(Q) 139 | print() 140 | 141 | pl.plot(y) 142 | pl.xlabel("Episode") 143 | pl.ylabel("Cumulated Rewards") 144 | pl.show() 145 | -------------------------------------------------------------------------------- /reinforced/conjgrad.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | 3 | #f(x,y) = 100*(y-x^2)^2+(1-x)^2 4 | 5 | #x = 0 6 | #y = 0 7 | 8 | function c∇(A,b,x) 9 | r = b - A*x 10 | p = r 11 | ξ = r⋅r 12 | 13 | for i in 1:5 14 | α = ξ/(p⋅(A*p)) 15 | x = x + α*p 16 | r = r - α*A*p 17 | new_ξ = r⋅r 18 | 19 | if (new_ξ < 1E-10) 20 | break 21 | else 22 | p = r + (new_ξ/ξ)*p 23 | ξ = new_ξ 24 | end 25 | end 26 | 27 | 28 | return x 29 | end 30 | 31 | 32 | A = [4 1;1 3] 33 | b = [1; 2] 34 | 35 | x = [2; 1] 36 | 37 | y = c∇(A,b,x) 38 | 39 | println(y) 40 | 41 | 42 | -------------------------------------------------------------------------------- /reinforced/deepQ.jl: -------------------------------------------------------------------------------- 1 | using Flux 2 | using PyPlot 3 | using IterTools: ncycle 4 | 5 | # Neural network architecture 6 | function SetNet(inputChannels,outputChannels) 7 | m = Chain( 8 | Dense(inputChannels,32,tanh; init = Flux.glorot_normal()), 9 | Dense(32,outputChannels,sigmoid; init = Flux.glorot_normal()) 10 | ) 11 | 12 | return m 13 | end 14 | 15 | # An approximator for the neural network with an optimiser 16 | mutable struct NNApprox 17 | model :: Chain 18 | optimiser :: Flux.Optimiser 19 | end 20 | 21 | # Returns an approximator 22 | function SetAppr(η) 23 | model = SetNet(1,4) 24 | op = Flux.Optimiser(ClipValue(1E-1),Flux.Optimise.ADAM(η)) 25 | 26 | return NNApprox(model,op) 27 | end 28 | 29 | # Creates a dataset 30 | function buildDataSet(N) 31 | x_set = Float64[0;0] 32 | y_set = Float64[0] 33 | 34 | for it in 1:N 35 | for (x1,x2,y) in zip([0 0 1 1],[0 1 0 1],[0 1 1 0]) 36 | r1 = (rand()-0.5)/10 37 | r2 = (rand()-0.5)/10 38 | x_set = hcat(x_set,[x1+r1;x2+r2]) 39 | y_set = hcat(y_set,y) 40 | end 41 | end 42 | 43 | return x_set,y_set 44 | end 45 | 46 | # Train the approximator with a dataset 47 | # function train!(ap :: NNApprox, x :: Matrix{Float64}, y :: Matrix{Float64}, batch_size, epochs) 48 | # train_data = Flux.Data.DataLoader((x,y),batchsize=batch_size,shuffle=true) 49 | # train_data = ncycle(train_data,epochs) 50 | # 51 | # for (a,b) in train_data 52 | # ∇ = Flux.gradient(params(ap.model)) do 53 | # loss = Flux.Losses.mse(ap.model(a),b) 54 | # end 55 | # Flux.Optimise.update!(ap.optimiser,Flux.params(ap.model),∇) 56 | # end 57 | # end 58 | 59 | # Evaluate the trained approximator 60 | function evaluate(ap :: NNApprox, M :: Matrix{Float64}) 61 | 62 | for x in eachcol(M) 63 | ŷ = ap.model(x) 64 | 65 | println(x," = ",ŷ) 66 | end 67 | end 68 | 69 | #================================================================================# 70 | # REPLAY BUFFER 71 | #================================================================================# 72 | mutable struct ReplayBuffer 73 | buffer::Vector{Tuple} 74 | max_size::Int 75 | curr_size::Int 76 | end 77 | 78 | function ReplayBuffer(buffer_size::Int) 79 | return ReplayBuffer(Vector{Tuple}(), buffer_size, 0) 80 | end 81 | 82 | function store!(buffer::ReplayBuffer, item) 83 | if (buffer.curr_size ≥ buffer.max_size) 84 | popfirst!(buffer.buffer) 85 | else 86 | buffer.curr_size += 1 87 | end 88 | push!(buffer.buffer, item) 89 | end 90 | 91 | function sample(buffer::ReplayBuffer, batch_size::Int) 92 | indices = rand(1:length(buffer.buffer), min(batch_size,buffer.curr_size)) 93 | return [buffer.buffer[i] for i in indices] 94 | end 95 | 96 | #---------------------------- 97 | # REINFORCEMENT LEARNING 98 | #---------------------------- 99 | function ε_greedy(s,ε,Q) 100 | sz = length(Q) 101 | 102 | if (rand() < ε) # Exploration 103 | a = rand(1:sz) 104 | else # Exploitation 105 | a = argmax(Q) 106 | end 107 | 108 | return a 109 | end 110 | 111 | function train!(N::NNApprox,R::ReplayBuffer) 112 | γ = 0.95 113 | S = sample(R,100) 114 | 115 | for (s,a,r,s′) in S 116 | y = r + γ*maximum(N.model([s′])) 117 | 118 | ∇ = Flux.gradient(params(N.model)) do 119 | loss = (y - N.model([s])[a])^2 120 | end 121 | Flux.Optimise.update!(N.optimiser,Flux.params(N.model),∇) 122 | end 123 | end 124 | 125 | # Reward matrix 126 | rewardMatrix = 127 | [-1.0 -1.0 -1.0 0.0; 128 | -1.0 0.5 0.0 -1.0; 129 | -1.0 -1.0 -1.0 0.0; 130 | 0.0 -1.0 10.0 -1.0] 131 | 132 | # Next state matrix 133 | stateMatrix = [1 1 1 2; 134 | 2 4 1 2; 135 | 3 3 3 4; 136 | 2 4 3 4] 137 | 138 | # Replay buffer 139 | R = ReplayBuffer(10) 140 | 141 | # Approximator for Q-value 142 | Actor = SetAppr(1E-3) 143 | 144 | γ = 0.95 145 | α = 0.1 146 | ζ = 1 # Exploration rate 147 | 148 | y_plot = [] 149 | for t in 1:30000 150 | # Begin 151 | s = rand([1,2,4]) 152 | totalReward = 0 153 | 154 | t = 0 155 | while(s ≠ 3 && t < 10) 156 | Q = Actor.model([s]) 157 | a = ε_greedy(s,ζ,Q) 158 | r = rewardMatrix[s,a] 159 | totalReward += r 160 | s′ = stateMatrix[s,a] 161 | 162 | store!(R,(s,a,r,s′)) 163 | #Q[s,a] = (1-α)*Q[s,a] + α*(r+γ*maximum(Q[s′,:])) 164 | s = s′ 165 | t += 1 166 | 167 | # Reduce exploration 168 | global ζ = max(0.0,ζ-1E-5) 169 | end 170 | 171 | push!(y_plot,totalReward) 172 | println(totalReward,", ",ζ,", ",t) 173 | train!(Actor,R) 174 | end 175 | 176 | function showmat(M) 177 | for m in eachrow(M) 178 | println(m) 179 | end 180 | end 181 | 182 | #showmat(Q) 183 | for s in 1:4 184 | println(Actor.model([s])) 185 | end 186 | 187 | plot(y_plot) 188 | show() 189 | 190 | #y = r + γ*maximum(Q(s′)) 191 | #loss = mse(y,Q) 192 | 193 | 194 | #================================================================# 195 | # MAIN CODE 196 | #================================================================# 197 | # Q = SetAppr(1E-3) 198 | # 199 | # a = evaluate(Q,s′,a′) 200 | # 201 | # x,y = buildDataSet(200) 202 | # train!(A,x,y,20,100) 203 | # 204 | # x = Float64[0 0 1 1;0 1 0 1] 205 | # evaluate(A,x) 206 | -------------------------------------------------------------------------------- /reinforced/deepQ/makefile: -------------------------------------------------------------------------------- 1 | TARGET = deepQ 2 | F90_SOURCE = ./source/activ.f90 \ 3 | ./source/loss.f90 \ 4 | ./source/layer.f90 \ 5 | ./source/neural.f90 \ 6 | ./source/deepQ.f90 \ 7 | 8 | 9 | #$(wildcard ./source/*.f90) 10 | OBJ = $(subst .f90,.o,$(subst source,objects,$(F90_SOURCE))) 11 | FC = gfortran 12 | FC_FLAGS = -O3 \ 13 | -ffast-math \ 14 | -llapack \ 15 | -lblas \ 16 | 17 | MOD = mods 18 | 19 | RM = rm -rf 20 | 21 | all : display $(TARGET) 22 | 23 | 24 | display: 25 | @clear 26 | @mkdir -p objects 27 | @mkdir -p mods 28 | 29 | @echo ".------------------------------------." 30 | @echo "| Compiling: DeepQ |#" 31 | @echo "| --------- |#" 32 | @echo "| |#" 33 | @echo "| By: Prof. Carlo R. da Cunha |#" 34 | @echo "| |#" 35 | @echo "| Created: Nov/2021 |#" 36 | @echo "| Revision: Dec/2021 |#" 37 | @echo "'------------------------------------'#" 38 | @echo " #####################################" 39 | @echo "" 40 | 41 | 42 | $(TARGET): $(OBJ) 43 | @echo "# Linking $@..." 44 | $(FC) $^ $(FC_FLAGS) -o $@ -I $(MOD) 45 | @echo "" 46 | 47 | ./objects/%.o: ./source/%.f90 48 | @echo "# Building target: $<" 49 | $(FC) $< $(FC_FLAGS) -c -o $@ -J $(MOD) 50 | @echo "" 51 | 52 | 53 | clean: 54 | @$(RM) ./objects/*.o $(TARGET) *~ 55 | @$(RM) ./mods/*.mod $(TARGET) *~ 56 | @rmdir objects 57 | @rmdir mods 58 | 59 | .PHONY: all clean 60 | 61 | 62 | -------------------------------------------------------------------------------- /reinforced/deepQ/source/activ.f90: -------------------------------------------------------------------------------- 1 | module NNActiv 2 | implicit none 3 | 4 | integer,parameter,private :: dp = kind(1.d0) 5 | 6 | contains 7 | 8 | !-- Elemental Activation --! 9 | elemental function elementalActivation(y,activation) result(z) 10 | implicit none 11 | 12 | real(dp),intent(in) :: y 13 | character(len=*),intent(in) :: activation 14 | real(dp) :: z 15 | 16 | select case(activation) 17 | case("Sigmoid") 18 | if (y > 100.0) then 19 | z = 1.0/(1.0 + exp(-100.0)) 20 | else if (y < -100.0) then 21 | z = exp(-100.0) 22 | else 23 | z = 1.0/(1.0 + exp(-y)) 24 | end if 25 | 26 | case("ReLU") 27 | if (y < 0.0) then 28 | z = 0.0 29 | else 30 | z = y 31 | end if 32 | 33 | case("lReLU") 34 | if (y < 0.0) then 35 | z = 1E-3*y 36 | else 37 | z = y 38 | end if 39 | 40 | case("tanh") 41 | if (y > 100.0) then 42 | z = tanh(100.0) 43 | else if (y < -100.0) then 44 | z = tanh(-100.0) 45 | else 46 | z = tanh(y) 47 | end if 48 | 49 | case("soft+") 50 | if (y > 100.0) then 51 | z = y 52 | else 53 | z = log(1.0+exp(y)) 54 | end if 55 | 56 | case("none") 57 | z = y 58 | 59 | end select 60 | end function 61 | 62 | !-- Elemental Deactivation --! 63 | elemental function elementalDeactivation(y,z,activation) result(dzdy) 64 | implicit none 65 | 66 | real(dp),intent(in) :: y,z 67 | character(len=*),intent(in) :: activation 68 | real(dp) :: dzdy 69 | 70 | select case(activation) 71 | case("Sigmoid") 72 | dzdy = z*(1-z) 73 | 74 | case("ReLU") 75 | if (y > 0) then 76 | dzdy = 1.0 77 | else 78 | dzdy = 0.0 79 | end if 80 | 81 | case("lReLU") 82 | if (y > 0) then 83 | dzdy = 1.0 84 | else 85 | dzdy = 1E-3 86 | end if 87 | 88 | case("tanh") 89 | dzdy = 1-z*z 90 | 91 | case("soft+") 92 | dzdy = 1-exp(-z) 93 | 94 | case("none") 95 | dzdy = y 96 | 97 | end select 98 | end function 99 | 100 | !-- ACTIVATE --! 101 | function activate(Y,activation) result(Z) 102 | implicit none 103 | 104 | real(dp),intent(in) :: Y(:,:) 105 | character(len=*),intent(in) :: activation 106 | real(dp) :: Z(size(Y,1),size(Y,2)) 107 | 108 | if (activation .eq. "softmax") then 109 | Z = softmax(Y) 110 | else 111 | Z = elementalActivation(Y,activation) 112 | end if 113 | end function 114 | 115 | 116 | 117 | !-- DEACTIVATE --! 118 | function deactivate(dLdZ,Y,Z,activation) result(dLdY) 119 | implicit none 120 | 121 | real(dp),intent(in) :: dLdZ(:,:) 122 | real(dp),intent(in) :: Y(:,:) 123 | real(dp),intent(in) :: Z(:,:) 124 | character(len=*),intent(in) :: activation 125 | real(dp) :: dLdY(size(dLdZ,1),size(dLdZ,2)) 126 | 127 | integer :: i,j 128 | 129 | 130 | do j = 1,size(dLdY,2) 131 | do i = 1,size(dLdY,1) 132 | if (activation .eq. "softMax") then 133 | dLdY(i,j) = -Z(j,i)*Z(j,i) 134 | if (i == j) then 135 | dLdY(j,j) = dLdY(j,j) + Z(j,i) 136 | end if 137 | dLdY(i,j) = dLdY(i,j)*dLdZ(i,j) 138 | else 139 | dLdY(i,j) = dLdZ(i,j)*elementalDeactivation(Y(j,i),Z(j,i),activation) 140 | end if 141 | end do 142 | end do 143 | 144 | 145 | end function 146 | 147 | !-- SOFTMAX --! 148 | function softmax(Y) result(Z) 149 | implicit none 150 | 151 | real(dp),intent(in) :: Y(:,:) 152 | real(dp) :: Z(size(Y,1),size(Y,2)) 153 | 154 | real(dp) :: mx,s 155 | integer :: i 156 | 157 | 158 | mx = maxval(Y(:,1)) 159 | 160 | s = 0 161 | do i = 1,size(Y,1) 162 | Z(i,1) = exp(Y(i,1)-mx) 163 | s = s + Z(i,1) 164 | end do 165 | do i = 1,size(y,1) 166 | Z(i,1) = Z(i,1)/s 167 | end do 168 | end function 169 | 170 | 171 | end module 172 | -------------------------------------------------------------------------------- /reinforced/deepQ/source/loss.f90: -------------------------------------------------------------------------------- 1 | module NNLoss 2 | 3 | integer,parameter,private :: dp = kind(1.d0) 4 | 5 | contains 6 | 7 | 8 | !================================================================================= 9 | ! ELEMENTAL LOSS FUNCTIONS 10 | !================================================================================= 11 | ! Elemental loss 12 | ! a: estimated, b: expected 13 | elemental function elementalLoss(estimated,expected,losstype) result(c) 14 | implicit none 15 | 16 | real(dp),intent(in) :: estimated,expected 17 | character(len=*),intent(in) :: losstype 18 | real(dp) :: c 19 | 20 | select case(losstype) 21 | case("L1") 22 | c = abs(expected-estimated) 23 | 24 | case("L2") 25 | c = (expected-estimated)**2 26 | 27 | case("BCE") 28 | c = maxval([real(dp) :: 0,estimated]) - expected*estimated + log(1.0+exp(-abs(estimated))) 29 | end select 30 | end function 31 | 32 | 33 | ! Elemental derivative of the loss function 34 | ! a: estimated, b: expected 35 | elemental function elementalDeLoss(estimated,expected,losstype) result(c) 36 | implicit none 37 | 38 | real(dp),intent(in) :: estimated,expected 39 | character(len=*),intent(in) :: losstype 40 | real(dp) :: c 41 | 42 | real(dp),parameter :: threshold = 1E-7 43 | 44 | select case(losstype) 45 | case("L1") 46 | c = sign(1.d0,estimated - expected) 47 | case("L2") 48 | c = 2*(estimated - expected) 49 | case("BCE") 50 | c = estimated - expected 51 | 52 | end select 53 | end function 54 | 55 | !================================================================================= 56 | ! TENSOR FUNCTIONS 57 | !================================================================================= 58 | ! Gradient of loss function 59 | function deLoss(estimated,expected,losstype) result(r) 60 | implicit none 61 | 62 | real(dp),intent(in) :: estimated(:,:) 63 | real(dp),intent(in) :: expected(:,:) 64 | character(len=*) :: losstype 65 | real(dp) :: r(size(estimated,2),size(estimated,1)) 66 | 67 | integer :: i 68 | real(dp) :: t(size(estimated,1),size(estimated,2)) 69 | 70 | 71 | t = elementalDeLoss(estimated,expected,losstype) 72 | r = transpose(t) 73 | end function 74 | 75 | end module 76 | -------------------------------------------------------------------------------- /reinforced/regret.py: -------------------------------------------------------------------------------- 1 | 2 | # -*- coding: utf-8 -*- 3 | #!/usr/bin/env python 4 | 5 | __author__ = """Prof. Carlo R. da Cunha, Ph.D. """ 6 | 7 | import os 8 | 9 | os.system('clear') 10 | 11 | print('.-------------------------------.') 12 | print('| REGRET Learning |#') 13 | print('| By.: Prof. Carlo R. da Cunha |#') 14 | print('| |#') 15 | print('| 2021 |#') 16 | print('\'-------------------------------\'#') 17 | print(' ################################') 18 | print('') 19 | print('Importing Libraries:') 20 | 21 | import numpy as np 22 | import matplotlib.pyplot as pl 23 | 24 | # Prisoner's dillema 25 | pmA = np.array([[2,4],[1,3]]) 26 | pmB = np.array([[2,1],[4,3]]) 27 | 28 | RA = np.array([0,0]) 29 | RB = np.array([0,0]) 30 | 31 | avA = 0 32 | avB = 0 33 | 34 | for it in range(100): 35 | # Action player A 36 | s = np.sum(RA) 37 | if (s != 0): 38 | p = RA[0]/s 39 | else: 40 | p = 0.5 41 | 42 | if (np.random.rand() < p): 43 | aA = 0 44 | else: 45 | aA = 1 46 | 47 | # Action player B 48 | s = np.sum(RB) 49 | if (s != 0): 50 | p = RB[0]/s 51 | else: 52 | p = 0.5 53 | 54 | if (np.random.rand() < p): 55 | aB = 0 56 | else: 57 | aB = 1 58 | 59 | # Utilities for playing actions aA and aB 60 | uA = pmA[aA,aB] 61 | uB = pmB[aA,aB] 62 | 63 | # Maximum utilities for this round given other players moves 64 | maxA = np.max(pmA[:,aB]) 65 | maxB = np.max(pmB[aA,:]) 66 | 67 | # Regrets for playing these actions 68 | rA = maxA - uA 69 | rB = maxB - uB 70 | 71 | # Cumulative regrets 72 | RA[aA] = RA[aA] + rA 73 | RB[aB] = RB[aB] + rB 74 | 75 | # Average actions 76 | avA = (it/(it+1))*avA + aA/(it+1) 77 | avB = (it/(it+1))*avB + aB/(it+1) 78 | 79 | print(avA,avB) 80 | -------------------------------------------------------------------------------- /statistics/KDE.jl: -------------------------------------------------------------------------------- 1 | using Statistics 2 | using PyPlot 3 | 4 | function kernel(u,k) 5 | if (abs(u) < 1) 6 | if (k == "Uni") 7 | return 0.5 8 | end 9 | if (k == "Epa") 10 | return 0.75*(1-u^2) 11 | end 12 | if (k == "Biw") 13 | return (15.0/16)*(1-u^2)^2 14 | end 15 | if (k == "Tri") 16 | return (35.0/32)*(1-u^2)^3 17 | end 18 | else 19 | return 0 20 | end 21 | end 22 | 23 | function KDE(x,Nw,k) 24 | mi = minimum(x) 25 | ma = maximum(x) 26 | N = length(x) 27 | 28 | h = 1.06*std(x)*N^(-0.2) 29 | 30 | x′ = LinRange(mi,ma,Nw) 31 | 32 | z = [] 33 | for xo in x′ 34 | s = 0 35 | for xi in x 36 | u = (xi-xo)/h 37 | s += kernel(u,k) 38 | end 39 | push!(z,s/(N*h)) 40 | end 41 | 42 | return x′,z#/sum(z) 43 | end 44 | 45 | function normal(x,μ,σ²) 46 | return exp(-(x-μ)^2/(2σ²))/sqrt(2π*σ²) 47 | end 48 | 49 | μ = 3.0 50 | σ² = 1.7 51 | 52 | f = 3.0 .+ sqrt(σ²)*randn(2000) 53 | x,y = KDE(f,50,"Biw") 54 | z = normal.(x,μ,σ²) 55 | 56 | plot(x,y,"s") 57 | plot(x,z) 58 | show() 59 | 60 | -------------------------------------------------------------------------------- /supervised/classification/forest.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | # Stump structure 4 | mutable struct stumpStructure 5 | attribute :: Int 6 | out :: Dict{String,Int} 7 | end 8 | 9 | # Fit a binary stump 10 | function fitBinaryStump!(T, s :: stumpStructure) 11 | # Find labels for attribute a 12 | feature = [] 13 | for t in eachrow(T) 14 | if ~(t[s.attribute] in feature) 15 | push!(feature,t[s.attribute]) 16 | end 17 | end 18 | N = length(feature) 19 | 20 | # Find scores 21 | score = zeros(N) 22 | for t in eachrow(T) 23 | for n in 1:N 24 | if (t[s.attribute] == feature[n]) 25 | score[n] += t[4] 26 | end 27 | end 28 | end 29 | 30 | # Fit 31 | for n in 1:length(feature) 32 | if (score[n] > 0) 33 | s.out[feature[n]] = 1 34 | else 35 | s.out[feature[n]] = -1 36 | end 37 | end 38 | end 39 | 40 | # Gives the output of a stump 41 | function stump(s :: stumpStructure,c1,c2,c3) 42 | if (s.attribute == 1) 43 | r = s.out[c1] 44 | elseif(s.attribute == 2) 45 | r = s.out[c2] 46 | else 47 | r = s.out[c3] 48 | end 49 | 50 | return r 51 | end 52 | 53 | # Binary Classifier for the Forest 54 | function Classifier(c1,c2,c3,Ensemble,alphas) 55 | C = 0 56 | for (s,α) in zip(Ensemble,alphas) 57 | C = C + stump(s,c1,c2,c3)*α 58 | end 59 | 60 | return sign(C) 61 | end 62 | 63 | # Add another stump to the forest 64 | function Add(Ensemble,alphas,weights,p,T) 65 | s = stumpStructure(p,Dict()) 66 | fitBinaryStump!(T,s) 67 | 68 | # Find w_{i,n} 69 | misclassified = 0 70 | total = 0 71 | ξ_list = [] 72 | for (xi,w) in zip(eachrow(T),weights) 73 | k = stump(s,xi[1],xi[2],xi[3]) 74 | 75 | # Find misclassification 76 | y = xi[4] 77 | if (k ≠ y) 78 | misclassified += w 79 | push!(ξ_list,1) 80 | else 81 | push!(ξ_list,-1) 82 | end 83 | total += w 84 | end 85 | # Error rate 86 | ε = misclassified/total 87 | 88 | α = 0.5*log((1-ε)/ε) 89 | 90 | # Update weights 91 | nw = [] 92 | Z = 0 93 | for (w,ξ) in zip(weights,ξ_list) 94 | el = w*exp(ξ*α) 95 | Z = Z + el 96 | push!(nw,w*exp(ξ*α)) 97 | end 98 | nw = nw/Z 99 | 100 | return vcat(Ensemble,s), vcat(alphas,α), nw 101 | end 102 | 103 | # Make predictions 104 | function Forest(ens,als,T) 105 | for t in eachrow(T) 106 | c = Classifier(t[1],t[2],t[3],ens,als) 107 | println(c, " should be ",t[4]) 108 | end 109 | end 110 | 111 | # Calculate performance 112 | function performance(ens,als,T) 113 | right = 0 114 | for t in eachrow(T) 115 | c = Classifier(t[1],t[2],t[3],ens,als) 116 | 117 | if (c == t[4]) 118 | right += 1 119 | end 120 | end 121 | 122 | return right/length(T[:,1]) 123 | end 124 | 125 | #------ MAIN FUNCTION -----# 126 | function main() 127 | ensemble = [] 128 | alphas = [] 129 | weights = [0.2 0.2 0.2 0.2 0.2] 130 | 131 | T = ["a" "c" "e" 1; 132 | "b" "d" "e" 1; 133 | "a" "c" "e" -1; 134 | "b" "c" "e" -1; 135 | "a" "d" "g" 1] 136 | 137 | y = [] 138 | for it in [1 3 2] 139 | ensemble,alphas,weights = Add(ensemble,alphas,weights,it,T) 140 | push!(y,performance(ensemble,alphas,T)) 141 | end 142 | 143 | Forest(ensemble,alphas,T) 144 | println(alphas) 145 | 146 | plot(y,"*-") 147 | show() 148 | end 149 | 150 | main() 151 | 152 | 153 | -------------------------------------------------------------------------------- /supervised/classification/knn.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | 4 | #=========================# 5 | # PRIORITY QUEUE 6 | #=========================# 7 | struct QueueElement 8 | index :: Int 9 | value :: Float64 10 | end 11 | 12 | struct PriorityQueue 13 | max_pos :: Int 14 | data :: Array{QueueElement,1} 15 | end 16 | 17 | function enqueue!(q::PriorityQueue,priority::Float64,index::Int) 18 | if length(q.data) < q.max_pos 19 | push!(q.data,QueueElement(index,priority)) 20 | else 21 | # find largest element 22 | max_value = -1E9 23 | max_pos = 0 24 | for (idx,el) in enumerate(q.data) 25 | if el.value > max_value 26 | max_value = el.value 27 | max_pos = idx 28 | end 29 | end 30 | 31 | # check if it replaces 32 | if priority < max_value 33 | q.data[max_pos] = QueueElement(index,priority) 34 | end 35 | end 36 | end 37 | 38 | #=========================# 39 | # CREATE DATA 40 | #=========================# 41 | μ_redness_orange = 0.5 42 | μ_redness_apple = 0.9 43 | μ_diameter_orange = 8.0 44 | μ_diameter_apple = 6.0 45 | 46 | N = 100 47 | training_set = [] 48 | xa = [] 49 | ya = [] 50 | xo = [] 51 | yo = [] 52 | 53 | σ = 0.6 54 | 55 | for i in 1:N 56 | if rand() < 0.65 57 | μr = μ_redness_orange + randn()*σ 58 | μd = μ_diameter_orange + randn()*σ 59 | label = "orange" 60 | push!(xo,μr) 61 | push!(yo,μd) 62 | else 63 | μr = μ_redness_apple + randn()*σ 64 | μd = μ_diameter_apple + randn()*σ 65 | label = "apple" 66 | push!(xa,μr) 67 | push!(ya,μd) 68 | end 69 | 70 | data = [μr,μd,label] 71 | push!(training_set,data) 72 | end 73 | 74 | #=========================# 75 | # KNN 76 | #=========================# 77 | K = 3 78 | x = rand() 79 | y = 4 + rand()*6 80 | 81 | # Calculate distance to all elements and keep K nearest neighbors 82 | q = PriorityQueue(K,[]) 83 | for i in 1:N 84 | d = sqrt((x - training_set[i][1])^2 + (y - training_set[i][2])^2) 85 | enqueue!(q,d,i) 86 | end 87 | 88 | # Find the most frequent label among the nearest neighbors 89 | orange = 0 90 | apple = 0 91 | for element in q.data 92 | if training_set[element.index][3] == "orange" 93 | global orange += 1 94 | else 95 | global apple += 1 96 | end 97 | end 98 | 99 | 100 | # Plot and print data 101 | println("Redness: ",x,", Diameter: ",y) 102 | if orange > apple 103 | println("Orange") 104 | else 105 | println("Apple") 106 | end 107 | 108 | plot(xa,ya,"o",color="red") 109 | plot(xo,yo,"s",color="orange") 110 | plot([x],[y],"*",color="green") 111 | legend(["apple","orange","test"]) 112 | xlabel("Redness") 113 | ylabel("Diameter") 114 | show() 115 | -------------------------------------------------------------------------------- /supervised/classification/logistic.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using LinearAlgebra 3 | 4 | # Synthetic training data 5 | function createData(N) 6 | e1 = randn(N) 7 | e2 = randn(N).+3 8 | f1 = 2*e1.+1 + randn(N) 9 | f2 = 3*e2 + randn(N) 10 | 11 | y = vcat(zeros(N),ones(N)) 12 | x1 = vcat(e1,e2) 13 | x2 = vcat(f1,f2) 14 | ve = ones(2*N) 15 | X = hcat(ve,x1,x2) 16 | 17 | return X,x1,x2,y 18 | end 19 | 20 | # Regression 21 | function regression(X,y) 22 | N = length(y) 23 | w = [rand(),rand(),rand()] 24 | p = zeros(N) 25 | 26 | for it in 1:N 27 | p = [1.0/(1.0 + exp(-w⋅r)) for r in eachrow(X)] 28 | S = diagm(p) 29 | 30 | w = w + inv(X'*S*X)*X'*(y-p) 31 | end 32 | 33 | # Quality 34 | L = 1 35 | for (qi,yi) in zip(p,y) 36 | L = L*(qi^yi)*((1-qi)^(1-yi)) 37 | end 38 | 39 | println(-2*log(L)) 40 | 41 | return w 42 | end 43 | 44 | # Make a prediction 45 | function predict(w) 46 | # Predict & Plot 47 | p = LinRange(-2,7,100) 48 | q = LinRange(-2,16,100) 49 | Z = zeros((100,100)) 50 | 51 | for i in 1:100 52 | for j in 1:100 53 | r = [1,p[i],q[j]] 54 | Z[i,j] = 1.0/(1.0 + exp(-w⋅r)) 55 | end 56 | end 57 | 58 | return p,q,Z 59 | end 60 | 61 | # Numpy-like meshgrid function 62 | function meshgrid(x, y) 63 | X = [i for i in x, j in 1:length(y)] 64 | Y = [j for i in 1:length(x), j in y] 65 | return X, Y 66 | end 67 | 68 | #========================================# 69 | # MAIN # 70 | #========================================# 71 | X,x1,x2,y = createData(100) 72 | w = regression(X,y) 73 | p,q,Z = predict(w) 74 | X,Y = meshgrid(p,q) 75 | 76 | # Plot results 77 | #p1 = scatter3D([],0) 78 | fig = figure() 79 | ax = fig.add_subplot(projection="3d") 80 | ax.plot_surface(X,Y,Z) 81 | 82 | ax.plot3D(x1,x2,y,".",color="gray") 83 | ax.set_xlabel("x") 84 | ax.set_ylabel("y") 85 | ax.set_zlabel("p") 86 | ax.view_init(21,-61) 87 | show() 88 | 89 | 90 | -------------------------------------------------------------------------------- /supervised/classification/logistic.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | # Synthetic training data 5 | N = 100 6 | 7 | e1 = np.random.randn(N) 8 | f1 = [2*xi+1 + np.random.randn() for xi in e1] 9 | e2 = np.random.randn(N)+3 10 | f2 = [3*xi+0.5 + np.random.randn() for xi in e2] 11 | y = np.append(np.zeros(N),np.ones(N)) 12 | 13 | x1 = np.append(e1,e2) 14 | x2 = np.append(f1,f2) 15 | e = [1 for i in range(2*N)] 16 | 17 | X = np.c_[e,x1,x2] 18 | 19 | # Regression 20 | w = [np.random.rand(),np.random.rand(),np.random.rand()] 21 | 22 | for it in range(200): 23 | p = [1.0/(1.0 + np.exp(-np.dot(w,r))) for r in X] 24 | S = np.diag(p) 25 | 26 | G = np.matmul(np.matmul(np.transpose(X),S),X) 27 | D = np.matmul(np.linalg.inv(G),np.transpose(X)) 28 | w = w + np.matmul(D,y-p) 29 | 30 | # Quality 31 | L = 1 32 | for pi,yi in zip(p,y): 33 | L = L*(pi**yi)*((1-pi)**(1-yi)) 34 | 35 | print(-2*np.log(L)) 36 | 37 | # Predict & Plot 38 | p = np.linspace(-2,7,100) 39 | q = np.linspace(-2,16,100) 40 | X,Y = np.meshgrid(p,q) 41 | Z = np.zeros((100,100)) 42 | 43 | for j in range(100): 44 | for i in range(100): 45 | r = [1,p[i],q[j]] 46 | Z[i][j] = 1.0/(1.0 + np.exp(-np.dot(w,r))) 47 | 48 | fig = pl.figure() 49 | ax = fig.add_subplot(111,projection='3d') 50 | ax.plot_surface(X,Y,Z,cmap="Greys",alpha=0.7,shade=True) 51 | 52 | ax.plot3D(x1,x2,y,'.',color='gray') 53 | ax.set_xlabel('x') 54 | ax.set_ylabel('y') 55 | ax.set_zlabel('p') 56 | ax.view_init(21,-61) 57 | #pl.savefig('../figs/src/logistic.svg') 58 | pl.show() 59 | 60 | -------------------------------------------------------------------------------- /supervised/classification/tree.jl: -------------------------------------------------------------------------------- 1 | T = ["low" "low" "no"; 2 | "low" "high" "yes"; 3 | "high" "low" "no"; 4 | "high" "high" "no"; 5 | "fair" "high" "yes"; 6 | "fair" "fair" "yes"] 7 | 8 | # Entropy of classes 9 | function Entropy(v) 10 | s = length(v) 11 | n = 0 12 | l = [] 13 | 14 | # Find number of classes present 15 | for vi in v 16 | if ~(vi in l) 17 | push!(l,vi) 18 | n = n + 1 19 | end 20 | end 21 | 22 | # Find frequencies 23 | p = zeros(n) 24 | 25 | for i in 1:s 26 | for j in 1:n 27 | if (v[i] == l[j]) 28 | p[j] = p[j] + 1 29 | end 30 | end 31 | end 32 | 33 | # Compute entropy 34 | p = p/s 35 | H = -sum(p.*log2.(p)) 36 | 37 | return H 38 | end 39 | 40 | # Information gain 41 | function igain(T,p) 42 | # Find number of elements in attribute 43 | l = [] # list of attributes 44 | n = 0 # number of attributes 45 | for vi in T[:,p] 46 | if ~(vi in l) 47 | push!(l,vi) 48 | n = n + 1 49 | end 50 | end 51 | 52 | # Find entropies 53 | E = 0 54 | for j in 1:n 55 | t = [] 56 | f = 0 57 | for vi in eachrow(T) 58 | if (vi[p] == l[j]) 59 | push!(t,vi[3]) 60 | f = f + 1 61 | end 62 | end 63 | S = Entropy(t) 64 | f = f / length(T[:,1]) 65 | E = E + S*f 66 | println(f," ",S) 67 | end 68 | 69 | return Entropy(T[:,3])-E 70 | end 71 | 72 | #println(Entropy(T[:,3])) 73 | println(igain(T,1)) 74 | println(igain(T,2)) 75 | -------------------------------------------------------------------------------- /supervised/classification/tree.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | Data = np.array([[5.9E7, 400.0, 3.0, 118.4, 0], 4 | [6.2E7, 430.0, 2.5, 125.6, 0], 5 | [1.7E7, 120.0, 2.5, 0.0, 0], 6 | [7.1E6, 29.0, 1.5, 28.9, 0], 7 | [3.3E6, 50.0, 3.5, 78.0, 0], 8 | [1.0E3, 150.0, 6.5, 133.6, 1], 9 | [1.0E-15, 0.205, 2.0, 200.0, 0], 10 | [2.0E3, 60.0, 6.0, 119.0, 1]]) 11 | 12 | Data = np.array([[10, 10,0], 13 | [10, 400,1], 14 | [1E7, 10,0], 15 | [1E7,400,0], 16 | [1E3, 60,1], 17 | [1E3, 60,1]]) 18 | 19 | nr,nc = np.shape(Data) 20 | p0 = np.sum(Data[:,nc-1])/nr 21 | p1 = (nr-np.sum(Data[:,nc-1]))/nr 22 | Ho = -p0*np.log2(p0)-p1*np.log2(p1) 23 | 24 | print(Ho) 25 | 26 | def condS(Data,col,X): 27 | X = np.array(X) 28 | N = np.size(X,0) 29 | M = np.zeros((N+1,5)) 30 | nr,nc = np.shape(Data) 31 | 32 | print(X[1,0]) 33 | 34 | for a,b in zip(Data[:,col],Data[:,nc-1]): 35 | for i in range(N): 36 | if (a >= X[i,0] and a <= X[i,1]): 37 | if (b == 1): 38 | M[i,0] = M[i,0] + 1 39 | else: 40 | M[i,1] = M[i,1] + 1 41 | 42 | for i in range(N): 43 | M[i,2] = np.sum(M[i,:]) 44 | 45 | for i in range(3): 46 | M[N,i] = np.sum(M[:,i]) 47 | 48 | X = condS(Data,0,[[0,100],[200,1E5],[1E6,1E8]]) 49 | print(X) 50 | -------------------------------------------------------------------------------- /supervised/regression/Anscombe.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | X = [ [10,8,13,9,11,14,6, 4,12,7,5], 5 | [10,8,13,9,11,14,6, 4,12,7,5], 6 | [10,8,13,9,11,14,6, 4,12,7,5], 7 | [8, 8, 8,8, 8, 8,8,19, 8,8,8]] 8 | 9 | Y = [ [8.04,6.95, 7.58,8.81,8.33,9.96,7.24, 4.26,10.84,4.82,5.68], 10 | [9.14,8.14, 8.74,8.77,9.26,8.10,6.13, 3.10, 9.13,7.26,4.74], 11 | [7.46,6.77,12.74,7.11,7.81,8.84,6.08, 5.39, 8.15,6.42,5.73], 12 | [6.58,5.76, 7.71,8.84,8.47,7.04,5.25,12.50, 5.56,7.91,6.89]] 13 | 14 | 15 | c = ['.','s','*','^'] 16 | 17 | for n in range(4): 18 | a = np.cov(X[n],Y[n])[0][1]/np.var(X[n]) 19 | b = np.mean(Y[n])-a*np.mean(X[n]) 20 | x = np.linspace(3,20,100) 21 | y = [a*xi + b for xi in x] 22 | 23 | print('Sample #'+str(n)) 24 | print('Mean x: '+str(np.mean(X[n]))) 25 | print('Mean y: '+str(np.mean(Y[n]))) 26 | print('Var x: '+str(np.var(X[n]))) 27 | print('Var y: '+str(np.var(Y[n]))) 28 | print('cor(x,y): '+str(np.corrcoef(X[n],Y[n])[0][1])) 29 | print('Line : '+str(a)+'x + '+str(b)) 30 | print('--------------------------------') 31 | 32 | pl.subplot(221 + n) 33 | pl.plot(x,y,color='lightgray') 34 | pl.plot(X[n],Y[n],c[n],color='gray') 35 | pl.axis([3,20,2,14]) 36 | pl.xlabel('x1') 37 | pl.ylabel('y1') 38 | 39 | pl.show() 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /supervised/regression/Gaussian.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using Distributions 3 | using PyPlot 4 | 5 | 6 | function kernel(x,y) 7 | σₒ = 1.0 # signal variance 8 | λ = 0.6 # length scale 9 | 10 | L2(x) = sum(x.^2) 11 | 12 | Nx = length(x) 13 | Ny = length(y) 14 | 15 | K = Array{Float64}(undef,Nx,Ny) 16 | 17 | for i in 1:Nx 18 | for j in 1:Ny 19 | K[i,j] = σₒ*exp(-L2(x[i]-y[j])/2λ^2) 20 | end 21 | end 22 | 23 | return K 24 | end 25 | 26 | N = 10 27 | M = 100 28 | 29 | x = 2π*rand(N) 30 | xₒ = LinRange(0,2π,M) 31 | f = sin.(x) 32 | 33 | μ = kernel(xₒ,x)*inv(kernel(x,x))*f 34 | Σ = kernel(xₒ,xₒ)-kernel(xₒ,x)*inv(kernel(x,x)+1E-6*I)*kernel(x,xₒ) 35 | 36 | L = cholesky(Symmetric(Σ),check=false).L 37 | 38 | for i in 1:15 39 | g = μ + L*randn(M) 40 | plot(xₒ,g,alpha=0.3) 41 | end 42 | 43 | plot(xₒ,μ) 44 | plot(x,f,"*",color="black") 45 | show() 46 | 47 | 48 | -------------------------------------------------------------------------------- /supervised/regression/LARS.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using Statistics 3 | using LinearAlgebra 4 | 5 | # Synthetic training data 6 | function createData(N) 7 | a0 = 1.29 8 | a1 = 1.43 9 | a2 = 1.15 10 | a = [a0,a1,a2] 11 | 12 | x0 = [] 13 | x1 = [] 14 | x2 = [] 15 | for i in 1:N 16 | push!(x0, 1) 17 | push!(x1, randn()) 18 | push!(x2, randn()) 19 | end 20 | X = hcat(x0,x1,x2) 21 | y = X*a + randn(N,1) 22 | 23 | return X,y 24 | end 25 | 26 | # Regression 27 | function LARS(X,y) 28 | η = 0.05 29 | a = [0.0,0.0,0.0] 30 | r = y 31 | 32 | x1 = X[:,2] 33 | x2 = X[:,3] 34 | 35 | y1 = [] 36 | y2 = [] 37 | y3 = [] 38 | x = [] 39 | lst = [] 40 | 41 | r2 = 0 42 | r1a = [] 43 | r2a = [] 44 | 45 | for it in 1:10000 46 | ρ = [sum(r), x1⋅r, x2⋅r] 47 | i = argmax(abs.(ρ)) 48 | 49 | if (~(i in lst)) 50 | push!(lst,i) 51 | end 52 | 53 | # Find equiangular direction 54 | d = 0 55 | for j in lst 56 | d = d + η*sign(ρ[j]) 57 | end 58 | d = d / length(lst) 59 | 60 | # Update all coefficients in the list and residuals 61 | for j in lst 62 | a[j] = a[j] + d 63 | r = r - d*X[:,j] 64 | end 65 | 66 | push!(x,norm(a)) 67 | push!(y1,a[1]) 68 | push!(y2,a[2]) 69 | push!(y3,a[3]) 70 | 71 | yh = X*a 72 | r2 = cor(yh,r)[1] 73 | push!(r2a,r2) 74 | push!(r1a,1-(r⋅r)/(y'*y)[1,1]) 75 | end 76 | 77 | println(a) 78 | println(r2) 79 | 80 | return x,y1,y2,y3,r1a 81 | end 82 | 83 | #===============================================# 84 | # MAIN # 85 | #===============================================# 86 | X,y = createData(100) 87 | x,y1,y2,y3,r1a = LARS(X,y) 88 | 89 | subplot(121) 90 | plot(x,y1,color="lightgray") 91 | plot(x,y2,color="gray") 92 | plot(x,y3,color="darkgray") 93 | axis([0,2.5,0,1.6]) 94 | xlabel("|a|") 95 | ylabel("a") 96 | 97 | subplot(122) 98 | plot(x,r1a,color="gray") 99 | xlabel("Step") 100 | ylabel("R^2") 101 | axis([0,2.5,0,1]) 102 | 103 | show() 104 | 105 | 106 | -------------------------------------------------------------------------------- /supervised/regression/LARS.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | 5 | # Synthetic training data 6 | N = 100 7 | 8 | a0 = 1.29 9 | a1 = 1.43 10 | a2 = 1.15 11 | a = [[a0],[a1],[a2]] 12 | 13 | x1 = np.array([np.random.randn() for i in range(N)]) 14 | x2 = np.array([np.random.randn() for i in range(N)]) 15 | e = [1 for i in range(N)] 16 | X = np.c_[e,x1,x2] 17 | 18 | y = np.dot(X,a) + np.random.randn(N,1) 19 | 20 | 21 | # Regression 22 | eta = 0.05 23 | a = [0,0,0] 24 | r = [yi[0] for yi in y] 25 | 26 | y1 = [] 27 | y2 = [] 28 | y3 = [] 29 | x = [] 30 | lst = [] 31 | 32 | r2 = 0 33 | r1a = [] 34 | r2a = [] 35 | for it in range(10000): 36 | rho = [np.dot(e,r), np.dot(x1,r), np.dot(x2,r)] 37 | i = np.argmax(np.absolute(rho)) 38 | 39 | if i not in lst: 40 | lst.append(i) 41 | 42 | # Find equiangular direction 43 | d = 0 44 | for j in lst: 45 | d = d + eta*np.sign(rho[j]) 46 | d = d / len(lst) 47 | 48 | # Update all coefficients in the list and residuals 49 | for j in lst: 50 | a[j] = a[j] + d 51 | r = r - d*X[:,j] 52 | 53 | x.append(np.linalg.norm(a)) 54 | y1.append(a[0]) 55 | y2.append(a[1]) 56 | y3.append(a[2]) 57 | 58 | yh = np.matmul(X,a) 59 | r2 = np.corrcoef(yh,np.transpose(r))[0][1] 60 | r2a.append(r2) 61 | r1a.append(1-np.dot(r,r)/np.matmul(np.transpose(y),y)[0][0]) 62 | 63 | print(a) 64 | print(r2) 65 | 66 | pl.subplot(121) 67 | pl.plot(x,y1,color='lightgray') 68 | pl.plot(x,y2,color='gray') 69 | pl.plot(x,y3,color='darkgray') 70 | pl.axis([0,2.5,0,1.6]) 71 | pl.xlabel('|a|') 72 | pl.ylabel('a') 73 | 74 | pl.subplot(122) 75 | pl.plot(x,r1a,color='gray') 76 | pl.xlabel('Step') 77 | pl.ylabel('R$^2$') 78 | pl.axis([0,2.5,0,1]) 79 | #pl.savefig('../figs/src/LARS.svg') 80 | 81 | pl.show() 82 | 83 | 84 | -------------------------------------------------------------------------------- /supervised/regression/LM.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | # Synthetic training data 4 | N = 100 5 | a = 1.5 6 | b = 2.0 7 | x = randn(N) 8 | y = a*sin.(x*b) + randn(N)/8 9 | 10 | # Levenberg-Marquardt 11 | w = [0.7,1.1] 12 | for it in 1:10 13 | J1 = sin.(w[2]*x) 14 | J2 = w[1]*x.*cos.(w[2]*x) 15 | J = hcat(J1,J2) 16 | 17 | f = w[1]*sin.(x*w[2]) 18 | 19 | global w = w + (inv(J'*J)*J')*(y-f) 20 | end 21 | 22 | # Predict 23 | px = LinRange(-3,3,100) 24 | py = w[1]*sin.(px*w[2]) 25 | 26 | println(w) 27 | 28 | plot(px,py,color="lightgray") 29 | plot(x,y,".",color="gray") 30 | show() 31 | -------------------------------------------------------------------------------- /supervised/regression/LM.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | # Synthetic training data 5 | N = 100 6 | a = 1.5 7 | b = 2.0 8 | x = [np.random.randn() for i in range(N)] 9 | y = np.array([[a*np.sin(xi*b)+np.random.randn()/8] for xi in x]) 10 | 11 | 12 | # Levenberg-Marquardt 13 | 14 | w = np.array([[0.7],[1.1]]) 15 | for it in range(10): 16 | J = [] 17 | f = [] 18 | for xi in x: 19 | J.append([np.sin(w[1][0]*xi),w[0][0]*xi*np.cos(w[1][0]*xi)]) 20 | f.append([w[0][0]*np.sin(xi*w[1][0])]) 21 | gram = np.dot(np.transpose(J),J) 22 | MP = np.matmul(np.linalg.inv(gram),np.transpose(J)) 23 | w = w + np.matmul(MP,y-f) 24 | 25 | # Predict 26 | px = np.linspace(-3,3,100) 27 | py = [w[0][0]*np.sin(xi*w[1][0]) for xi in px] 28 | 29 | print(w) 30 | 31 | pl.plot(px,py,color="lightgray") 32 | pl.plot(x,y,'.',color="gray") 33 | #pl.savefig("../figs/src/LM.svg") 34 | pl.show() 35 | -------------------------------------------------------------------------------- /supervised/regression/Simpson.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | xo = [0,1,2,3] 5 | yo = [30,20,10,0] 6 | 7 | xl = [] 8 | yl = [] 9 | 10 | for n in range(4): 11 | x = np.random.randn(100) 12 | y = np.array([2*xi + np.random.randn() for xi in x]) 13 | 14 | xd = x + xo[n] 15 | yd = y + yo[n] 16 | 17 | xl = np.append(xl,xd) 18 | yl = np.append(yl,yd) 19 | 20 | xf = np.linspace(-4,4,100) 21 | a = np.cov(x,y)[1][0]/np.var(x) 22 | b = np.mean(y)-a*np.mean(x) 23 | yf = np.array([a*xi + b for xi in xf]) 24 | 25 | xf = xf + xo[n] 26 | yf = yf + yo[n] 27 | 28 | pl.plot(xf,yf,color='lightgray') 29 | pl.plot(xd,yd,'.',color='gray') 30 | 31 | x = np.linspace(-4,7,100) 32 | a = np.cov(xl,yl)[0][1]/np.var(xl) 33 | b = np.mean(yl) - a*np.mean(xl) 34 | y = np.array([a*xi + b for xi in x]) 35 | pl.plot(x,y,':',color='darkgray') 36 | pl.axis([-6,8,-10,40]) 37 | pl.xlabel('x') 38 | pl.ylabel('y') 39 | 40 | pl.show() 41 | -------------------------------------------------------------------------------- /supervised/regression/linear.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using Statistics 3 | 4 | # Synthetic training data 5 | N = 100 6 | a = 1.5 7 | b = 1.0 8 | x = [randn() for i in 1:N] 9 | y = [a*xi + b + randn()/2 for xi in x] 10 | 11 | # Linear Regression 12 | a = cov(x,y) 13 | b = mean(y) - a*mean(x) 14 | nx = LinRange(-2,2,100) 15 | ny = [a*xi + b for xi in nx] 16 | 17 | # Quality of regression 18 | ry = [a*xi + b for xi in x] 19 | r2 = cor(y,ry)^2 20 | println("R2 = ",100*r2," %") 21 | 22 | # Plot 23 | plot(x,y,".",color="gray") 24 | plot(nx,ny,color="lightgray") 25 | axis([-3,3,-3,4]) 26 | xlabel("x") 27 | ylabel("y") 28 | #pl.savefig('../figs/src/linear.svg') 29 | show() 30 | -------------------------------------------------------------------------------- /supervised/regression/linear.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | 5 | # Synthetic training data 6 | N = 100 7 | a = 1.5 8 | b = 1.0 9 | x = [np.random.randn() for i in range(N)] 10 | y = [a*xi + b + np.random.randn()/2 for xi in x] 11 | 12 | # Linear Regression 13 | a = np.cov(x,y)[0][1] 14 | b = np.mean(y) - a*np.mean(x) 15 | nx = np.linspace(-2,2,100) 16 | ny = [a*xi + b for xi in nx] 17 | 18 | # Quality of regression 19 | ry = [a*xi + b for xi in x] 20 | r2 = np.corrcoef(y,ry)[0][1]**2 21 | print("R2 = "+str(100*r2)+" %") 22 | 23 | # Plot 24 | pl.plot(x,y,'.',color='gray') 25 | pl.plot(nx,ny,color='lightgray') 26 | pl.axis([-3,3,-3,4]) 27 | pl.xlabel('x') 28 | pl.ylabel('y') 29 | #pl.savefig('../figs/src/linear.svg') 30 | pl.show() 31 | 32 | -------------------------------------------------------------------------------- /supervised/regression/mlinear.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using Statistics 3 | using LinearAlgebra 4 | 5 | 6 | # Synthetic training data 7 | N = 100 8 | 9 | a0 = 1.29 10 | a1 = 1.43 11 | a2 = 1.15 12 | a = [a0, a1, a2] 13 | 14 | X = zeros(N,3) 15 | for i in 1:N 16 | x1 = randn() 17 | x2 = x1*a2 + randn()/2 18 | X[i,:] = [1 x1 x2] 19 | end 20 | x1 = X[:,1] 21 | x2 = X[:,2] 22 | 23 | y = X*a + randn(N)/2 24 | 25 | # Regression 26 | lbd = 0.1 # <- Ridge 27 | Gram = X'*X + I*lbd 28 | MP = inv(Gram)*X' 29 | a = MP*y 30 | println(a) 31 | 32 | # Quality 33 | ry = X*a 34 | r2 = cor(ry,y) 35 | println("R2 = ",100*r2," %") 36 | 37 | # Predict 38 | for i in 1:N 39 | px = -2 + 4*(i-1)/99 40 | py = px 41 | X[i,:] = [1 px py] 42 | end 43 | pz = X*a 44 | px = X[:,1] 45 | py = X[:,2] 46 | 47 | # Plot 48 | p1 = scatter3D([],0) 49 | fig = figure() 50 | ax = fig.add_subplot(projection="3d") 51 | y = [xi[1] for xi in y] 52 | pz = [zi[1] for zi in pz] 53 | 54 | ax.plot3D(x1,x2,y,".",color="darkgray") 55 | ax.plot3D(px,py,pz,color="gray") 56 | ax.set_xlabel("x") 57 | ax.set_ylabel("y") 58 | ax.set_zlabel("z") 59 | show() 60 | -------------------------------------------------------------------------------- /supervised/regression/mlinear.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | 5 | # Synthetic training data 6 | N = 100 7 | 8 | a0 = 1.29 9 | a1 = 1.43 10 | a2 = 1.15 11 | a = [[a0],[a1],[a2]] 12 | 13 | x1 = [np.random.randn() for i in range(N)] 14 | x2 = [ex*a2 + np.random.randn()/2 for ex in x1] 15 | e = [1 for i in range(N)] 16 | X = np.c_[e,x1,x2] 17 | 18 | y = np.dot(X,a) + np.random.randn(N,1)/2 19 | 20 | # Regression 21 | lbd = 0.1 # <- Ridge 22 | Gram = np.dot(np.transpose(X),X) + np.eye(3)*lbd 23 | MP = np.dot(np.linalg.inv(Gram),np.transpose(X)) 24 | a = np.dot(MP,y) 25 | print(a) 26 | 27 | # Quality 28 | ry = np.dot(X,a) 29 | r2 = np.corrcoef(np.transpose(ry),np.transpose(y))[0][1] 30 | print("R2 = "+str(100*r2)+" %") 31 | 32 | # Predict 33 | px = np.linspace(-2,2,100) 34 | py = np.linspace(-2,2,100) 35 | X = np.c_[e,px,py] 36 | pz = np.dot(X,a) 37 | 38 | # Plot 39 | y = [xi[0] for xi in y] 40 | pz = [zi[0] for zi in pz] 41 | 42 | fig = pl.figure() 43 | ax = pl.axes(projection='3d') 44 | ax.plot3D(x1,x2,y,'.',color='darkgray') 45 | ax.plot3D(px,py,pz,color='gray') 46 | ax.set_xlabel('x') 47 | ax.set_ylabel('y') 48 | ax.set_zlabel('z') 49 | ax.axes.set_xlim3d(left=-4,right=4) 50 | ax.axes.set_ylim3d(bottom=-4,top=4) 51 | ax.axes.set_zlim3d(bottom=-6,top=8) 52 | #pl.savefig('../figs/src/mlinear.svg') 53 | pl.show() 54 | -------------------------------------------------------------------------------- /supervised/regression/stagewise.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | 5 | # Synthetic training data 6 | N = 100 7 | 8 | a0 = 1.29 9 | a1 = 1.43 10 | a2 = 1.15 11 | a = [[a0],[a1],[a2]] 12 | 13 | x1 = np.array([np.random.randn() for i in range(N)]) 14 | x2 = np.array([np.random.randn() for i in range(N)]) 15 | e = [1 for i in range(N)] 16 | X = np.c_[e,x1,x2] 17 | 18 | y = np.dot(X,a) + np.random.randn(N,1) 19 | 20 | 21 | # Regression 22 | eta = 0.05 23 | a = [0,0,0] 24 | r = [yi[0] for yi in y] 25 | 26 | y1 = [] 27 | y2 = [] 28 | y3 = [] 29 | x = [] 30 | 31 | r2 = 0 32 | for it in range(15000): 33 | rho = [np.dot(e,r), np.dot(x1,r), np.dot(x2,r)] 34 | i = np.argmax(np.absolute(rho)) 35 | 36 | d = eta*np.sign(rho[i]) 37 | a[i] = a[i] + d 38 | r = r - d*X[:,i] 39 | 40 | x.append(np.linalg.norm(a)) 41 | y1.append(a[0]) 42 | y2.append(a[1]) 43 | y3.append(a[2]) 44 | 45 | yh = np.matmul(X,a) 46 | r2 = np.corrcoef(yh,np.transpose(y))[0][1] 47 | 48 | print(a) 49 | print(r2) 50 | 51 | pl.plot(x,y1) 52 | pl.plot(x,y2) 53 | pl.plot(x,y3) 54 | 55 | pl.show() 56 | 57 | 58 | -------------------------------------------------------------------------------- /unsupervised/clustering/AGNES.jl: -------------------------------------------------------------------------------- 1 | function getData(fname) 2 | mat = zeros(252,7) 3 | f = open(fname,"r") 4 | for i in 1:252 5 | line = readline(f) 6 | columns = split(line,"\t") 7 | for j in 1:7 8 | mat[i,j] = parse(Float64,columns[j]) 9 | end 10 | end 11 | close(f) 12 | 13 | return mat 14 | end 15 | 16 | 17 | function Euclidean(M,i,j) 18 | t, = size(M) 19 | return sum((M[:,i]-M[:,j]).^2)/t 20 | end 21 | 22 | function Manhattan(M,i,j) 23 | return sum(abs.(M[:,i]-M[:,j])) 24 | end 25 | 26 | function Chebyshev(M,i,j) 27 | return maximum(M[:,i]-M[:,j]) 28 | end 29 | 30 | function showmat(X) 31 | i,j = size(X) 32 | 33 | for k in 1:i 34 | println(X[k,:]) 35 | end 36 | end 37 | 38 | function AGNES(M) 39 | t,NClu = size(M) 40 | c1 = 0 41 | c2 = 0 42 | 43 | Labels = ["INTC","AMD","IBM","NVDA","MCHP","ADI","TXN"] 44 | 45 | # Create distance matrix 46 | D = zeros(7,7) 47 | for i in 1:(NClu-1) 48 | for j in (i+1):NClu 49 | d = Euclidean(M,i,j) 50 | D[i,j] = d 51 | D[j,i] = D[i,j] 52 | end 53 | end 54 | 55 | # Clustering loop 56 | for it in 1:6 57 | d_min = 1E7 58 | for i in 1:(NClu-1) 59 | for j in (i+1):NClu 60 | if (D[i,j] < d_min) 61 | d_min = D[i,j] 62 | c1 = i 63 | c2 = j 64 | end 65 | end 66 | end 67 | 68 | # Create mapping 69 | map = zeros(Int,NClu) 70 | j = 1 71 | for i in 1:NClu 72 | if (i != c1 && i != c2) 73 | map[i] = j 74 | j = j + 1 75 | else 76 | map[i] = 0 77 | end 78 | end 79 | 80 | # New distance matrix 81 | nL = ["" for i in 1:NClu-1] 82 | nD = zeros(NClu-1,NClu-1) 83 | for j in 1:NClu 84 | if (j != c1 && j != c2) 85 | nL[map[j]] = Labels[j] 86 | for i in 1:NClu 87 | if (i != c1 && i != c2) 88 | nD[map[i],map[j]] = D[i,j] 89 | end 90 | end 91 | end 92 | end 93 | 94 | # Add new distances 95 | for i in 1:NClu 96 | if (i != c1 && i != c2) 97 | nL[NClu-1] = Labels[c1]*"/"*Labels[c2] 98 | d = 0.5*(D[i,c1]+D[i,c2]) 99 | nD[map[i],NClu-1] = d 100 | nD[NClu-1,map[i]] = d 101 | end 102 | end 103 | 104 | println("Link: ",Labels[c1]," and ",Labels[c2]," with distance ",d_min,", forming new cluster ",nL[NClu-1]) 105 | println("-------------------------------------------------------------------") 106 | 107 | NClu = NClu - 1 108 | Labels = nL 109 | D = nD 110 | 111 | #showmat(D) 112 | end 113 | end 114 | 115 | M = getData("data.dat") 116 | AGNES(M) 117 | -------------------------------------------------------------------------------- /unsupervised/clustering/DBSCAN.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | function createdata(N) 4 | R = [] 5 | for i in 1:N 6 | r = 5+rand()*2 7 | θ = (rand()-0.5)*π 8 | x = r*cos(θ) 9 | y = r*sin(θ) 10 | 11 | if (i == 1) 12 | R = [x y 0] 13 | else 14 | R = vcat(R,[x y 0]) 15 | end 16 | 17 | x = randn() 18 | y = randn() 19 | R = vcat(R,[x y 0]) 20 | end 21 | 22 | return R 23 | end 24 | 25 | function Euclidean(x,y) 26 | return sum((x-y).^2) 27 | end 28 | 29 | function neighborhood(p,R,dmin) 30 | N,M = size(R) 31 | nei = [] 32 | 33 | for i in 1:N 34 | d = Euclidean(R[p,1:2],R[i,1:2]) 35 | if (d < dmin) 36 | push!(nei,i) 37 | end 38 | end 39 | 40 | return nei 41 | end 42 | 43 | function clusterize(p,R,cluster,Nmin,dmin) 44 | list = [] 45 | push!(list,p) 46 | 47 | while(length(list) != 0) 48 | q = pop!(list) 49 | 50 | nei = neighborhood(q,R,dmin) 51 | if (R[q,3] == 0 && length(nei) > Nmin) 52 | R[q,3] = cluster 53 | while(length(nei) > 0) 54 | t = pop!(nei) 55 | push!(list,t) 56 | end 57 | end 58 | end 59 | 60 | return R 61 | end 62 | 63 | function Scan(R,Nmin,dmin) 64 | N,M = size(R) 65 | 66 | C = 0 67 | for i in 1:N 68 | nei = neighborhood(i,R,dmin) 69 | if (length(nei) > Nmin && R[i,3] == 0) 70 | C = C + 1 71 | R = clusterize(i,R,C,Nmin,dmin) 72 | end 73 | end 74 | 75 | return R 76 | end 77 | 78 | R = createdata(150) 79 | R = Scan(R,3,1) 80 | scatter(R[:,1],R[:,2],10,R[:,3]) 81 | show() 82 | -------------------------------------------------------------------------------- /unsupervised/clustering/DIANA.jl: -------------------------------------------------------------------------------- 1 | function getData(fname) 2 | mat = Array{Any}(undef,253,7) 3 | mat[1,:] = ["INTC","AMD","IBM","NVDA","MCHP","ADI","TXN"] 4 | f = open(fname,"r") 5 | for i in 2:253 6 | line = readline(f) 7 | columns = split(line,"\t") 8 | for j in 1:7 9 | mat[i,j] = parse(Float64,columns[j]) 10 | end 11 | end 12 | close(f) 13 | 14 | return mat 15 | end 16 | 17 | function Euclidean(x,y) 18 | t = length(x) 19 | return sum((x-y).^2)/t 20 | end 21 | 22 | 23 | function avg(x,A) 24 | d = 0 25 | m = length(A) 26 | 27 | if (m == 0) 28 | return 0 29 | else 30 | for y in A 31 | d = d + Euclidean(x[2:end],y[2:end]) 32 | end 33 | 34 | return d/(length(A)-1) 35 | end 36 | end 37 | 38 | function diam(A) 39 | dmax = -1 40 | for x in A 41 | for y in A 42 | d = Euclidean(x[2:end],y[2:end]) 43 | if (d > dmax) 44 | dmax = d 45 | end 46 | end 47 | end 48 | 49 | return dmax 50 | end 51 | 52 | function DIANA_split(C) 53 | # Initial conditions 54 | A = Set(C) 55 | B = Set() 56 | 57 | # Run until Dmax > 0 58 | L = 1 59 | while(L > 0) 60 | D_max = -1 61 | v = [] 62 | for x in A 63 | dA = avg(x,setdiff(A,[x])) 64 | dB = avg(x,B) 65 | D = dA - dB 66 | 67 | if (D > 0 && D > D_max) 68 | D_max = D 69 | v = x 70 | end 71 | end 72 | 73 | # If Dmax > 0, then A = A\v, B = B U v 74 | L = length(v) 75 | if (L > 0) 76 | setdiff!(A,[v]) 77 | push!(B,v) 78 | end 79 | end 80 | 81 | # Split cluster 82 | return A,B 83 | end 84 | 85 | function DIANA(M) 86 | # Initial conditions 87 | t,NClu = size(M) 88 | C = Set([M[:,i] for i in 1:NClu]) 89 | Clusters = Set([C]) 90 | 91 | for it in 1:7 92 | # Find largest cluster 93 | Lmax = -1 94 | csplit = [] 95 | for c in Clusters 96 | L = diam(c) 97 | if (L > Lmax) 98 | Lmax = L 99 | csplit = c 100 | end 101 | end 102 | 103 | # If cluster has more than one element, split 104 | if (length(csplit) > 1) 105 | setdiff!(Clusters,[csplit]) 106 | A,B = DIANA_split(csplit) 107 | push!(Clusters,A) 108 | push!(Clusters,B) 109 | 110 | # print 111 | println("Cluster:") 112 | for x in csplit 113 | println(" ",x[1]) 114 | end 115 | println("Split into:") 116 | for x in A 117 | println(" ",x[1]) 118 | end 119 | println("And:") 120 | for x in B 121 | println(" ",x[1]) 122 | end 123 | println("-----------------------") 124 | end 125 | end 126 | end 127 | 128 | M = getData("data.dat") 129 | DIANA(M) 130 | -------------------------------------------------------------------------------- /unsupervised/clustering/PAM.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | function createdata(N) 4 | R = [] 5 | for i in 1:N 6 | for (kx,ky) in zip([1 5 10],[10 1 7]) 7 | x = kx + randn() 8 | y = ky + randn() 9 | z = rand([1 2 3]) 10 | 11 | if (i == 1) 12 | R = [x y z] 13 | else 14 | R = vcat(R,[x y z]) 15 | end 16 | end 17 | end 18 | 19 | return R 20 | end 21 | 22 | # Average intracluster distance 23 | function Cost(M,R) 24 | N,M = size(R) 25 | 26 | s = zeros(3) 27 | n = zeros(3) 28 | for i in 1:(N-1) 29 | p = trunc(Int,R[i,3]) 30 | for j in (i+1):N 31 | q = trunc(Int,R[j,3]) 32 | if (p == q) 33 | s[p] = s[p] + Euclidean(R[i,1:2],R[j,1:2]) 34 | n[p] = n[p] + 1 35 | end 36 | end 37 | end 38 | 39 | return sum(s./n) 40 | end 41 | 42 | # Partition around medoids 43 | function PAM(R) 44 | N,M = size(R) 45 | 46 | # Initial conditions 47 | Medoids = [0 0 0] 48 | while(Medoids[1] == 0 || Medoids[2] == 0 || Medoids[3] == 0) 49 | i = rand(1:N) 50 | p = trunc(Int,R[i,3]) 51 | Medoids[p] = i 52 | end 53 | 54 | for it in 1:50 55 | # Assign 56 | for i in 1:N 57 | dmin = 1E5 58 | for k in 1:3 59 | d = Euclidean(R[i,1:2],R[Medoids[k],1:2]) 60 | if (d < dmin) 61 | dmin = d 62 | R[i,3]= k 63 | end 64 | end 65 | end 66 | 67 | # Recalculate 68 | BestCost = Cost(Medoids,R) 69 | for i in 1:N 70 | MedoidsBK = Medoids 71 | p = trunc(Int,R[i,3]) 72 | Medoids[p] = i 73 | c = Cost(Medoids,R) 74 | if (c < BestCost) 75 | BestCost = c 76 | else 77 | Medoids = MedoidsBK 78 | end 79 | end 80 | end 81 | 82 | return R 83 | end 84 | 85 | function Euclidean(x,y) 86 | t = length(x) 87 | return sum((x-y).^2)/t 88 | end 89 | 90 | function silhouette(R) 91 | N,M = size(R) 92 | NC = 3 93 | s = zeros(N) 94 | 95 | # Find size of clusters 96 | nC = zeros(NC) 97 | for i in 1:N 98 | p = trunc(Int,R[i,3]) 99 | nC[p] = nC[p] + 1 100 | end 101 | 102 | # Scan other elements 103 | for i in 1:N 104 | t = zeros(NC) 105 | p = trunc(Int,R[i,3]) 106 | a = 0 107 | for j in 1:N 108 | q = trunc(Int,R[j,3]) 109 | d = Euclidean(R[i,1:2],R[j,1:2]) 110 | if (p == q) 111 | a = a + d/(nC[q]-1) 112 | else 113 | t[q] = t[q] + d/nC[q] 114 | end 115 | end 116 | b = minimum(t[1:NC .≠ p]) 117 | 118 | # Silhouette itself 119 | if (a < b) 120 | s[i] = 1-a/b 121 | elseif (a > b) 122 | s[i] = b/a-1 123 | else 124 | s[i] = 0 125 | end 126 | end 127 | 128 | return s 129 | end 130 | 131 | 132 | R = createdata(50) 133 | R = PAM(R) 134 | scatter(R[:,1],R[:,2],10,R[:,3]) 135 | #plot(silhouette(R),"o") 136 | show() 137 | -------------------------------------------------------------------------------- /unsupervised/clustering/dbscan.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | class dbscan: 5 | def __init__(self,n): 6 | self.NPoints = n 7 | self.xv = [] 8 | self.yv = [] 9 | self.zv = [] 10 | 11 | for i in range(n): 12 | ro = 1 13 | if np.random.rand() > 0.5: 14 | ro = ro + 1 15 | r = ro + 2*(np.random.rand()-0.5)/10 16 | 17 | t = (np.random.rand()-0.5)*2*np.pi 18 | x = r*np.cos(t) 19 | y = r*np.sin(t) 20 | 21 | self.xv.append(x) 22 | self.yv.append(y) 23 | self.zv.append(0) 24 | 25 | def neighborhood(self,j): 26 | N = [] 27 | for i in range(self.NPoints): 28 | d = np.sqrt((self.xv[j]-self.xv[i])**2 + (self.yv[j]-self.yv[i])**2) 29 | if (d < 0.5): 30 | N.append(i) 31 | 32 | return N 33 | 34 | # Private 35 | def singleshot(self,i,C): 36 | visit = [] 37 | visit.append(i) 38 | while(len(visit) > 0): 39 | el = visit.pop() 40 | 41 | v = self.neighborhood(el) 42 | if (len(v) > 3 and self.zv[el] == 0): 43 | self.zv[el] = C 44 | 45 | for k in v: 46 | visit.append(k) 47 | 48 | def clusterize(self): 49 | C = 0 50 | for i in range(self.NPoints): 51 | if (self.zv[i] == 0): 52 | v = self.neighborhood(i) 53 | if (len(v) > 3): 54 | C = C + 1 55 | self.singleshot(i,C) 56 | 57 | def plot(self): 58 | pl.scatter(self.xv,self.yv,c=self.zv) 59 | 60 | 61 | d = dbscan(300) 62 | d.clusterize() 63 | d.plot() 64 | pl.show() 65 | 66 | #def neighborhood(x,y): 67 | 68 | 69 | #NClusters = 0 70 | 71 | #for i in range(NPoints): 72 | #if (z[i] == 0): 73 | #lista.append((xv[i],yv[i])) 74 | 75 | #x,y = lista.pop() 76 | #V = neighborhood(x,y) 77 | -------------------------------------------------------------------------------- /unsupervised/clustering/imgKMeans.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using Images 3 | using Statistics 4 | using LinearAlgebra 5 | 6 | function distance(r1,r2) 7 | return norm(r1 - r2) 8 | end 9 | 10 | 11 | function KMeans(filename,Nc) 12 | img = load(filename) 13 | img = channelview(img) 14 | 15 | Lc,Ly,Lx = size(img) 16 | Nc = 16 17 | 18 | # Initialization 19 | C = zeros(3,16) 20 | for i in 1:16 21 | C[:,i] = [1.0/i,1.0/i,1.0/i] 22 | end 23 | 24 | imgc = zeros(Ly,Lx) 25 | for steps = 1:10 26 | # Assignment 27 | for j in 1:Lx, i in 1:Ly 28 | d_min = 1E9 29 | c_min = 0 30 | 31 | for c in 1:Nc 32 | d = distance(img[:,i,j], C[:,c]) 33 | 34 | if d < d_min 35 | d_min = d 36 | c_min = c 37 | end 38 | end 39 | 40 | imgc[i,j] = c_min 41 | end 42 | 43 | # Recentering 44 | C = zeros(Lc,Nc) 45 | Sc = zeros(Nc) 46 | for j in 1:Lx, i in 1:Ly 47 | C[:,Int(imgc[i,j])] += img[:,i,j] 48 | Sc[Int(imgc[i,j])] += 1 49 | end 50 | 51 | for i in 1:Nc 52 | if Sc[i] > 0 53 | C[:,i] = C[:,i]/Sc[i] 54 | end 55 | end 56 | end 57 | 58 | # Reconstruct 59 | rec = zeros(Ly,Lx,Lc) 60 | for j in 1:Lx, i in 1:Ly 61 | rec[i,j,:] = C[:,Int(imgc[i,j])] 62 | end 63 | 64 | return rec 65 | end 66 | 67 | # Load image 68 | rec = KMeans("NAU.jpg",16) 69 | imshow(rec) 70 | show() 71 | 72 | -------------------------------------------------------------------------------- /unsupervised/clustering/kmeans.f90: -------------------------------------------------------------------------------- 1 | 2 | program kmeans 3 | implicit none 4 | 5 | integer,parameter :: width=410,height=512 6 | 7 | real :: C(64,3) 8 | integer :: cluster_size(64) 9 | real :: d_min,d 10 | integer :: i_min 11 | integer :: i,j,k,t,ac,loop 12 | integer :: label(height,width) 13 | integer :: fig_in(height,width,3) 14 | real :: fig_out(height,width,3) 15 | character(len=50) :: fname 16 | logical :: existent 17 | 18 | 19 | ! Load image 20 | open(1,file="fig_in.dat",status="old") 21 | 22 | do j = 1,width 23 | do i = 1,height 24 | read(1,*) fig_in(i,j,:) 25 | end do 26 | end do 27 | 28 | close(1) 29 | 30 | ! Set initial medoids 31 | ac = 1 32 | do k = 1,4 33 | do j = 1,4 34 | do i = 1,4 35 | C(ac,3) = k*64 36 | C(ac,2) = j*64 37 | C(ac,1) = i*64 38 | ac = ac + 1 39 | end do 40 | end do 41 | end do 42 | 43 | do loop = 1,10 44 | ! Clusterize data 45 | do j = 1,width 46 | do i = 1,height 47 | d_min = 1E5 48 | do k = 1,64 49 | ! L2 50 | d = 0 51 | do t = 1,3 52 | d = d + (fig_in(i,j,t) - C(k,t))**2 53 | end do 54 | ! Find nearest cluster 55 | if (d < d_min) then 56 | d_min = d 57 | i_min = k 58 | end if 59 | end do 60 | label(i,j) = i_min 61 | end do 62 | end do 63 | 64 | ! Recalculate centroids 65 | C = 0.0 66 | cluster_size = 0 67 | do j = 1,width 68 | do i = 1,height 69 | C(label(i,j),:) = C(label(i,j),:) + fig_in(i,j,:) 70 | cluster_size(label(i,j)) = cluster_size(label(i,j)) + 1 71 | end do 72 | end do 73 | 74 | do i = 1,64 75 | C(i,:) = C(i,:)/cluster_size(i) 76 | end do 77 | end do 78 | 79 | ! Reconstruct image 80 | do j = 1,width 81 | do i = 1,height 82 | fig_out(i,j,:) = C(label(i,j),:) 83 | end do 84 | end do 85 | 86 | ! Save image 87 | fname = "fig_out.dat" 88 | inquire(file=fname,exist=existent) 89 | 90 | if (existent) then 91 | open(1,file=fname,status="old") 92 | else 93 | open(1,file=fname,status="new") 94 | end if 95 | 96 | do j = 1,width 97 | do i = 1,height 98 | write(1,*) real(fig_out(i,j,:))/255 99 | end do 100 | end do 101 | 102 | close(1) 103 | end program 104 | -------------------------------------------------------------------------------- /unsupervised/clustering/kmeans.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | function createdata(N) 4 | R = [] 5 | for i in 1:N 6 | for (kx,ky) in zip([1 5 10],[10 1 7]) 7 | x = kx + randn() 8 | y = ky + randn() 9 | z = rand([1 2 3]) 10 | 11 | if (i == 1) 12 | R = [x y z] 13 | else 14 | R = vcat(R,[x y z]) 15 | end 16 | end 17 | end 18 | 19 | return R 20 | end 21 | 22 | function kmeans(R) 23 | N,M = size(R) 24 | 25 | C = [0 10;4 1;11 8] 26 | 27 | for it in 1:10 28 | # Assignment 29 | for i in 1:N 30 | smin = 1E5 31 | for k in 1:3 32 | s = sum((R[i,1:2] - C[k,:]).^2) 33 | if (s < smin) 34 | smin = s 35 | R[i,3] = k 36 | end 37 | end 38 | end 39 | 40 | # Recalculate 41 | C = zeros(3,2) 42 | num = zeros(3) 43 | for i in 1:N 44 | p = trunc(Int,R[i,3]) 45 | C[p,:] = C[p,:] + R[i,1:2] 46 | num[p] = num[p] + 1 47 | end 48 | 49 | for i in 1:3 50 | C[i,:] = C[i,:]/num[i] 51 | end 52 | end 53 | 54 | return R 55 | end 56 | 57 | function Euclidean(x,y) 58 | t = length(x) 59 | return sum((x-y).^2)/t 60 | end 61 | 62 | function silhouette(R) 63 | N,M = size(R) 64 | NC = 3 65 | s = zeros(N) 66 | 67 | # Find size of clusters 68 | nC = zeros(NC) 69 | for i in 1:N 70 | p = trunc(Int,R[i,3]) 71 | nC[p] = nC[p] + 1 72 | end 73 | 74 | # Scan other elements 75 | for i in 1:N 76 | t = zeros(NC) 77 | p = trunc(Int,R[i,3]) 78 | a = 0 79 | for j in 1:N 80 | q = trunc(Int,R[j,3]) 81 | d = Euclidean(R[i,1:2],R[j,1:2]) 82 | if (p == q) 83 | a = a + d/(nC[q]-1) 84 | else 85 | t[q] = t[q] + d/nC[q] 86 | end 87 | end 88 | b = minimum(t[1:NC .≠ p]) 89 | 90 | # Silhouette itself 91 | if (a < b) 92 | s[i] = 1-a/b 93 | elseif (a > b) 94 | s[i] = b/a-1 95 | else 96 | s[i] = 0 97 | end 98 | end 99 | 100 | return s 101 | end 102 | 103 | 104 | R = createdata(50) 105 | R = kmeans(R) 106 | #scatter(R[:,1],R[:,2],10,R[:,3]) 107 | plot(silhouette(R),"o") 108 | show() 109 | -------------------------------------------------------------------------------- /unsupervised/clustering/kmeans.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as pl 3 | 4 | NSamples = 100 5 | 6 | # Generate synthetic data 7 | x = [np.random.randn() for i in range(NSamples)] 8 | y = [np.random.randn() for i in range(NSamples)] 9 | 10 | x = np.append(x,[5 + np.random.randn() for i in range(NSamples)]) 11 | y = np.append(y,[5 + np.random.randn() for i in range(NSamples)]) 12 | 13 | x = np.append(x,[-1 + np.random.randn() for i in range(NSamples)]) 14 | y = np.append(y,[6 + np.random.randn() for i in range(NSamples)]) 15 | 16 | R = np.c_[x,y] 17 | 18 | # k-means 19 | C = [[0,0],[3,3],[0,4]] # Centroids 20 | z = [0 for i in range(3*NSamples)] # Labels 21 | 22 | for loop in range(4): 23 | # Clusterize points 24 | for j in range(3*NSamples): 25 | d_min = 10 26 | for i in range(3): 27 | d = np.linalg.norm(R[j]-C[i]) 28 | if (d < d_min): 29 | d_min = d 30 | i_min = i 31 | z[j] = i_min 32 | 33 | # Recalculate centroids 34 | C = [[0,0],[0,0],[0,0]] 35 | s = [0,0,0] 36 | for j in range(3*NSamples): 37 | C[z[j]] = C[z[j]] + R[j] 38 | s[z[j]] = s[z[j]] + 1 39 | 40 | for i in range(3): 41 | C[i] = C[i]/s[i] 42 | 43 | # Print results 44 | for c in C: 45 | print(c) 46 | 47 | pl.subplot(121) 48 | pl.scatter(x,y) 49 | pl.subplot(122) 50 | pl.scatter(x,y,c=z) 51 | 52 | # Silhouette 53 | 54 | 55 | pl.show() 56 | -------------------------------------------------------------------------------- /unsupervised/clustering/kmedoids.f90: -------------------------------------------------------------------------------- 1 | 2 | module kmod 3 | 4 | contains 5 | 6 | ! Metric distance between two vectors 7 | ! let's use Euclidean metric 8 | function distance(a,b) result(c) 9 | implicit none 10 | 11 | real,intent(in) :: a(:),b(:) 12 | real :: c 13 | 14 | integer :: i 15 | 16 | c = 0 17 | do i = 1,size(a,1) 18 | c = c + (a(i)-b(i))**2 19 | end do 20 | c = sqrt(c) 21 | end function 22 | 23 | function cost(medoids,dados,labels) result(c) 24 | implicit none 25 | 26 | real,intent(in) :: medoids(:,:) 27 | real,intent(in) :: dados(:,:) 28 | integer,intent(in) :: labels(:) 29 | real :: c 30 | 31 | integer :: i 32 | 33 | do i = 1,size(dados,1) 34 | c = c + distance(dados(i,:),medoids(labels(i),:)) 35 | end do 36 | end function 37 | end module 38 | 39 | program kmed 40 | use kmod 41 | implicit none 42 | 43 | integer,parameter :: datalength = 300 44 | real :: data(datalength,2) 45 | real :: medoid(3,2) 46 | real :: d,d_min 47 | real :: c1,c2 48 | real :: tmp(2),best(2) 49 | integer :: i,j,k(1),swap 50 | integer :: label(datalength) 51 | real :: s(datalength) 52 | integer :: clustersize(3) 53 | real :: t(3) 54 | real :: a,b 55 | 56 | character(len=50) :: fname 57 | logical :: existent 58 | logical :: change 59 | 60 | 61 | 62 | ! Load image 63 | open(1,file="data.dat",status="old") 64 | 65 | do i = 1,datalength 66 | read(1,*) data(i,:) 67 | end do 68 | 69 | close(1) 70 | 71 | ! Set itial medoids 72 | medoid(1,:) = data(50,:) 73 | medoid(2,:) = data(150,:) 74 | medoid(3,:) = data(250,:) 75 | 76 | swap = 1 77 | do while(swap > 0) 78 | ! Assignment step 79 | do i = 1,datalength 80 | d_min = 1E5 81 | do j = 1,3 82 | d = distance(data(i,:),medoid(j,:)) 83 | if (d < d_min) then 84 | label(i) = j 85 | d_min = d 86 | end if 87 | end do 88 | end do 89 | 90 | ! For each medoid... 91 | swap = 0 92 | do j = 1,3 93 | c1 = cost(medoid,data,label) 94 | tmp = medoid(j,:) 95 | ! ...check if non-medoid point has lower cost, and... 96 | do i = 1,datalength 97 | medoid(j,:) = data(i,:) 98 | c2 = cost(medoid,data,label) 99 | ! ... remember the best choice. 100 | if (c2 < c1) then 101 | c1 = c2 102 | best = medoid(j,:) 103 | change = .true. 104 | end if 105 | end do 106 | ! If any non-medoid improved, swap 107 | if (change) then 108 | medoid(j,:) = best 109 | swap = swap + 1 110 | else 111 | medoid(j,:) = tmp 112 | end if 113 | end do 114 | end do 115 | 116 | ! Save labels 117 | fname = "labels.dat" 118 | inquire(file=fname,exist=existent) 119 | 120 | if (existent) then 121 | open(1,file=fname,status="old") 122 | else 123 | open(1,file=fname,status="new") 124 | end if 125 | 126 | do i = 1,datalength 127 | write(1,*) label(i) 128 | end do 129 | 130 | close(1) 131 | do i = 1,3 132 | write(*,*) medoid(i,:) 133 | end do 134 | 135 | ! Silhouette 136 | ! find cluster sizes 137 | clustersize = 0 138 | s = 0 139 | t = 0 140 | do i = 1,datalength 141 | do j = 1,3 142 | if (label(i) == j) then 143 | clustersize(j) = clustersize(j) + 1 144 | end if 145 | end do 146 | end do 147 | 148 | ! Find coefficients a and b 149 | do i = 1,datalength 150 | a = 0 151 | d_min = 1E5 152 | do j = 1,datalength 153 | ! If they are from the same cluster 154 | if (label(j) .eq. label(i)) then 155 | if (i .ne. j) then 156 | a = a + distance(data(i,:),data(j,:)) 157 | end if 158 | else 159 | t(label(j)) = t(label(j)) + distance(data(i,:),data(j,:)) 160 | end if 161 | end do 162 | if (clustersize(label(i)) .le. 1) then 163 | s(i) = 0 164 | else 165 | a = a/(clustersize(label(i))-1) 166 | 167 | select case(label(i)) 168 | case(1) 169 | if (t(2) < t(3)) then 170 | b = t(2)/clustersize(2) 171 | else 172 | b = t(3)/clustersize(3) 173 | end if 174 | case(2) 175 | if (t(1) < t(3)) then 176 | b = t(1)/clustersize(1) 177 | else 178 | b = t(3)/clustersize(3) 179 | end if 180 | case(3) 181 | if (t(1) < t(2)) then 182 | b = t(1)/clustersize(1) 183 | else 184 | b = t(2)/clustersize(2) 185 | end if 186 | end select 187 | 188 | write(*,*) a,b,a/b 189 | 190 | if (a < b) then 191 | s(i) = 1.0-a/b 192 | end if 193 | if (a == b) then 194 | s(i) = 0 195 | end if 196 | if (a > b) then 197 | s(i) = b/a-1.0 198 | end if 199 | end if 200 | end do 201 | 202 | ! Save filhouette 203 | fname = "silhouette.dat" 204 | inquire(file=fname,exist=existent) 205 | 206 | if (existent) then 207 | open(1,file=fname,status="old") 208 | else 209 | open(1,file=fname,status="new") 210 | end if 211 | 212 | do i = 1,datalength 213 | write(1,*) s(i) 214 | end do 215 | 216 | close(1) 217 | 218 | 219 | end program 220 | -------------------------------------------------------------------------------- /unsupervised/clustering/kmedoids.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as pl 3 | 4 | NSamples = 100 5 | 6 | if (False): 7 | # Generate synthetic data 8 | x = [np.random.randn() for i in range(NSamples)] 9 | y = [np.random.randn() for i in range(NSamples)] 10 | 11 | x = np.append(x,[5 + np.random.randn() for i in range(NSamples)]) 12 | y = np.append(y,[5 + np.random.randn() for i in range(NSamples)]) 13 | 14 | x = np.append(x,[-1 + np.random.randn() for i in range(NSamples)]) 15 | y = np.append(y,[6 + np.random.randn() for i in range(NSamples)]) 16 | 17 | R = np.c_[x,y] 18 | 19 | f = open("data.dat","w") 20 | 21 | for ex,ey in zip(x,y): 22 | f.write(str(ex)+"\t"+str(ey)) 23 | f.write("\n") 24 | 25 | f.close() 26 | else: 27 | f = open("data.dat","r") 28 | g = open("labels.dat","r") 29 | h = open("silhouette.dat","r") 30 | 31 | x = [] 32 | y = [] 33 | z = [] 34 | t = [] 35 | for i in range(300): 36 | line = f.readline() 37 | row = line.split() 38 | 39 | x.append(float(row[0])) 40 | y.append(float(row[1])) 41 | 42 | line = g.readline() 43 | row = line.split() 44 | 45 | z.append(int(row[0])) 46 | 47 | line = h.readline() 48 | row = line.split() 49 | t.append(float(row[0])) 50 | f.close() 51 | g.close() 52 | 53 | pl.subplot(221) 54 | pl.scatter(x,y,color='gray') 55 | pl.subplot(222) 56 | pl.scatter(x,y,c=z) 57 | pl.subplot(223) 58 | #pl.bar(np.arange(len(t)),t,width=1.0,color='gray') 59 | pl.plot(t,color='gray') 60 | pl.axis([0,300,0,1.25]) 61 | #pl.savefig("clusters.svg") 62 | pl.show() 63 | -------------------------------------------------------------------------------- /unsupervised/clustering/spectral.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using LinearAlgebra 3 | 4 | function createdata(N) 5 | R = [] 6 | for i in 1:N 7 | r = 5+rand()*2 8 | θ = 2*(rand()-0.5)*π 9 | x = r*cos(θ) 10 | y = r*sin(θ) 11 | 12 | if (i == 1) 13 | R = [x y 0] 14 | else 15 | R = vcat(R,[x y 0]) 16 | end 17 | 18 | x = randn() 19 | y = randn() 20 | R = vcat(R,[x y 0]) 21 | end 22 | 23 | return R 24 | end 25 | 26 | function Euclidean(x,y) 27 | return sum((x-y).^2) 28 | end 29 | 30 | function spec(R) 31 | N,M = size(R) 32 | 33 | A = zeros(N,N) 34 | D = zeros(N,N) 35 | 36 | σ² = 1 37 | 38 | # Create adjacency and degree matrices 39 | for i in 1:(N-1) 40 | for j in (i+1):N 41 | d = Euclidean(R[i,1:2],R[j,1:2]) 42 | A[i,j] = exp(-d/(2σ²)) 43 | A[j,i] = A[i,j] 44 | end 45 | end 46 | for i in 1:N 47 | D[i,i] = sum(A[i,:]) 48 | end 49 | 50 | # Find second eigenvector 51 | K = I-inv(D)*A 52 | Λ = eigvals(K) 53 | z = eigvecs(K)[:,2] 54 | 55 | # Cluster 56 | return sign.(z) 57 | end 58 | 59 | R = createdata(200) 60 | z = spec(R) 61 | scatter(R[:,1],R[:,2],10,z) 62 | 63 | show() 64 | -------------------------------------------------------------------------------- /unsupervised/dimensionality/ICA.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra 2 | using Statistics 3 | using Images 4 | using PyPlot 5 | 6 | function createdata(T) 7 | img = load("img2.png") 8 | y = zeros(100,100) 9 | 10 | for j in 1:100 11 | for i in 1:100 12 | r = red(img[i,j]) 13 | g = green(img[i,j]) 14 | b = blue(img[i,j]) 15 | 16 | y[i,j] = 0.2126*r + 0.7152*g + 0.0722*b 17 | end 18 | end 19 | 20 | noise = rand(100,100) 21 | 22 | y1 = reshape(y,(10000,1)) 23 | y2 = reshape(noise,(10000,1)) 24 | 25 | S = hcat(y1,y2)' 26 | 27 | A = [0.70 0.30; 0.40 0.60] 28 | R = A*S 29 | 30 | return R,S 31 | end 32 | 33 | function sphere(R) 34 | #---- Sphering ---- 35 | # Centering 36 | R = (R .- mean(R,dims=2)) 37 | 38 | # ZCA Whitening 39 | C = R*R'/Te 40 | v = eigvals(C) 41 | U = eigvecs(C) 42 | 43 | Σ = Diagonal(1 ./ sqrt.(v)) 44 | 45 | T = U*Σ*U' 46 | Rw = T*R 47 | 48 | return Rw 49 | end 50 | 51 | g(u) = 4u^3 52 | h(u) = 12u^2 53 | 54 | function estimate(Rw) 55 | η = 0.01 56 | 57 | #---- ICA ---- 58 | V = rand(2,2) 59 | v1 = V[1,:] 60 | v2 = V[2,:] 61 | 62 | for it in 1:100 63 | t = v1'*Rw 64 | λ = (g.(t)*t')[1,1] 65 | f = Rw*g.(t')-λ*v1 66 | J = Rw*diagm(h.(t)[1,:])*Rw'-λ*I 67 | p = v1 - η*inv(J)*f 68 | v1 = p/norm(p) 69 | 70 | t = v2'*Rw 71 | λ = (g.(t)*t')[1,1] 72 | f = Rw*g.(t')-λ*v2 73 | J = Rw*diagm(h.(t)[1,:])*Rw'-λ*I 74 | p = v2 - η*inv(J)*f 75 | v2 = p/norm(p) 76 | v2 = v2 - (v2'*v1)*v1 77 | v2 = v2/norm(v2) 78 | end 79 | 80 | V = hcat(v1,v2) 81 | println(V) 82 | Sh = V'*Rw 83 | 84 | return Sh 85 | end 86 | 87 | #=========================================# 88 | # MAIN # 89 | #=========================================# 90 | Te = 150 91 | 92 | R,S = createdata(Te) 93 | Rw = sphere(R) 94 | Sh = estimate(Rw) 95 | 96 | 97 | #--- Plotting --- 98 | imshow(reshape(R[1,:],(100,100)),cmap="gray") 99 | show() 100 | imshow(reshape(R[2,:],(100,100)),cmap="gray") 101 | show() 102 | imshow(reshape(S[1,:],(100,100)),cmap="gray") 103 | show() 104 | imshow(reshape(S[2,:],(100,100)),cmap="gray") 105 | show() 106 | imshow(reshape(Sh[1,:],(100,100)),cmap="gray") 107 | show() 108 | 109 | 110 | -------------------------------------------------------------------------------- /unsupervised/dimensionality/KPCA.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using LinearAlgebra 3 | using Statistics 4 | 5 | function nonlineardata(N) 6 | R = [] 7 | c = [] 8 | for θ in LinRange(0,π,N÷2) 9 | x = cos(θ) 10 | y = sin(θ) 11 | if (length(R) == 0) 12 | R = [x;y] 13 | else 14 | R = hcat(R,[x;y]) 15 | end 16 | if (length(c) == 0) 17 | c = [0.5 0.5 0.5] 18 | else 19 | c = vcat(c,[0.5 0.5 0.5]) 20 | end 21 | 22 | x = 1 + cos(θ+π) 23 | y = 0.5 + sin(θ+π) 24 | R = hcat(R,[x;y]) 25 | c = vcat(c,[0.25 0.25 0.25]) 26 | end 27 | 28 | return R,c 29 | end 30 | 31 | 32 | R,c = nonlineardata(100) 33 | scatter(R[1,:],R[2,:],10,c) 34 | xlabel("x") 35 | ylabel("y") 36 | axis("equal") 37 | show() 38 | 39 | const γ = 15 40 | kernel(x,y) = exp(-γ*sum((x - y).^2)) 41 | 42 | function kernelPCA(X,kernel) 43 | N = size(X,2) 44 | 45 | K = [kernel(X[:,i],X[:,j]) for i in 1:N,j in 1:N] 46 | 47 | # recenter K 48 | J = ones(N,N) 49 | Kp = (I-J/N)*K*(I-J/N) 50 | 51 | # eigendecomposition 52 | v = eigvals(Kp) 53 | A = eigvecs(Kp) 54 | 55 | A = reverse(A,dims=2) 56 | v = reverse(v) 57 | v[v .< 0] .= 0 58 | Σ = Diagonal(sqrt.(v)) 59 | 60 | # Projection 61 | nΦ = Σ*A' 62 | 63 | return nΦ 64 | end 65 | 66 | # Main and plotting 67 | Φ = kernelPCA(R,kernel) 68 | scatter(Φ[1,:],Φ[2,:],10,c) 69 | xlabel("Phi_x") 70 | ylabel("Phi_y") 71 | axis("equal") 72 | show() 73 | 74 | -------------------------------------------------------------------------------- /unsupervised/dimensionality/PCA.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | using Statistics 3 | using LinearAlgebra 4 | 5 | # Random data 6 | d = 3 7 | N = 100 8 | 9 | x = randn(N)' 10 | y = [0.25*xi + 0.13 + 0.1*(randn()-0.5) for xi in x] 11 | z = [0.37*xi + 0.74 + 0.1*(randn()-0.5) for xi in x] 12 | 13 | R = vcat(x,y,z) 14 | 15 | # Normalization 16 | R = (R .- mean(R,dims=2))./std(R,dims=2) 17 | 18 | # Correlation matrix 19 | C = R*R'/(N-1) 20 | 21 | # Eigenstates 22 | va = eigvals(C) 23 | ve = eigvecs(C) 24 | 25 | # Plot data and axes 26 | if (false) 27 | pygui(true) 28 | fig = figure() 29 | ax = fig.gca(projection="3d") 30 | ax.scatter(R[1,:],R[2,:],R[3,:]) 31 | 32 | mx = mean(R[1,:]) 33 | my = mean(R[2,:]) 34 | mz = mean(R[3,:]) 35 | 36 | ax.quiver([mx],[my],[mz],[ve[1,1]],[ve[2,1]],[ve[3,1]],color="red") 37 | ax.quiver([mx],[my],[mz],[ve[1,2]],[ve[2,2]],[ve[3,2]],color="red") 38 | ax.quiver([mx],[my],[mz],[ve[1,3]],[ve[2,3]],[ve[3,3]],color="red") 39 | legend(["","v_1","v_2","v_3"]) 40 | show() 41 | end 42 | 43 | # Plot explained variance 44 | if (false) 45 | R = rand(100,100) 46 | R = (R .- mean(R,dims=2))./std(R,dims=2) 47 | C = R*R'/99 48 | va = eigvals(C) 49 | 50 | va = reverse(va) 51 | cs = sum(va) 52 | PEV = 100*va./cs 53 | CPEV = 100*cumsum(va)./cs 54 | 55 | plot(PEV,"o-") 56 | xlabel("Eigenvalue number") 57 | ylabel("PEV [%]") 58 | 59 | pl = twinx() 60 | plot(CPEV,"s-",color="orange") 61 | ylabel("CPEV [%]") 62 | show() 63 | end 64 | 65 | # Plot projected data 66 | if (true) 67 | W = hcat(ve[:,1],ve[:,2]) 68 | R = W'*R 69 | scatter(R[1,:],R[2,:]) 70 | show() 71 | end 72 | -------------------------------------------------------------------------------- /unsupervised/vector/LVQ.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | 4 | η = 0.1 5 | 6 | # Euclidean distance 7 | function d(x,y) 8 | m,n = size(x) 9 | z = [] 10 | 11 | for i in 1:n 12 | push!(z,(x[1,i]-y[1])^2 + (x[2,i]-y[2])^2) 13 | end 14 | 15 | return z 16 | end 17 | 18 | 19 | # Original data 20 | x_sp = LinRange(0,2π,100) 21 | y_sp = sin.(x_sp) 22 | x_sp = hcat(x_sp,y_sp)' 23 | 24 | # Initial guess 25 | w = zeros(2,10) 26 | for i in 1:10 27 | w[1,i] = rand(x_sp[1,:]) 28 | w[2,i] = rand()-0.5 29 | end 30 | 31 | # LVQ Loop 32 | for it in 1:10000 33 | r = rand(1:100) 34 | x = x_sp[:,r] # Choose input vector randomly 35 | 36 | n = argmin(d(w,x)) # Find closest output 37 | w[:,n] = w[:,n] + η*(x-w[:,n]) # Move winning node towards input 38 | end 39 | 40 | plot(x_sp[1,:],x_sp[2,:]) 41 | scatter(w[1,:],w[2,:]) 42 | show() 43 | -------------------------------------------------------------------------------- /unsupervised/vector/SOM.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | # Euclidean distance 4 | function distance(x,y) 5 | m,n = size(x) 6 | z = [] 7 | 8 | for i in 1:n 9 | push!(z,(x[1,i]-y[1])^2 + (x[2,i]-y[2])^2) 10 | end 11 | 12 | return z 13 | end 14 | 15 | # Read image and create vector x 16 | function loadData() 17 | data = [] 18 | dx = [] 19 | dy = [] 20 | r = 2 21 | for it in 1:200 22 | θ = rand()*2π 23 | x = r*cos(θ) 24 | y = r*sin(θ) 25 | 26 | push!(data,[y x]) 27 | push!(dx,x) 28 | push!(dy,y) 29 | end 30 | 31 | return data,dx,dy 32 | end 33 | 34 | #=========================================================# 35 | x,dx,dy = loadData() 36 | N = length(x) 37 | println(N," vectors") 38 | Nr = 20 # Number of new vectors 39 | 40 | # Parameters 41 | σo = 0.2 42 | τσ = 1E5 43 | τη = 1E5 44 | ηo = 0.1 45 | 46 | # Initial conditions 47 | w = (rand(2,Nr).-0.5)*6 48 | t = 0 49 | 50 | # SOM loop 51 | for it in 1:100000 52 | r = rand(1:N) # Choose random vector 53 | d = distance(w,x[r]) # Find BMU 54 | i = argmin(d) 55 | BMU = w[:,i] 56 | 57 | # Time-dependent parameters 58 | σ² = 1E-10 + σo*exp(-t/τσ) 59 | η = ηo*exp(-t/τη) 60 | global t = t + 1 61 | 62 | # Move everybody towards BMU 63 | for i in 1:Nr 64 | d = sqrt((w[1,i]-BMU[1])^2 + (w[2,i]-BMU[2])^2) 65 | Nei = exp(-d/σ²) 66 | w[:,i] = w[:,i] + η*Nei*(x[r]'-w[:,i]) 67 | end 68 | 69 | # Error 70 | d_max = 0 71 | for i in 1:Nr 72 | d_min = 1E8 73 | for j in 1:N 74 | d = sqrt((w[1,i]-x[j][1])^2+(w[2,i]-x[j][2])^2) 75 | if (d < d_min) 76 | d_min = d 77 | end 78 | end 79 | if (d_min > d_max) 80 | d_max = d_min 81 | end 82 | end 83 | println(it,": ",d_max,", η=",η,", σ²=",σ²) 84 | end 85 | 86 | scatter(dx,dy) 87 | scatter(w[1,:],w[2,:]) 88 | show() 89 | -------------------------------------------------------------------------------- /unsupervised/vector/SOM.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as pl 3 | 4 | grid = np.random.rand(5,5,2) 5 | x = np.zeros(2) 6 | tau_s = 15 7 | tau_e = 15 8 | sigma2 = 20 9 | eta = 0.1 10 | t = 0 11 | 12 | for it in range(10000): 13 | # Sample 14 | x[0] = 2*(np.random.rand()-0.5) 15 | x[1] = np.sqrt(1-x[0]*x[0]) 16 | if (np.random.rand() > 0.5): 17 | x[1] = -x[1] 18 | 19 | # Find BMU 20 | d_min = 1E5 21 | for i in range(5): 22 | for j in range(5): 23 | d = np.linalg.norm(x - grid[i,j,:]) 24 | if d < d_min: 25 | d_min = d 26 | iw = i 27 | jw = j 28 | 29 | # Adjust weights 30 | for i in range(5): 31 | for j in range(5): 32 | nei = np.exp(-((i-iw)**2+(j-jw)**2)/(2*sigma2)) 33 | grid[i,j,:] = grid[i,j,:] + eta*nei*(x - grid[i,j,:]) 34 | 35 | # Evolution 36 | t = t + 0.00001 37 | sigma2 = sigma2*np.exp(-t/tau_s) 38 | eta = eta*np.exp(-t/tau_e) 39 | 40 | for i in range(5): 41 | for j in range(5): 42 | pl.plot(grid[i,j,0],grid[i,j,1],'s') 43 | 44 | pl.show() 45 | -------------------------------------------------------------------------------- /unsupervised/vector/gas.jl: -------------------------------------------------------------------------------- 1 | using PyPlot 2 | 3 | 4 | 5 | 6 | # Euclidean distance 7 | function d(x,y) 8 | m,n = size(x) 9 | z = [] 10 | 11 | for i in 1:n 12 | push!(z,(x[1,i]-y[1])^2 + (x[2,i]-y[2])^2) 13 | end 14 | 15 | return z 16 | end 17 | 18 | # Quantization error 19 | function qerr(sub,mani) 20 | sm, sn = size(sub) 21 | mm, mn = size(mani) 22 | 23 | d_av = 0 24 | for s in 1:sn 25 | d_min = 1E8 26 | for m in 1:mn 27 | d = (sub[1,s]-mani[1,m])^2 + (sub[2,s]-mani[2,m])^2 28 | if (d < d_min) 29 | d_min = d 30 | end 31 | end 32 | d_av = d_av + d_min 33 | end 34 | 35 | return d_av/sn 36 | end 37 | 38 | # Connect nodes 39 | function connect(i,j,C,H) 40 | n,m = size(C) 41 | 42 | # Connect nodes 43 | C[i,j] = 1 44 | C[j,i] = 1 45 | 46 | # Set history to zero 47 | H[i,j] = 0 48 | H[j,i] = 0 49 | 50 | # Age edges 51 | for k in 1:n 52 | if (C[i,k] == 1) 53 | H[i,k] = H[i,k] + 1 54 | H[k,i] = H[k,i] + 1 55 | 56 | # Remove old edges 57 | if (H[i,k] > 10) 58 | C[i,k] = 0 59 | C[k,i] = 0 60 | H[i,k] = 0 61 | H[k,i] = 0 62 | end 63 | end 64 | end 65 | 66 | return C,H 67 | end 68 | 69 | # Draw network 70 | function draw_net(w,C) 71 | n,m = size(C) 72 | 73 | for i in 1:(n-1) 74 | for j in (i+1):n 75 | if (C[i,j] == 1) 76 | plot([w[1,i],w[1,j]],[w[2,i],w[2,j]]) 77 | end 78 | end 79 | end 80 | end 81 | 82 | # Neural gas 83 | function ggas(x_sp,Nr) 84 | # Initial guess 85 | w = zeros(2,Nr) 86 | for i in 1:Nr 87 | w[1,i] = rand()*2π 88 | w[2,i] = 2*(rand()-0.5) 89 | end 90 | 91 | # Connection and history 92 | C = zeros(Nr,Nr) 93 | H = zeros(Nr,Nr) 94 | 95 | β = 5 96 | ηo = 1E-3 97 | 98 | # VQ Loop 99 | err = 1 100 | cnt = 0 101 | while(err > 0.01 && cnt < 1E6) 102 | # Choose input vector randomly 103 | chosen = rand(1:N) 104 | x = x_sp[:,chosen] 105 | 106 | # Sort 107 | ki = sortperm(d(w,x)) # Indexes 108 | k = (ki.-1)/(Nr-1) # Weights 109 | 110 | # Update topological neigborhood 111 | for i in 1:Nr 112 | if (C[ki[1],i] == 1 || ki[1] == i) 113 | η = ηo*exp(-β*k[i]) 114 | w[:,i] = η*x + (1-η)*w[:,i] 115 | end 116 | end 117 | 118 | C,H = connect(ki[1],ki[2],C,H) 119 | err = qerr(w,x_sp) 120 | println(cnt,",",err) 121 | cnt = cnt + 1 122 | end 123 | 124 | return w,C 125 | end 126 | 127 | # Original data 128 | N = 100 129 | x_sp = LinRange(0,2π,N) 130 | y_sp = sin.(x_sp) 131 | x_sp = hcat(x_sp,y_sp)' 132 | 133 | # Neural gas 134 | w,C = ggas(x_sp,20) 135 | 136 | # Draw 137 | draw_net(w,C) 138 | plot(x_sp[1,:],x_sp[2,:]) 139 | scatter(w[1,:],w[2,:]) 140 | show() 141 | -------------------------------------------------------------------------------- /unsupervised/vector/gas.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as pl 2 | import numpy as np 3 | 4 | class neuron: 5 | def __init__(self): 6 | self.w = np.array([2*(np.random.rand()-0.5), 2*(np.random.rand()-0.5)]) 7 | 8 | def D(self,x): 9 | return np.linalg.norm(self.w-x) 10 | 11 | def adjust(self,i,x,eta,lbd): 12 | self.w = self.w + eta*np.exp(-float(i)/lbd)*(x-self.w) 13 | 14 | class gas: 15 | def __init__(self,N,eta): 16 | self.Nnodes = N 17 | self.eta = eta 18 | self.nodes = [neuron() for i in range(N)] 19 | self.lbd = 0.2 20 | self.C = -1*np.ones((N,N)) 21 | 22 | def sort(self,x): 23 | d = [] 24 | for node in self.nodes: 25 | d.append(node.D(x)) 26 | self.k = np.argsort(d) 27 | 28 | def update(self,x): 29 | for i in range(self.Nnodes): 30 | self.nodes[i].adjust(self.k[i],x,self.eta,self.lbd) 31 | self.eta = self.eta*0.99 32 | 33 | def age(self): 34 | # Connect 35 | self.C[self.k[0]][self.k[1]] = 0 36 | self.C[self.k[1]][self.k[0]] = 0 37 | 38 | # age 39 | for i in range(self.Nnodes): 40 | if (self.C[self.k[0]][i] > -1 and self.k[0] != i): 41 | self.C[self.k[0]][i] = self.C[self.k[0]][i] + 1 42 | self.C[i][self.k[0]] = self.C[i][self.k[0]] + 1 43 | 44 | # Died 45 | if (self.C[self.k[0]][i] > 4): 46 | self.C[self.k[0]][i] = -1 47 | self.C[i][self.k[0]] = -1 48 | def adjust(self,x): 49 | self.sort(x) 50 | self.update(x) 51 | self.age() 52 | 53 | def show(self): 54 | for i in range(self.Nnodes-1): 55 | for j in range(i+1,self.Nnodes): 56 | if (self.C[i][j] > -1): 57 | x = [self.nodes[i].w[0],self.nodes[j].w[0]] 58 | y = [self.nodes[i].w[1],self.nodes[j].w[1]] 59 | pl.plot(x,y) 60 | 61 | 62 | G = gas(500,0.75) 63 | 64 | for it in range(4000): 65 | # Sample from a disc 66 | r = 2*(np.random.rand()-0.5) 67 | t = np.random.rand()*2*np.pi 68 | x = np.array([r*np.cos(t), r*np.sin(t)]) 69 | 70 | G.adjust(x) 71 | #ax = pl.gca() 72 | #ax.clear() 73 | #G.show() 74 | #pl.pause(0.001) 75 | 76 | G.show() 77 | 78 | for t in range(360): 79 | x = np.cos(2*np.pi*float(t)/360) 80 | y = np.sin(2*np.pi*float(t)/360) 81 | pl.plot(x,y,'.',color='gray') 82 | 83 | pl.show() 84 | --------------------------------------------------------------------------------