Neural Network
Started on implementing neural network from NNFS. I've done ReLU and stopped at p.104. Softmax is not ready.
This commit is contained in:
@@ -2,12 +2,16 @@
|
||||
#define _matrix_n_
|
||||
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/random.h"
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
namespace utils{
|
||||
@@ -25,6 +29,72 @@ public:
|
||||
: rows_(rows), cols_(cols), data_(rows * cols, value) {}
|
||||
|
||||
|
||||
// Construct from list-of-lists:
|
||||
// utils::Mf A{{1,2,3}, {4,5,6}};
|
||||
Matrix(std::initializer_list<std::initializer_list<T>> init) {
|
||||
rows_ = static_cast<uint64_t>(init.size());
|
||||
if (rows_ > 0) {
|
||||
cols_ = static_cast<uint64_t>(init.begin()->size());
|
||||
} else {
|
||||
cols_ = 0;
|
||||
}
|
||||
|
||||
// Validate all rows have the same length
|
||||
for (const auto& row : init) {
|
||||
if (row.size() != cols_) {
|
||||
throw std::runtime_error("Matrix(list of lists): ragged rows");
|
||||
}
|
||||
}
|
||||
|
||||
data_.resize(rows_ * cols_);
|
||||
uint64_t r = 0;
|
||||
for (uint64_t i = 0; i < init.size(); ++i, ++r){
|
||||
const std::initializer_list<T>& row = *(init.begin() + i);
|
||||
|
||||
uint64_t c = 0;
|
||||
for (uint64_t j = 0; j < row.size(); ++j, ++c){
|
||||
const T& val = *(row.begin() + j);
|
||||
data_[r * cols_ + c] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Assign from list-of-lists after default construction:
|
||||
// utils::Md M; M = {{1,2},{3,4}};
|
||||
Matrix& operator=(std::initializer_list<std::initializer_list<T>> init) {
|
||||
// Set sizes
|
||||
rows_ = static_cast<uint64_t>(init.size());
|
||||
if (rows_ > 0) {
|
||||
cols_ = static_cast<uint64_t>((init.begin())->size());
|
||||
} else {
|
||||
cols_ = 0;
|
||||
}
|
||||
|
||||
// Validate: all rows must have same length
|
||||
for (uint64_t i = 0; i < rows_; ++i) {
|
||||
const std::initializer_list<T>& row = *(init.begin() + i);
|
||||
if (row.size() != cols_) {
|
||||
throw std::runtime_error("Matrix(list of lists): ragged rows");
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate storage
|
||||
data_.resize(rows_ * cols_);
|
||||
|
||||
// Copy data row by row
|
||||
for (uint64_t i = 0; i < rows_; ++i) {
|
||||
const std::initializer_list<T>& row = *(init.begin() + i);
|
||||
for (uint64_t j = 0; j < cols_; ++j) {
|
||||
const T& val = *(row.begin() + j);
|
||||
data_[i * cols_ + j] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//# MATRIX: basic properties #
|
||||
uint64_t rows() const noexcept {return rows_;}
|
||||
uint64_t cols() const noexcept {return cols_;}
|
||||
@@ -45,6 +115,20 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void random(uint64_t rows, uint64_t cols, const T& lower, const T& higher){
|
||||
rows_ = rows;
|
||||
cols_ = cols;
|
||||
data_.resize(rows_*cols_, 0);
|
||||
|
||||
// Copy data row by row
|
||||
for (uint64_t i = 0; i < rows_; ++i) {
|
||||
for (uint64_t j = 0; j < cols_; ++j) {
|
||||
data_[i * cols_ + j] = utils::random(lower, higher);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//# MATRIX: row helpers (copy out) #
|
||||
// Read whole row as an owning Vector<T>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "./core/omp_config.h"
|
||||
#include <random>
|
||||
|
||||
namespace utils{
|
||||
|
||||
// Shared engine
|
||||
inline std::mt19937& rng() {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
return gen;
|
||||
}
|
||||
|
||||
// Integral overload
|
||||
template <
|
||||
typename T,
|
||||
typename std::enable_if<std::is_integral<T>::value, int>::type = 0
|
||||
>
|
||||
T random(T low, T high) {
|
||||
std::uniform_int_distribution<T> dist(low, high);
|
||||
return dist(rng());
|
||||
}
|
||||
|
||||
// Floating-point overload
|
||||
template <
|
||||
typename T,
|
||||
typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0
|
||||
>
|
||||
T random(T low, T high) {
|
||||
std::uniform_real_distribution<T> dist(low, high);
|
||||
return dist(rng());
|
||||
}
|
||||
|
||||
|
||||
} // end namespace utils
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
|
||||
#include "./utils/vector.h"
|
||||
#include "./utils/matrix.h"
|
||||
#include "./utils/generators.h"
|
||||
#include "./utils/generators.h"
|
||||
#include "./utils/random.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <vector>
|
||||
#include <random>
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
@@ -31,6 +33,9 @@ public:
|
||||
v.resize(size, value);
|
||||
}
|
||||
|
||||
// Construct from a braced list: utils::Vf v{1,2,3};
|
||||
Vector(std::initializer_list<T> init) : v(init) {}
|
||||
|
||||
|
||||
|
||||
//##########################################################
|
||||
@@ -47,6 +52,13 @@ public:
|
||||
// a = vector[2];
|
||||
const T& operator[](uint64_t idx) const { return v[idx]; }
|
||||
|
||||
|
||||
// Assign from a braced list after default construction:
|
||||
Vector& operator=(std::initializer_list<T> init) {
|
||||
v = init;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// vector.size();
|
||||
uint64_t size() const noexcept { return v.size(); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user