Skip to main content

Mini deep learning framework

Project description

Poliflow

Poliflow es un framework de Deep Learning desarrollado en Python desde cero, diseñado con fines educativos y de investigación.
Incluye tensores, capas neuronales, funciones de activación, optimizadores y entrenamiento de modelos.


Instalación

pip install poliflow

Características

  • Tensores personalizados
  • Redes neuronales
  • Capas Lineal
  • Funciones de activación
  • Función de pérdida
  • Optimizador
  • Entrenamiento de modelo
  • Predicción de datos

Ejemplo de un Tensor

Los Tensor son la base de Poliflow.
Permiten realizar operaciones matemáticas y calcular gradientes automáticamente mediante autograd.


Características principales

  • Soporte para operaciones matemáticas
  • Backpropagation automático
  • Compatible con NumPy
  • Grafo computacional dinámico
  • Operadores intuitivos (+, -, *, @, /)
  • Soporte para gradientes

Crear un Tensor

from poliflow.core.Tensor import Tensor

x = Tensor([1, 2, 3])

print(x)

Salida

Tensor(
  data=[1. 2. 3.],
  shape=(3,),
  requieres_grad=False
)

Explicación

Aquí se crea un tensor unidimensional a partir de una lista de Python.


Tensor con gradientes

Para entrenar redes neuronales normalmente necesitamos calcular derivadas.

from poliflow.core.Tensor import Tensor

x = Tensor([2.0], requieres_grad=True)

print(x)

Explicación

El parámetro:

requiere_grad=True

indica que Poliflow debe almacenar operaciones para calcular gradientes posteriormente.


Operaciones matemáticas

Los tensores soportan operaciones básicas.

from poliflow.core.Tensor import Tensor

a = Tensor([2.0], requieres_grad=True)
b = Tensor([3.0], requieres_grad=True)

c = a + b
d = a * b

print(c.data)
print(d.data)

Explicación

Poliflow construye automáticamente el grafo computacional de las operaciones.


Multiplicación matricial

También puedes trabajar con matrices.

from poliflow.core.Tensor import Tensor

x = Tensor([[1, 2]])
w = Tensor([[3], [4]])

y = x @ w

print(y.data)

Salida

Tensor([[11.]])

Explicación

El operador:

@

realiza multiplicación matricial.


Backpropagation automático

Poliflow puede calcular derivadas automáticamente.

from poliflow.core.Tensor import Tensor

x = Tensor([2.0], requieres_grad=True)

y = x * x
y.backward()

print(x.grad)

Salida

[4.]

Explicación

La función:

tiene derivada:

Cuando:

x = 2

el gradiente es:

4

Operaciones soportadas

Actualmente Poliflow soporta:

+
-
*
/
@
pow()
sum()
mean()
exp()
log()
abs()

Ejemplo completo

from poliflow import Tensor

# Datos de entrada
x = Tensor([2.0], requiere_grad=True)

# Peso
w = Tensor([3.0], requiere_grad=True)

# Bias
b = Tensor([1.0], requiere_grad=True)

# Forward
y = x * w + b

# Backward
y.backward()

print("Salida:", y.data)
print("Gradiente de x:", x.grad)
print("Gradiente de w:", w.grad)
print("Gradiente de b:", b.grad)

Explicación

Poliflow construye automáticamente un grafo computacional dinámico a partir de las operaciones entre tensores.

La operación realizada es:

y = xw + b

Sustituyendo valores:

y = (2)(3) + 1
y = 6 + 1
y = 7

Durante el forward, Poliflow guarda todas las operaciones realizadas:

x ----\
       (*) ---- (+) ---> y
w ----/          ^
                 |
                 b

Después, al ejecutar:

y.backward()

Poliflow aplica automáticamente backpropagation y calcula las derivadas de cada variable usando la regla de la cadena.

Gradiente respecto a x

Gradiente respecto a w

Gradiente respecto a b

Por lo tanto:

Salida: [7.]
Gradiente de x: [3.]
Gradiente de w: [2.]
Gradiente de b: [1.]

Esto permite entrenar modelos automáticamente mediante descenso por gradiente, igual que en frameworks de deep learning modernos.

Módulo nn en Poliflow

