Skip to content

Instantly share code, notes, and snippets.

@sbugrov
Last active August 31, 2017 20:20
Show Gist options
  • Save sbugrov/8d7836e18302abb45db93f3a13a653a2 to your computer and use it in GitHub Desktop.
Save sbugrov/8d7836e18302abb45db93f3a13a653a2 to your computer and use it in GitHub Desktop.
//
// 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