Proyecto Final - Turinmachin
Recreación del minijuego de matemáticas de Brain-Age usando redes neuronales
Loading...
Searching...
No Matches
neural_network.h
Go to the documentation of this file.
1#ifndef PROG3_NN_FINAL_PROJECT_V2025_01_NEURAL_NETWORK_H
2#define PROG3_NN_FINAL_PROJECT_V2025_01_NEURAL_NETWORK_H
3
4#include <iostream>
5#include <memory>
6#include <numeric>
7#include <random>
8#include "interfaces.h"
9#include "optimizer.h"
12
13namespace utec::neural_network {
15 constexpr std::uint8_t FORMAT_CURRENT_VERSION = 1;
16
21 template <typename T>
24 std::vector<std::unique_ptr<ILayer<T>>> layers;
25
26 public:
31
39 template <typename L, typename... Args>
40 void add_layer(Args&&... args) {
41 layers.emplace_back(std::make_unique<L>(std::forward<Args>(args)...));
42 }
43
64 template <template <typename...> class LossType,
65 template <typename...> class OptimizerType = SGD>
67 const algebra::Tensor<T, 2>& y,
68 const size_t epochs,
69 const size_t batch_size,
70 T learning_rate,
71 std::mt19937& rng) {
72 OptimizerType<T> optimizer(learning_rate);
73 const size_t num_samples = x.shape()[0];
74
75 std::vector<size_t> indices(num_samples);
76 std::ranges::iota(indices, 0);
77
78 for (size_t epoch = 0; epoch < epochs; ++epoch) {
79 if (epoch % 100 == 0) {
80 std::cout << "Epoch " << epoch << '\n';
81 }
82
83 std::ranges::shuffle(indices, rng);
84
85 for (size_t batch_start = 0; batch_start < num_samples; batch_start += batch_size) {
86 size_t current_batch_size = std::min(batch_size, num_samples - batch_start);
87
88 algebra::Tensor<T, 2> batch_x(current_batch_size, x.shape()[1]);
89 algebra::Tensor<T, 2> batch_y(current_batch_size, y.shape()[1]);
90
91 for (size_t i = 0; i < current_batch_size; ++i) {
92 batch_x.set_row(i, x.row(indices[batch_start + i]));
93 batch_y.set_row(i, y.row(indices[batch_start + i]));
94 }
95
96 algebra::Tensor<T, 2> output = batch_x;
97 for (auto& layer : layers) {
98 output = layer->forward(output);
99 }
100
101 LossType<T> loss_function(output, batch_y);
102 algebra::Tensor<T, 2> grad = loss_function.loss_gradient();
103
104 for (auto layer = layers.rbegin(); layer != layers.rend(); ++layer) {
105 grad = (*layer)->backward(grad);
106 (*layer)->update_params(optimizer);
107 }
108 }
109 }
110 }
111
119 algebra::Tensor<T, 2> output = X;
120 for (auto& layer : layers) {
121 output = layer->forward(output);
122 }
123 return output;
124 }
125
131 void save(std::ostream& out) const {
132 out.put(FORMAT_CURRENT_VERSION);
133 out.put(static_cast<std::uint8_t>(sizeof(T)));
134
135 serialization::write_numeric(out, static_cast<std::uint64_t>(layers.size()));
136
137 for (const auto& layer : layers) {
138 out.put(static_cast<std::uint8_t>(layer->id()));
139 layer->save(out);
140 }
141 }
142
150 static auto load(std::istream& in) -> NeuralNetwork<T> {
151 const int version = in.get();
152 if (version != FORMAT_CURRENT_VERSION) {
153 throw std::runtime_error("Invalid file format version: " + std::to_string(version));
154 }
155
156 const std::size_t t_size = in.get();
157 if (t_size != sizeof(T)) {
158 throw std::runtime_error(
159 "Stored data size does not match this platform's data size.");
160 }
161
162 const auto layers_size = serialization::read_numeric<std::uint64_t>(in);
163
165 net.layers.reserve(layers_size);
166
167 for (std::size_t i = 0; i < layers_size; ++i) {
168 const int id_raw = in.get();
169 const auto id = static_cast<LayerId>(id_raw);
170
171 net.layers.push_back(LayerRegistry<T>::create(id, in));
172 }
173
174 return net;
175 }
176 };
177} // namespace utec::neural_network
178
179#endif
return p * x
Definition catch_amalgamated.cpp:321
NeuralNetwork()
Constructor por defecto.
Definition neural_network.h:28
Representa un tensor de tipo T y rango Rank.
Definition tensor.h:63
auto shape() const noexcept -> const std::array< size_t, Rank > &
Definition tensor.h:179
auto row(const size_t index) const -> Tensor< T, 2 > requires(Rank==2)
Genera tensor con fila particular.
Definition tensor.h:223
void set_row(const size_t index, const Tensor< T, 2 > &row_tensor)
Cambia fila especifica de un tensor.
Definition tensor.h:243
static auto create(LayerId id, std::istream &in) -> std::unique_ptr< ILayer< T > >
Crea una instancia de una capa registrada a partir de su ID. Busca la función asociada al ID proporci...
Definition layer_registry.h:46
void save(std::ostream &out) const
Guarda el modelo en un flujo de salida binario.
Definition neural_network.h:131
NeuralNetwork()
Constructor por defecto.
Definition neural_network.h:28
static auto load(std::istream &in) -> NeuralNetwork< T >
Carga una red neuronal desde un flujo de entrada binario.
Definition neural_network.h:150
void add_layer(Args &&... args)
Agrega una nueva capa a la red.
Definition neural_network.h:40
auto predict(const algebra::Tensor< T, 2 > &X) -> algebra::Tensor< T, 2 >
Realiza una predicción sobre un conjunto de datos.
Definition neural_network.h:118
void train(const algebra::Tensor< T, 2 > &x, const algebra::Tensor< T, 2 > &y, const size_t epochs, const size_t batch_size, T learning_rate, std::mt19937 &rng)
Entrena la red neuronal usando descenso por lotes.
Definition neural_network.h:66
Optimizador Stochastic Gradient Descent (SGD). Actualiza los parámetros en dirección opuesta al gradi...
Definition optimizer.h:14
auto read_numeric(std::istream &in) -> T
Definition serialization.h:17
void write_numeric(std::ostream &out, const T n)
Definition serialization.h:9
Capa de activación de Rectified Linear Unit (ReLU). Los valores negativos del input se convierten en ...
Definition activation.h:14
LayerId
Identificador para los diferentes tipos de capas en la red neuronal. Se emplea uint8_t (unsigned 8-bi...
Definition interfaces.h:11
constexpr std::uint8_t FORMAT_CURRENT_VERSION
Versión actual del formato .pp20 (Profe Pónganos 20).
Definition neural_network.h:15
void register_all_layers()
Registra todas las capas disponibles en el sistema. Llamado al inicio del programa para asegurar que ...
Definition layer_registry.h:75