Voltar para os desafios
Médio 0 resolvidos 0% de aceitação

Algoritmo de aprendizado do perceptron

Treine o perceptron original, que só atualiza os pesos quando erra.

O que você vai aprender

  • Atualizar os pesos só quando erra
  • Treinar por várias épocas
  • Conhecer como funcionava o primeiro modelo neural

Problema

Ver original (inglês)

O perceptron (1958) é o primeiro algoritmo de aprendizado para um neurônio artificial. Ele prevê com uma função degrau e aprende com os erros.

Comece com todos os pesos e o viés em 0. Em cada época, percorra os exemplos em ordem e, para cada exemplo x com rótulo y (0 ou 1):

  1. previsão = 1 se x · weights + bias > 0, senão 0
  2. error = y - previsão (ou seja, -1, 0 ou 1)
  3. Se error ≠ 0: weights[i] ← weights[i] + learning_rate × error × x[i] para cada i, e bias ← bias + learning_rate × error

Implemente train_perceptron(samples, labels, learning_rate, epochs).

Entrada

samples: m exemplos com n variáveis cada.

labels: Os m rótulos, cada um 0 ou 1.

learning_rate, epochs: O tamanho do passo e o número de passadas pelos dados.

Saída

Retorne os pesos finais seguidos do viés (n + 1 números).

Restrições

1 ≤ m ≤ 100, 1 ≤ n ≤ 10, 1 ≤ epochs ≤ 100

0 < learning_rate ≤ 1

-10 ≤ cada variável ≤ 10

Exemplos

Exemplo 1
Entrada:
epochs = 1
labels = [0, 0, 0, 1]
samples = [
    [0.0, 0.0],
    [0.0, 1.0],
    [1.0, 0.0],
    [1.0, 1.0]
]
learning_rate = 1.0

Saída esperada:
expected = [1.0, 1.0, 1.0]
Entrada:
long long epochs = 1;
std::vector<long long> labels = {0, 0, 0, 1};
std::vector<std::vector<double>> samples = {
    {0.0, 0.0},
    {0.0, 1.0},
    {1.0, 0.0},
    {1.0, 1.0}
};
double learning_rate = 1.0;

Saída esperada:
std::vector<double> expected = {1.0, 1.0, 1.0};
Entrada:
long epochs = 1;
long[] labels = new long[] {0, 0, 0, 1};
double[][] samples = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {0.0, 1.0},
    new double[] {1.0, 0.0},
    new double[] {1.0, 1.0}
};
double learning_rate = 1.0;

Saída esperada:
double[] expected = new double[] {1.0, 1.0, 1.0};

Explicação

[0, 0]: z = 0, prevê 0, correto. [0, 1] e [1, 0]: também preveem 0, correto. [1, 1]: prevê 0, mas o rótulo é 1, então error = 1: os pesos viram [1, 1] e o viés vira 1. Resultado: [1, 1, 1].

Exemplo 2
Entrada:
epochs = 10
labels = [0, 0, 0, 1]
samples = [
    [0.0, 0.0],
    [0.0, 1.0],
    [1.0, 0.0],
    [1.0, 1.0]
]
learning_rate = 1.0

Saída esperada:
expected = [2.0, 1.0, -2.0]
Entrada:
long long epochs = 10;
std::vector<long long> labels = {0, 0, 0, 1};
std::vector<std::vector<double>> samples = {
    {0.0, 0.0},
    {0.0, 1.0},
    {1.0, 0.0},
    {1.0, 1.0}
};
double learning_rate = 1.0;

Saída esperada:
std::vector<double> expected = {2.0, 1.0, -2.0};
Entrada:
long epochs = 10;
long[] labels = new long[] {0, 0, 0, 1};
double[][] samples = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {0.0, 1.0},
    new double[] {1.0, 0.0},
    new double[] {1.0, 1.0}
};
double learning_rate = 1.0;

Saída esperada:
double[] expected = new double[] {2.0, 1.0, -2.0};

Explicação

Depois de 10 épocas o perceptron aprendeu a porta AND: com pesos [2, 1] e viés -2, só [1, 1] dá z > 0.

Como abordar

Tente sozinho primeiro e depois abra uma dica de cada vez.

Dica 1

Processe as amostras em ordem a cada época, porque atualizações anteriores afetam predições posteriores.

Dica 2

Atualize só quando a classe prevista for diferente do rótulo, ajustando pesos e bias juntos.

Dica 3

A regra de predição usa um teste de sinal estrito, então score zero conta como classe 0.

Complexidade esperada

tempo O(epochs × m × n), espaço extra O(n)

Referências

Este desafio foi adaptado para o CodeUtility. Siga o enunciado e as restrições acima.

Aprenda com outros

Soluções da comunidade

Ainda não há soluções publicadas. Resolva este desafio para compartilhar a primeira.