├── 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 | [](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 |
--------------------------------------------------------------------------------