2. Perceptron
Atividade: Entendendo Perceptrons e Suas Limitações
Esta atividade é projetada para testar suas habilidades em Perceptrons e suas limitações.
O fio condutor da atividade é a separabilidade: você vai treinar o mesmo perceptron em dois conjuntos de dados — um que o algoritmo resolve, outro que não — e o que interessa não é que o segundo falhe, e sim como ele falha.
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/seaborn. O perceptron em si — a ativação, a predição, a regra de atualização e o laço de treino — DEVE SER ESCRITO POR VOCÊ. Oscikit-learn(ou qualquer outra biblioteca) não pode fornecer o modelo: nada dePerceptron,SGDClassifieroufit. 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 (pesos, bias, épocas, acurácia), 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
Dados separáveis: o caso para o qual o perceptron foi projetado
A — Gere os dados
Gere duas classes de pontos 2D, 1000 amostras por classe, a partir de distribuições normais multivariadas:
- Classe 0: Média \(= [1.5, 1.5]\), Covariância \(= [[0.5, 0], [0, 0.5]]\)
- Classe 1: Média \(= [5, 5]\), Covariância \(= [[0.5, 0], [0, 0.5]]\)
As médias estão distantes em relação ao espalhamento, então as duas nuvens são linearmente separáveis a menos de um punhado de exceções.
Produza a Figura 1: um gráfico de dispersão dos 2000 pontos, uma cor por classe.
B — Implemente o perceptron
Escreva um perceptron de camada única do zero. Esta mesma implementação é reutilizada no Exercício 2 — escreva uma vez, como função ou classe.
-
Predição. \(\hat{y} = \text{degrau}(\mathbf{w} \cdot \mathbf{x} + b)\), onde \(\text{degrau}(z) = 1\) se \(z \geq 0\) e \(0\) caso contrário.
-
Regra de atualização. Para cada amostra \((\mathbf{x}, y)\), calcule \(\hat{y}\) e aplique
\[ \mathbf{w} \leftarrow \mathbf{w} + \eta \, (y - \hat{y}) \, \mathbf{x}, \qquad b \leftarrow b + \eta \, (y - \hat{y}) \]com \(y, \hat{y} \in \{0, 1\}\). O erro \((y - \hat{y})\) é \(0\) quando a predição está correta — logo amostras bem classificadas não produzem atualização — e \(+1\) ou \(-1\) nos dois tipos de engano.
Por que não \(\mathbf{w} \leftarrow \mathbf{w} + \eta \, y \, \mathbf{x}\)?
Você vai encontrar essa forma em muitos livros. Ela pertence à convenção em que os rótulos são \(-1\) e \(+1\). Com os rótulos \(0/1\) usados aqui, ela nunca atualizaria na Classe 0, e o perceptron jamais conseguiria corrigir um falso positivo. Case a regra com os seus rótulos.
-
Inicialização. Sorteie \(\mathbf{w}\) com
rng.normal(0, 0.01, size=2)e use \(b = 0\). Não comece de \(\mathbf{w} = \mathbf{0}\) — o item D pede que você raciocine sobre a taxa de aprendizado, e a partir de um início todo zero a taxa comprovadamente não muda nada (ela apenas reescala \(\mathbf{w}\), deixando a fronteira de decisão e a contagem de épocas idênticas). -
Taxa de aprendizado. \(\eta = 0.01\).
-
Parada. Treine até que uma passagem completa pelo dataset não produza nenhuma atualização, ou por no máximo 100 épocas, o que vier primeiro. Registre a acurácia no dataset completo após cada época.
C — Treine e meça
- Treine o modelo e reporte o \(\mathbf{w}\) final, o \(b\) final, o número de épocas e a acurácia final.
- Produza a Figura 2: a fronteira de decisão \(\mathbf{w} \cdot \mathbf{x} + b = 0\) desenhada sobre os pontos, com os pontos mal classificados marcados de forma distinta.
- Produza a Figura 3: acurácia \(\times\) época.
D — Análise
- Por que dados separáveis convergem rápido? Ligue sua resposta à regra de atualização: o que acontece com o número de atualizações por época ao longo do treino?
- Re-execute o treino com \(\eta = 1.0\), sem mudar mais nada. Reporte a contagem de épocas e a acurácia final, e compare a direção de \(\mathbf{w}\) (ou seja, \(\mathbf{w} / \lVert \mathbf{w} \rVert\)) com a da execução com \(\eta = 0.01\). As duas devem chegar a 100%, mas por fronteiras diferentes — explique o que \(\eta\) controla, sabendo que cada atualização soma \(\eta \, \mathbf{x}\) a pesos que começaram com magnitude em torno de \(0{,}01\).
- Agora argumente o que teria acontecido partindo de \(\mathbf{w} = \mathbf{0}\), \(b = 0\). Mostre algebricamente que rodar todo o treino duas vezes, com \(\eta_1\) e \(\eta_2\), produz pesos que diferem apenas pelo fator constante \(\eta_2 / \eta_1\) — de modo que a fronteira de decisão e a contagem de épocas são idênticas e \(\eta\) não tem efeito algum. É por isso que o item B proíbe a partida do zero.
Exercício 2
Dados sobrepostos: o caso que o perceptron não resolve
A — Gere os dados
Gere duas classes de pontos 2D, 1000 amostras por classe:
- Classe 0: Média \(= [3, 3]\), Covariância \(= [[1.5, 0], [0, 1.5]]\)
- Classe 1: Média \(= [4, 4]\), Covariância \(= [[1.5, 0], [0, 1.5]]\)
Agora as médias estão próximas e o espalhamento é três vezes maior, então as nuvens se sobrepõem bastante e nenhuma reta as separa.
Produza a Figura 4: um gráfico de dispersão dos 2000 pontos, uma cor por classe.
B — Treine guardando os melhores pesos
Reutilize a implementação do Exercício 1, sem alterações, com o mesmo \(\eta = 0.01\) e o mesmo limite de 100 épocas. Como os dados não são separáveis, o laço de treino nunca vai parar de atualizar — então você vai acompanhar dois conjuntos de pesos:
- os pesos finais — os que o laço tiver na mão depois da última época;
- os pesos do pocket — o melhor até agora: toda vez que uma atualização produzir uma acurácia no dataset completo maior que qualquer uma já vista, copie \((\mathbf{w}, b)\) para o seu "bolso" e guarde. Este é o algoritmo pocket, e essa cópia é a única coisa que você acrescenta ao laço.
Reporte, para os dois conjuntos: \(\mathbf{w}\), \(b\) e a acurácia.
O que esperar
Os dois números vão ficar bem distantes, e a acurácia dos pesos finais vai parecer quebrada — perto de 50%, que é o que se obtém chutando. Esse é o resultado correto, não um bug no seu código. O item D pede que você explique.
C — Figuras
- Produza a Figura 5: as duas fronteiras de decisão — final e pocket — desenhadas sobre os pontos, com os mal classificados marcados.
- Produza a Figura 6: duas curvas contra a época — a acurácia dos pesos atuais e a melhor até agora (pocket).
D — Análise
- A melhor reta para estes dados acerta cerca de 73%. Seus pesos do pocket devem chegar perto disso; os finais, não. Explique a diferença. Onde a fronteira final fica em relação à nuvem de pontos, e por que o laço de treino a deixa ali? Dica: compare o quanto \(b\) anda por engano com o quanto \(\mathbf{w}\) anda, sabendo que \(\lVert \mathbf{x} \rVert \approx 5\) nestes dados.
- Compare a Figura 3 com a Figura 6. No Exercício 1 a curva de acurácia estabiliza; aqui, não. O que o teorema da convergência do perceptron garante, e qual das suas hipóteses este dataset viola?
- Mais épocas resolvem? Um \(\eta\) menor resolve? Justifique pela regra de atualização, e não por tentativa e erro.
Resumo dos resultados
Encerre o relatório com esta tabela, preenchida:
| # | Quantidade | Valor |
|---|---|---|
| 1 | Exercício 1 — \(\mathbf{w}\) e \(b\) finais | |
| 2 | Exercício 1 — épocas até convergir | |
| 3 | Exercício 1 — acurácia final | |
| 4 | Exercício 1 — épocas e acurácia final com \(\eta = 1.0\) | |
| 5 | Exercício 2 — \(\mathbf{w}\) e \(b\) finais | |
| 6 | Exercício 2 — acurácia dos pesos finais | |
| 7 | Exercício 2 — acurácia dos pesos do pocket | |
| 8 | Exercício 2 — época em que o melhor do pocket ocorreu |
Critérios de Avaliação
O entregável desta atividade é um relatório que inclui:
- Uma breve descrição da sua abordagem de implementação e dos desafios enfrentados.
- O código do perceptron 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.
- 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 — o Exercício 2 deve ir mal. O que é avaliado é o método, as figuras e o relato honesto do que você obteve.
Exercício 1 — Dados separáveis (4 pontos):
| Pontos | Critério | O que garante nota cheia |
|---|---|---|
| 0,5 | Geração dos dados (A) | Parâmetros corretos, 1000 amostras por classe, semente fixa, Figura 1 legível. |
| 2,0 | Implementação (B) | Perceptron escrito do zero, com a regra dirigida pelo erro em \(\{0,1\}\), inicialização não nula e a condição de parada especificada. Sem modelo de terceiros. |
| 1,0 | Treino e figuras (C) | \(\mathbf{w}\), \(b\), épocas e acurácia finais reportados no texto; Figuras 2 e 3 corretas e rotuladas. |
| 0,5 | Análise (D) | Explica a convergência pela regra de atualização; reporta as duas execuções de \(\eta\) com as direções das fronteiras; e mostra algebricamente que, a partir do zero, \(\eta\) apenas reescalaria \(\mathbf{w}\), deixando a fronteira e a contagem de épocas inalteradas. |
Exercício 2 — Dados sobrepostos (4 pontos):
| Pontos | Critério | O que garante nota cheia |
|---|---|---|
| 0,5 | Geração dos dados (A) | Parâmetros corretos, 1000 amostras por classe, semente fixa, Figura 4 legível. |
| 1,0 | Treino com o pocket (B) | A implementação do Exercício 1 reutilizada sem alterações, mais o rastreio do melhor até agora; os dois conjuntos de pesos e as duas acurácias reportados. |
| 1,0 | Figuras (C) | Figura 5 com as duas fronteiras e os pontos mal classificados marcados; Figura 6 com as duas curvas. |
| 1,5 | Análise (D) | Explica a diferença entre a acurácia final e a do pocket pela regra de atualização e pela posição da fronteira; identifica a hipótese de que o teorema da convergência precisa e que este dataset quebra; argumenta corretamente que nem mais épocas nem um \(\eta\) menor resolvem. |
Relatório (2 pontos):
| Pontos | Critério | O que garante nota cheia |
|---|---|---|
| 1,0 | Organização | Um título por exercício e por item, na ordem do enunciado; figuras numeradas como pedido; código comentado. |
| 1,0 | Resumo e reprodutibilidade | A tabela de resumo preenchida, e os números reportados reproduzíveis a partir da semente indicada. |