main
Brett 2024-10-21 19:25:00 -04:00
parent d6b96ce14f
commit 86aff4d2e9
39 changed files with 879 additions and 648 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.28) cmake_minimum_required(VERSION 3.25)
project(COSC-4P80-Assignment-2 VERSION 0.0.2) project(COSC-4P80-Assignment-2 VERSION 0.0.2)
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)

View File

@ -19,6 +19,8 @@
#ifndef COSC_4P80_ASSIGNMENT_2_COMMON_H #ifndef COSC_4P80_ASSIGNMENT_2_COMMON_H
#define COSC_4P80_ASSIGNMENT_2_COMMON_H #define COSC_4P80_ASSIGNMENT_2_COMMON_H
#include <Eigen/Dense>
namespace assign2 namespace assign2
{ {
struct data_t struct data_t
@ -31,6 +33,13 @@ namespace assign2
{ {
std::vector<data_t> data_points; std::vector<data_t> data_points;
}; };
class layer_t;
class network_t;
using Scalar = float;
using matrix_t = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
using vector_t = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
} }
#endif //COSC_4P80_ASSIGNMENT_2_COMMON_H #endif //COSC_4P80_ASSIGNMENT_2_COMMON_H

View File

@ -0,0 +1,53 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef COSC_4P80_ASSIGNMENT_2_FUNCTIONS_H
#define COSC_4P80_ASSIGNMENT_2_FUNCTIONS_H
#include <assign2/common.h>
#include <cmath>
namespace assign2
{
struct sigmoid_function
{
[[nodiscard]] Scalar call(Scalar s) const // NOLINT
{
return 1 / (1 + std::exp(-s));
}
[[nodiscard]] Scalar derivative(Scalar s) const
{
return call(s) * (1 - call(s));
}
vector_t operator()(vector_t out) const
{
for (auto& v : out)
v = call(v);
return out;
}
};
struct linear_function
{
};
}
#endif //COSC_4P80_ASSIGNMENT_2_FUNCTIONS_H

View File

@ -0,0 +1,78 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef COSC_4P80_ASSIGNMENT_2_INITIALIZERS_H
#define COSC_4P80_ASSIGNMENT_2_INITIALIZERS_H
#include <blt/std/types.h>
#include <blt/std/random.h>
#include <assign2/common.h>
namespace assign2
{
struct empty_init
{
template<int rows, int columns>
inline void operator()(Eigen::Matrix<Scalar, rows, columns>& matrix) const
{
for (auto r : matrix.rowwise())
{
for (auto& v : r)
v = 0;
}
}
};
struct half_init
{
template<int rows, int columns>
inline void operator()(Eigen::Matrix<Scalar, rows, columns>& matrix) const
{
for (auto r : matrix.rowwise())
{
for (auto& v : r)
v = 0.5f;
}
}
};
struct random_init
{
public:
explicit random_init(blt::size_t seed, float min = 0.5 - 0.125, float max = 0.5 + 0.125): seed(seed), min(min), max(max)
{}
template<int rows, int columns>
inline void operator()(Eigen::Matrix<Scalar, rows, columns>& matrix) const
{
blt::random::random_t random(seed);
for (auto r : matrix.rowwise())
{
for (auto& v : r)
v = random.get_float(min, max);
}
}
private:
blt::size_t seed;
float min, max;
};
}
#endif //COSC_4P80_ASSIGNMENT_2_INITIALIZERS_H

View File

@ -19,35 +19,43 @@
#ifndef COSC_4P80_ASSIGNMENT_2_LAYER_H #ifndef COSC_4P80_ASSIGNMENT_2_LAYER_H
#define COSC_4P80_ASSIGNMENT_2_LAYER_H #define COSC_4P80_ASSIGNMENT_2_LAYER_H
#include <Eigen/Dense>
#include <blt/std/types.h> #include <blt/std/types.h>
#include <assign2/initializers.h>
namespace assign2 namespace assign2
{ {
class layer_t class layer_t
{ {
public: public:
using matrix_t = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>;
using vector_t = Eigen::Matrix<float, Eigen::Dynamic, 1>;
layer_t(const blt::i32 in, const blt::i32 out): in_size(in), out_size(out) layer_t(const blt::i32 in, const blt::i32 out): in_size(in), out_size(out)
{} {}
template<typename WeightsFunc = empty_init, typename BiasFunc = empty_init>
void init(WeightsFunc weightFunc = empty_init{}, BiasFunc biasFunc = empty_init{})
{
weights.resize(in_size, out_size);
bias.resize(out_size);
weightFunc(weights);
biasFunc(bias);
}
template<typename ActFunction> template<typename ActFunction>
vector_t forward(const vector_t & in, ActFunction func = ActFunction{}) vector_t call(const vector_t& in, ActFunction func = ActFunction{})
{ {
vector_t out; vector_t out;
out.resize(out_size, Eigen::NoChange_t{}); out.resize(out_size, Eigen::NoChange_t{});
out.noalias() = weights.transpose() * in; out.noalias() = weights.transpose() * in;
out.colwise() += bias; out.colwise() += bias;
return func(out); return func(std::move(out));
} }
private: private:
const blt::i32 in_size, out_size; const blt::i32 in_size, out_size;
matrix_t weights{}; matrix_t weights{};
matrix_t dweights{}; // derivative of weights
vector_t bias{}; vector_t bias{};
vector_t dbias{}; // derivative of bias
}; };
} }

