-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathactivation.cpp
More file actions
138 lines (111 loc) · 2.87 KB
/
Copy pathactivation.cpp
File metadata and controls
138 lines (111 loc) · 2.87 KB
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 "activation.h"
// Return max of two numbers, a and b.
double max(double a, double b){
if (a > b){
return a;
} else {
return b;
}
}
// Calculate the logistic sigmoid value of x.
double sigmoid(double x){
return 1/(1 + exp(-x));
}
// Normalizes each row or column of a matrix into a probability distribution.
std::vector<std::vector<double>> softmax(std::vector<std::vector<double>> X, int axis){
std::vector<std::vector<double>> result;
std::vector<double> row;
int numSamples, numOutputs;
double sumExp;
bool transposed = false;
const int ROWS = 1,
COLS = 2;
switch(axis){
case COLS:
X = transpose(X);
transposed = true;
case ROWS:
numSamples = getSize(X)[0];
numOutputs = getSize(X)[1];
break;
default:
std::cout << "Axis selection invalid" << std::endl;
return {{}};
}
while (numSamples < numOutputs){
std::cout << "You have more outputs than samples, is this correct [y/n]:" << std::endl;
std::string verify;
std::cin >> verify;
if (verify == "y"){
break;
} else {
std::cout << "Transposing input." << std::endl;
X = transpose(X);
transposed = !transposed;
numSamples = getSize(X)[0];
numOutputs = getSize(X)[1];
break;
}
}
for (int i = 0; i < numSamples; i++){
row = {};
sumExp = 0;
for (int j = 0; j < numOutputs; j++){
sumExp += exp(X[i][j]);
}
for (int j = 0; j < numOutputs; j++){
row.push_back(exp(X[i][j])/sumExp);
}
result.push_back(row);
}
if (transposed){
result = transpose(result);
}
return result;
}
// Applies a chosen activation function to each element of a matrix
double activate(double x, std::string fcn){
double result;
int function;
const int SIGMOID = 1,
TANH = 2,
RELU = 3;
transform(fcn.begin(), fcn.end(), fcn.begin(), ::tolower);
if (fcn == "sigmoid"){
function = SIGMOID;
} else if (fcn == "tanh"){
function = TANH;
} else if (fcn == "relu"){
function = RELU;
} else {
std::cout << "No activation function of the specified type is available" << std::endl;
return nan("1");
}
switch (function){
case SIGMOID:
result = sigmoid(x);
break;
case TANH:
result = tanh(x);
break;
case RELU:
result = max(0,x);
break;
}
return result;
}
// Applies a chosen activation function to each element in a matrix
std::vector<std::vector<double>> matrixActivation(std::vector<std::vector<double>> mat, std::string activation){
std::vector<std::vector<double>> result;
double value;
for (int i = 0; i < mat.size(); i++){
std::vector<double> row;
for (int j = 0; j < mat[i].size(); j++){
value = activate(mat[i][j], activation);
row.push_back(value);
}
result.push_back(row);
delete &row;
}
return result;
}