Tất cả thử thách
Trung bình 0 đã giải Tỷ lệ chấp nhận 0%

Lan truyền xuôi trong mạng hai lớp

Đưa đầu vào qua một lớp ẩn ReLU và một lớp đầu ra sigmoid.

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

  • Nối một lớp ẩn với lớp đầu ra
  • Đưa đầu ra của lớp này vào lớp tiếp theo
  • Chạy dự đoán của cả mạng

Đề bài

Xem bản gốc (English)

Một mạng nơ-ron nhỏ có lớp ẩn và lớp đầu ra. Dữ liệu đi tuần tự qua chúng:

  1. Lớp ẩn: h_j = ReLU(inputs · hidden_weights[j] + hidden_biases[j]), với ReLU(z) = max(0, z)
  2. Lớp đầu ra: y_k = sigmoid(h · output_weights[k] + output_biases[k]), với sigmoid(z) = 1 / (1 + e^(-z))

Hãy cài đặt forward_pass(inputs, hidden_weights, hidden_biases, output_weights, output_biases).

Đầu vào

inputs: n giá trị đầu vào.

hidden_weights, hidden_biases: Lớp ẩn, mỗi nơ-ron ẩn một hàng trọng số và một bias.

output_weights, output_biases: Lớp đầu ra, mỗi đầu ra một hàng và một bias; mỗi hàng có một trọng số cho mỗi nơ-ron ẩn.

Đầu ra

Trả về danh sách đầu ra y của mạng.

Ràng buộc

1 ≤ số đầu vào, số nơ-ron ẩn, số đầu ra ≤ 50

-10 ≤ mỗi giá trị ≤ 10

Ví dụ

Ví dụ 1
Đầu vào:
inputs = [1.0, 0.5]
hidden_biases = [0.0, 0.5]
output_biases = [0.0]
hidden_weights = [
    [1.0, -2.0],
    [0.5, 1.0]
]
output_weights = [
    [1.0, -1.0]
]

Kết quả mong đợi:
expected = [0.182426]
Đầu vào:
std::vector<double> inputs = {1.0, 0.5};
std::vector<double> hidden_biases = {0.0, 0.5};
std::vector<double> output_biases = {0.0};
std::vector<std::vector<double>> hidden_weights = {
    {1.0, -2.0},
    {0.5, 1.0}
};
std::vector<std::vector<double>> output_weights = {
    {1.0, -1.0}
};

Kết quả mong đợi:
std::vector<double> expected = {0.182426};
Đầu vào:
double[] inputs = new double[] {1.0, 0.5};
double[] hidden_biases = new double[] {0.0, 0.5};
double[] output_biases = new double[] {0.0};
double[][] hidden_weights = new double[][] {
    new double[] {1.0, -2.0},
    new double[] {0.5, 1.0}
};
double[][] output_weights = new double[][] {
    new double[] {1.0, -1.0}
};

Kết quả mong đợi:
double[] expected = new double[] {0.182426};

Giải thích

Lớp ẩn: ReLU(1×1 + 0.5×(-2) + 0) = ReLU(0) = 0 và ReLU(1×0.5 + 0.5×1 + 0.5) = 1.5. Đầu ra: sigmoid(0×1 + 1.5×(-1) + 0) = sigmoid(-1.5) ≈ 0.182426.

Ví dụ 2
Đầu vào:
inputs = [2.0]
hidden_biases = [0.0, 0.0]
output_biases = [-1.0, 0.0]
hidden_weights = [
    [1.0],
    [-1.0]
]
output_weights = [
    [0.5, 0.5],
    [-0.5, 2.0]
]

Kết quả mong đợi:
expected = [0.5, 0.268941]
Đầu vào:
std::vector<double> inputs = {2.0};
std::vector<double> hidden_biases = {0.0, 0.0};
std::vector<double> output_biases = {-1.0, 0.0};
std::vector<std::vector<double>> hidden_weights = {
    {1.0},
    {-1.0}
};
std::vector<std::vector<double>> output_weights = {
    {0.5, 0.5},
    {-0.5, 2.0}
};

Kết quả mong đợi:
std::vector<double> expected = {0.5, 0.268941};
Đầu vào:
double[] inputs = new double[] {2.0};
double[] hidden_biases = new double[] {0.0, 0.0};
double[] output_biases = new double[] {-1.0, 0.0};
double[][] hidden_weights = new double[][] {
    new double[] {1.0},
    new double[] {-1.0}
};
double[][] output_weights = new double[][] {
    new double[] {0.5, 0.5},
    new double[] {-0.5, 2.0}
};

Kết quả mong đợi:
double[] expected = new double[] {0.5, 0.268941};

Giải thích

Lớp ẩn: ReLU(2) = 2 và ReLU(-2) = 0. Đầu ra 1: sigmoid(2×0.5 + 0 - 1) = sigmoid(0) = 0.5. Đầu ra 2: sigmoid(2×(-0.5) + 0) = sigmoid(-1) ≈ 0.268941.

Hướng tiếp cận

Hãy tự thử trước, sau đó mở từng gợi ý một.

Gợi ý 1

Trước hết tính toàn bộ hidden activations từ input, rồi dùng các output đó cho lớp cuối.

Gợi ý 2

Mỗi lớp là một loạt dot product cộng bias, với ReLU ở hidden layer và sigmoid ở output.

Gợi ý 3

Không trộn input gốc vào lớp thứ hai; nó chỉ nhận các giá trị từ hidden layer.

Độ phức tạp mong đợi

thời gian O(hn + oh), bộ nhớ phụ O(h + o)

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.