Skip to content

Commit

Permalink
main.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
SermetPekin committed Dec 9, 2024
1 parent b344e76 commit 48f05ed
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 208 deletions.
20 changes: 1 addition & 19 deletions easy_df.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,4 @@

// MIT License
// Copyright (c) [2024] Sermet Pekin
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// */

#include "micrograd.hpp"
#include "value.hpp"
#include "mlp.hpp"
Expand Down
208 changes: 19 additions & 189 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,198 +1,28 @@
// MIT License

// Copyright (c) [2024] Sermet Pekin

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// */

#include <iostream>
#include <random>
#include <utility>

#include "micrograd.hpp"

using namespace microgradCpp;

/*
g++ -g -o main main.cpp
g++ -g -std=c++17 -Iinclude -O2 -o main main.cpp
clang++ -std=c++17 -Iinclude -g -o main main.cpp
(lldb) breakpoint set --file main.cpp --line 75
(lldb) run
(lldb) bt
(lldb) print some_variable
*/

#include <iostream>
#include <vector>
#include <memory>
// #include "value.hpp" // Assuming Value class is defined here
// #include "mlp.hpp" // Assuming MLP class is defined here

// using ColRows = std::vector<std::vector<std::shared_ptr<Value>>>;
// using DatasetType = std::vector<std::pair<std::vector<std::shared_ptr<Value>>, std::vector<std::shared_ptr<Value>>>>;

#include <iostream>
#include <vector>
#include <memory>
#include <iomanip>
#include <sstream>
#include "value.hpp" // Assuming Value class is defined here
#include "mlp.hpp" // Assuming MLP class is defined here

// using ColRows = std::vector<std::vector<std::shared_ptr<Value>>>;
// using DatasetType = std::vector<std::pair<std::vector<std::shared_ptr<Value>>, std::vector<std::shared_ptr<Value>>>>;

int main()
{

DatasetType dataset = get_iris2();

shuffle(dataset);

// DatasetType dataset = get_iris();
DataFrame df;
df.from_csv("./data/iris.csv");
df.normalize();
df.encode_column("variety");
df.print();
df.shuffle();
df.print();
// stop();
// return 0;
// shuffle(dataset);
double TRAIN_SIZE{0.8};

// Split into train and test sets (80-20 split)
ColRows train_inputs, train_targets;
ColRows test_inputs, test_targets;

train_test_split(dataset, TRAIN_SIZE, train_inputs, train_targets, test_inputs, test_targets);

// Create MLP model
// Input: 4 features, hidden layers: [7,7], output: 3 classes
MLP model(4, {7, 7, 3});

// Validate dataset and model
if (!validate_dataset_and_model(dataset, model, TRAIN_SIZE))
{
std::cerr << "Validation failed. Exiting." << std::endl;
return 1;
}

// Create SGD optimizer with a learning rate of 0.005
SGD optimizer(0.01);

int epochs = 100;

int x = 0;
std::cout << "Epoch: " << epochs << ", Sample: " << x << std::endl;

// Validate input size
std::cout << "Input size: " << train_inputs[x].size() << std::endl;
std::cout << "Target size: " << train_targets[x].size() << std::endl;

for (int epoch = 0; epoch < epochs; ++epoch)
{
double total_loss = 0.0;

// Training loop
for (size_t i = 0; i < train_inputs.size(); ++i)
{

// Forward pass (training=true to possibly enable dropout or other training-specific behavior in MLP)
auto predictions = model.forward(train_inputs[i], true);

// Compute Cross-Entropy Loss
auto loss = Loss::cross_entropy(predictions, train_targets[i]);
total_loss += loss->data;

// Backpropagation
optimizer.zero_grad(model.parameters());
loss->backward();

// Update weights
optimizer.step(model.parameters());
}

std::cout << "Epoch " << epoch + 1 << "/" << epochs << ", Loss: " << total_loss / train_inputs.size() << std::endl;

// Evaluate test accuracy every 10 epochs and on the last epoch
if (epoch % 10 == 0 || epoch == epochs - 1)
{
int correct = 0;
for (size_t i = 0; i < test_inputs.size(); ++i)
{
// Forward pass in evaluation mode (e.g., no dropout)
auto predictions = model.forward(test_inputs[i], false);

// Find predicted class (the index with max value)
int predicted_class = 0;
double max_value = predictions[0]->data;
for (size_t j = 1; j < predictions.size(); ++j)
{
if (predictions[j]->data > max_value)
{
max_value = predictions[j]->data;
predicted_class = static_cast<int>(j);
}
}

// Check if prediction matches the target
for (size_t j = 0; j < test_targets[i].size(); ++j)
{
if (test_targets[i][j]->data == 1.0 && j == predicted_class)
{
correct++;
break;
}
}
}

double accuracy = static_cast<double>(correct) / test_inputs.size();
std::cout << "Epoch " << epoch + 1 << ": Test Accuracy = " << accuracy * 100.0 << "%" << std::endl;
}
}

// Define the model and hyperparameters
// MLP model(4, {10, 10, 3});
MLP model(4, {16, 16, 3});
double learning_rate = 0.001;
int epochs = 300;
// Train and evaluate the model
train_eval(df, TRAIN_SIZE, model, learning_rate, epochs);
return 0;
}

/*
Notes
-----------
g++ -std=c++17 -Iinclude -O2 -o main main.cpp
// or
make run
g++ -std=c++20 -Iinclude -O2 -g -o main easy_df.cpp
g++ -std=c++20 -Iinclude -g -O0 -o main easy_df.cpp
lldb ./main
r
bt
... g++ -std=c++20 -fsanitize=address -g -o main main.cpp
Address Sanitizer will provide detailed error messages if there are invalid memory accesses.
g++ -std=c++20 -fsanitize=address -Iinclude -g -O0 -o main easy_df.cpp
./main
*/
}

0 comments on commit 48f05ed

Please sign in to comment.