Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tutorial: Redes Neurais Artificiais do Zero 🧠

Leia isto em qualquer nível: não precisa ser matemático, programador ou cientista para começar. Logo abaixo você encontra uma explicação simples e divertida de como uma rede neural "pensa". Quem quiser, pode mergulhar na matemática completa mais adiante. 🤓⬇️

Projeto didático de Rede Neural Artificial (ANN) implementada em Python puro, sem frameworks de machine learning.

A ideia é estudar os fundamentos de:

  • neurônio artificial;
  • camadas;
  • feedforward;
  • backpropagation;
  • atualização de pesos e bias.

Baseado nos conceitos de Classic Computer Science Problems (David Kopec).


🎈 Para todos: o que é isso em palavras simples?

Imagine que você quer ensinar uma criança a reconhecer flores. Você mostra uma flor e diz: "Esta é uma íris-setosa". Mostra outra e diz: "Esta é uma íris-versicolor". Depois de ver muitas flores e ouvir muitas correções, a criança começa a acertar sozinha — mesmo em flores que nunca viu.

Uma rede neural artificial é como essa criança, mas feita de números:

  1. Você mostra os dados (as medidas da flor: comprimento das pétalas, largura, etc.). 📏
  2. A rede chuta um resultado (qual espécie de flor). 🎲
  3. Você corrige o erro (a resposta certa). ✅
  4. A rede aprende com o erro e ajusta seus "pensamentos" internos — os pesos. 🔧
  5. Repete-se isso milhares de vezes, até a rede acertar sozinha. 🎯

É assim que este projeto funciona: cada neurônio é um pequeno "funcionário" que soma informações e repassa adiante, e as camadas são os andares dessa fábrica de decisões.

💡 Curiosidade lúdica: se um neurônio fosse um chef de cozinha, os pesos seriam "quanto de cada ingrediente entra na receita", o bias seria "o tempero-base" e a função de ativação seria "a regra para dizer se o prato está bom o suficiente para sair da cozinha". 🍳

🌱 O "ciclo de vida" de um aprendizado

  1. Alimentar 🍽️ — os dados de entrada entram na primeira camada.
  2. Processar ⚙️ — cada camada transforma os sinais e repassa à próxima (feedforward).
  3. Comparar ⚖️ — a saída é comparada com a resposta esperada.
  4. Corrigir 🩹 — o erro volta pelas camadas (backpropagation).
  5. Ajustar 🛠️ — pesos e bias mudam um pouquinho para errar menos da próxima vez.
  6. Repetir 🔁 — depois de muitas épocas, a rede fica craque!

E quando ela aprende, você pode salvar o "cérebro" dela em um arquivo (JSON) e reutilizar quando quiser, sem treinar de novo. 💾

👥 Para quem é este projeto?

  • Estudantes de programação e machine learning que querem ver "o motor por dentro". 🎓
  • Curiosos que perguntam "mas como a IA funciona por baixo dos panos?". 🤔
  • Professoras e professores que precisam de um exemplo simples e sem caixa-preta para mostrar em aula. 👩‍🏫
  • Entusiastas que gostam de ler código limpo e didático. 💚

Attribution and License

This project is based on the neural network implementation from the book:

"Classic Computer Science Problems in Python" by David Kopec (2018)
Original repository: https://github.com/davecom/ClassicComputerScienceProblemsInPython

The original code is licensed under the Apache License 2.0.
This project complies with that license and includes proper attribution in all derived files.

What this project adds

This repository extends the original implementation with:

  • Additional activation functions: tanh, ReLU, Leaky ReLU
  • Numerical stability improvements (e.g., sigmoid)
  • Command-line parameterization
  • Unit testing (unittest)
  • Modular project structure
  • Reproducibility via random seed control
  • New: explicit loss functions (MSE, cross-entropy) with per-epoch history
  • New: mini-batch training, momentum/Adam/RMSProp optimizers and learning-rate schedulers
  • New: weight regularization (L2), validation set and early stopping
  • New: k-fold cross-validation
  • New: per-layer activation functions and softmax output
  • New: model serialization (save/load as JSON)
  • New: classification metrics (confusion matrix, precision, recall, F1)
  • New: optional learning-curve plots (matplotlib)
  • New: unified runner and classic XOR example

This project should be understood as an educational extension and adaptation, not a fully original implementation.

Guia rápido

  • Visão resumida do projeto: ann/read.md
  • Este arquivo: explicação completa, matemática e tutorial passo a passo

Neurônio biológico x neurônio artificial

Neurônio biológico e artificial

Neurônio biológico (ideia intuitiva)

  • Dendritos recebem sinais.
  • Corpo celular integra esses sinais.
  • Axônio transmite a resposta para outros neurônios.

🧩 Tradução lúdica: o dendrito é o "orelhão" que escuta, o corpo celular é o "cérebro" que decide e o axônio é a "boca" que fala com o próximo neurônio.

Em resumo: recebe estímulos, combina informações e gera uma resposta.

Neurônio artificial (no código)

No projeto, um neurônio recebe entradas x₁, x₂, …, xₙ, aplica pesos w₁, w₂, …, wₙ, soma com o viés b e passa por uma função de ativação:

