Skip to content

Commit

Permalink
some more tests tests+ opt-
Browse files Browse the repository at this point in the history
  • Loading branch information
SermetPekin committed Dec 8, 2024
1 parent 7874199 commit 464a043
Show file tree
Hide file tree
Showing 10 changed files with 7,932 additions and 47 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ CXX = g++
CXXFLAGS = -std=c++20 -Iinclude -I/usr/local/include
LDFLAGS = -L/usr/local/lib -lgtest -lgtest_main -pthread

# CXXFLAGS = -std=c++20 -Iinclude -I/usr/local/include
# LDFLAGS = -L/usr/local/lib -lgtest -lgtest_main -pthread

CXXFLAGS += -fsanitize=address -g
LDFLAGS += -fsanitize=address


# Output binary for main program
TARGET = main

Expand Down
10 changes: 8 additions & 2 deletions easy_df.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#include "micrograd.hpp"

#include "value.hpp"
#include "mlp.hpp"


using namespace microgradCpp;

int main()
Expand All @@ -20,9 +25,10 @@ int main()
// Create MLP model
// Input: 4 features, hidden layers: [7,7], output: 3 classes
// Define the model and hyperparameters
// MLP model(4, {10, 10, 3});
MLP model(4, {10, 10, 3});
double learning_rate = 0.01;
int epochs = 2;
double learning_rate = 0.001;
int epochs = 100;
// Train and evaluate the model
train_eval(df, TRAIN_SIZE, model, learning_rate, epochs);

Expand Down
42 changes: 42 additions & 0 deletions include/data_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,48 @@ using namespace microgradCpp;
using vv_string = std::vector<std::vector<std::string>>;
using vv_double = std::vector<std::vector<double>>;



#include <iostream>
#include <iomanip>
#include <vector>
#include <memory>
#include "value.hpp"

inline
void display_data(const ColRows& inputs, const ColRows& targets, const std::vector<std::string>& column_names ) {
// Print column headers
for (const auto& col_name : column_names) {
std::cout << std::setw(15) << std::left << col_name;
}
std::cout << std::setw(15) << std::left << "target";
std::cout << "\n";

// Print separator line
for (size_t i = 0; i < column_names.size() + 1; ++i) {
std::cout << std::setw(15) << std::setfill('-') << "" << std::setfill(' ');
}
std::cout << "\n";

// Print rows of data
for (size_t i = 0; i < inputs.size(); ++i) {
for (const auto& value : inputs[i]) {
std::cout << std::setw(15) << std::left << value->data;
}

// Print the target
for (const auto& target : targets[i]) {
std::cout << std::setw(15) << std::left << target->data;
}

std::cout << "\n";
}

// Print final separator line
std::cout << "========================\n";
}


