3. MLP
Atividade: Entendendo Perceptrons de Múltiplas Camadas (MLPs)
Esta atividade é projetada para testar suas habilidades em Perceptrons de Múltiplas Camadas (MLPs).
O fio condutor da atividade é o que uma camada oculta compra: um exercício na mão para ver a retropropagação mover cada parâmetro, depois um conjunto de dados que reta nenhuma resolve, depois mais classes — e por fim um quarto exercício que pergunta se empilhar uma segunda camada oculta compra alguma coisa.
Regras técnicas (valem para toda a atividade)
- Fixe a semente aleatória —
rng = np.random.default_rng(42)— e use o mesmorngem todo o relatório. Resultados que não podem ser reproduzidos não valem ponto; - Todo gráfico deve ter título, rótulos nos eixos e legenda das classes;
- Bibliotecas permitidas:
numpy,pandas,matplotlib/seaborne oscikit-learnapenas para gerar os dados e dividi-los (make_blobs,make_classification,train_test_split) e para a matriz de confusão. O MLP em si — ativações, perda, passagem direta, gradientes e atualização — DEVE SER ESCRITO POR VOCÊ. Nada de TensorFlow, PyTorch ouMLPClassifier. Usar um deles zera o critério de implementação e o exercício que depende dele; - Sempre que o enunciado pedir um número (um gradiente, uma acurácia, um parâmetro após a atualização), reporte o número no texto — não apenas na saída do código;
- Organize o relatório com um título por exercício e um subtítulo por item (
Exercício 1,A,B, …), na mesma ordem do enunciado, e numere as figuras como indicado. A última seção do relatório deve ser o Resumo dos resultados descrito no fim desta página.
Exercício 1
Um passo de retropropagação, na mão
Considere um MLP com 2 features de entrada, 1 camada oculta de 2 neurônios e 1 neurônio de saída. Use \(\tanh\) como ativação nas duas camadas. A perda é o erro quadrático médio sobre uma única amostra, então \(N = 1\):
Notação
Esta página escreve \(\mathbf{W}^{(1)}, \mathbf{W}^{(2)}\) para as duas matrizes de pesos porque os Exercícios 3 e 4 precisam de um número arbitrário de camadas. A aula escreve a mesma rede de duas camadas como \(\mathbf{W}, \mathbf{V}\), com biases \(\mathbf{b}^h, b^y\) — ou seja, \(\mathbf{W}^{(1)} \equiv \mathbf{W}\), \(\mathbf{W}^{(2)} \equiv \mathbf{V}\), \(\mathbf{b}^{(1)} \equiv \mathbf{b}^h\) e \(b^{(2)} \equiv b^y\). O exemplo resolvido da aula usa a sigmoide; aqui você usa \(\tanh\), cuja derivada é \(\frac{d}{du}\tanh(u) = 1 - \tanh^2(u)\).
Use estes valores:
-
Entrada e alvo: \(\mathbf{x} = [0.5, -0.2]\), \(y = 1.0\)
-
Pesos da camada oculta: \(\mathbf{W}^{(1)} = \begin{bmatrix} 0.3 & -0.1 \\ 0.2 & 0.4 \end{bmatrix}\)
-
Biases da camada oculta: \(\mathbf{b}^{(1)} = [0.1, -0.2]\)
-
Pesos da camada de saída: \(\mathbf{W}^{(2)} = [0.5, -0.3]\)
-
Bias da camada de saída: \(b^{(2)} = 0.2\)
-
Taxa de aprendizado: \(\eta = 0.3\)
Mostre cada derivação e cada número intermediário, com pelo menos 4 casas decimais. Este exercício é feito no papel (ou em Markdown) — não chamando uma biblioteca.
A — Passagem direta
- Pré-ativações da camada oculta: \(\mathbf{z}^{(1)} = \mathbf{W}^{(1)} \mathbf{x} + \mathbf{b}^{(1)}\)
- Ativações da camada oculta: \(\mathbf{h}^{(1)} = \tanh(\mathbf{z}^{(1)})\)
- Pré-ativação de saída: \(u^{(2)} = \mathbf{W}^{(2)} \mathbf{h}^{(1)} + b^{(2)}\)
- Saída: \(\hat{y} = \tanh(u^{(2)})\), e em seguida a perda \(L\).
B — Passagem reversa
Compute o gradiente da perda em relação a cada peso e cada bias. Comece por \(\displaystyle \frac{\partial L}{\partial \hat{y}}\) e encadeie para fora:
- \(\displaystyle \frac{\partial L}{\partial u^{(2)}}\), usando a derivada do \(\tanh\);
- Camada de saída: \(\displaystyle \frac{\partial L}{\partial \mathbf{W}^{(2)}}\) e \(\displaystyle \frac{\partial L}{\partial b^{(2)}}\);
- Propague de volta: \(\displaystyle \frac{\partial L}{\partial \mathbf{h}^{(1)}}\) e \(\displaystyle \frac{\partial L}{\partial \mathbf{z}^{(1)}}\);
- Camada oculta: \(\displaystyle \frac{\partial L}{\partial \mathbf{W}^{(1)}}\) e \(\displaystyle \frac{\partial L}{\partial \mathbf{b}^{(1)}}\).
C — Atualização dos parâmetros
Com \(\eta = 0.3\), aplique o gradiente descendente aos oito parâmetros:
Reporte o valor numérico de cada parâmetro atualizado e diga se a perda subiria ou desceria numa segunda passagem direta — e por quê.
Exercício 2
Classificação binária que uma reta não resolve
A — Gere os dados
A Classe 1 é dividida em dois grupos que ficam em lados opostos da Classe 0, de modo que nenhuma reta as separa — que é exatamente a situação para a qual existe uma camada oculta. Use estes parâmetros, sem alterações:
from sklearn.datasets import make_blobs
centers = np.array([[0., 0.], [3., 3.], [-3., -3.]])
X, c = make_blobs(n_samples=[500, 250, 250], centers=centers,
cluster_std=1.2, random_state=42)
y = (c > 0).astype(int) # classe 0: 1 grupo | classe 1: 2 grupos
Divida 80% treino / 20% teste com train_test_split(..., test_size=0.2, random_state=42, stratify=y).
Produza a Figura 1: um gráfico de dispersão dos 1000 pontos coloridos por y.
B — Estabeleça a linha de base
Antes de construir qualquer coisa, ajuste uma única fronteira linear ao conjunto de treino e reporte a acurácia dela no teste. Aqui você pode usar sklearn.linear_model.LogisticRegression — esta é a linha de base, não o seu modelo. Ela deve ficar perto de 48%: pior do que chutar. Guarde esse número; o item D pergunta sobre ele.
C — Implemente o MLP
Escreva um MLP do zero. Você escolhe a arquitetura, mas ela precisa ter pelo menos uma camada oculta, e você precisa implementar você mesmo:
- a passagem direta;
- a perda (entropia cruzada binária é a escolha natural);
- a passagem reversa — cada gradiente derivado, não obtido por autodiff;
- a atualização dos parâmetros.
Escreva como função ou classe que recebe os tamanhos das camadas como argumento. Os Exercícios 3 e 4 reutilizam este mesmo código, então uma rede de duas camadas fixa no código vai lhe custar caro lá.
Treine por um número razoável de épocas (de algumas centenas a alguns milhares), registrando a perda de treino a cada época. Depois:
- Reporte a arquitetura, a taxa de aprendizado, o número de épocas e a acurácia no teste. Uma implementação correta fica em torno de 90–93%.
- Produza a Figura 2: perda de treino \(\times\) época.
- Produza a Figura 3: a fronteira de decisão sobre os pontos de teste — avalie sua rede em uma grade e sombreie as duas regiões.
D — Análise
Por que a linha de base linear fica abaixo de 50% enquanto o seu MLP passa de 90%? Aponte para a Figura 3: descreva o formato da região que sua rede atribui à Classe 1 e explique por que nenhuma reta sozinha consegue produzi-la.
Exercício 3
Multiclasse, a mesma rede
A — Gere os dados
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1500, n_features=4, n_informative=4,
n_redundant=0, n_repeated=0, n_classes=3,
n_clusters_per_class=2, class_sep=1.0,
random_state=42)
São 1500 amostras, 4 features informativas, 3 classes, 2 grupos cada. Divida 80/20 com a mesma semente e stratify=y.
B — Adapte a rede
Estenda a implementação do Exercício 2 para três classes. As mudanças necessárias estão na camada de saída e na perda:
- a camada de saída passa a ter 3 unidades;
- a softmax transforma essas saídas em probabilidades;
- a entropia cruzada categórica substitui a binária.
Derive \(\partial L / \partial u\) para o par softmax + entropia cruzada e mostre a derivação no relatório — o resultado é famosamente simples, e saber por quê é o ponto deste item.
Ponto extra
Vale +1 se o núcleo da sua implementação do Exercício 2 for reutilizado literalmente no Exercício 3: a passagem direta, a reversa e a atualização precisam ser o mesmo código, intocado. O tamanho da saída, a função de perda e os hiperparâmetros podem mudar — esses são argumentos, não estrutura. A nota do exercício é limitada a 10/10, então este ponto funciona como seguro contra perdas em outros itens, e não como acréscimo a uma nota cheia.
C — Treine e avalie
- Reporte a arquitetura, os hiperparâmetros e a acurácia no teste. Espere algo em torno de 83–86%.
- Produza a Figura 4: perda de treino \(\times\) época.
- Produza a Figura 5: a matriz de confusão no conjunto de teste.
D — Análise
Qual par de classes a rede mais confunde, segundo a Figura 5? Os dados têm 4 dimensões informativas e 6 grupos no total — ofereça uma explicação para a confusão que se apoie nessa estrutura. Reporte também a linha de base da regressão logística nestes dados (em torno de 66%) e diga o que a camada oculta acrescentou.
Exercício 4
Uma segunda camada oculta ajuda?
Os mesmos dados do Exercício 3, o mesmo orçamento de treino, a mesma semente. A única mudança é a profundidade: pelo menos 2 camadas ocultas.
Esta é uma comparação controlada, não uma caça a um número melhor. Mude uma coisa de cada vez e mantenha o resto fixo, ou a comparação não significa nada.
A — Treine a rede mais profunda
Reporte a arquitetura e a acurácia no teste, treinada com o mesmo número de épocas e a mesma taxa de aprendizado do Exercício 3.
B — Compare
Produza a Figura 6: as curvas de perda de treino da rede do Exercício 3 e da rede do Exercício 4 nos mesmos eixos. Depois preencha esta comparação no texto:
| camadas ocultas | parâmetros | perda final de treino | acurácia no teste | |
|---|---|---|---|---|
| Exercício 3 | 1 | |||
| Exercício 4 | ≥ 2 |
Rode as duas com pelo menos 3 sementes diferentes e reporte a média, para estar comparando modelos e não sorte.
C — Análise
Reporte o que você mediu
A rede mais profunda muito provavelmente não vai superar a mais rasa aqui, e pode até ir pior. Esse é o resultado esperado, e vale nota cheia quando reportado honestamente e explicado. Ajustar até a profundidade "ganhar" não é o que está sendo avaliado.
Explique o resultado. Ângulos úteis: quantos grupos os dados realmente têm e quão complexa precisa ser a fronteira para separá-los; o que uma segunda camada acrescenta em termos de representação contra o que ela custa em otimização; se a perda de treino conta a mesma história que a acurácia no teste. Diga que tipo de dado faria a profundidade extra compensar.
Resumo dos resultados
Encerre o relatório com esta tabela, preenchida:
| # | Quantidade | Valor |
|---|---|---|
| 1 | Ex. 1 — \(\mathbf{z}^{(1)}\) e \(\mathbf{h}^{(1)}\) | |
| 2 | Ex. 1 — \(u^{(2)}\), \(\hat{y}\) e \(L\) | |
| 3 | Ex. 1 — os oito parâmetros atualizados | |
| 4 | Ex. 2 — acurácia da linha de base linear | |
| 5 | Ex. 2 — arquitetura e acurácia no teste | |
| 6 | Ex. 3 — arquitetura e acurácia no teste | |
| 7 | Ex. 3 — par de classes mais confundido | |
| 8 | Ex. 4 — arquitetura e acurácia no teste | |
| 9 | Ex. 4 — diferença de acurácia em relação ao Ex. 3 (média de ≥ 3 sementes) |
Critérios de Avaliação
O entregável desta atividade é um relatório que inclui:
- O Exercício 1 resolvido inteiramente na mão, com cada passo mostrado com pelo menos 4 casas decimais.
- O código do seu MLP e da geração dos dados, comentado.
- As Figuras 1 a 6, numeradas conforme pedido.
- Suas respostas às perguntas de análise dos itens D (e 4C).
- A tabela de Resumo dos resultados.
Notas Importantes:
-
A entrega é um site no GitHub Pages apoiado em um repositório público — veja Formato de Entrega para a estrutura obrigatória, o front matter e o checklist;
-
Há uma política estrita contra plágio. Qualquer forma de plágio resultará em nota zero na atividade e pode levar a outras medidas disciplinares conforme as políticas de integridade acadêmica da universidade;
-
O prazo de cada atividade não é estendido — NENHUMA EXCEÇÃO será feita para entregas atrasadas.
-
Colaboração com IA é permitida, mas cada aluno DEVE ENTENDER e ser capaz de explicar todas as partes do código e da análise entregues. Qualquer uso de ferramentas de IA deve ser devidamente citado. PROVAS ORAIS podem ser realizadas.
-
Todos os entregáveis das atividades individuais devem ser enviados pela plataforma insper.blackboard.com.
Critérios de Nota:
Cada linha vale os pontos indicados, atribuídos integralmente, parcialmente (metade) ou não atribuídos: integralmente quando o item está completo e correto; parcialmente quando está implementado mas falta a análise pedida, ou quando a análise não traz o resultado numérico que a sustenta; zero quando ausente ou incorreto.
O valor da acurácia em si não é avaliado. Os conjuntos de dados são fixos e com semente, então os números são o que são; o que se avalia é o método, as figuras e o relato honesto do que você obteve — inclusive no Exercício 4, onde o resultado esperado é que a profundidade não ajude.
Exercício 1 — Retropropagação na mão (2 pontos):
| Pontos | Critério | O que garante nota cheia |
|---|---|---|
| 0,5 | Passagem direta (A) | \(\mathbf{z}^{(1)}\), \(\mathbf{h}^{(1)}\), \(u^{(2)}\), \(\hat{y}\) e \(L\) com os valores dados, com pelo menos 4 casas decimais. |
| 1,0 | Passagem reversa (B) | \(\partial L/\partial \hat{y}\), \(\partial L/\partial u^{(2)}\), os dois gradientes de pesos e os dois de biases — cada um derivado, não apenas declarado. |
| 0,5 | Atualização (C) | Os oito parâmetros atualizados com \(\eta = 0.3\), valores reportados, com a resposta sobre a direção da perda. |
Exercício 2 — Classificação binária (3 pontos):
| Pontos | Critério | O que garante nota cheia |
|---|---|---|
| 0,5 | Dados e linha de base (A, B) | O gerador e a semente especificados, divisão 80/20 estratificada, Figura 1 e a linha de base linear reportada. |
| 1,5 | MLP do zero (C) | Passagem direta, perda, gradientes e atualização escritos à mão e corretos; os tamanhos das camadas são argumento, não constante no código. |
| 0,5 | Treino e figuras (C) | Arquitetura e hiperparâmetros declarados, acurácia no teste reportada, Figuras 2 e 3 corretas. |
| 0,5 | Análise (D) | Explica a linha de base abaixo de 50% pela geometria da Figura 3, e não apenas afirmando que os dados são não lineares. |
Exercício 3 — Multiclasse (3 pontos):
| Pontos | Critério | O que garante nota cheia |
|---|---|---|
| 0,5 | Dados (A) | O gerador e a semente especificados, divisão 80/20 estratificada. |
| 1,5 | Adaptação multiclasse (B) | Softmax e entropia cruzada categórica implementadas, com \(\partial L/\partial u\) derivado no relatório. |
| 0,5 | Treino e figuras (C) | Arquitetura e hiperparâmetros declarados, acurácia no teste reportada, Figuras 4 e 5 corretas. |
| 0,5 | Análise (D) | Identifica o par mais confundido pela matriz de confusão e o explica pela estrutura de grupos; reporta a comparação com a linha de base. |
| +1,0 | Extra — reutilização literal (B) | O código de passagem direta/reversa/atualização do Exercício 2 reutilizado intocado. Opcional; a nota do exercício é limitada a 10/10. |
Exercício 4 — Comparação de profundidade (2 pontos):
| Pontos | Critério | O que garante nota cheia |
|---|---|---|
| 0,5 | Rede mais profunda (A) | Pelo menos 2 camadas ocultas, mesmos dados, semente e orçamento de treino do Exercício 3. |
| 1,0 | Comparação controlada (B) | A tabela de comparação preenchida, a Figura 6 com as duas curvas de perda, e os dois modelos com média de pelo menos 3 sementes. |
| 0,5 | Explicação (C) | Explica o resultado — inclusive quando a profundidade perde — a partir da estrutura dos dados, e diz que dados recompensariam a profundidade extra. |