-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.cpp
138 lines (107 loc) · 4.26 KB
/
utils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "utils.hpp"
#include <iostream>
#include <string>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
// function that changes the target labels into one-hot encoding format
MatrixXd OnehotEncoding(MatrixXd X)
{
MatrixXd res = MatrixXd::Zero(X.rows(),m); // creating a matrix of zeroes of X.rows x m(output class)
for(int i = 0; i < X.rows(); i++) // for each row
{
int index = X(i,0); // the value of the ouput label becomes the index
res(i,index) = (double) 1; // where we set it as 1 in its corresponding row in res
}
return res;
}
// function that computes sigmoid activation
double Sigmoid(double x)
{
return (1/(1 + exp(-x)));
}
// function tht computes the derivative of ReLU
double DRelu(double x)
{
if (x > 0.0){
return 1;
}
else{
return 0;
}
}
// function that computes the ReLU activation
MatrixXd Relu(MatrixXd S_1, MatrixXd &drelu_1)
{
drelu_1 = S_1.unaryExpr(&DRelu); // computing derivative of relu for each value in matrix
MatrixXd res = S_1.cwiseProduct(drelu_1); // element-wise corresponding multiplication
return res.cwiseAbs(); // returning the absolute value
}
MatrixXd Softmax(MatrixXd S2)
{
MatrixXd res(S2.rows(), S2.cols()); // declaring a matrix of S2 dimension to hold the result
MatrixXd S2_e = S2.array().exp(); // applying e^x to every element in matrix
// cout << S2_e.row(0) << endl;
VectorXd S2_sum= S2_e.rowwise().sum(); // finding the row wise sum
// cout << S2_sum(0,0) << endl;
for (int i = 0; i < S2.rows(); i++) // for each row in matrix
{
res.row(i) = S2_e.row(i)/S2_sum(i,0); // divide it by its sum
}
return res;
}
// function that computes the error of a iterations using cross entropy loss function
double ComputeLoss(MatrixXd Y, MatrixXd Y_hat)
{
// cout << Y_hat.row(0) << endl;
MatrixXd Y_hat_log = Y_hat.array().log(); // applying log-base e to each element in y_hat
// cout << Y_hat_log.row(0) << endl;
// cout << Y.row(0) << endl;
MatrixXd Y_Y_hat_mult = Y.cwiseProduct(Y_hat_log); // element-wise multilication between y and logy_hat
// cout << Y_Y_hat_mult.row(0) << endl;
// cout << Y_Y_hat_mult.sum() << endl;
return -(Y_Y_hat_mult.sum()); // returning the sum of final matrix
}
double ComputeCount(MatrixXd Y, MatrixXd Y_hat)
{
// cout << Y_hat.row(0) << endl;
// cout << Y_hat.rows() << "," << Y_hat.cols() << endl;
VectorXd Y_hat_maxVal_idx(Y.rows()); // creating a column vector of dimension (Y.rows x 1) to store indexes
for(int i = 0; i < Y_hat.rows(); i++) // for each row in Y_hat
{
Y_hat.row(i).maxCoeff(&Y_hat_maxVal_idx[i]); // storing the index of maximum value for row i at Y_hat_maxVal_idx[i]
}
// cout << Y_hat_maxVal_idx(0,0) << endl;
// cout << Y(0,0) << endl;
// cout << Y_hat_maxVal_idx.rows() << "," << Y_hat_maxVal_idx.cols() << endl;
// cout << Y.rows() << "," << Y.cols() << endl;
double count = 0.0;
for (int j = 0; j < Y.rows(); j++)
{
// cout << Y_hat_maxVal_idx(j,0) << "," << Y(j,0) << endl;
if (Y_hat_maxVal_idx(j,0)==Y(j,0))
{
count += 1;
}
}
// cout << " Count: " << count << endl;
return count;
}
MatrixXd ForwardPass(MatrixXd X, MatrixXd w_1, MatrixXd w_2, MatrixXd &Z_1, MatrixXd &drelu_1)
{
// cout << X.rows() << "," << X.cols() << endl;
// cout << w_1.rows() << "," << w_1.cols() << endl;
MatrixXd S_1 = X * w_1.transpose(); // X(B, d) * w_1(d_1,d), weighted sum of 1st layer
// cout << S_1.row(0) << endl;
Z_1 = Relu(S_1, drelu_1); // applying relu on weight sum S_1 to get the ouput of first layer
// cout << Z_1.row(0) << endl;
// cout << Z_1.rows() << "," << Z_1.cols() << endl;
// cout << w_2.rows() << "," << w_2.cols() << endl;
MatrixXd S_2 = Z_1 * w_2.transpose(); // Z_1(B,d_1) * w_2(m, d_1), weighted sum of 2nd layer
// cout << S_2.row(0) << endl;
// cout << S_2.rows() << "," << S_2.cols() << endl;
MatrixXd Z_2 = Softmax(S_2); // applying softmax to get final output
// cout << Z_2.rows() << "," << Z_2.cols() << endl;
// cout << Z_2.row(0) << endl;
return Z_2; // returning the final output
}