51
include/assign2/network.h Normal file
View File

@ -0,0 +1,51 @@
#pragma once
/*
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef COSC_4P80_ASSIGNMENT_2_NETWORK_H
#define COSC_4P80_ASSIGNMENT_2_NETWORK_H
#include <assign2/common.h>
#include <assign2/layer.h>
namespace assign2
{
class network_t
{
public:
network_t(blt::i32 input_size, blt::i32 output_size, blt::i32 hidden_count, blt::i32 hidden_size):
input_size(input_size), output_size(output_size), hidden_count(hidden_count), hidden_size(hidden_size)
{
if (hidden_count > 0)
{
layers.push_back(layer_t{input_size, hidden_size});
for (blt::i32 i = 0; i < hidden_count; i++)
layers.push_back(layer_t{hidden_size, hidden_size});
layers.push_back(layer_t{hidden_size, output_size});
} else
{
}
}
private:
blt::i32 input_size, output_size, hidden_count, hidden_size;
std::vector<layer_t> layers;
};
}
#endif //COSC_4P80_ASSIGNMENT_2_NETWORK_H

0
lib/eigen-3.4.0/Eigen/src/Core/Assign_MKL.h Executable file → Normal file
View File

View File

0
lib/eigen-3.4.0/Eigen/src/Core/arch/SSE/PacketMath.h Executable file → Normal file
View File

View File

0
lib/eigen-3.4.0/Eigen/src/Core/util/BlasUtil.h Executable file → Normal file
View File

View File

0
lib/eigen-3.4.0/Eigen/src/Core/util/MKL_support.h Executable file → Normal file
View File

0
lib/eigen-3.4.0/Eigen/src/Core/util/Meta.h Executable file → Normal file
View File

0
lib/eigen-3.4.0/Eigen/src/misc/lapacke.h Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/bench_multi_compilers.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/bench_unrolling Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/benchmark_suite Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/btl/data/go_mean Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/btl/data/mk_new_gnuplot.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/btl/data/smooth_all.sh Executable file → Normal file
View File

View File

0
lib/eigen-3.4.0/bench/perf_monitoring/make_plot.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/perf_monitoring/run.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/perf_monitoring/runall.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/bench/tensors/eigen_sycl_bench.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/blas/testing/runblastest.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/scripts/check.in Executable file → Normal file
View File

0
lib/eigen-3.4.0/scripts/debug.in Executable file → Normal file
View File

0
lib/eigen-3.4.0/scripts/eigen_monitor_perf.sh Executable file → Normal file
View File

0
lib/eigen-3.4.0/scripts/release.in Executable file → Normal file
View File

View File

View File

View File

@ -4,6 +4,8 @@
#include <assign2/common.h> #include <assign2/common.h>
#include <filesystem> #include <filesystem>
#include "blt/iterator/enumerate.h" #include "blt/iterator/enumerate.h"
#include <assign2/layer.h>
#include <assign2/functions.h>
using namespace assign2; using namespace assign2;
@ -75,6 +77,36 @@ int main(int argc, const char** argv)
auto data_files = load_data_files(get_data_files(data_directory)); auto data_files = load_data_files(get_data_files(data_directory));
vector_t input;
input.resize(16);
for (auto f : data_files)
{
if (f.data_points.begin()->bins.size() == 16)
{
for (auto [i, b] : blt::enumerate(f.data_points.begin()->bins))
input(static_cast<Eigen::Index>(i)) = b;
}
}
random_init randomizer{619};
sigmoid_function sig;
layer_t layer1{16, 4};
layer_t layer2{4, 4};
layer_t layer3{4, 4};
layer_t layer_output{4, 1};
layer1.init(randomizer, empty_init{});
layer2.init(randomizer, empty_init{});
layer3.init(randomizer, empty_init{});
layer_output.init(randomizer, empty_init{});
auto output = layer1.call(input, sig);
output = layer2.call(output, sig);
output = layer3.call(output, sig);
output = layer_output.call(output, sig);
std::cout << output << std::endl;
// for (auto d : data_files) // for (auto d : data_files)
// { // {
// BLT_TRACE_STREAM << "\nSilly new file:\n"; // BLT_TRACE_STREAM << "\nSilly new file:\n";