-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
94 lines (75 loc) · 2.83 KB
/
main.cpp
File metadata and controls
94 lines (75 loc) · 2.83 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
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <chrono>
#include <fstream>
#include "mnist_loader.h"
#include "loss_activation.h"
#include "mlp.h"
using namespace std;
int main() {
srand(time(0));
CrossEntropy ce_loss;
Softmax softmax;
cout << "=== MLP Classifier Training Benchmark ===" << endl;
auto [inputs, targets] = loadMNIST("mnist_train.csv", 1000);
MLP model(784, {32, 32}, 10);
model.loss_function = &ce_loss;
model.set_activation(&softmax, model.layers.size() - 1);
cout << "Architecture: 784 -> 32 -> 32 -> 10" << endl;
cout << "Training samples: " << inputs.size() << endl;
cout << "Epochs: 10" << endl << endl;
double learning_rate = 0.01;
int epochs = 10;
for (int epoch = 0; epoch < epochs; epoch++) {
double total_loss = 0.0;
auto start_time = chrono::high_resolution_clock::now();
for (size_t i = 0; i < inputs.size(); i++) {
vector<double> output = model.forward(inputs[i]);
double loss = ce_loss.forward(output, targets[i]);
model.backward(targets[i]);
model.update(learning_rate);
total_loss += loss;
}
auto end_time = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::milliseconds>(end_time - start_time);
double avg_loss = total_loss / inputs.size();
double time_seconds = duration.count() / 1000.0;
double samples_per_sec = inputs.size() / time_seconds;
cout << "Epoch " << (epoch + 1) << "/" << epochs
<< ", Loss: " << avg_loss
<< ", Time: " << time_seconds << "s"
<< ", Throughput: " << samples_per_sec << " samples/s" << endl;
}
cout << "\n=== Evaluating Accuracy ===" << endl;
auto [test_inputs, test_targets] = loadMNIST("mnist_test.csv", 200);
int correct = 0;
int total = 0;
for (size_t i = 0; i < test_inputs.size(); i++) {
vector<double> output = model.forward(test_inputs[i]);
int predicted = 0;
double max_prob = output[0];
for (size_t j = 1; j < output.size(); j++) {
if (output[j] > max_prob) {
max_prob = output[j];
predicted = j;
}
}
int true_label = 0;
for (size_t j = 0; j < test_targets[i].size(); j++) {
if (test_targets[i][j] > 0.5) {
true_label = j;
break;
}
}
if (predicted == true_label) {
correct++;
}
total++;
}
double accuracy = (double)correct / total * 100.0;
cout << "Test Accuracy: " << correct << "/" << total << " = " << accuracy << "%" << endl;
return 0;
}