diff --git a/README.md b/README.md index ee9b45f..6a8583a 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,10 @@ int main() { std::vector ys; // ---------- INPUT ----------- | -------- OUTPUT --------- // - xs.push_back(Vec32::of({0, 0})); ys.push_back(Vec32::of({0})); - xs.push_back(Vec32::of({1, 0})); ys.push_back(Vec32::of({1})); - xs.push_back(Vec32::of({0, 1})); ys.push_back(Vec32::of({1})); - xs.push_back(Vec32::of({1, 1})); ys.push_back(Vec32::of({0})); + xs.push_back(Vec32::of(0, 0)); ys.push_back(Vec32::of(0)); + xs.push_back(Vec32::of(1, 0)); ys.push_back(Vec32::of(1)); + xs.push_back(Vec32::of(0, 1)); ys.push_back(Vec32::of(1)); + xs.push_back(Vec32::of(1, 1)); ys.push_back(Vec32::of(0)); auto network = SequentialBuilder::begin() .add(Linear32::create(2, 15)) diff --git a/docs/tutorials/Cheatsheet.md b/docs/tutorials/Cheatsheet.md index 8b057aa..a1b94df 100644 --- a/docs/tutorials/Cheatsheet.md +++ b/docs/tutorials/Cheatsheet.md @@ -16,6 +16,22 @@ Adam64 = Adam {Class}64 = {Class} = {Class} ``` +## Vectors + +Here are all the available operations using `Vector`: + +```{.cpp} +auto a = Vector::of(1, 2, 3); +auto b = Vector::of({2, 3, 4}); // a[i] == b[i]; + +a.size() // 3 +a.dot(b) // 1 * 2 + 2 * 3 + 3 * 4 = 20 +a.sum() // 6 +a *= 3 // a = {3, 6, 9} +a /= 2 // a = {1.5, 3, 4.5} +a[1] // 3 +``` + ## Layers Here's a full list of available layers: @@ -32,7 +48,7 @@ These are all implemented optimizers: ```{.cpp} auto simple = Optimizer32(network->parameters(), learningRate); auto sgdWithMomentum = SGD32(network->parameters(), learningRate, momentum = 0.9); -auto adam = Adam32(network->parameters(), learningRate, beta1 = 0.9, beta2=0.999, epsilon=1e-8); +auto adam = Adam32(network->parameters(), learningRate, beta1 = 0.9, beta2 = 0.999, epsilon = 1e-8); ``` ## Loss functions diff --git a/docs/tutorials/GetStarted.md b/docs/tutorials/GetStarted.md index f750ee4..e426608 100644 --- a/docs/tutorials/GetStarted.md +++ b/docs/tutorials/GetStarted.md @@ -79,21 +79,24 @@ If you want some refreshment on derivatives, check out [this wonderful video](ht Multiple scalars can be grouped together in a `Vector` to simplify operating on them. Input to any `Module` (more on them later) is a `Vector`. This abstraction provides some functionality that allows you to compute, for example a dot product. ```{.cpp} -// The easiest way to create a Vector -auto a = Vector::of({1, 2, 3}); +// The easiest way to create e Vector +auto a = Vector::of(1, 2, 3); + +// A bit more annoying way to create a Vector +auto b = Vector::of({1, 2, 3}); // The hard way to create a Vector -auto b = Vector(Value::create(2), Value::create(3), Value::create(4)); +auto c = Vector(Value::create(2), Value::create(3), Value::create(4)); // You can access elements in a vector -auto c = Vector::of({a[0]*b[0], a[1]*b[1], a[2]*b[2]}); +auto d = Vector::of({a[0]*b[0], a[1]*b[1], a[2]*b[2]}); // And even iterate over it -for(auto &entry : c) - std::cout << c << std::endl; // prints: 2 6 12 +for(auto &entry : d) + std::cout << entry << std::endl; // prints: 2 6 12 -auto d = a.dot(b) // c = 1 * 2 + 2 * 3 + 3 * 4 = 20 -d->backward(); // You can compute of this result since it's a scalar! +auto e = b.dot(c) // c = 1 * 2 + 2 * 3 + 3 * 4 = 20 +e->backward(); // You can compute of this result since it's a scalar! ``` `Vectors` are very useful since this is the way both the input and output data is represented. Each sample consits of an input `Vector` and a target output `Vector`. @@ -169,10 +172,10 @@ std::vector xs; std::vector ys; // ---------- INPUT ----------- | -------- OUTPUT --------- // -xs.push_back(Vec32::of({0, 0})); ys.push_back(Vec32::of({0})); -xs.push_back(Vec32::of({1, 0})); ys.push_back(Vec32::of({1})); -xs.push_back(Vec32::of({0, 1})); ys.push_back(Vec32::of({1})); -xs.push_back(Vec32::of({1, 1})); ys.push_back(Vec32::of({0})); +xs.push_back(Vec32::of(0, 0)); ys.push_back(Vec32::of(0)); +xs.push_back(Vec32::of(1, 0)); ys.push_back(Vec32::of(1)); +xs.push_back(Vec32::of(0, 1)); ys.push_back(Vec32::of(1)); +xs.push_back(Vec32::of(1, 1)); ys.push_back(Vec32::of(0)); ``` ### Neural Network diff --git a/examples/xor_classification.cpp b/examples/xor_classification.cpp index 9a0e238..49abd45 100644 --- a/examples/xor_classification.cpp +++ b/examples/xor_classification.cpp @@ -8,10 +8,10 @@ int main() { std::vector ys; // ---------- INPUT ----------- | -------- OUTPUT --------- // - xs.push_back(Vec32::of({0, 0})); ys.push_back(Vec32::of({1, 0})); - xs.push_back(Vec32::of({1, 0})); ys.push_back(Vec32::of({0, 1})); - xs.push_back(Vec32::of({0, 1})); ys.push_back(Vec32::of({0, 1})); - xs.push_back(Vec32::of({1, 1})); ys.push_back(Vec32::of({1, 0})); + xs.push_back(Vec32::of(0, 0)); ys.push_back(Vec32::of(1, 0)); + xs.push_back(Vec32::of(1, 0)); ys.push_back(Vec32::of(0, 1)); + xs.push_back(Vec32::of(0, 1)); ys.push_back(Vec32::of(0, 1)); + xs.push_back(Vec32::of(1, 1)); ys.push_back(Vec32::of(1, 0)); auto mlp = SequentialBuilder::begin() .add(Linear32::create(2, 15)) diff --git a/examples/xor_regression.cpp b/examples/xor_regression.cpp index 46be3e9..61d6630 100644 --- a/examples/xor_regression.cpp +++ b/examples/xor_regression.cpp @@ -9,10 +9,10 @@ int main() { std::vector ys; // ---------- INPUT ----------- | -------- OUTPUT --------- // - xs.push_back(Vec32::of({0, 0})); ys.push_back(Vec32::of({0})); - xs.push_back(Vec32::of({1, 0})); ys.push_back(Vec32::of({1})); - xs.push_back(Vec32::of({0, 1})); ys.push_back(Vec32::of({1})); - xs.push_back(Vec32::of({1, 1})); ys.push_back(Vec32::of({0})); + xs.push_back(Vec32::of(0, 0)); ys.push_back(Vec32::of(0)); + xs.push_back(Vec32::of(1, 0)); ys.push_back(Vec32::of(1)); + xs.push_back(Vec32::of(0, 1)); ys.push_back(Vec32::of(1)); + xs.push_back(Vec32::of(1, 1)); ys.push_back(Vec32::of(0)); auto network = SequentialBuilder::begin() .add(Linear32::create(2, 15)) diff --git a/include/core/Vector.hpp b/include/core/Vector.hpp index e730cb9..9b0b7bf 100644 --- a/include/core/Vector.hpp +++ b/include/core/Vector.hpp @@ -28,6 +28,8 @@ template class Vector { Vector(std::vector> values); static Vector of(const std::vector &values); + template static Vector of(const Args &...args); + ValuePtr dot(const Vector &other) const; ValuePtr sum() const; size_t size() const; @@ -73,6 +75,15 @@ template Vector Vector::of(const std::vector &values) { return valuePtrs; } +template template Vector Vector::of(const Args &...args) { + std::vector> valuePtrs; + valuePtrs.reserve(sizeof...(args)); + + (valuePtrs.emplace_back(Value::create(args)), ...); + + return Vector(valuePtrs); +} + template size_t Vector::size() const { return _values.size(); } template ValuePtr Vector::dot(const Vector &other) const { @@ -96,12 +107,12 @@ template ValuePtr Vector::sum() const { } template Vector operator/(Vector x, T val) { - x /= val; + x *= Value::create(val); return x; } template Vector operator*(Vector x, T val) { - x *= val; + x *= Value::create(val); return x; }