Đề bài
Để huấn luyện một nơ-ron, ta cần biết mỗi trọng số ảnh hưởng đến sai số thế nào. Với một ví dụ huấn luyện:
- z = inputs · weights + bias
- y = sigmoid(z) = 1 / (1 + e^(-z))
- hàm mất mát L = (y - target)²
Theo quy tắc chuỗi, với delta = dL/dz = 2 × (y - target) × y × (1 - y):
- dL/dw_i = delta × x_i
- dL/dbias = delta
Hãy cài đặt neuron_gradients(inputs, weights, bias, target).
Đầu vào
inputs, weights: Hai danh sách cùng độ dài n.
bias: Bias của nơ-ron.
target: Đầu ra đúng cho ví dụ này (từ 0 đến 1).
Đầu ra
Trả về danh sách n + 1 số: gradient của từng trọng số theo thứ tự, sau đó là gradient của bias.
Ràng buộc
1 ≤ n ≤ 100
-10 ≤ mỗi đầu vào, trọng số và bias ≤ 10
0 ≤ target ≤ 1
Ví dụ
Đầu vào:
bias = 0.0
inputs = [1.0, 2.0]
target = 1.0
weights = [0.5, -0.25]
Kết quả mong đợi:
expected = [-0.25, -0.5, -0.25]
Đầu vào:
double bias = 0.0;
std::vector<double> inputs = {1.0, 2.0};
double target = 1.0;
std::vector<double> weights = {0.5, -0.25};
Kết quả mong đợi:
std::vector<double> expected = {-0.25, -0.5, -0.25};
Đầu vào:
double bias = 0.0;
double[] inputs = new double[] {1.0, 2.0};
double target = 1.0;
double[] weights = new double[] {0.5, -0.25};
Kết quả mong đợi:
double[] expected = new double[] {-0.25, -0.5, -0.25};
Giải thích
z = 1×0.5 + 2×(-0.25) = 0, nên y = 0.5. delta = 2 × (0.5 - 1) × 0.5 × 0.5 = -0.25. Gradient: [-0.25×1, -0.25×2, -0.25] = [-0.25, -0.5, -0.25].
Đầu vào:
bias = 0.0
inputs = [3.0]
target = 0.0
weights = [0.0]
Kết quả mong đợi:
expected = [0.75, 0.25]
Đầu vào:
double bias = 0.0;
std::vector<double> inputs = {3.0};
double target = 0.0;
std::vector<double> weights = {0.0};
Kết quả mong đợi:
std::vector<double> expected = {0.75, 0.25};
Đầu vào:
double bias = 0.0;
double[] inputs = new double[] {3.0};
double target = 0.0;
double[] weights = new double[] {0.0};
Kết quả mong đợi:
double[] expected = new double[] {0.75, 0.25};
Giải thích
z = 0 và y = 0.5. delta = 2 × (0.5 - 0) × 0.5 × 0.5 = 0.25, nên gradient là [0.25×3, 0.25] = [0.75, 0.25]. Gradient dương nghĩa là trọng số nên giảm xuống.
Hướng tiếp cận
Hãy tự thử trước, sau đó mở từng gợi ý một.
Gợi ý 1
Bắt đầu bằng cách tính output sigmoid của neuron và đạo hàm loss theo giá trị trước activation.
Gợi ý 2
Gradient của mỗi weight là cùng một delta nhân với input đó, còn bias chỉ dùng delta.
Gợi ý 3
Giữ gradient của weight theo đúng thứ tự input, rồi thêm gradient của bias ở cuối.
Độ phức tạp mong đợi
thời gian O(n), bộ nhớ phụ O(n)
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.