$$ z = \sum_{i=1}^{n} x_i w_i + b $$

$$ \hat{y} = f(z) $$

Onde:

  • (z): combinação linear;
  • (b): bias;
  • (f): ativação (sigmoid, tanh, relu ou leaky_relu).

🍳 Na nossa analogia do chef: as entradas (x_i) são os ingredientes, os pesos (w_i) são "quantas colheradas de cada", o bias (b) é o tempero-base e (f(z)) é a regra final que decide a resposta.

Funções de ativação disponíveis

Implementadas em ann/Core/util.py:

  1. Sigmoid — "o termômetro que transforma qualquer número em uma nota de 0 a 1". 🌡️

$$ \sigma(x)=\frac{1}{1+e^{-x}} $$

$$ \sigma'(x)=\sigma(x)\left(1-\sigma(x)\right) $$

  1. Tanh — "como a sigmoid, mas a nota vai de -1 a 1". ↔️

$$ \tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} $$

$$ \frac{d}{dx}\tanh(x)=1-\tanh^2(x) $$

  1. ReLU — "o interruptor: se for negativo, desliga; se for positivo, deixa passar". 💡

$$ \text{ReLU}(x)=\max(0,x) $$

$$ \text{ReLU}'(x)= \begin{cases} 1, & x>0 \\ 0, & x\le 0 \end{cases} $$

  1. Leaky ReLU — "o interruptor com vazamento: negativo não desliga 100%, escapa um pouquinho". 🚰

$$ \text{LeakyReLU}(x)= \begin{cases} x, & x>0 \\ \alpha x, & x\le 0 \end{cases} $$

$$ \text{LeakyReLU}'(x)= \begin{cases} 1, & x>0 \\ \alpha, & x\le 0 \end{cases} $$

Matemática do treinamento (passo a passo)

1) Feedforward

Cada camada calcula sua saída e repassa para a próxima:

$$ a^{(l)} = f!\left(W^{(l)}a^{(l-1)} + b^{(l)}\right) $$

🧭 Em palavras: os sinais caminham da entrada até a saída, andando de camada em camada.

2) Erro na saída

Para cada neurônio de saída, o código usa o erro:

$$ e_j = y_j - \hat{y}_j $$

📏 Em palavras: "quanto a minha resposta chute está longe da resposta certa".

3) Delta da camada de saída

$$ \delta_j^{(L)} = f'(z_j^{(L)}) \cdot (y_j - \hat{y}_j) $$

4) Delta das camadas ocultas

$$ \delta_i^{(l)} = f'(z_i^{(l)}) \sum_j w_{ij}^{(l+1)}\delta_j^{(l+1)} $$

🩹 Em palavras: o erro "viaja para trás", cada camada interna descobre quanto da culpa é dela.

5) Atualização dos pesos e bias

Para cada peso:

$$ w_{ij} \leftarrow w_{ij} + \eta \cdot a_i^{(l-1)} \cdot \delta_j^{(l)} $$

Para o bias:

$$ b_j \leftarrow b_j + \eta \cdot \delta_j^{(l)} $$

Onde (\eta) é a taxa de aprendizado (learning_rate).

🎛️ Em palavras: cada peso dá um passo pequenino na direção que diminui o erro — e o tamanho do passo é o learning_rate. Passo grande = aprende rápido (mas pode tropeçar); passo pequeno = aprende devagar (mas firme). 🐢🐇

Modernizações já aplicadas

  • bias em cada neurônio;
  • sigmoid numericamente estável;
  • novas ativações: tanh, relu, leaky_relu;
  • seleção de ativação por parâmetro de linha de comando;
  • caminhos de dados robustos com Path(__file__);
  • seed configurável para reprodutibilidade;
  • testes automatizados com unittest;
  • estrutura de pacotes explícita com __init__.py;
  • dependências externas não obrigatórias (stdlib);
  • novo: funções de perda (MSE, cross-entropy) e histórico por época;
  • novo: mini-batches, otimizadores (momentum, RMSProp, Adam) e schedulers de learning rate;
  • novo: regularização L2, validação com early stopping e k-fold cross-validation;
  • novo: ativação por camada e saída softmax;
  • novo: salvar/carregar modelos (JSON);
  • novo: métricas de classificação (precisão, recall, F1, matriz de confusão);
  • novo: curvas de aprendizado (matplotlib opcional);
  • novo: runner unificado train.py, exemplo XOR e comparador de ativações;
  • novo: CI com ruff, mypy e testes; pyproject.toml completo.

Estrutura do projeto

