Projeto de aprendizado de máquina com Redes Neurais MLP (Multi-Layer Perceptron) aplicado ao clássico dataset de classificação de vinhos do Scikit-learn. O objetivo é comparar o comportamento de duas funções de ativação — ReLU e Sigmoid — em termos de acurácia, convergência e estabilidade de treinamento.
MLP_Wines_Classifier_NN/
│
├── venvMLPP/ # Ambiente virtual Python
├── MLP_vinhos.ipynb # Notebook principal com todo o código
├── requirements.txt # Dependências do projeto
├── .gitignore # Arquivos ignorados pelo Git
└── README.md # Documentação do projeto
Um Multi-Layer Perceptron é uma rede neural artificial composta por:
- Camada de entrada — recebe as features do dataset
- Camadas ocultas — processam a informação através de neurônios com funções de ativação
- Camada de saída — produz a predição final
[13 features] → [64 neurônios] → [32 neurônios] → [3 classes de vinho]
| Característica | ReLU | Sigmoid |
|---|---|---|
| Fórmula | f(x) = max(0, x) |
f(x) = 1 / (1 + e^-x) |
| Saída | [0, +∞) |
(0, 1) |
| Vanishing Gradient | Menos suscetível | Mais suscetível |
| Velocidade | Converge mais rápido | Converge mais devagar |
| Uso típico | Redes profundas, padrão atual | Redes pequenas, saída binária |
- Fonte:
sklearn.datasets.load_wine() - Documentação: https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_wine.html
- Amostras: 178
- Features: 13 (propriedades químicas dos vinhos)
- Classes: 3 (cultivares de vinho italiano)
from sklearn.datasets import load_wine
data = load_wine()
X, y = data.data, data.target- Python 3.8+
- pip atualizado
git clone https://github.com/jharantes/MLP_Wines_Classifier_NN.git
cd MLP_Wines_Classifier_NN# Criar
python -m venv venvMLPP
# Ativar — Windows
venvMLPP\Scripts\activate
# Ativar — Linux/macOS
source venvMLPP/bin/activatepip install -r requirements.txtjupyter notebook MLP_vinhos.ipynbscikit-learn
numpy
matplotlib
jupyter
Ambos os modelos utilizam a mesma arquitetura para que a comparação seja justa — a única variável diferente é a função de ativação.
from sklearn.neural_network import MLPClassifier
# Modelo 1 — ReLU
model_relu = MLPClassifier(
hidden_layer_sizes=(64, 32), # 2 camadas ocultas
activation='relu', # função de ativação
solver='adam', # otimizador
learning_rate_init=0.0005, # taxa de aprendizado
max_iter=2000, # épocas máximas
early_stopping=False, # deixa treinar completo
random_state=42 # reprodutibilidade
)
# Modelo 2 — Sigmoid
model_sigmoid = MLPClassifier(
hidden_layer_sizes=(64, 32),
activation='logistic', # sigmoid no sklearn = 'logistic'
solver='adam',
learning_rate_init=0.0005,
max_iter=2000,
early_stopping=False,
random_state=42
)
⚠️ Atenção aoearly_stopping: Em datasets pequenos como o Wine (178 amostras), o sinal de validação interna é muito ruidoso. Comearly_stopping=Trueo modelo pode parar em apenas 12–30 épocas, antes de aprender qualquer padrão útil — causando colapso de classe (o modelo prevê sempre a mesma classe). MantenhaFalsee deixe convergir pelomax_iter.
Carregar dados → Split treino/teste → Normalização → Treino → Avaliação
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Split com estratificação para manter proporção das classes
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Normalização — essencial para MLPs
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test) # NUNCA fit no test!O
StandardScaleré essencial porque MLPs são sensíveis à escala. Features com magnitudes muito diferentes (ex: alcalinidade vs. flavonoides) distorcem o gradiente e dificultam a convergência.
O projeto utiliza três formas de avaliação:
print(f"Acurácia ReLU: {model_relu.score(X_test, y_test):.4f}")
print(f"Acurácia Sigmoid: {model_sigmoid.score(X_test, y_test):.4f}")
print(f"Épocas ReLU: {model_relu.n_iter_}")
print(f"Épocas Sigmoid: {model_sigmoid.n_iter_}")Mostra precision, recall e F1-score por classe — muito mais informativo que só a acurácia.
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred_relu, target_names=data.target_names))Visualiza onde cada modelo está errando e acertando por classe.
Compara a convergência dos dois modelos ao longo das épocas.
plt.plot(model_relu.loss_curve_, label="ReLU")
plt.plot(model_sigmoid.loss_curve_, label="Sigmoid")- Colapso de classe ocorre quando o modelo trava em mínimo local e prevê sempre a mesma classe — sinal claro de configuração inadequada
early_stoppingpode ser prejudicial em datasets pequenos com alta variância de validação- Arquitetura idêntica nos dois modelos garante que a comparação isola o efeito da função de ativação
- ReLU tende a convergir mais rápido e com maior acurácia em problemas de classificação multiclasse
Projeto desenvolvido para fins educacionais — comparação de funções de ativação em redes neurais MLP.