El módulo nn (neural networks) de Poliflow proporciona las piezas fundamentales para construir redes neuronales de forma modular.

Su objetivo es abstraer operaciones complejas en capas reutilizables.


Estructura general del módulo nn

Dentro de nn normalmente encontramos:

  • Lineal → capa totalmente conectada
  • Secuencial → contenedor de capas en secuencia
  • Modulo
  • (Opcional) funciones de activación como ReLU, Sigmoid, Tanh

Capa Linear (Dense Layer)

La capa Linear es la base de las redes neuronales.

¿Qué hace?

Realiza la transformación:

donde:

  • x = entrada
  • W = pesos
  • b = sesgo (bias)

Ejemplo de uso

from poliflow.nn.Lineal import Lineal
from poliflow.core.Tensor import Tensor

capa = Linear(tam_entrada=3, tam_salida=2)

x = Tensor([[1.0, 2.0, 3.0]])

y = capa(x)

print(y)

Internamente

La capa Linear:

  • Inicializa pesos aleatorios W
  • Inicializa bias b
  • Aplica multiplicación matricial
  • Usa autograd para permitir backpropagation

¿Qué representa la salida?

La variable y es la salida de la capa Lineal, es decir, el resultado de aplicar una transformación lineal a la entrada:

Ejemplo de salida

Tensor( data=[[0.03735598 1.67213206]], shape=(1, 2), requieres_grad=True )

Esto significa:

y tiene forma (1, 2) Hay 1 muestra (batch size = 1) La capa tiene 2 neuronas de salida Cada valor corresponde a una neurona distinta


Múltiples capas (stack manual)

Las redes neuronales pueden construirse apilando capas lineales una encima de otra, donde la salida de una capa se convierte en la entrada de la siguiente.

Esto se conoce como un stack manual de capas.


Idea principal

Una red de múltiples capas realiza transformaciones sucesivas:

Donde:

  • ( x ): entrada
  • ( h ): capa oculta
  • ( y ): salida final
  • ( f_1, f_2 ): capas lineales

Arquitectura del ejemplo

  • Capa 1: Lineal(4 → 3)
  • Capa 2: Lineal(3 → 1)

Esto significa:

  • Entrada de 4 características → salida de 3
  • Luego de 3 → salida final de 1

Puedes apilar capas manualmente:

from poliflow.nn.Lineal import Lineal
from poliflow.core.Tensor import Tensor

c1 = Lineal(4, 3)
c2 = Lineal(3, 1)

x = Tensor([[1.0, 2.0, 3.0, 4.0]])

h = c1(x)
salida = c2(h)

print(salida)

Fórmulas matemáticas

Cada capa lineal realiza la operación:

Entonces:

Primera capa


Segunda capa


Composición completa


Interpretación

  • La red aprende representaciones intermedias en h
  • Cada capa transforma los datos a otro espacio de características
  • La segunda capa trabaja sobre una representación más abstracta

Secuencial (modelo en cadena)

Secuencial permite encadenar capas de forma automática.

¿Qué hace?

Ejecuta las capas en orden:

entrada → capa1 → capa2 → capa3 → salida

Ejemplo básico

from poliflow.nn.Secuencial import Secuencial
from poliflow.nn.Lineal import Lineal
from poliflow.core.Tensor import Tensor

modelo = Secuencial(
    Lineal(4, 8),
    Lineal(8, 3),
    Lineal(3, 1)
)

x = Tensor([[1.0, 2.0, 3.0, 4.0]])

y = modelo(x)

print(y)

Cómo funciona internamente

Secuencial:

  1. Recibe una lista de capas
  2. Guarda el orden
  3. En el paso_adelante:
    • pasa la salida de una capa como entrada a la siguiente
  4. Devuelve el resultado final

Flujo de ejecución

x
 ↓
Lineal(4 → 8)
 ↓
Lineal(8 → 3)
 ↓
Lineal(3 → 1)
 ↓
salida

Representación matemática

Un modelo Secuencial es una composición de funciones:

Donde cada ( f_i ) es una capa lineal:


Expansión completa

Sustituyendo cada capa:


Interpretación

  • Cada capa aplica una transformación lineal
  • Los parámetros ( W_i ) y ( b_i ) se aprenden durante el entrenamiento
  • El modelo completo es una composición encadenada de transformaciones

