Created
October 13, 2016 13:46
-
-
Save sasamijp/fb084690f4cd6cdc88697d2c0482cb29 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "./Eigen/Core" | |
using namespace std; | |
using namespace Eigen; | |
class NN { | |
private: | |
float reactified_linear(float u){ | |
return u * (u > 0); | |
} | |
float d_reactified_linear(float u){ | |
return (u > 0); | |
} | |
float sigmoid(float u){ | |
return 1/(1+exp(-u)); | |
} | |
void backpropagation(float* d){ | |
for(int i=0; i<layer_len[2]; i++) | |
deltas[1][i] = layers[2][i]- d[i]; | |
for(int i=0; i<layer_len[1]; i++) | |
fdashu[i] = d_reactified_linear(u_layers[1][i]); | |
w_delta = W[1].transpose() * deltas[1]; | |
for(int i=0; i<layer_len[1]; i++) | |
deltas[0][i] = fdashu[i] * w_delta[i]; | |
d_W[0] = -eps * deltas[0] * layers[0].transpose(); | |
d_W[1] = -eps * deltas[1] * layers[1].transpose(); | |
W[0] += d_W[0]; | |
W[1] += d_W[1]; | |
biases[0] += -eps * deltas[0]; | |
biases[1] += -eps * deltas[1]; | |
cout << abs(deltas[1][0]) << ", "; | |
} | |
void backpropagation_momentum(float* d){ | |
for(int i=0; i<layer_len[2]; i++) | |
deltas[1][i] = layers[2][i]- d[i]; | |
for(int i=0; i<layer_len[1]; i++) | |
fdashu[i] = d_reactified_linear(u_layers[1][i]); | |
w_delta = W[1].transpose() * deltas[1]; | |
for(int i=0; i<layer_len[1]; i++) | |
deltas[0][i] = fdashu[i] * w_delta[i]; | |
d_W[0] = -eps * deltas[0] * layers[0].transpose(); | |
d_W[1] = -eps * deltas[1] * layers[1].transpose(); | |
W[0] += d_W[0] + moment * d_W_m[0]; | |
W[1] += d_W[1] + moment * d_W_m[1]; | |
d_W_m[0] = d_W[0]; | |
d_W_m[1] = d_W[1]; | |
biases[0] += -eps * deltas[0]; | |
biases[1] += -eps * deltas[1]; | |
cout << abs(deltas[1][0]) << ", "; | |
} | |
public: | |
VectorXd layers[3], u_layers[3], biases[2]; | |
MatrixXd W[2]; | |
MatrixXd d_W[2], d_W_m[2]; | |
VectorXd fdashu, w_delta; | |
VectorXd deltas[2]; | |
float eps, moment; | |
int* layer_len; | |
NN(int* len){ | |
layer_len = len; | |
eps = 1; | |
moment = 0.9; | |
// サイズを適用する | |
for(int i=0; i<3; i++){ | |
layers[i].resize(layer_len[i]); | |
u_layers[i].resize(layer_len[i]); | |
} | |
for(int i=0; i<2; i++) | |
biases[i].resize(layer_len[i+1]); | |
W[0].resize(layer_len[1], layer_len[0]); | |
W[1].resize(layer_len[2], layer_len[1]); | |
d_W[0].resize(layer_len[1], layer_len[0]); | |
d_W[1].resize(layer_len[2], layer_len[1]); | |
d_W_m[0] = MatrixXd::Zero(layer_len[1], layer_len[0]); | |
d_W_m[1] = MatrixXd::Zero(layer_len[2], layer_len[1]); | |
fdashu.resize(layer_len[1]); | |
w_delta.resize(layer_len[1]); | |
deltas[1].resize(layer_len[2]); | |
deltas[0].resize(layer_len[1]); | |
// 重み初期値 | |
W[0] << 1,1, | |
1,0, | |
1,0, | |
1,0, | |
1,0, | |
1,1; | |
W[1] << 1,1,1,1,1,1; | |
// バイアス初期値 | |
biases[0] << 0,0,0,0,0,0; | |
biases[1] << 0; | |
} | |
void print_layers(){ | |
cout << "unit state : ======" << endl; | |
cout << layers[0] << endl << endl; | |
//cout << layers[1] << endl << endl; | |
cout << layers[2] << endl; | |
cout << "========" << endl; | |
} | |
// 引数は入力ベクトルと出力ベクトルのペア | |
void train(float sample_input[4][2], float sample_output[4][1]){ | |
cout << ",a,b,c,d" << endl; | |
for(int epoch=0; epoch<100; epoch++){ | |
cout << epoch << " ,"; | |
for(int i=0; i<4; i++){ | |
propagation(sample_input[i]); | |
//print_layers(); | |
backpropagation(sample_output[i]); | |
} | |
cout << endl; | |
//cout << biases[0] << endl; | |
} | |
} | |
// propagationとbackpropagationは重みや出力層の状態を変更するだけの処理 | |
void propagation(float* input){ | |
// 1層目 | |
for(int i=0; i<layer_len[0]; i++) | |
layers[0][i] = input[i]; | |
// 2層目 | |
u_layers[1] = W[0] * layers[0] + biases[0]; | |
for(int i=0; i<layer_len[1]; i++) | |
layers[1][i] = reactified_linear( u_layers[1][i] ); | |
// 3層目 | |
u_layers[2] = W[1] * layers[1] + biases[1]; | |
for(int i=0; i<layer_len[2]; i++) | |
layers[2][i] = sigmoid( u_layers[2][i] ); | |
} | |
}; | |
int main(){ | |
int layer_len[3] = {2, 6, 1}; | |
float sample_input[4][2] = { | |
1,1, | |
1,0, | |
0,1, | |
0,0 | |
}; | |
float sample_output[4][1] = { | |
1, | |
0, | |
0, | |
0 | |
}; | |
NN nn(layer_len); | |
nn.train(sample_input, sample_output); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment