Đề bài
Lan truyền ngược nhân gradient với đạo hàm của từng hàm kích hoạt. Hãy cài đặt activation_derivative(name, values) và trả về đạo hàm tại mọi giá trị:
| name | đạo hàm |
|---|---|
"sigmoid" | s × (1 - s), với s = 1 / (1 + e^(-x)) |
"relu" | 1 nếu x > 0, ngược lại 0 |
"leaky_relu" | 1 nếu x > 0, ngược lại 0.01 |
"tanh" | 1 - tanh(x)² |
Đầu vào
name: Một trong "sigmoid", "relu", "leaky_relu" hoặc "tanh".
values: Các đầu vào x của hàm kích hoạt.
Đầu ra
Trả về đạo hàm tại từng giá trị, giữ nguyên thứ tự.
Ràng buộc
1 ≤ độ dài ≤ 1.000
-50 ≤ mỗi giá trị ≤ 50
Ví dụ
Đầu vào:
name = "sigmoid"
values = [0.0, 2.0]
Kết quả mong đợi:
expected = [0.25, 0.104994]
Đầu vào:
std::string name = "sigmoid";
std::vector<double> values = {0.0, 2.0};
Kết quả mong đợi:
std::vector<double> expected = {0.25, 0.104994};
Đầu vào:
string name = "sigmoid";
double[] values = new double[] {0.0, 2.0};
Kết quả mong đợi:
double[] expected = new double[] {0.25, 0.104994};
Giải thích
Tại 0, s = 0.5 và độ dốc là 0.5 × 0.5 = 0.25, điểm dốc nhất của sigmoid. Tại 2, s ≈ 0.880797 và độ dốc khoảng 0.104994.
Đầu vào:
name = "relu"
values = [-3.0, 0.0, 4.5]
Kết quả mong đợi:
expected = [0.0, 0.0, 1.0]
Đầu vào:
std::string name = "relu";
std::vector<double> values = {-3.0, 0.0, 4.5};
Kết quả mong đợi:
std::vector<double> expected = {0.0, 0.0, 1.0};
Đầu vào:
string name = "relu";
double[] values = new double[] {-3.0, 0.0, 4.5};
Kết quả mong đợi:
double[] expected = new double[] {0.0, 0.0, 1.0};
Giải thích
ReLU nằm ngang khi x ≤ 0 (độ dốc 0) và có độ dốc 1 khi x > 0, nên kết quả là [0, 0, 1].
Hướng tiếp cận
Hãy tự thử trước, sau đó mở từng gợi ý một.
Gợi ý 1
Đạo hàm phụ thuộc vào loại activation, nên xử lý từng function riêng cho mỗi giá trị đầu vào.
Gợi ý 2
Với sigmoid và tanh, hãy dùng lại output của activation hoặc giá trị function chuẩn thay vì tính lại từ đầu theo cách rườm rà.
Gợi ý 3
Chú ý dấu ngưỡng: ReLU dùng kiểm tra dương nghiêm ngặt, còn leaky ReLU giữ một độ dốc nhỏ cho giá trị không dương.
Độ 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.