static inline v_shared_Value one_hot_encode(int class_index, int num_classes)
{

Expand Down
54 changes: 33 additions & 21 deletions include/linear.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,32 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/


#include "value.hpp"
#include <vector>
#include <random>
#include <memory>
#include <iostream>

class Linear {
class Linear
{
public:
int in_features, out_features;
std::vector<std::vector<std::shared_ptr<Value>>> weights;
std::vector<std::shared_ptr<Value>> biases;

Linear(int in_features, int out_features)
: in_features(in_features), out_features(out_features) {

: in_features(in_features), out_features(out_features)
{

std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dist(-1.0, 1.0);

for (int i = 0; i < out_features; ++i) {
for (int i = 0; i < out_features; ++i)
{
std::vector<std::shared_ptr<Value>> row;
for (int j = 0; j < in_features; ++j) {
for (int j = 0; j < in_features; ++j)
{
row.push_back(std::make_shared<Value>(dist(gen), "w"));
}
weights.push_back(row);
Expand All @@ -55,37 +58,46 @@ class Linear {
}

// Forward pass
std::vector<std::shared_ptr<Value>> forward(const std::vector<std::shared_ptr<Value>>& inputs) {
std::vector<std::shared_ptr<Value>> forward(const std::vector<std::shared_ptr<Value>> &inputs)
{

if (inputs.empty())
{
throw std::runtime_error("Empty input provided to Linear layer forward pass.");
}

std::vector<std::shared_ptr<Value>> outputs;
for (int i = 0; i < out_features; ++i) {
for (int i = 0; i < out_features; ++i)
{
auto activation = biases[i];
for (int j = 0; j < in_features; ++j) {
for (int j = 0; j < in_features; ++j)
{
activation = activation + (weights[i][j] * inputs[j]);
}
outputs.push_back(activation);
}

// Debugging: Print outputs
/* std::cout << "Linear Layer Activations: ";
for (const auto& output : outputs) {
std::cout << output->data << " ";
}
std::cout << std::endl;
*/
// Debugging: Print outputs
/* std::cout << "Linear Layer Activations: ";
for (const auto& output : outputs) {
std::cout << output->data << " ";
}
std::cout << std::endl;
*/
return outputs;
}

// Get all parameters (weights and biases)
std::vector<std::shared_ptr<Value>> parameters() const {
// Get all parameters (weights and biases)
std::vector<std::shared_ptr<Value>> parameters() const
{
std::vector<std::shared_ptr<Value>> params;
for (const auto& row : weights) {
for (const auto &row : weights)
{
params.insert(params.end(), row.begin(), row.end());
}
params.insert(params.end(), biases.begin(), biases.end());
return params;
}

};

#endif // LINEAR_HPP

6 changes: 6 additions & 0 deletions include/mlp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ class MLP

std::vector<std::shared_ptr<Value>> forward(const std::vector<std::shared_ptr<Value>> &inputs, bool training = true)
{

if (inputs.empty())
{
throw std::runtime_error("Empty input provided to MLP forward pass.");
}

auto activations = inputs;
for (size_t i = 0; i < layers.size(); ++i)
{
Expand Down
52 changes: 36 additions & 16 deletions include/train_eval.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "dataframe.hpp"
#include "types.hpp"
#include "datasetType.hpp"
#include "value.hpp"
#include "mlp.hpp"

using namespace microgradCpp;

Expand All @@ -34,6 +36,21 @@ using namespace microgradCpp;
// // test_targets = test_df.get_targets(); // Extract targets from test DataFrame
// }

inline std::vector<std::shared_ptr<Value>> one_hot_encodeLocal(int class_index, int num_classes)
{
std::vector<std::shared_ptr<Value>> target(num_classes, std::make_shared<Value>(0.0));
target[class_index] = std::make_shared<Value>(1.0);
return target;
}

inline void shuffleLocal(DatasetType &dataset)
{
std::random_device rd;
std::mt19937 gen(rd());
// gen.seed(42); // A fixed seed for reproducibility
std::shuffle(dataset.begin(), dataset.end(), gen);
}

// The updated train_eval function
inline void train_test_split(
const DataFrame &df,
Expand All @@ -49,17 +66,28 @@ inline void train_test_split(
DatasetType dataset;

dataset = convert_to_dataset(df);
shuffleLocal(dataset);

size_t train_size = static_cast<size_t>(dataset.size() * TRAIN_SIZE);

std::cout << "train_size : " << train_size;
// stop();
int num_classes = 3;
for (size_t i = 0; i < train_size; ++i)
{
train_inputs.push_back(dataset[i].first);
train_targets.push_back(dataset[i].second);

// train_targets.push_back(dataset[i].second);
int class_index = static_cast<int>(dataset[i].second[0]->data);
train_targets.push_back(one_hot_encodeLocal(class_index, num_classes));
}
for (size_t i = train_size; i < dataset.size(); ++i)
{
test_inputs.push_back(dataset[i].first);
test_targets.push_back(dataset[i].second);
// test_targets.push_back(dataset[i].second);

int class_index = static_cast<int>(dataset[i].second[0]->data);
test_targets.push_back(one_hot_encodeLocal(class_index, num_classes));
}
}
inline void print(const ColRows &colrows)
Expand Down Expand Up @@ -106,19 +134,16 @@ inline void train_eval(DataFrame &df, double train_size, MLP &model, double lr =

auto start = std::chrono::high_resolution_clock::now();

print(test_targets);
print(train_targets);
print(train_inputs);
print(test_inputs);
// throw std::runtime_error("[ok]");

// return std::EXIT_SUCCESS ;
v_string Dummy = {"aa", "bb"};
display_data(train_inputs, train_targets, Dummy);
std::cout << "=================================\n";
display_data(test_inputs, test_targets, Dummy);
// stop("...");

// Training loop
for (int epoch = 0; epoch < epochs; ++epoch)
{
double total_loss = 0.0;
std::cout << "[ Here it is ] ...Epoch " << epoch + 1 << "/" << epochs << ", Loss: " << total_loss / train_inputs.size() << std::endl;

size_t NUM_Training = train_inputs.size();

Expand All @@ -127,10 +152,6 @@ inline void train_eval(DataFrame &df, double train_size, MLP &model, double lr =

// Forward pass (training=true)
auto predictions = model.forward(train_inputs[i], true);
std::cout << "[ Here it is ] predictions ";

// int num_classes = predictions.size(); // Number of classes inferred from predictions
// v_shared_Value target = one_hot_encode(train_targets[i], num_classes); // Convert class index to one-hot

// Compute Cross-Entropy Loss
auto loss = Loss::cross_entropy(predictions, train_targets[i]);
Expand All @@ -144,8 +165,6 @@ inline void train_eval(DataFrame &df, double train_size, MLP &model, double lr =
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)
{
Expand All @@ -161,6 +180,7 @@ inline void train_eval(DataFrame &df, double train_size, MLP &model, double lr =
int predicted_class = std::distance(predictions.begin(), std::max_element(predictions.begin(), predictions.end()));

// Check if prediction matches the target
// if (test_targets[i][predicted_class]->data == 1.0)
if (test_targets[i][predicted_class]->data == 1.0)
{
correct++;
Expand Down
20 changes: 20 additions & 0 deletions test_output.dSYM/Contents/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.test_output</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
Loading

0 comments on commit 464a043

Please sign in to comment.