1#ifndef PROG3_NN_FINAL_PROJECT_V2025_01_KAN_H
2#define PROG3_NN_FINAL_PROJECT_V2025_01_KAN_H
30 auto eval(T
x)
const -> std::vector<T> {
31 std::vector<T> B(
knots, T{0});
43 const auto i =
static_cast<size_t>(pos);
53 class Kan final :
public ILayer<T> {
62 algebra::Tensor<T, 3> psi_weights;
63 algebra::Tensor<T, 2> phi_weights;
64 algebra::Tensor<T, 2> phi_biases;
66 algebra::Tensor<T, 3> gradient_psi_weights;
67 algebra::Tensor<T, 2> gradient_phi_weights;
68 algebra::Tensor<T, 2> gradient_phi_biases;
70 algebra::Tensor<T, 2> input;
71 algebra::Tensor<T, 3> psi_output;
72 algebra::Tensor<T, 2> psi_sum;
77 Kan(
const size_t in_f,
84 width((2 * in_f) + 1),
88 psi_weights(width, in_f, knots),
89 phi_weights(out_f, width),
91 gradient_psi_weights(width, in_f, knots),
92 gradient_phi_weights(out_f, width),
93 gradient_phi_biases(1, out_f),
97 basis(knots, x_min, x_max) {}
99 Kan(
const size_t in_f,
105 :
Kan(in_f, out_f, knots) {
106 init_psi_w_fun(psi_weights);
107 init_phi_w_fun(phi_weights);
108 init_phi_b_fun(phi_biases);
113 const size_t B =
x.shape()[0];
115 psi_output.reshape(B, width, in_f);
116 psi_sum.reshape(B, width);
118 for (
size_t b = 0; b < B; ++b) {
119 for (
size_t q = 0; q < width; ++q) {
121 for (
size_t p = 0;
p < in_f; ++
p) {
122 auto&& Bk = basis.eval(
x(b,
p));
124 for (
size_t k = 0; k < knots; ++k) {
125 acc += psi_weights(q,
p, k) * Bk[k];
127 psi_output(b, q,
p) = acc;
130 psi_sum(b, q) = sum_q;
134 auto phi_w_T = phi_weights.transpose_2d();
137 for (
size_t b = 0; b < B; ++b) {
138 for (
size_t j = 0; j < out_f; ++j) {
139 out(b, j) += phi_biases(0, j);
147 const size_t B = input.shape()[0];
152 gradient_phi_biases.fill(0);
153 for (
size_t j = 0; j < out_f; ++j) {
154 for (
size_t b = 0; b < B; ++b) {
155 gradient_phi_biases(0, j) += dZ(b, j);
161 gradient_psi_weights.fill(0);
165 for (
size_t b = 0; b < B; ++b) {
166 for (
size_t q = 0; q < width; ++q) {
167 const T dPs = DPsiSum(b, q);
168 for (
size_t p = 0;
p < in_f; ++
p) {
169 auto&& Bk = basis.eval(input(b,
p));
171 for (
size_t k = 0; k < knots; ++k) {
172 const T B_val = Bk[k];
173 gradient_psi_weights(q,
p, k) += dPs * B_val;
174 weighted_sum += psi_weights(q,
p, k) * B_val;
176 dInput(b,
p) += dPs * weighted_sum;
185 for (
size_t q = 0; q < width; ++q) {
186 auto psi_slice = psi_weights.slice(q);
187 auto grad_slice = gradient_psi_weights.slice(q);
188 optimizer.
update(psi_slice, grad_slice);
189 psi_weights.set_slice(q, psi_slice);
191 optimizer.
update(phi_weights, gradient_phi_weights);
192 optimizer.
update(phi_biases, gradient_phi_biases);
199 void save(std::ostream& out)
const override {
206 for (
const auto&
x : psi_weights) {
210 for (
const auto&
x : phi_weights) {
214 for (
const auto&
x : phi_biases) {
226 Kan<T> layer(in_feat, out_feat, knots, a, b);
227 for (
auto&
x : layer.psi_weights) {
231 for (
auto&
x : layer.phi_weights) {
235 for (
auto&
x : layer.phi_biases) {
return p * x
Definition catch_amalgamated.cpp:321
double p
Definition catch_amalgamated.cpp:251
Kan(const size_t in_f, const size_t out_f, const size_t knots, const T x_min=-1, const T x_max=+1)
Definition kan.h:77
Representa un tensor de tipo T y rango Rank.
Definition tensor.h:63
void fill(const T &value) noexcept
Llena la data de un tesor con un valor.
Definition tensor.h:213
void update_params(IOptimizer< T > &optimizer) override
Actualiza los parámetros internos de la capa (si tiene).
Definition kan.h:184
Kan(const size_t in_f, const size_t out_f, const size_t knots, auto init_psi_w_fun, auto init_phi_w_fun, auto init_phi_b_fun)
Definition kan.h:99
Kan(const size_t in_f, const size_t out_f, const size_t knots, const T x_min=-1, const T x_max=+1)
Definition kan.h:77
static auto load(std::istream &in) -> Kan< T >
Definition kan.h:219
void save(std::ostream &out) const override
Guarda los parámetros internos de la capa en un flujo binario.
Definition kan.h:199
auto backward(const algebra::Tensor< T, 2 > &dZ) -> algebra::Tensor< T, 2 > override
Propagación hacia atrás de la capa.
Definition kan.h:146
auto id() const -> LayerId override
Devuelve el tipo de la capa. Sirve para serialización o reconstrucción de la red.
Definition kan.h:195
auto forward(const algebra::Tensor< T, 2 > &x) -> algebra::Tensor< T, 2 > override
Propagación hacia adelante de la capa.
Definition kan.h:111
auto read_numeric(std::istream &in) -> T
Definition serialization.h:17
void write_numeric(std::ostream &out, const T n)
Definition serialization.h:9
constexpr auto matrix_product(const Tensor< T, 2 > &lhs, const Tensor< T, 2 > &rhs) -> Tensor< T, 2 >
Realiza producto matricial entre 2 tensores de dimension 2.
Definition tensor.h:563
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
@ Kan
Definition interfaces.h:16
T inv_step
Definition kan.h:21
T step
Definition kan.h:20
auto eval(T x) const -> std::vector< T >
Definition kan.h:30
T x_max
Definition kan.h:18
T x_min
Definition kan.h:17
size_t knots
Definition kan.h:15
BSpline(size_t knots, T a, T b)
Definition kan.h:23
Interfaz para definir un optimizador (ej. SGD, Adam, ...). Un optimizador se encarga de actualizar lo...
Definition interfaces.h:26
virtual void update(algebra::Tensor< T, 2 > ¶ms, const algebra::Tensor< T, 2 > &gradients)=0
Actualiza los parámetros del modelo usando los gradientes.