Skip to content

Commit 21e2fcb

Browse files
fix backward_layer template function calling
1 parent f9c0c36 commit 21e2fcb

File tree

2 files changed

+52
-16
lines changed

2 files changed

+52
-16
lines changed

NN/FFN/basicFFN/include/ffn.hxx

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#pragma once
2121

22+
#include <algorithm>
23+
#include <cmath>
2224
#include <cstddef>
2325
#include <random>
2426
#include <thread>
@@ -44,15 +46,15 @@ class BasicFFN {
4446
inline static FP epsilon = 1e-6; // untuk mencegah dead neuron ketika menggunakan ReLU
4547
bool xavier = false;
4648
FP eta = 1e-2;
49+
std::random_device rd;
50+
std::mt19937 gen;
4751
// FP = Floating Point @param FP1 current eta/learning rate @param FP2 grad
4852
FP (*adaptive_eta_func)(FP, FP);
4953

5054
// setiap layer punya distribusi yang berbeda
5155
template <size_t inSize, size_t outSize>
5256
void init_layer(FP k, FP (&w)[inSize][outSize], FP (&b)[outSize]) {
53-
// setup random
54-
std::random_device rd;
55-
std::mt19937 gen(rd());
57+
// setup normal distribution
5658
std::normal_distribution<FP> dis(0, std::sqrt(k));
5759

5860
for (size_t i = 0; i < outSize; ++i) {
@@ -65,6 +67,8 @@ class BasicFFN {
6567
* sedangkan xavier init make k = input + output;
6668
*/
6769
void init_wb() {
70+
// setup random number generator
71+
gen.seed(rd());
6872
FP k0 = inputSize, k1 = hidden1Size, k2 = hidden2Size;
6973
if (xavier) {
7074
k0 += hidden1Size;
@@ -111,16 +115,16 @@ class BasicFFN {
111115
FP eta) {
112116
// update bobot dan bias berdasarkan delta in
113117
for (size_t i = 0; i < inSize; ++i) {
114-
for (size_t j = 0; j < outSize; ++j) w[j][i] -= eta * deltaIn[inSize] * dataIn[i];
115-
b[i] -= eta * deltaIn[inSize];
118+
for (size_t j = 0; j < outSize; ++j) w[j][i] -= eta * deltaIn[i] * dataIn[i];
119+
b[i] -= eta * deltaIn[i];
116120
}
117121

118122
if (!deltaOut) return;
119123
// update delta Out jika disediakan
120124
for (size_t i = 0; i < outSize; ++i) {
121-
for (size_t j = 0; j < inSize; ++j) deltaOut[i] += w[i][j] * deltaIn[j];
125+
for (size_t j = 0; j < inSize; ++j) (*deltaOut)[i] += w[i][j] * deltaIn[j];
122126
// aturan rantai
123-
if (actFuncDeriv) deltaOut[i] *= actFuncDeriv(dataIn[i]);
127+
if (actFuncDeriv) (*deltaOut)[i] *= actFuncDeriv(dataIn[i]);
124128
}
125129
}
126130

@@ -137,6 +141,12 @@ class BasicFFN {
137141
@note array will be lost after class is destroyed
138142
*/
139143
FP (&forward(FP (&data)[inputSize]))[outputSize] {
144+
// zeroing data layer agar tidak menumpuk
145+
std::fill(toHid1, toHid1 + hidden1Size, 0);
146+
std::fill(toHid2, toHid2 + hidden2Size, 0);
147+
std::fill(out, out + outputSize, 0);
148+
149+
// lambda switch for mathing activation function
140150
auto actFuncFromType = [](ACTIVATION_TYPE act_t) {
141151
switch (act_t) {
142152
case ACTIVATION_TYPE::RELU: return ReLU;
@@ -176,6 +186,12 @@ class BasicFFN {
176186
*/
177187
void backward(FP (&inputData)[inputSize], FP (&targetData)[outputSize]) {
178188
forward(inputData);
189+
// zeroing delta layer agar tidak menumpuk
190+
std::fill(dOut, dOut + outputSize, 0);
191+
std::fill(dHid2, dHid2 + hidden2Size, 0);
192+
std::fill(dHid1, dHid1 + hidden1Size, 0);
193+
194+
// lambda switch for mathing activation function derivative
179195
auto actFuncDerivFromType = [](ACTIVATION_TYPE act_t) {
180196
switch (act_t) {
181197
case ACTIVATION_TYPE::RELU: return ReLU_deriv;
@@ -197,10 +213,10 @@ class BasicFFN {
197213
// calculate dOut first for update through backward_layer template function
198214
for (size_t i = 0; i < outputSize; ++i) dOut[i] = lossDerivFunc(out[i], targetData[i]) * actFuncDeriv(out[i]);
199215

200-
backward_layer<outputSize, hidden2Size>(wHid2, bHid2, dOut, dHid2, actFuncDeriv, eta);
201-
backward_layer<hidden2Size, hidden1Size>(wHid1, bHid1, dHid2, dHid1, actFuncDeriv, eta);
202-
backward_layer<hidden1Size, inputSize>(wIn, bIn, dHid1, 0, 0, eta);
216+
backward_layer<outputSize, hidden2Size>(wHid2, bHid2, out, dOut, &dHid2, actFuncDeriv, eta);
217+
backward_layer<hidden2Size, hidden1Size>(wHid1, bHid1, toHid2, dHid2, &dHid1, actFuncDeriv, eta);
218+
backward_layer<hidden1Size, inputSize>(wIn, bIn, toHid1, dHid1, 0, 0, eta);
203219
}
204220
};
205221

206-
} // namespace NN
222+
} // namespace NN

NN/FFN/basicFFN/src/basicFFN.cxx

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
1+
#include <cmath>
12
#include <ffn.hxx>
23
#include <iostream>
4+
#include <numbers>
35

46
int main() {
57
using namespace NN;
68
using namespace std;
7-
BasicFFN<float, 3, 128, 128, 1> ffn;
9+
BasicFFN<double, 1, 64, 64, 1> ffn;
10+
// ffn.set_learning_rate(1e-4);
11+
812
// ffn.set_epsilon(1e-12) recommended for double
9-
float inputData[] = {0.2, 0.7, 0.5}; // this is just test if theres no
10-
// runtime error not test for logical
11-
float (&out)[1] = ffn.forward(inputData);
12-
cout << out[0] << endl;
13+
14+
double input[100][1];
15+
double x = 0.0f;
16+
cout << "init data" << endl;
17+
for (int e = 0; e < 100; ++e) {
18+
x = 0;
19+
for (int i = 0; i < 100; x += 1e-2, ++i) {
20+
input[i][0] = x;
21+
double sinx[] = {std::sin(x)};
22+
cout << "train ke" << i << endl;
23+
ffn.backward(input[i], sinx);
24+
}
25+
}
26+
27+
cout << "after trains" << endl;
28+
29+
for (int i = 0; i < 100; ++i) {
30+
cout << "Result for input " << input[i][0] << " = " << ffn.forward(input[i])[0] << endl;
31+
cout << "Real result = " << std::sin(input[i][0]) << endl;
32+
}
1333
return 0;
1434
}

0 commit comments

Comments
 (0)