Skip to content

Commit 8c99aa9

Browse files
author
Yusuke Sugomori
committed
java
1 parent c291e7e commit 8c99aa9

File tree

7 files changed

+870
-28
lines changed

7 files changed

+870
-28
lines changed

.gitignore

+3-28
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,8 @@
33
*.out
44
*.o
55

6-
#
7-
# from https://github.com/github/gitignore/blob/master/Global/Eclipse.gitignore
8-
#
9-
10-
*.pydevproject
6+
*.class
7+
*.classpath
8+
*.settings
119
.project
1210
.metadata
13-
bin/**
14-
tmp/**
15-
tmp/**/*
16-
*.tmp
17-
*.bak
18-
*.swp
19-
*~.nib
20-
local.properties
21-
.classpath
22-
.settings/
23-
.loadpath
24-
25-
# External tool builders
26-
.externalToolBuilders/
27-
28-
# Locally stored "Eclipse launch configurations"
29-
*.launch
30-
31-
# CDT-specific
32-
.cproject
33-
34-
# PDT-specific
35-
.buildpath

java/DBN/src/DBN.java

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

java/DBN/src/HiddenLayer.java

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import java.util.Random;
2+
3+
public class HiddenLayer {
4+
public int N;
5+
public int n_in;
6+
public int n_out;
7+
public double[][] W;
8+
public double[] b;
9+
Random rng;
10+
11+
public double uniform(double min, double max) {
12+
return rng.nextDouble() * (max - min) + min;
13+
}
14+
15+
public int binomial(int n, double p) {
16+
if(p < 0 || p > 1) return 0;
17+
18+
int c = 0;
19+
double r;
20+
21+
for(int i=0; i<n; i++) {
22+
r = rng.nextDouble();
23+
if (r < p) c++;
24+
}
25+
26+
return c;
27+
}
28+
29+
public static double sigmoid(double x) {
30+
return 1.0 / (1.0 + Math.pow(Math.E, -x));
31+
}
32+
33+
34+
35+
public HiddenLayer(int N, int n_in, int n_out, double[][] W, double[] b, Random rng) {
36+
this.N = N;
37+
this.n_in = n_in;
38+
this.n_out = n_out;
39+
40+
if(rng == null) this.rng = new Random(1234);
41+
else this.rng = rng;
42+
43+
if(W == null) {
44+
this.W = new double[n_out][n_in];
45+
double a = 1.0 / this.n_in;
46+
47+
for(int i=0; i<n_out; i++) {
48+
for(int j=0; j<n_in; j++) {
49+
this.W[i][j] = uniform(-a, a);
50+
}
51+
}
52+
} else {
53+
this.W = W;
54+
}
55+
56+
if(b == null) this.b = new double[n_out];
57+
else this.b = b;
58+
}
59+
60+
public double output(int[] input, double[] w, double b) {
61+
double linear_output = 0.0;
62+
for(int j=0; j<n_in; j++) {
63+
linear_output += w[j] * input[j];
64+
}
65+
linear_output += b;
66+
return sigmoid(linear_output);
67+
}
68+
69+
public void sample_h_given_v(int[] input, int[] sample) {
70+
for(int i=0; i<n_out; i++) {
71+
sample[i] = binomial(1, output(input, W[i], b[i]));
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)