Skip to content

Instantly share code, notes, and snippets.

@sasamijp
Created October 13, 2016 13:46
Show Gist options
  • Save sasamijp/fb084690f4cd6cdc88697d2c0482cb29 to your computer and use it in GitHub Desktop.
Save sasamijp/fb084690f4cd6cdc88697d2c0482cb29 to your computer and use it in GitHub Desktop.
#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