Quay lại danh sách thử thách
Dễ 0 đã giải Tỷ lệ chấp nhận 0%

Đạo hàm của các hàm kích hoạt

Tính đạo hàm của sigmoid, ReLU, Leaky ReLU hoặc tanh tại từng giá trị, chính là độ dốc mà lan truyền ngược cần.

Bạn sẽ học được gì

  • Tính độ dốc của các hàm kích hoạt phổ biến
  • Dùng lại đầu ra sigmoid để tính đạo hàm
  • Chuẩn bị các phần lan truyền ngược cần

Đề bài

Xem bản gốc (English)

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ụ

Ví dụ 1
Đầ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.

Ví dụ 2
Đầ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.

Học hỏi từ người khác

Giải pháp cộng đồng

Chưa có giải pháp nào được chia sẻ. Hãy giải thử thách này để đăng giải pháp đầu tiên.