Diferencia: Linear vs Sequential

Componente Función
Lineal Una sola transformación lineal
Secuencial Encadena múltiples capas

🔁 Retropropagación (Backpropagation)

La retropropagación es el algoritmo que permite calcular automáticamente los gradientes de cada parámetro en la red neuronal usando la regla de la cadena.

Esto es lo que hace posible el aprendizaje en redes neuronales.


🧠 Idea principal

Después del forward pass, se calcula el gradiente desde la salida hacia atrás:


Ejemplo en Poliflow

from poliflow.nn.Secuencial import Secuencial
from poliflow.nn.Lineal import Lineal
from poliflow.core.Tensor import Tensor

model = Secuencial(
    Lineal(2, 4),
    Lineal(4, 1)
)

x = Tensor([[0.5, 1.5]])

# Forward pass
y = model(x)

# Backpropagation
y.backward()

print("Salida:", y.data)

Flujo

Backward pass (gradientes)

 ↓
Linear(2 → 4)
 ↓
h
 ↓
Linear(4 → 1)
 ↓
y

Retropropagacíon (gradientes)
dy/dy = 1
   ↓
∂L/∂h
   ↓
Linear(4 → 1)ᵀ
   ↓
∂L/∂x
   ↓
Linear(2 → 4)ᵀ

Representación matemática


Forward

h = xW₁ + b₁

y = hW₂ + b₂

Backpropagation (regla de la cadena):

∂L/∂W₂ = hᵀ · (∂L/∂y)
∂L/∂W₁ = xᵀ · (∂L/∂h)
∂L/∂x = (∂L/∂h) · W₁ᵀ

Diagrama del proceso

Backpropagation GIF

Fuente: Birow — https://www.birow.com/news/backpropagation-explained

⚡ Funciones de Activación en Poliflow

Las funciones de activación introducen no linealidad en la red neuronal y permiten que el modelo aprenda patrones complejos.

En Poliflow, cada activación está implementada como un Modulo con soporte completo de autograd (forward + backward).


1. ReLU (Rectified Linear Unit)

Definición


Derivada (backprop)

[ \frac{d}{dx} f(x) = \begin{cases} 1 & x > 0 \ 0 & x \le 0 \end{cases} ]


Comportamiento

x < 0  →  0
x ≥ 0  →  x

Uso

from poliflow.nn.Activacion import ReLU
from poliflow.core.Tensor import Tensor

# Crear la activación
act = ReLU()

# Entrada
x = Tensor([[1.0, -2.0, 3.0]])

# Aplicar ReLU
y = act(x)

print("Salida:", y)

salida

Salida: Tensor(
  data=[[1. 0. 3.]],)

2. Sigmoid

Definición


Derivada (backprop)


Comportamiento

x → -∞   → 0
x → 0    → 0.5
x → +∞   → 1

Uso

from poliflow.nn.Activacion import Sigmoide
from poliflow.core.Tensor import Tensor

# Crear activación
act = Sigmoide()

# Entrada
x = Tensor([[1.0, -2.0, 3.0]])

# Aplicar Sigmoid
y = act(x)

print("Salida:", y)

salida

Salida: Tensor(
  data=[[0.7310586  0.11920292 0.95257413]],)

3. Tanh

Definición


Derivada (backprop)

---

Comportamiento

x → -∞   → -1
x → 0    → 0
x → +∞   → 1

Uso

from poliflow.nn.Activacion import Tanh
from poliflow.core.Tensor import Tensor

# Crear activación
act = Tanh()

# Entrada
x = Tensor([[1.0, -2.0, 3.0]])

# Aplicar Tanh
y = act(x)

print("Salida:", y)

Salida

Salida: Tensor(
  data=[[ 0.76159416 -0.96402758  0.99505475]],)

4. Leaky ReLU

Definición


Derivada (backprop)


Comportamiento

x > 0   → x
x ≤ 0   → αx

Uso

from poliflow.nn.Activacion import LeakyReLU
from poliflow.core.Tensor import Tensor

# Crear activación
act = LeakyReLU(alpha=0.01)

# Entrada
x = Tensor([[1.0, -2.0, 3.0]])

