Neural Network from Scratch
Multilayer Perceptron (MLP) projetado do zero em Python e exportado para inferência nativa em navegador (HTML/JS) para OCR. Baseado em Tariq Rashid, 2016.
Specifications
Arquitetura
784 → 200 → 10
Ativação
Sigmóide
Dataset
MNIST CSV (1k + 3× aug)
Augmentation
Rotação ±10° (scipy)
Pesos Export
weights.js (3.4 MB)
Inferência
Browser (canvas 28×28)
Tech Stack
Overview
Rede neural MLP com 784 entradas (pixels), 200 neurônios ocultos e 10 saídas (classes 0-9). Inicialização de pesos por distribuição normal. Aprendizado por descida de gradiente com backpropagation. Data augmentation real via matrizes de rotação scipy.ndimage (±10°), triplicando o dataset de 1.000 para 3.000 amostras. Exportação dos pesos pré-treinados para weights.js (3.4 MB) para contornar políticas CORS em execução file:///. Normalização visual no canvas: algoritmo de centro de massa com bounding box, interpolação bilinear 20×20px e centralização em frame 28×28 normalizado [0.01, 0.99].
Key Features
- Forward propagation e backpropagation implementados do zero com NumPy
- Data augmentation via matrizes de rotação scipy.ndimage (±10°, 3× dataset)
- Export de pesos para JS standalone (weights.js, 3.4 MB) — bypass CORS
- Algoritmo de centro de massa + bounding box para normalização MNIST-style no canvas
- Interpolação bilinear para rescale 20×20px → frame 28×28 centralizado
- Inferência 100% client-side no navegador sem backend
Backpropagation — Atualização de Pesos
def backward(self, X, y, learning_rate=0.01):
m = X.shape[0]
output = self.activations[-1]
delta = (output - y) * self.sigmoid_derivative(
self.z_values[-1]
)
for i in range(len(self.weights) - 1, -1, -1):
dw = np.dot(self.activations[i].T, delta) / m
db = np.sum(delta, axis=0, keepdims=True) / m
if i > 0:
delta = np.dot(
delta, self.weights[i].T
) * self.sigmoid_derivative(self.z_values[i-1])
self.weights[i] -= learning_rate * dw
self.biases[i] -= learning_rate * db