Problème
Le perceptron (1958) est le premier algorithme d'apprentissage pour un neurone artificiel. Il prédit avec une fonction en escalier et apprend de ses erreurs.
Partez de poids et d'un biais tous à 0. À chaque époque, parcourez les exemples dans l'ordre, et pour chaque exemple x d'étiquette y (0 ou 1) :
- prédiction = 1 si x · weights + bias > 0, sinon 0
- error = y - prédiction (donc -1, 0 ou 1)
- Si error ≠ 0 : weights[i] ← weights[i] + learning_rate × error × x[i] pour chaque i, et bias ← bias + learning_rate × error
Implémentez train_perceptron(samples, labels, learning_rate, epochs).
Entrée
samples : m exemples de n variables chacun.
labels : les m étiquettes, chacune 0 ou 1.
learning_rate, epochs : le pas et le nombre de passages sur les données.
Sortie
Renvoyez les poids finaux suivis du biais (n + 1 nombres).
Contraintes
1 ≤ m ≤ 100, 1 ≤ n ≤ 10, 1 ≤ epochs ≤ 100
0 < learning_rate ≤ 1
-10 ≤ chaque variable ≤ 10
Exemples
Entrée :
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
Sortie attendue :
expected = [1.0, 1.0, 1.0]
Entrée :
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;
Sortie attendue :
std::vector<double> expected = {1.0, 1.0, 1.0};
Entrée :
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;
Sortie attendue :
double[] expected = new double[] {1.0, 1.0, 1.0};
Explication
[0, 0] : z = 0, prédit 0, correct. [0, 1] et [1, 0] : prédisent aussi 0, correct. [1, 1] : prédit 0 mais l'étiquette vaut 1, donc error = 1 : les poids deviennent [1, 1] et le biais 1. Résultat : [1, 1, 1].
Entrée :
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
Sortie attendue :
expected = [2.0, 1.0, -2.0]
Entrée :
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;
Sortie attendue :
std::vector<double> expected = {2.0, 1.0, -2.0};
Entrée :
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;
Sortie attendue :
double[] expected = new double[] {2.0, 1.0, -2.0};
Explication
Après 10 époques, le perceptron a appris la porte ET : avec les poids [2, 1] et le biais -2, seul [1, 1] donne z > 0.
Comment l'aborder
Essayez d'abord seul, puis ouvrez les indices un par un.
Indice 1
Traitez les échantillons dans l’ordre à chaque epoch, car les mises à jour précédentes influencent les prédictions suivantes.
Indice 2
Mettez à jour seulement quand la classe prédite diffère de l’étiquette, et ajustez weights et bias ensemble.
Indice 3
La règle de prédiction utilise un test de signe strict, donc un score de zéro compte comme la classe 0.
Complexité attendue
temps O(epochs × m × n), espace supplémentaire O(n)
Références
Ce défi a été adapté pour CodeUtility. Suivez l'énoncé et les contraintes ci-dessus.