Đề bài
Perceptron (1958) là thuật toán học đầu tiên cho một nơ-ron nhân tạo. Nó dự đoán bằng hàm bậc thang và học từ những lần sai.
Bắt đầu với mọi trọng số và bias bằng 0. Ở mỗi epoch, duyệt các mẫu theo thứ tự, và với mỗi mẫu x có nhãn y (0 hoặc 1):
- dự đoán = 1 nếu x · weights + bias > 0, ngược lại 0
- error = y - dự đoán (tức là -1, 0 hoặc 1)
- Nếu error ≠ 0: weights[i] ← weights[i] + learning_rate × error × x[i] với mọi i, và bias ← bias + learning_rate × error
Hãy cài đặt train_perceptron(samples, labels, learning_rate, epochs).
Đầu vào
samples: m mẫu, mỗi mẫu n đặc trưng.
labels: m nhãn, mỗi nhãn là 0 hoặc 1.
learning_rate, epochs: Bước nhảy và số lượt duyệt qua dữ liệu.
Đầu ra
Trả về các trọng số cuối cùng, tiếp theo là bias (n + 1 số).
Ràng buộc
1 ≤ m ≤ 100, 1 ≤ n ≤ 10, 1 ≤ epochs ≤ 100
0 < learning_rate ≤ 1
-10 ≤ mỗi đặc trưng ≤ 10
Ví dụ
Đầu vào:
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
Kết quả mong đợi:
expected = [1.0, 1.0, 1.0]
Đầu vào:
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;
Kết quả mong đợi:
std::vector<double> expected = {1.0, 1.0, 1.0};
Đầu vào:
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;
Kết quả mong đợi:
double[] expected = new double[] {1.0, 1.0, 1.0};
Giải thích
[0, 0]: z = 0, dự đoán 0, đúng. [0, 1] và [1, 0]: cũng dự đoán 0, đúng. [1, 1]: dự đoán 0 nhưng nhãn là 1, nên error = 1: trọng số thành [1, 1] và bias thành 1. Kết quả: [1, 1, 1].
Đầu vào:
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
Kết quả mong đợi:
expected = [2.0, 1.0, -2.0]
Đầu vào:
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;
Kết quả mong đợi:
std::vector<double> expected = {2.0, 1.0, -2.0};
Đầu vào:
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;
Kết quả mong đợi:
double[] expected = new double[] {2.0, 1.0, -2.0};
Giải thích
Sau 10 epoch, perceptron đã học được cổng AND: với trọng số [2, 1] và bias -2, chỉ [1, 1] cho z > 0.
Tham khảo
Thử thách này đã được điều chỉnh cho CodeUtility. Hãy làm theo đề bài và các ràng buộc ở trên.