aboutsummaryrefslogtreecommitdiff
path: root/src/lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/test')
-rw-r--r--src/lib/test/neuralnet_test.c103
-rw-r--r--src/lib/test/train_linear_perceptron_non_origin_test.c46
-rw-r--r--src/lib/test/train_linear_perceptron_test.c44
-rw-r--r--src/lib/test/train_sigmoid_test.c46
-rw-r--r--src/lib/test/train_xor_test.c55
5 files changed, 169 insertions, 125 deletions
diff --git a/src/lib/test/neuralnet_test.c b/src/lib/test/neuralnet_test.c
index 14d9438..0f8d7b8 100644
--- a/src/lib/test/neuralnet_test.c
+++ b/src/lib/test/neuralnet_test.c
@@ -1,8 +1,8 @@
1#include <neuralnet/neuralnet.h> 1#include <neuralnet/neuralnet.h>
2 2
3#include <neuralnet/matrix.h>
4#include "activation.h" 3#include "activation.h"
5#include "neuralnet_impl.h" 4#include "neuralnet_impl.h"
5#include <neuralnet/matrix.h>
6 6
7#include "test.h" 7#include "test.h"
8#include "test_util.h" 8#include "test_util.h"
@@ -10,23 +10,31 @@
10#include <assert.h> 10#include <assert.h>
11 11
12TEST_CASE(neuralnet_perceptron_test) { 12TEST_CASE(neuralnet_perceptron_test) {
13 const int num_layers = 1; 13 const int num_layers = 2;
14 const int layer_sizes[] = { 1, 1 }; 14 const int input_size = 1;
15 const nnActivation layer_activations[] = { nnSigmoid }; 15 const R weights[] = {0.3};
16 const R weights[] = { 0.3 }; 16 const R biases[] = {0.0};
17 const nnLayer layers[] = {
18 {.type = nnLinear,
19 .linear =
20 {.weights = nnMatrixFromArray(1, 1, weights),
21 .biases = nnMatrixFromArray(1, 1, biases)}},
22 {.type = nnSigmoid},
23 };
17 24
18 nnNeuralNetwork* net = nnMakeNet(num_layers, layer_sizes, layer_activations); 25 nnNeuralNetwork* net = nnMakeNet(layers, num_layers, input_size);
19 assert(net); 26 assert(net);
20 nnSetWeights(net, weights);
21 27
22 nnQueryObject* query = nnMakeQueryObject(net, /*num_inputs=*/1); 28 nnQueryObject* query = nnMakeQueryObject(net, 1);
23 29
24 const R input[] = { 0.9 }; 30 const R input[] = {0.9};
25 R output[1]; 31 R output[1];
26 nnQueryArray(net, query, input, output); 32 nnQueryArray(net, query, input, output);
27 33
28 const R expected_output = sigmoid(input[0] * weights[0]); 34 const R expected_output = sigmoid(input[0] * weights[0]);
29 printf("\nOutput: %f, Expected: %f\n", output[0], expected_output); 35 printf(
36 "\n[neuralnet_perceptron_test] Output: %f, Expected: %f\n", output[0],
37 expected_output);
30 TEST_TRUE(double_eq(output[0], expected_output, EPS)); 38 TEST_TRUE(double_eq(output[0], expected_output, EPS));
31 39
32 nnDeleteQueryObject(&query); 40 nnDeleteQueryObject(&query);
@@ -34,53 +42,66 @@ TEST_CASE(neuralnet_perceptron_test) {
34} 42}
35 43
36TEST_CASE(neuralnet_xor_test) { 44TEST_CASE(neuralnet_xor_test) {
37 const int num_layers = 2; 45 // First (hidden) layer.
38 const int layer_sizes[] = { 2, 2, 1 }; 46 const R weights0[] = {1, 1, 1, 1};
39 const nnActivation layer_activations[] = { nnRelu, nnIdentity }; 47 const R biases0[] = {0, -1};
40 const R weights[] = { 48 // Second (output) layer.
41 1, 1, 1, 1, // First (hidden) layer. 49 const R weights1[] = {1, -2};
42 1, -2 // Second (output) layer. 50 const R biases1[] = {0};
43 }; 51 // Network.
44 const R biases[] = { 52 const int num_layers = 3;
45 0, -1, // First (hidden) layer. 53 const int input_size = 2;
46 0 // Second (output) layer. 54 const nnLayer layers[] = {
55 {.type = nnLinear,
56 .linear =
57 {.weights = nnMatrixFromArray(2, 2, weights0),
58 .biases = nnMatrixFromArray(1, 2, biases0)}},
59 {.type = nnRelu},
60 {.type = nnLinear,
61 .linear =
62 {.weights = nnMatrixFromArray(2, 1, weights1),
63 .biases = nnMatrixFromArray(1, 1, biases1)}},
47 }; 64 };
48 65
49 nnNeuralNetwork* net = nnMakeNet(num_layers, layer_sizes, layer_activations); 66 nnNeuralNetwork* net = nnMakeNet(layers, num_layers, input_size);
50 assert(net); 67 assert(net);
51 nnSetWeights(net, weights);
52 nnSetBiases(net, biases);
53 68
54 // First layer weights. 69 // First layer weights.
55 TEST_EQUAL(nnMatrixAt(&net->weights[0], 0, 0), 1); 70 TEST_EQUAL(nnMatrixAt(&net->layers[0].linear.weights, 0, 0), 1);
56 TEST_EQUAL(nnMatrixAt(&net->weights[0], 0, 1), 1); 71 TEST_EQUAL(nnMatrixAt(&net->layers[0].linear.weights, 0, 1), 1);
57 TEST_EQUAL(nnMatrixAt(&net->weights[0], 0, 2), 1); 72 TEST_EQUAL(nnMatrixAt(&net->layers[0].linear.weights, 0, 2), 1);
58 TEST_EQUAL(nnMatrixAt(&net->weights[0], 0, 3), 1); 73 TEST_EQUAL(nnMatrixAt(&net->layers[0].linear.weights, 0, 3), 1);
59 // Second layer weights. 74 // Second linear layer (third layer) weights.
60 TEST_EQUAL(nnMatrixAt(&net->weights[1], 0, 0), 1); 75 TEST_EQUAL(nnMatrixAt(&net->layers[2].linear.weights, 0, 0), 1);
61 TEST_EQUAL(nnMatrixAt(&net->weights[1], 0, 1), -2); 76 TEST_EQUAL(nnMatrixAt(&net->layers[2].linear.weights, 0, 1), -2);
62 // First layer biases. 77 // First layer biases.
63 TEST_EQUAL(nnMatrixAt(&net->biases[0], 0, 0), 0); 78 TEST_EQUAL(nnMatrixAt(&net->layers[0].linear.biases, 0, 0), 0);
64 TEST_EQUAL(nnMatrixAt(&net->biases[0], 0, 1), -1); 79 TEST_EQUAL(nnMatrixAt(&net->layers[0].linear.biases, 0, 1), -1);
65 // Second layer biases. 80 // Second linear layer (third layer) biases.
66 TEST_EQUAL(nnMatrixAt(&net->biases[1], 0, 0), 0); 81 TEST_EQUAL(nnMatrixAt(&net->layers[2].linear.biases, 0, 0), 0);
67 82
68 // Test. 83 // Test.
69 84
70 #define M 4 85#define M 4
71 86
72 nnQueryObject* query = nnMakeQueryObject(net, /*num_inputs=*/M); 87 nnQueryObject* query = nnMakeQueryObject(net, M);
73 88
74 const R test_inputs[M][2] = { { 0., 0. }, { 1., 0. }, { 0., 1. }, { 1., 1. } }; 89 const R test_inputs[M][2] = {
90 {0., 0.},
91 {1., 0.},
92 {0., 1.},
93 {1., 1.}
94 };
75 nnMatrix test_inputs_matrix = nnMatrixMake(M, 2); 95 nnMatrix test_inputs_matrix = nnMatrixMake(M, 2);
76 nnMatrixInit(&test_inputs_matrix, (const R*)test_inputs); 96 nnMatrixInit(&test_inputs_matrix, (const R*)test_inputs);
77 nnQuery(net, query, &test_inputs_matrix); 97 nnQuery(net, query, &test_inputs_matrix);
78 98
79 const R expected_outputs[M] = { 0., 1., 1., 0. }; 99 const R expected_outputs[M] = {0., 1., 1., 0.};
80 for (int i = 0; i < M; ++i) { 100 for (int i = 0; i < M; ++i) {
81 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0); 101 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0);
82 printf("\nInput: (%f, %f), Output: %f, Expected: %f\n", 102 printf(
83 test_inputs[i][0], test_inputs[i][1], test_output, expected_outputs[i]); 103 "\nInput: (%f, %f), Output: %f, Expected: %f\n", test_inputs[i][0],
104 test_inputs[i][1], test_output, expected_outputs[i]);
84 } 105 }
85 for (int i = 0; i < M; ++i) { 106 for (int i = 0; i < M; ++i) {
86 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0); 107 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0);
diff --git a/src/lib/test/train_linear_perceptron_non_origin_test.c b/src/lib/test/train_linear_perceptron_non_origin_test.c
index 5a320ac..40a42e0 100644
--- a/src/lib/test/train_linear_perceptron_non_origin_test.c
+++ b/src/lib/test/train_linear_perceptron_non_origin_test.c
@@ -1,9 +1,8 @@
1#include <neuralnet/train.h> 1#include <neuralnet/train.h>
2 2
3#include "neuralnet_impl.h"
3#include <neuralnet/matrix.h> 4#include <neuralnet/matrix.h>
4#include <neuralnet/neuralnet.h> 5#include <neuralnet/neuralnet.h>
5#include "activation.h"
6#include "neuralnet_impl.h"
7 6
8#include "test.h" 7#include "test.h"
9#include "test_util.h" 8#include "test_util.h"
@@ -11,19 +10,21 @@
11#include <assert.h> 10#include <assert.h>
12 11
13TEST_CASE(neuralnet_train_linear_perceptron_non_origin_test) { 12TEST_CASE(neuralnet_train_linear_perceptron_non_origin_test) {
14 const int num_layers = 1; 13 const int num_layers = 1;
15 const int layer_sizes[] = { 1, 1 }; 14 const int input_size = 1;
16 const nnActivation layer_activations[] = { nnIdentity }; 15 const nnLayer layers[] = {
16 {.type = nnLinear, .linear = {.input_size = 1, .output_size = 1}}
17 };
17 18
18 nnNeuralNetwork* net = nnMakeNet(num_layers, layer_sizes, layer_activations); 19 nnNeuralNetwork* net = nnMakeNet(layers, num_layers, input_size);
19 assert(net); 20 assert(net);
20 21
21 // Train. 22// Train.
22 23
23 // Try to learn the Y = 2X + 1 line. 24// Try to learn the Y = 2X + 1 line.
24 #define N 2 25#define N 2
25 const R inputs[N] = { 0., 1. }; 26 const R inputs[N] = {0., 1.};
26 const R targets[N] = { 1., 3. }; 27 const R targets[N] = {1., 3.};
27 28
28 nnMatrix inputs_matrix = nnMatrixMake(N, 1); 29 nnMatrix inputs_matrix = nnMatrixMake(N, 1);
29 nnMatrix targets_matrix = nnMatrixMake(N, 1); 30 nnMatrix targets_matrix = nnMatrixMake(N, 1);
@@ -31,31 +32,32 @@ TEST_CASE(neuralnet_train_linear_perceptron_non_origin_test) {
31 nnMatrixInit(&targets_matrix, targets); 32 nnMatrixInit(&targets_matrix, targets);
32 33
33 nnTrainingParams params = { 34 nnTrainingParams params = {
34 .learning_rate = 0.7, 35 .learning_rate = 0.7,
35 .max_iterations = 20, 36 .max_iterations = 20,
36 .seed = 0, 37 .seed = 0,
37 .weight_init = nnWeightInit01, 38 .weight_init = nnWeightInit01,
38 .debug = false, 39 .debug = false,
39 }; 40 };
40 41
41 nnTrain(net, &inputs_matrix, &targets_matrix, &params); 42 nnTrain(net, &inputs_matrix, &targets_matrix, &params);
42 43
43 const R weight = nnMatrixAt(&net->weights[0], 0, 0); 44 const R weight = nnMatrixAt(&net->layers[0].linear.weights, 0, 0);
44 const R expected_weight = 2.0; 45 const R expected_weight = 2.0;
45 printf("\nTrained network weight: %f, Expected: %f\n", weight, expected_weight); 46 printf(
47 "\nTrained network weight: %f, Expected: %f\n", weight, expected_weight);
46 TEST_TRUE(double_eq(weight, expected_weight, WEIGHT_EPS)); 48 TEST_TRUE(double_eq(weight, expected_weight, WEIGHT_EPS));
47 49
48 const R bias = nnMatrixAt(&net->biases[0], 0, 0); 50 const R bias = nnMatrixAt(&net->layers[0].linear.biases, 0, 0);
49 const R expected_bias = 1.0; 51 const R expected_bias = 1.0;
50 printf("Trained network bias: %f, Expected: %f\n", bias, expected_bias); 52 printf("Trained network bias: %f, Expected: %f\n", bias, expected_bias);
51 TEST_TRUE(double_eq(bias, expected_bias, WEIGHT_EPS)); 53 TEST_TRUE(double_eq(bias, expected_bias, WEIGHT_EPS));
52 54
53 // Test. 55 // Test.
54 56
55 nnQueryObject* query = nnMakeQueryObject(net, /*num_inputs=*/1); 57 nnQueryObject* query = nnMakeQueryObject(net, 1);
56 58
57 const R test_input[] = { 2.3 }; 59 const R test_input[] = {2.3};
58 R test_output[1]; 60 R test_output[1];
59 nnQueryArray(net, query, test_input, test_output); 61 nnQueryArray(net, query, test_input, test_output);
60 62
61 const R expected_output = test_input[0] * expected_weight + expected_bias; 63 const R expected_output = test_input[0] * expected_weight + expected_bias;
diff --git a/src/lib/test/train_linear_perceptron_test.c b/src/lib/test/train_linear_perceptron_test.c
index 2b1336d..667643b 100644
--- a/src/lib/test/train_linear_perceptron_test.c
+++ b/src/lib/test/train_linear_perceptron_test.c
@@ -1,9 +1,8 @@
1#include <neuralnet/train.h> 1#include <neuralnet/train.h>
2 2
3#include "neuralnet_impl.h"
3#include <neuralnet/matrix.h> 4#include <neuralnet/matrix.h>
4#include <neuralnet/neuralnet.h> 5#include <neuralnet/neuralnet.h>
5#include "activation.h"
6#include "neuralnet_impl.h"
7 6
8#include "test.h" 7#include "test.h"
9#include "test_util.h" 8#include "test_util.h"
@@ -11,19 +10,21 @@
11#include <assert.h> 10#include <assert.h>
12 11
13TEST_CASE(neuralnet_train_linear_perceptron_test) { 12TEST_CASE(neuralnet_train_linear_perceptron_test) {
14 const int num_layers = 1; 13 const int num_layers = 1;
15 const int layer_sizes[] = { 1, 1 }; 14 const int input_size = 1;
16 const nnActivation layer_activations[] = { nnIdentity }; 15 const nnLayer layers[] = {
16 {.type = nnLinear, .linear = {.input_size = 1, .output_size = 1}}
17 };
17 18
18 nnNeuralNetwork* net = nnMakeNet(num_layers, layer_sizes, layer_activations); 19 nnNeuralNetwork* net = nnMakeNet(layers, num_layers, input_size);
19 assert(net); 20 assert(net);
20 21
21 // Train. 22// Train.
22 23
23 // Try to learn the Y=X line. 24// Try to learn the Y=X line.
24 #define N 2 25#define N 2
25 const R inputs[N] = { 0., 1. }; 26 const R inputs[N] = {0., 1.};
26 const R targets[N] = { 0., 1. }; 27 const R targets[N] = {0., 1.};
27 28
28 nnMatrix inputs_matrix = nnMatrixMake(N, 1); 29 nnMatrix inputs_matrix = nnMatrixMake(N, 1);
29 nnMatrix targets_matrix = nnMatrixMake(N, 1); 30 nnMatrix targets_matrix = nnMatrixMake(N, 1);
@@ -31,26 +32,27 @@ TEST_CASE(neuralnet_train_linear_perceptron_test) {
31 nnMatrixInit(&targets_matrix, targets); 32 nnMatrixInit(&targets_matrix, targets);
32 33
33 nnTrainingParams params = { 34 nnTrainingParams params = {
34 .learning_rate = 0.7, 35 .learning_rate = 0.7,
35 .max_iterations = 10, 36 .max_iterations = 10,
36 .seed = 0, 37 .seed = 0,
37 .weight_init = nnWeightInit01, 38 .weight_init = nnWeightInit01,
38 .debug = false, 39 .debug = false,
39 }; 40 };
40 41
41 nnTrain(net, &inputs_matrix, &targets_matrix, &params); 42 nnTrain(net, &inputs_matrix, &targets_matrix, &params);
42 43
43 const R weight = nnMatrixAt(&net->weights[0], 0, 0); 44 const R weight = nnMatrixAt(&net->layers[0].linear.weights, 0, 0);
44 const R expected_weight = 1.0; 45 const R expected_weight = 1.0;
45 printf("\nTrained network weight: %f, Expected: %f\n", weight, expected_weight); 46 printf(
47 "\nTrained network weight: %f, Expected: %f\n", weight, expected_weight);
46 TEST_TRUE(double_eq(weight, expected_weight, WEIGHT_EPS)); 48 TEST_TRUE(double_eq(weight, expected_weight, WEIGHT_EPS));
47 49
48 // Test. 50 // Test.
49 51
50 nnQueryObject* query = nnMakeQueryObject(net, /*num_inputs=*/1); 52 nnQueryObject* query = nnMakeQueryObject(net, 1);
51 53
52 const R test_input[] = { 2.3 }; 54 const R test_input[] = {2.3};
53 R test_output[1]; 55 R test_output[1];
54 nnQueryArray(net, query, test_input, test_output); 56 nnQueryArray(net, query, test_input, test_output);
55 57
56 const R expected_output = test_input[0]; 58 const R expected_output = test_input[0];
diff --git a/src/lib/test/train_sigmoid_test.c b/src/lib/test/train_sigmoid_test.c
index 588e7ca..39a84b0 100644
--- a/src/lib/test/train_sigmoid_test.c
+++ b/src/lib/test/train_sigmoid_test.c
@@ -1,9 +1,9 @@
1#include <neuralnet/train.h> 1#include <neuralnet/train.h>
2 2
3#include <neuralnet/matrix.h>
4#include <neuralnet/neuralnet.h>
5#include "activation.h" 3#include "activation.h"
6#include "neuralnet_impl.h" 4#include "neuralnet_impl.h"
5#include <neuralnet/matrix.h>
6#include <neuralnet/neuralnet.h>
7 7
8#include "test.h" 8#include "test.h"
9#include "test_util.h" 9#include "test_util.h"
@@ -11,21 +11,24 @@
11#include <assert.h> 11#include <assert.h>
12 12
13TEST_CASE(neuralnet_train_sigmoid_test) { 13TEST_CASE(neuralnet_train_sigmoid_test) {
14 const int num_layers = 1; 14 const int num_layers = 2;
15 const int layer_sizes[] = { 1, 1 }; 15 const int input_size = 1;
16 const nnActivation layer_activations[] = { nnSigmoid }; 16 const nnLayer layers[] = {
17 {.type = nnLinear, .linear = {.input_size = 1, .output_size = 1}},
18 {.type = nnSigmoid},
19 };
17 20
18 nnNeuralNetwork* net = nnMakeNet(num_layers, layer_sizes, layer_activations); 21 nnNeuralNetwork* net = nnMakeNet(layers, num_layers, input_size);
19 assert(net); 22 assert(net);
20 23
21 // Train. 24// Train.
22 25
23 // Try to learn the sigmoid function. 26// Try to learn the sigmoid function.
24 #define N 3 27#define N 3
25 R inputs[N]; 28 R inputs[N];
26 R targets[N]; 29 R targets[N];
27 for (int i = 0; i < N; ++i) { 30 for (int i = 0; i < N; ++i) {
28 inputs[i] = lerp(-1, +1, (R)i / (R)(N-1)); 31 inputs[i] = lerp(-1, +1, (R)i / (R)(N - 1));
29 targets[i] = sigmoid(inputs[i]); 32 targets[i] = sigmoid(inputs[i]);
30 } 33 }
31 34
@@ -35,29 +38,30 @@ TEST_CASE(neuralnet_train_sigmoid_test) {
35 nnMatrixInit(&targets_matrix, targets); 38 nnMatrixInit(&targets_matrix, targets);
36 39
37 nnTrainingParams params = { 40 nnTrainingParams params = {
38 .learning_rate = 0.9, 41 .learning_rate = 0.9,
39 .max_iterations = 100, 42 .max_iterations = 100,
40 .seed = 0, 43 .seed = 0,
41 .weight_init = nnWeightInit01, 44 .weight_init = nnWeightInit01,
42 .debug = false, 45 .debug = false,
43 }; 46 };
44 47
45 nnTrain(net, &inputs_matrix, &targets_matrix, &params); 48 nnTrain(net, &inputs_matrix, &targets_matrix, &params);
46 49
47 const R weight = nnMatrixAt(&net->weights[0], 0, 0); 50 const R weight = nnMatrixAt(&net->layers[0].linear.weights, 0, 0);
48 const R expected_weight = 1.0; 51 const R expected_weight = 1.0;
49 printf("\nTrained network weight: %f, Expected: %f\n", weight, expected_weight); 52 printf(
53 "\nTrained network weight: %f, Expected: %f\n", weight, expected_weight);
50 TEST_TRUE(double_eq(weight, expected_weight, WEIGHT_EPS)); 54 TEST_TRUE(double_eq(weight, expected_weight, WEIGHT_EPS));
51 55
52 // Test. 56 // Test.
53 57
54 nnQueryObject* query = nnMakeQueryObject(net, /*num_inputs=*/1); 58 nnQueryObject* query = nnMakeQueryObject(net, 1);
55 59
56 const R test_input[] = { 0.3 }; 60 const R test_input[] = {0.3};
57 R test_output[1]; 61 R test_output[1];
58 nnQueryArray(net, query, test_input, test_output); 62 nnQueryArray(net, query, test_input, test_output);
59 63
60 const R expected_output = 0.574442516811659; // sigmoid(0.3) 64 const R expected_output = 0.574442516811659; // sigmoid(0.3)
61 printf("Output: %f, Expected: %f\n", test_output[0], expected_output); 65 printf("Output: %f, Expected: %f\n", test_output[0], expected_output);
62 TEST_TRUE(double_eq(test_output[0], expected_output, OUTPUT_EPS)); 66 TEST_TRUE(double_eq(test_output[0], expected_output, OUTPUT_EPS));
63 67
diff --git a/src/lib/test/train_xor_test.c b/src/lib/test/train_xor_test.c
index 6ddc6e0..78695a3 100644
--- a/src/lib/test/train_xor_test.c
+++ b/src/lib/test/train_xor_test.c
@@ -1,9 +1,9 @@
1#include <neuralnet/train.h> 1#include <neuralnet/train.h>
2 2
3#include <neuralnet/matrix.h>
4#include <neuralnet/neuralnet.h>
5#include "activation.h" 3#include "activation.h"
6#include "neuralnet_impl.h" 4#include "neuralnet_impl.h"
5#include <neuralnet/matrix.h>
6#include <neuralnet/neuralnet.h>
7 7
8#include "test.h" 8#include "test.h"
9#include "test_util.h" 9#include "test_util.h"
@@ -11,18 +11,27 @@
11#include <assert.h> 11#include <assert.h>
12 12
13TEST_CASE(neuralnet_train_xor_test) { 13TEST_CASE(neuralnet_train_xor_test) {
14 const int num_layers = 2; 14 const int num_layers = 3;
15 const int layer_sizes[] = { 2, 2, 1 }; 15 const int input_size = 2;
16 const nnActivation layer_activations[] = { nnRelu, nnIdentity }; 16 const nnLayer layers[] = {
17 {.type = nnLinear, .linear = {.input_size = 2, .output_size = 2}},
18 {.type = nnRelu},
19 {.type = nnLinear, .linear = {.input_size = 2, .output_size = 1}}
20 };
17 21
18 nnNeuralNetwork* net = nnMakeNet(num_layers, layer_sizes, layer_activations); 22 nnNeuralNetwork* net = nnMakeNet(layers, num_layers, input_size);
19 assert(net); 23 assert(net);
20 24
21 // Train. 25 // Train.
22 26
23 #define N 4 27#define N 4
24 const R inputs[N][2] = { { 0., 0. }, { 0., 1. }, { 1., 0. }, { 1., 1. } }; 28 const R inputs[N][2] = {
25 const R targets[N] = { 0., 1., 1., 0. }; 29 {0., 0.},
30 {0., 1.},
31 {1., 0.},
32 {1., 1.}
33 };
34 const R targets[N] = {0., 1., 1., 0.};
26 35
27 nnMatrix inputs_matrix = nnMatrixMake(N, 2); 36 nnMatrix inputs_matrix = nnMatrixMake(N, 2);
28 nnMatrix targets_matrix = nnMatrixMake(N, 1); 37 nnMatrix targets_matrix = nnMatrixMake(N, 1);
@@ -30,31 +39,37 @@ TEST_CASE(neuralnet_train_xor_test) {
30 nnMatrixInit(&targets_matrix, targets); 39 nnMatrixInit(&targets_matrix, targets);
31 40
32 nnTrainingParams params = { 41 nnTrainingParams params = {
33 .learning_rate = 0.1, 42 .learning_rate = 0.1,
34 .max_iterations = 500, 43 .max_iterations = 500,
35 .seed = 0, 44 .seed = 0,
36 .weight_init = nnWeightInit01, 45 .weight_init = nnWeightInit01,
37 .debug = false, 46 .debug = false,
38 }; 47 };
39 48
40 nnTrain(net, &inputs_matrix, &targets_matrix, &params); 49 nnTrain(net, &inputs_matrix, &targets_matrix, &params);
41 50
42 // Test. 51 // Test.
43 52
44 #define M 4 53#define M 4
45 54
46 nnQueryObject* query = nnMakeQueryObject(net, /*num_inputs=*/M); 55 nnQueryObject* query = nnMakeQueryObject(net, M);
47 56
48 const R test_inputs[M][2] = { { 0., 0. }, { 1., 0. }, { 0., 1. }, { 1., 1. } }; 57 const R test_inputs[M][2] = {
58 {0., 0.},
59 {1., 0.},
60 {0., 1.},
61 {1., 1.}
62 };
49 nnMatrix test_inputs_matrix = nnMatrixMake(M, 2); 63 nnMatrix test_inputs_matrix = nnMatrixMake(M, 2);
50 nnMatrixInit(&test_inputs_matrix, (const R*)test_inputs); 64 nnMatrixInit(&test_inputs_matrix, (const R*)test_inputs);
51 nnQuery(net, query, &test_inputs_matrix); 65 nnQuery(net, query, &test_inputs_matrix);
52 66
53 const R expected_outputs[M] = { 0., 1., 1., 0. }; 67 const R expected_outputs[M] = {0., 1., 1., 0.};
54 for (int i = 0; i < M; ++i) { 68 for (int i = 0; i < M; ++i) {
55 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0); 69 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0);
56 printf("\nInput: (%f, %f), Output: %f, Expected: %f\n", 70 printf(
57 test_inputs[i][0], test_inputs[i][1], test_output, expected_outputs[i]); 71 "\nInput: (%f, %f), Output: %f, Expected: %f\n", test_inputs[i][0],
72 test_inputs[i][1], test_output, expected_outputs[i]);
58 } 73 }
59 for (int i = 0; i < M; ++i) { 74 for (int i = 0; i < M; ++i) {
60 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0); 75 const R test_output = nnMatrixAt(nnNetOutputs(query), i, 0);