# Aplicar Leaky ReLU
y = act(x)

print("Salida:", y)

Salida

Salida: Tensor(
  data=[[ 1.   -0.02  3.  ]],)

Herramienta

Poliflow incluye herramientas que permiten:

  • construir redes neuronales rápidamente
  • entrenar modelos con pocas líneas
  • visualizar arquitecturas automáticamente

Esto evita escribir manualmente cada capa y el ciclo de entrenamiento.


Construcción automática de redes densas

La función construir_red_densa permite crear una red neuronal completa de forma automática.


Ejemplo de uso

from poliflow.core.Tensor import Tensor
from poliflow.herramientas.constructor import construir_red_densa
from poliflow.herramientas.entrenador import entrenar

# Datos simples
X = Tensor([[1.0], [2.0], [3.0], [4.0]])
y = Tensor([[2.0], [4.0], [6.0], [8.0]])

# Construcción automática de la red
modelo = construir_red_densa(
    tamaño_entrada=1,
    tamaño_salida=1,
    num_capas_ocultas=2,
    tamaño_capa_oculta=8,
    fn_activacion="relu",
    tarea="regresion"
)

# Entrenamiento automático
entrenar(
    modelo=modelo,
    x_entrenamiento=X,
    y_entrenamiento=y,
    epocas=100,
    lr=0.01,
    perdida="mse"
)

# Predicción
pred = modelo(Tensor([[5.0]]))

print(pred)

¿Qué hace construir_red_densa?

Esta herramienta:

  • crea automáticamente capas lineales
  • agrega funciones de activación
  • construye una arquitectura secuencial completa
  • permite configurar profundidad y tamaño de la red

Arquitectura generada

El ejemplo anterior crea una red similar a:

1 → 8 → 8 → 1

Donde:

  • 1 = tamaño de entrada
  • 8 = neuronas ocultas
  • 1 = salida

¿Qué hace entrenar?

La función entrenar automatiza:

  • forward propagation
  • cálculo de pérdida
  • backpropagation
  • actualización de parámetros
  • ciclo completo de entrenamiento

Internamente

Durante el entrenamiento Poliflow ejecuta:

y_pred = modelo(X)

loss = perdida(y_pred, y)

loss.backward()

optimizador.step()

Todo esto ocurre automáticamente.


Ventajas

Las herramientas de alto nivel permiten:

  • crear modelos rápidamente
  • reducir código repetitivo
  • experimentar arquitecturas fácilmente
  • entrenar redes neuronales con pocas líneas

Intuición

En lugar de construir manualmente cada capa:

Lineal(...)
ReLU()
Lineal(...)
ReLU()
Lineal(...)

Poliflow puede generar toda la arquitectura automáticamente usando únicamente parámetros de configuración.


Visualización de redes neuronales

Poliflow permite visualizar arquitecturas de redes neuronales automáticamente utilizando NetworkX y Matplotlib.

La herramienta dibujar_red genera un grafo donde:

  • cada nodo representa una neurona
  • cada línea representa una conexión
  • las capas se organizan automáticamente

Ejemplo de uso

from poliflow.herramientas.constructor import construir_red_densa
from poliflow.visual.Grafo import dibujar_red

modelo = construir_red_densa(
    tamaño_entrada=3,
    tamaño_salida=1,
    num_capas_ocultas=2,
    tamaño_capa_oculta=4,
    fn_activacion="relu",
    tarea="regresion"
)

dibujar_red(modelo)

¿Qué se visualizará?

La herramienta mostrará:

  • neuronas de entrada
  • capas ocultas
  • neuronas de salida
  • conexiones entre capas

Además:

  • entrada → color verde
  • capas ocultas → color azul
  • salida → color rojo

Resultado esperado

Inserta aquí una imagen generada de la arquitectura:

![Visualización de la red](https://raw.githubusercontent.com/Th3copolo0X/Poliflow/main/grafo_computacional.png)

Ejercicios

Ejercicio 1 — Aprender la relación ( y = 2x )

Objetivo

Entrenar una red neuronal simple para aprender la relación lineal:

y = 2x

Datos

X = [[1], [2], [3], [4], [5]]
Y = [[2], [4], [6], [8], [10]]

Arquitectura

Linear(1,1)

La red tiene:

  • 1 entrada
  • 1 salida
  • Sin capas ocultas

Parámetros

learning_rate = 0.01
epochs = 1000

Código completo

from poliflow.nn.Lineal import Lineal
from poliflow.core.Tensor import Tensor

# Modelo
model = Lineal(1, 1)

# Datos
X = Tensor([[1], [2], [3], [4], [5]])
Y = Tensor([[2], [4], [6], [8], [10]])

learning_rate = 0.01
epochs = 1000

for epoch in range(epochs):

    # Forward
    pred = model(X)

    # Loss MSE
    loss = ((pred - Y) * (pred - Y)).mean()

    # Backward
    loss.backward()

    # Actualización manual
    for param in model.parameters():
        param.data -= learning_rate * param.grad

    # Limpiar gradientes
    model.zero_grad()

    if epoch % 100 == 0:
        print(f"Epoch {epoch} | Loss: {loss.data}")

print("Predicción final:")
print(model(X))

Resultado esperado

La red aprenderá pesos cercanos a:

w ≈ 2
b ≈ 0

Ejercicio 2 — Comprender ReLU

Objetivo

Comprender cómo funciona la activación ReLU eliminando valores negativos.


Datos

X = [[-3], [-2], [-1], [0], [1], [2], [3]]

Y = [[0], [0], [0], [0], [1], [2], [3]]

Arquitectura

Sequential(
    Linear(1,1),
    ReLU()
)

⚙️ Parámetros

learning_rate = 0.01
epochs = 1500

Código completo

from poliflow.nn.Secuencial import Secuencial
from poliflow.nn.Lineal import Lineal
from poliflow.nn.Activacion import ReLU
from poliflow.core.Tensor import Tensor

# Modelo
model = Secuencial(
    Lineal(1,1),
    ReLU()
)

# Datos
X = Tensor([[-3], [-2], [-1], [0], [1], [2], [3]])
Y = Tensor([[0], [0], [0], [0], [1], [2], [3]])

learning_rate = 0.01
epochs = 400

for epoch in range(epochs):

    # Forward
    pred = model(X)

    # Loss
    loss = ((pred - Y) * (pred - Y)).mean()

    # Backward
    loss.backward()

    # Update
    for param in model.parameters():
        param.data -= learning_rate * param.grad

    model.zero_grad()

    if epoch % 100 == 0:
        print(f"Epoch {epoch} | Loss: {loss.data}")

print("Predicciones:")
print(model(X))

Qué observar

x < 0  →  salida ≈ 0
x > 0  →  salida ≈ x

La red aprenderá el comportamiento típico de ReLU.


Qué observar

  • La red aprende una relación no lineal
  • La capa oculta permite representar curvas
  • ReLU introduce no linealidad
  • Más neuronas = mayor capacidad de aproximación

Resumen

Ejercicio Objetivo
1 Aprender relación lineal
2 Comprender activación ReLU
3 Aproximar función no lineal

GitHub del proyecto

Repositorio oficial de Poliflow

https://github.com/Th3copolo0X/PoliFlow

Licencia

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

poliflow-0.2.2.tar.gz (31.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

poliflow-0.2.2-py3-none-any.whl (29.3 kB view details)

Uploaded Python 3

File details

Details for the file poliflow-0.2.2.tar.gz.

File metadata

  • Download URL: poliflow-0.2.2.tar.gz
  • Upload date:
  • Size: 31.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for poliflow-0.2.2.tar.gz
Algorithm Hash digest
SHA256 c237e2a7830f2e68db3a3614cbc397bb0bb6850f947aaf2e62cce4b32362c35d
MD5 8e0c6d3062cfd574fadb40913c76308d
BLAKE2b-256 a604d60339eaf61561b47b98a3f2fe14e48a376384299cd4dc21469be61a8357

See more details on using hashes here.

File details

Details for the file poliflow-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: poliflow-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 29.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for poliflow-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 303b872fa1fbd16f436eb72ea6c52d11e6be400a9514fe318ba62ceb8ea87749
MD5 52e843c245a563151d5cf66d96812eb7
BLAKE2b-256 b440d4eabe3ae66c8945fa3ac293513eac27d7d173539c5c83cdccebde3c3481

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page