ANN/
├── ann/
│   ├── Core/
│   │   ├── util.py              # ativações, perdas, softmax, normalização, schedulers
│   │   ├── neuron.py            # estrutura de um neurônio
│   │   ├── layer.py             # camada de neurônios
│   │   ├── network.py           # treino, validação, save/load
│   │   ├── optimizer.py         # SGD, momentum, RMSProp, Adam
│   │   ├── data.py              # carregamento de dados e splits
│   │   ├── metrics.py           # matriz de confusão, precisão, recall, F1
│   │   ├── cross_validation.py  # k-fold
│   │   └── plotting.py          # curvas de aprendizado (opcional)
│   ├── data/
│   │   ├── iris.csv
│   │   └── wine.csv
│   ├── examples/
│   │   ├── train.py             # runner unificado
│   │   ├── iris_test.py
│   │   ├── wine_test.py
│   │   ├── xor_test.py
│   │   └── compare_activations.py
│   └── read.md
├── tests/
│   ├── test_util.py
│   ├── test_network.py
│   ├── test_data.py
│   ├── test_metrics.py
│   ├── test_optimizers.py
│   └── test_examples.py
├── pyproject.toml
└── readme.md

Tutorial de execução (detalhado)

1) Pré-requisitos

  • Python 3.11+
  • terminal na raiz do projeto (pasta que contém ann/)

Opcional: ambiente virtual.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

2) Executar os exemplos

Com parâmetros padrão:

python -m ann.examples.iris_test
python -m ann.examples.wine_test
python -m ann.examples.xor_test

Com ativação parametrizada:

python -m ann.examples.iris_test --activation tanh --epochs 60 --seed 42
python -m ann.examples.wine_test --activation relu --epochs 20 --seed 7
python -m ann.examples.iris_test --activation leaky_relu --leaky-alpha 0.05

3) Runner unificado (novo 🚀)

Um único comando para treinar qualquer dataset:

python -m ann.examples.train --dataset iris
python -m ann.examples.train --dataset wine --epochs 20 --activation relu

Com todos os recursos:

# saída softmax + cross-entropy + métricas
python -m ann.examples.train --dataset iris --softmax --loss cross_entropy --metrics

# otimizador Adam + mini-batches + decaimento de learning rate
python -m ann.examples.train --dataset wine --optimizer adam --batch-size 16 --schedule linear --epochs 50

# validação com early stopping
python -m ann.examples.train --dataset iris --validation-size 0.15 --patience 5

# k-fold cross-validation
python -m ann.examples.train --dataset iris --kfold 5

# salvar e carregar o modelo
python -m ann.examples.train --dataset iris --save modelo.json
python -m ann.examples.train --dataset iris --load modelo.json

# curvas de aprendizado (requer matplotlib)
python -m ann.examples.train --dataset iris --plot curvas.png

Parâmetros disponíveis:

  • --activation / --output-activation: ativação das camadas ocultas e de saída
  • --softmax: usa softmax na saída (recomendado com --loss cross_entropy)
  • --loss: mse ou cross_entropy
  • --optimizer: sgd, momentum, rmsprop, adam
  • --weight-decay: regularização L2
  • --schedule / --lr-end: decaimento da taxa de aprendizado
  • --batch-size: treino em mini-batches
  • --validation-size / --patience: validação e early stopping
  • --kfold: cross-validation
  • --metrics: matriz de confusão, precisão, recall e F1
  • --plot: salva as curvas de aprendizado em PNG
  • --save / --load: serialização do modelo
  • --epochs, --seed, --leaky-alpha, --no-shuffle

4) Exemplo clássico XOR (novo 🧩)

O XOR é o "exercício de aquecimento" clássico de redes neurais: ele não pode ser resolvido com uma reta, então prova que a rede com camada oculta aprende de verdade.

python -m ann.examples.xor_test

Saída esperada: Acertos: 4/4 com a rede aprendendo a tabela 0 XOR 0 = 0, 0 XOR 1 = 1, etc.

5) Comparar ativações (novo 🆚)

Descubra qual ativação (sigmoid, tanh, relu, leaky_relu) se sai melhor com a mesma semente e épocas:

python -m ann.examples.compare_activations --dataset iris

6) Executar os testes

Rode toda a suíte:

python -m unittest discover -s tests -v

Como interpretar:

  • ok: teste passou;
  • FAIL/ERROR: algo precisa ser corrigido;
  • no final, o resumo mostra quantos testes foram executados.

7) Qualidade de código (CI)

O projeto inclui pipeline de CI (GitHub Actions) com ruff, mypy e testes. Localmente:

pip install ruff mypy
ruff check ann tests
mypy ann

❓ Perguntas frequentes (em linguagem simples)

  • A rede "pensa" de verdade? Não! Ela apenas soma números e ajusta pesos seguindo regras matemáticas. O "pensar" é uma metáfora — mas o efeito prático impressiona. ✨
  • Preciso instalar algo? Não. O núcleo usa só a biblioteca padrão do Python. O matplotlib só é necessário se você quiser gerar as curvas de aprendizado. 📦
  • Por que testes? Para ter certeza de que mexer em uma parte não quebra outra — como freios num carro que você ainda está ajustando. 🚗🔧
  • Posso usar meus próprios dados? O carregador de dados (ann/Core/data.py) é genérico: basta um CSV com features e um rótulo (ou usar one-hot encoding). 🗂️
  • Como sei se a rede está aprendendo? Acompanhe a loss (erro) a cada época: se ela cai, a rede está melhorando. Os exemplos com --plot mostram isso num gráfico. 📉➡️📈

Referência

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages