Last active
August 31, 2017 20:20
-
-
Save sbugrov/8d7836e18302abb45db93f3a13a653a2 to your computer and use it in GitHub Desktop.
This file contains 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
// | |
// main.cpp | |
// mlperceptron | |
// | |
// Created by Sergei Bugrov on 7/11/17. | |
// Copyright © 2017 Sergei Bugrov. All rights reserved. | |
// | |
#include <iostream> | |
#include <vector> | |
#include <math.h> | |
using std::vector; | |
using std::cout; | |
using std::endl; | |
// XOR Dataset | |
vector<float> X { | |
0.0, 0.0, | |
0.0, 1.0, | |
1.0, 0.0, | |
1.0, 1.0}; | |
// Quasi random numbers | |
vector<float> W0 { | |
-0.07555777, -0.04661271, -0.0982434, 0.01800294, | |
-0.03213882, -0.09211904, -0.0674924, 0.04203922}; | |
vector<float> W1 { | |
0.03445321, | |
0.07976875, | |
-0.0502343, | |
-0.0995293}; | |
// All 0.1s | |
vector<float> W0_b { | |
0.1, 0.1, 0.1, 0.1, | |
0.1, 0.1, 0.1, 0.1}; | |
vector<float> W1_b { | |
0.1, | |
0.1, | |
0.1, | |
0.1}; | |
vector<float> y { | |
0.0, | |
1.0, | |
1.0, | |
0.0 }; | |
vector <float> sigmoid_d (const vector <float>& m1) { | |
/* Returns the value of the sigmoid function derivative f'(x) = f(x)(1 - f(x)), | |
where f(x) is sigmoid function. | |
Input: m1, a vector. | |
Output: x(1 - x) for every element of the input matrix m1. | |
*/ | |
const unsigned long VECTOR_SIZE = m1.size(); | |
vector <float> output (VECTOR_SIZE); | |
for( unsigned i = 0; i != VECTOR_SIZE; ++i ) { | |
output[ i ] = m1[ i ] * (1 - m1[ i ]); | |
} | |
return output; | |
} | |
vector <float> sigmoid (const vector <float>& m1) { | |
/* Returns the value of the sigmoid function f(x) = 1/(1 + e^-x). | |
Input: m1, a vector. | |
Output: 1/(1 + e^-x) for every element of the input matrix m1. | |
*/ | |
const unsigned long VECTOR_SIZE = m1.size(); | |
vector <float> output (VECTOR_SIZE); | |
for( unsigned i = 0; i != VECTOR_SIZE; ++i ) { | |
if (fabs(m1[ i ]) < 6) | |
{ | |
output[ i ] = 1 / (1 + exp(-m1[ i ])); | |
} else { | |
output[ i ] = 0.0; | |
} | |
} | |
return output; | |
} | |
vector <float> operator+(const vector <float>& m1, const vector <float>& m2){ | |
/* Returns the elementwise sum of two vectors. | |
Inputs: | |
m1: a vector | |
m2: a vector | |
Output: a vector, sum of the vectors m1 and m2. | |
*/ | |
const unsigned long VECTOR_SIZE = m1.size(); | |
vector <float> sum (VECTOR_SIZE); | |
for (unsigned i = 0; i != VECTOR_SIZE; ++i){ | |
sum[i] = m1[i] + m2[i]; | |
}; | |
return sum; | |
} | |
vector <float> operator-(const vector <float>& m1, const vector <float>& m2){ | |
/* Returns the difference between two vectors. | |
Inputs: | |
m1: vector | |
m2: vector | |
Output: vector, m1 - m2, difference between two vectors m1 and m2. | |
*/ | |
const unsigned long VECTOR_SIZE = m1.size(); | |
vector <float> difference (VECTOR_SIZE); | |
for (unsigned i = 0; i != VECTOR_SIZE; ++i){ | |
difference[i] = m1[i] - m2[i]; | |
}; | |
return difference; | |
} | |
vector <float> operator*(const vector <float>& m1, const vector <float>& m2){ | |
/* Returns the product of two vectors (elementwise multiplication). | |
Inputs: | |
m1: vector | |
m2: vector | |
Output: vector, m1 * m2, product of two vectors m1 and m2 | |
*/ | |
const unsigned long VECTOR_SIZE = m1.size(); | |
vector <float> product (VECTOR_SIZE); | |
for (unsigned i = 0; i != VECTOR_SIZE; ++i){ | |
product[i] = m1[i] * m2[i]; | |
}; | |
return product; | |
} | |
vector <float> operator*(const vector <float>& m1, const float s){ | |
/* Returns the product of a vector and a number (elementwise multiplication). | |
Inputs: | |
m1: vector | |
s: float | |
Output: vector, m1 * s, product of a vector and a number | |
*/ | |
const unsigned long VECTOR_SIZE = m1.size(); | |
vector <float> product (VECTOR_SIZE); | |
for (unsigned i = 0; i != VECTOR_SIZE; ++i){ | |
product[i] = m1[i] * s; | |
}; | |
return product; | |
} | |
vector <float> transpose (float *m, const int C, const int R) { | |
/* Returns a transpose matrix of input matrix. | |
Inputs: | |
m: vector, input matrix | |
C: int, number of columns in the input matrix | |
R: int, number of rows in the input matrix | |
Output: vector, transpose matrix mT of input matrix m | |
*/ | |
vector <float> mT (C*R); | |
for(unsigned n = 0; n != C*R; n++) { | |
unsigned i = n/C; | |
unsigned j = n%C; | |
mT[n] = m[R*j + i]; | |
} | |
return mT; | |
} | |
vector <float> dot (const vector <float>& m1, const vector <float>& m2, const int m1_rows, const int m1_columns, const int m2_columns) { | |
/* Returns the product of two matrices: m1 x m2. | |
Inputs: | |
m1: vector, left matrix of size m1_rows x m1_columns | |
m2: vector, right matrix of size m1_columns x m2_columns (the number of rows in the right matrix | |
must be equal to the number of the columns in the left one) | |
m1_rows: int, number of rows in the left matrix m1 | |
m1_columns: int, number of columns in the left matrix m1 | |
m2_columns: int, number of columns in the right matrix m2 | |
Output: vector, m1 * m2, product of two vectors m1 and m2, a matrix of size m1_rows x m2_columns | |
*/ | |
vector <float> output (m1_rows*m2_columns); | |
for( int row = 0; row != m1_rows; ++row ) { | |
for( int col = 0; col != m2_columns; ++col ) { | |
output[ row * m2_columns + col ] = 0.f; | |
for( int k = 0; k != m1_columns; ++k ) { | |
output[ row * m2_columns + col ] += m1[ row * m1_columns + k ] * m2[ k * m2_columns + col ]; | |
} | |
} | |
} | |
return output; | |
} | |
void print ( const vector <float>& m, int n_rows, int n_columns ) { | |
/* "Couts" the input vector as n_rows x n_columns matrix. | |
Inputs: | |
m: vector, matrix of size n_rows x n_columns | |
n_rows: int, number of rows in the matrix m | |
n_columns: int, number of columns in the matrix m | |
*/ | |
for( int i = 0; i != n_rows; ++i ) { | |
for( int j = 0; j != n_columns; ++j ) { | |
cout << m[ i * n_columns + j ] << " "; | |
} | |
cout << '\n'; | |
} | |
cout << endl; | |
} | |
int main(int argc, const char * argv[]) { | |
for (unsigned i = 0; i != 10000; ++i) { | |
vector<float> layer_1 = sigmoid(dot(X, W0, 4, 2, 4 ) ); | |
vector<float> layer_2 = sigmoid(dot(layer_1, W1, 4, 4, 1 ) ); | |
vector<float> layer_2_delta = (y - layer_2) * sigmoid_d(layer_2); | |
vector<float> layer_1_delta = dot(layer_2_delta, transpose( &W1[0], 4, 1 ), 4, 1, 4) * sigmoid_d(layer_1); | |
W1 = W1 + dot(transpose( &layer_1[0], 4, 4 ), layer_2_delta, 4, 4, 1); | |
W0 = W0 + dot(transpose( &X[0], 4, 2 ), layer_1_delta, 2, 4, 4); | |
if (i == 9999){ | |
print ( layer_2, 4, 1 ); | |
}; | |
}; | |
for (unsigned i = 0; i != 10000; ++i) { | |
vector<float> layer_1 = sigmoid(dot(X, W0_b, 4, 2, 4 ) ); | |
vector<float> layer_2 = sigmoid(dot(layer_1, W1_b, 4, 4, 1 ) ); | |
vector<float> layer_2_delta = (y - layer_2) * sigmoid_d(layer_2); | |
vector<float> layer_1_delta = dot(layer_2_delta, transpose( &W1_b[0], 4, 1 ), 4, 1, 4) * sigmoid_d(layer_1); | |
W1_b = W1_b + dot(transpose( &layer_1[0], 4, 4 ), layer_2_delta, 4, 4, 1); | |
W0_b = W0_b + dot(transpose( &X[0], 4, 2 ), layer_1_delta, 2, 4, 4); | |
if (i == 9999){ | |
print ( layer_2, 4, 1 ); | |
}; | |
}; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment