Skip to content

Commit e9996e2

Browse files
committed
Add README
1 parent 912f53f commit e9996e2

File tree

7 files changed

+67
-270
lines changed

7 files changed

+67
-270
lines changed

README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Exercise Denoise Cosine
2+
The goal of this exercise is to implement a multilayer dense neuralnetwork from scratch using C++.
3+
Specifically, you will implement gradient descent and use it to learn a cosine function.
4+
- First, take a look and understand array datatype defined in `line 8` in `src/utils.cpp`.
5+
- Further now, code the linear algebra operations such as matrix multplication, addition, subtraction, hadamard (element-wise) product, matrix elements sum, transpose, and matrix power (element-wise) in `src/utils.cpp`.
6+
- You can check your implementation of functions in `src/utils.cpp` by running tests with following commands
7+
```bash
8+
cd <exercise_folder>/tests
9+
g++ -o test_utils_executable test_utils.cpp
10+
./test_utils_executable
11+
```
12+
- If you see no output by running the executable, this means the implementation is right.
13+
- Navigate to `src/mlutils.cpp` and code `sigmoid` activation function as first step.
14+
```math
15+
\sigma(x) = \frac{1}{1 + e^{-x}}
16+
```
17+
- In next step, given ground truth and predictions, compute Mean Square Error (MSE) in `cost` function as follows
18+
```math
19+
MSE = \frac{1}{2}\sum(y-h)^2
20+
```
21+
- Similarly you can test your implementation of `src/mlutils.cpp` by executing `test_mlutils.cpp`.
22+
- Navigate to `src/denoise_cosine.cpp` with the above custom datatype, declare $W_1, W_2, bias$ variables and intialise the weights using the corresponding initialisation function in `src/utils.cpp`. Similarly declare the gradient variables.
23+
- Code the forward pass in `network` function in `src/denoise_cosine.cpp` and call this forward pass in main function training followed by above implemented loss function.
24+
- As a next step, derive the gradients for each variable and implement in `compute_gradients` function in `src/mlutils.cpp`. Note: `compute_gradients` function needs the above declared gradient variables as arguments and they are pass by reference, so no return type is necessary.
25+
- As a final training step implement the gradient descent step using the following formula.
26+
```math
27+
W_{new} = W_{old} - lr*\nabla W_{old}
28+
```
29+
- Finally compute the network predictions and assign it to `y_hat` variable. Now you can run the C++ program by runnig the following commands
30+
```bash
31+
cd <exercise_folder>/src
32+
g++ -o denoise_executable denoise_cosing.cpp
33+
./denoise_executable
34+
```
35+
- Finally, to check our cosine fit, you need to run the following commands
36+
```bash
37+
cd <exercise_folder>/src
38+
python plot.py
39+
```

requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
numpy
2+
matplotlib

src/denoise_cos.png

-384 KB
Binary file not shown.

src/denoise_cosine.cpp

+15-24
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,33 @@
77
using namespace std;
88

99
twod_array network(twod_array w1, twod_array w2, twod_array b, twod_array x){
10-
twod_array h0 = sigmoid(matadd(matmul(w1, x), b));
11-
twod_array h1 = matmul(w2, h0);
12-
return h1;
10+
// TODO: Implement forward pass
1311
}
1412

1513
int main(){
14+
int input_neurons = 200;
15+
int output_neurons = 200;
16+
int hidden_neurons = 10;
1617
double lr = 0.01;
1718
int epochs = 150;
19+
20+
twod_array y_noise(input_neurons, vector<double>(1));
21+
twod_array y(input_neurons, vector<double>(1));
22+
read_cosine(y_noise, y);
23+
1824
twod_array y_hat;
1925
double loss_val;
20-
vector<double> gradients;
21-
twod_array W1(10, vector<double>(200));
22-
twod_array W2(200, vector<double>(10));
23-
twod_array bias(10, vector<double>(1));
24-
twod_array grad_w1(10, vector<double>(200));
25-
twod_array grad_w2(200, vector<double>(10));
26-
twod_array grad_bias(10, vector<double>(1));
27-
twod_array y_noise(200, vector<double>(1));
28-
twod_array y(200, vector<double>(1));
29-
30-
read_cosine(y_noise, y);
3126

32-
initialise_weights(W1);
33-
initialise_weights(W2);
34-
initialise_weights(bias);
27+
// TODO: Declare and intialise parameters
28+
// TODO: Declare gradients
3529

3630
for(int epoch=0; epoch<epochs; epoch++){
37-
y_hat = network(W1, W2, bias, y_noise);
38-
loss_val = cost(y, y_hat);
39-
compute_gradients(W2, W1, bias, y_noise, y, grad_w2, grad_w1, grad_bias);
40-
W2 = matadd(W2, ele_product(ele_product(grad_w2, lr), -1.0));
41-
W1 = matadd(W1, ele_product(ele_product(grad_w1, lr), -1.0));
42-
bias = matadd(bias, ele_product(ele_product(grad_bias, lr), -1.0));
31+
// TODO: Forward pass
32+
// TODO: Compute cost and gradients
33+
// TODO: Update parameters using SGD
4334
cout << "Epoch: " << epoch << " Loss: " << loss_val << endl;
4435
}
45-
y_hat = network(W1, W2, bias, y_noise);
36+
// TODO: Get network predictions on y_noise and assign to y_hat variable.
4637
write_cosine(y_hat);
4738
return 0;
4839
}

src/fit.txt

-200
This file was deleted.

src/mlutils.cpp

+3-8
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,13 @@
55
using namespace std;
66

77
twod_array sigmoid(twod_array matrix){
8-
for (int i=0; i<matrix.size(); i++){
9-
for (int j=0; j<matrix[0].size(); j++){
10-
matrix[i][j] = 1 / (1 + exp(-1*matrix[i][j]));
11-
}
12-
}
8+
// TODO: Implemet sigmoid activation.
139
return matrix;
1410
}
1511

1612
double cost(twod_array gt, twod_array h){
17-
twod_array error = matpow(matsub(gt, h), 2);
18-
double sum_val = matsum(error);
19-
return 0.5 * sum_val;
13+
//TODO: Compute mse loss
14+
return 0.0;
2015
}
2116

2217
void compute_gradients(twod_array w_2, twod_array w_1, twod_array bias, twod_array x, twod_array y,

0 commit comments

Comments
 (0)