Skip to content

Commit 7e71420

Browse files
author
Yusuke Sugomori
committed
dA.scala
1 parent ff41d30 commit 7e71420

File tree

1 file changed

+212
-0
lines changed

1 file changed

+212
-0
lines changed

scala/dA.scala

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
import scala.util.Random
2+
import scala.math
3+
4+
class dA(val N: Int, val n_visible: Int, val n_hidden: Int,
5+
_W: Array[Array[Double]]=null, _hbias: Array[Double]=null, _vbias: Array[Double]=null,
6+
var rng: Random=null) {
7+
8+
var W: Array[Array[Double]] = Array.ofDim[Double](n_hidden, n_visible)
9+
var hbias: Array[Double] = new Array[Double](n_hidden)
10+
var vbias: Array[Double] = new Array[Double](n_visible)
11+
12+
13+
if(rng == null) rng = new Random(1234)
14+
15+
if(_W == null) {
16+
var i: Int = 0
17+
var j: Int = 0
18+
19+
val a: Double = 1 / n_visible
20+
for(i <- 0 until n_hidden)
21+
for(j <- 0 until n_visible)
22+
W(i)(j) = uniform(-a, a)
23+
24+
} else {
25+
W = _W
26+
}
27+
28+
if(_hbias == null) {
29+
var i: Int = 0
30+
for(i <- 0 until n_hidden) hbias(i) = 0
31+
} else {
32+
hbias = _hbias
33+
}
34+
35+
if(_vbias == null) {
36+
var i: Int = 0
37+
for(i <- 0 until n_visible) vbias(i) = 0
38+
} else {
39+
vbias = _vbias
40+
}
41+
42+
43+
def uniform(min: Double, max: Double): Double = rng.nextDouble() * (max - min) + min
44+
def binomial(n: Int, p: Double): Int = {
45+
if(p < 0 || p > 1) return 0
46+
47+
var c: Int = 0
48+
var r: Double = 0
49+
50+
var i: Int = 0
51+
for(i <- 0 until n) {
52+
r = rng.nextDouble()
53+
if(r < p) c += 1
54+
}
55+
56+
c
57+
}
58+
59+
def sigmoid(x: Double): Double = 1.0 / (1.0 + math.pow(math.E, -x))
60+
61+
62+
def get_corrupted_input(x: Array[Int], tilde_x: Array[Int], p: Double) {
63+
var i: Int = 0;
64+
for(i <- 0 until n_visible) {
65+
if(x(i) == 0) {
66+
tilde_x(i) = 0;
67+
} else {
68+
tilde_x(i) = binomial(1, p)
69+
}
70+
}
71+
}
72+
73+
// Encode
74+
def get_hidden_values(x: Array[Int], y: Array[Double]) {
75+
var i: Int = 0
76+
var j: Int = 0
77+
for(i <- 0 until n_hidden) {
78+
y(i) = 0
79+
for(j <- 0 until n_visible) {
80+
y(i) += W(i)(j) * x(j)
81+
}
82+
y(i) += hbias(i)
83+
y(i) = sigmoid(y(i))
84+
}
85+
}
86+
87+
// Decode
88+
def get_reconstructed_input(y: Array[Double], z: Array[Double]) {
89+
var i: Int = 0
90+
var j: Int = 0
91+
for(i <- 0 until n_visible) {
92+
z(i) = 0
93+
for(j <- 0 until n_hidden) {
94+
z(i) += W(j)(i) * y(j)
95+
}
96+
z(i) += vbias(i)
97+
z(i) = sigmoid(z(i))
98+
}
99+
}
100+
101+
def train(x: Array[Int], lr: Double, corruption_level: Double) {
102+
var i: Int = 0
103+
var j: Int = 0
104+
105+
val tilde_x: Array[Int] = new Array[Int](n_visible)
106+
val y: Array[Double] = new Array[Double](n_hidden)
107+
val z: Array[Double] = new Array[Double](n_visible)
108+
109+
val L_vbias: Array[Double] = new Array[Double](n_visible)
110+
val L_hbias: Array[Double] = new Array[Double](n_hidden)
111+
112+
val p: Double = 1 - corruption_level
113+
114+
get_corrupted_input(x, tilde_x, p)
115+
get_hidden_values(tilde_x, y)
116+
get_reconstructed_input(y, z)
117+
118+
// vbias
119+
for(i <- 0 until n_visible) {
120+
L_vbias(i) = x(i) - z(i)
121+
vbias(i) += lr * L_vbias(i) / N
122+
}
123+
124+
// hbias
125+
for(i <- 0 until n_hidden) {
126+
L_hbias(i) = 0
127+
for(j <- 0 until n_visible) {
128+
L_hbias(i) += W(i)(j) * L_vbias(j)
129+
}
130+
L_hbias(i) *= y(i) * (1 - y(i))
131+
hbias(i) += lr * L_hbias(i) / N
132+
}
133+
134+
// W
135+
for(i <- 0 until n_hidden) {
136+
for(j <- 0 until n_visible) {
137+
W(i)(j) += lr * (L_hbias(i) * tilde_x(j) + L_vbias(j) * y(i)) / N
138+
}
139+
}
140+
}
141+
142+
def reconstruct(x: Array[Int], z: Array[Double]) {
143+
val y: Array[Double] = new Array[Double](n_hidden)
144+
145+
get_hidden_values(x, y)
146+
get_reconstructed_input(y, z)
147+
}
148+
149+
}
150+
151+
152+
object dA {
153+
def test_dA() {
154+
val rng: Random = new Random(123)
155+
var learning_rate: Double = 0.1
156+
val corruption_level: Double = 0.3
157+
val training_epochs: Int = 500
158+
159+
val train_N: Int = 10
160+
val test_N: Int = 2
161+
162+
val n_visible: Int = 20
163+
val n_hidden: Int = 5
164+
165+
val train_X: Array[Array[Int]] = Array(
166+
Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
167+
Array(1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
168+
Array(1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
169+
Array(1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
170+
Array(0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
171+
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
172+
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1),
173+
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1),
174+
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1),
175+
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0)
176+
)
177+
178+
val da: dA = new dA(train_N, n_visible, n_hidden, rng=rng)
179+
180+
var i: Int = 0
181+
var j: Int = 0
182+
183+
// train
184+
var epoch: Int = 0
185+
for(epoch <- 0 until training_epochs) {
186+
for(i <- 0 until train_N) {
187+
da.train(train_X(i), learning_rate, corruption_level)
188+
}
189+
}
190+
191+
192+
// test data
193+
val test_X: Array[Array[Int]] = Array(
194+
Array(1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
195+
Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0)
196+
)
197+
198+
val reconstructed_X: Array[Array[Double]] = Array.ofDim[Double](test_N, n_visible)
199+
for(i <- 0 until test_N) {
200+
da.reconstruct(test_X(i), reconstructed_X(i))
201+
for(j <- 0 until n_visible) {
202+
printf("%.5f ", reconstructed_X(i)(j))
203+
}
204+
println()
205+
}
206+
}
207+
208+
def main(args: Array[String]) {
209+
test_dA()
210+
}
211+
212+
}

0 commit comments

Comments
 (0)