forked from yusugomori/DeepLearning
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDBN.scala
More file actions
231 lines (176 loc) · 6.03 KB
/
DBN.scala
File metadata and controls
231 lines (176 loc) · 6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
import scala.util.Random
import scala.math
class DBN(val N: Int, val n_ins: Int, hidden_layer_sizes: Array[Int], val n_outs: Int, val n_layers: Int, var rng: Random=null) {
def sigmoid(x: Double): Double = {
return 1.0 / (1.0 + math.pow(math.E, -x))
}
var input_size: Int = 0
val sigmoid_layers: Array[HiddenLayer] = new Array[HiddenLayer](n_layers)
val rbm_layers: Array[RBM] = new Array[RBM](n_layers)
if(rng == null) rng = new Random(1234)
var i: Int = 0
// construct multi-layer
for(i <- 0 until n_layers) {
if(i == 0) {
input_size = n_ins
} else {
input_size = hidden_layer_sizes(i-1)
}
// construct sigmoid_layer
sigmoid_layers(i) = new HiddenLayer(N, input_size, hidden_layer_sizes(i), null, null, rng)
// construct rbm_layer
rbm_layers(i) = new RBM(N, input_size, hidden_layer_sizes(i), sigmoid_layers(i).W, sigmoid_layers(i).b, null, rng)
}
// layer for output using LogisticRegression
val log_layer: LogisticRegression = new LogisticRegression(N, hidden_layer_sizes(n_layers-1), n_outs)
def pretrain(train_X: Array[Array[Int]], lr: Double, k: Int, epochs: Int) {
var layer_input: Array[Int] = new Array[Int](0)
var prev_layer_input_size: Int = 0
var prev_layer_input: Array[Int] = new Array[Int](0)
var i: Int = 0
var j: Int = 0
var epoch: Int = 0
var n: Int = 0
var l: Int = 0
for(i <- 0 until n_layers) { // layer-wise
for(epoch <- 0 until epochs) { // training epochs
for(n <- 0 until N) { // input x1...xN
// layer input
for(l <- 0 to i) {
if(l == 0) {
layer_input = new Array[Int](n_ins)
for(j <- 0 until n_ins) layer_input(j) = train_X(n)(j)
} else {
if(l == 1) prev_layer_input_size = n_ins
else prev_layer_input_size = hidden_layer_sizes(l-2)
prev_layer_input = new Array[Int](prev_layer_input_size)
for(j <- 0 until prev_layer_input_size) prev_layer_input(j) = layer_input(j)
layer_input = new Array[Int](hidden_layer_sizes(l-1))
sigmoid_layers(l-1).sample_h_given_v(prev_layer_input, layer_input)
}
}
rbm_layers(i).contrastive_divergence(layer_input, lr, k)
}
}
}
}
def finetune(train_X: Array[Array[Int]], train_Y: Array[Array[Int]], lr: Double, epochs: Int) {
var layer_input: Array[Int] = new Array[Int](0)
var prev_layer_input: Array[Int] = new Array[Int](0)
var epoch: Int = 0
var n: Int = 0
var i: Int = 0
var j: Int = 0
for(epoch <- 0 until epochs) {
for(n <- 0 until N) {
// layer input
for(i <- 0 until n_layers) {
if(i == 0) {
prev_layer_input = new Array[Int](n_ins)
for(j <- 0 until n_ins) prev_layer_input(j) = train_X(n)(j)
} else {
prev_layer_input = new Array[Int](hidden_layer_sizes(i-1))
for(j <- 0 until hidden_layer_sizes(i-1)) prev_layer_input(j) = layer_input(j)
}
layer_input = new Array[Int](hidden_layer_sizes(i))
sigmoid_layers(i).sample_h_given_v(prev_layer_input, layer_input)
}
log_layer.train(layer_input, train_Y(n), lr)
}
// lr *= 0.95
}
}
def predict(x: Array[Int], y: Array[Double]) {
var layer_input: Array[Double] = new Array[Double](0)
var prev_layer_input: Array[Double] = new Array[Double](n_ins)
var i: Int = 0
var j: Int = 0
var k: Int = 0
for(j <- 0 until n_ins) prev_layer_input(j) = x(j)
var linear_outoput: Double = 0
// layer activation
for(i <- 0 until n_layers) {
layer_input = new Array[Double](sigmoid_layers(i).n_out)
for(k <- 0 until sigmoid_layers(i).n_out) {
linear_outoput = 0.0
for(j <- 0 until sigmoid_layers(i).n_in) {
linear_outoput += sigmoid_layers(i).W(k)(j) * prev_layer_input(j)
}
linear_outoput += sigmoid_layers(i).b(k)
layer_input(k) = sigmoid(linear_outoput)
}
if(i < n_layers-1) {
prev_layer_input = new Array[Double](sigmoid_layers(i).n_out)
for(j <- 0 until sigmoid_layers(i).n_out) prev_layer_input(j) = layer_input(j)
}
}
for(i <- 0 until log_layer.n_out) {
y(i) = 0
for(j <- 0 until log_layer.n_in) {
y(i) += log_layer.W(i)(j) * layer_input(j)
}
y(i) += log_layer.b(i)
}
log_layer.softmax(y)
}
}
object DBN {
def test_dbn() {
val rng: Random = new Random(123)
val pretrain_lr: Double = 0.1
val pretraining_epochs: Int = 1000
val k: Int = 1
val finetune_lr: Double = 0.1
val finetune_epochs: Int = 500
val train_N: Int = 6
val test_N: Int = 4
val n_ins: Int = 6
val n_outs: Int = 2
val hidden_layer_sizes: Array[Int] = Array(3, 3)
val n_layers = hidden_layer_sizes.length
// training data
val train_X: Array[Array[Int]] = Array(
Array(1, 1, 1, 0, 0, 0),
Array(1, 0, 1, 0, 0, 0),
Array(1, 1, 1, 0, 0, 0),
Array(0, 0, 1, 1, 1, 0),
Array(0, 0, 1, 1, 0, 0),
Array(0, 0, 1, 1, 1, 0)
)
val train_Y: Array[Array[Int]] = Array(
Array(1, 0),
Array(1, 0),
Array(1, 0),
Array(0, 1),
Array(0, 1),
Array(0, 1)
)
// construct DBN
val dbn: DBN = new DBN(train_N, n_ins, hidden_layer_sizes, n_outs, n_layers, rng)
// pretrain
dbn.pretrain(train_X, pretrain_lr, k, pretraining_epochs);
// finetune
dbn.finetune(train_X, train_Y, finetune_lr, finetune_epochs);
// test data
val test_X: Array[Array[Int]] = Array(
Array(1, 1, 0, 0, 0, 0),
Array(1, 1, 1, 1, 0, 0),
Array(0, 0, 0, 1, 1, 0),
Array(0, 0, 1, 1, 1, 0)
)
val test_Y: Array[Array[Double]] = Array.ofDim[Double](test_N, n_outs)
var i: Int = 0
var j: Int = 0
// test
for(i <- 0 until test_N) {
dbn.predict(test_X(i), test_Y(i))
for(j <- 0 until n_outs) {
print(test_Y(i)(j) + " ")
}
println()
}
}
def main(args: Array[String]) {
test_dbn()
}
}