모든 챌린지
보통 0명 해결 정답률 0%

2층 신경망의 순전파

입력을 ReLU 은닉층과 sigmoid 출력층에 통과시킵니다.

배우게 될 내용

  • 은닉층과 출력층 연결하기
  • 한 층의 출력을 다음 층에 넣기
  • 신경망 전체로 예측하기

문제

원문 보기 (영어)

작은 신경망에는 은닉층과 출력층이 있습니다. 데이터는 이들을 차례로 흐릅니다.

  1. 은닉층: h_j = ReLU(inputs · hidden_weights[j] + hidden_biases[j]), 여기서 ReLU(z) = max(0, z)
  2. 출력층: y_k = sigmoid(h · output_weights[k] + output_biases[k]), 여기서 sigmoid(z) = 1 / (1 + e^(-z))

forward_pass(inputs, hidden_weights, hidden_biases, output_weights, output_biases)를 구현하세요.

입력

inputs: n개의 입력 값.

hidden_weights, hidden_biases: 은닉층. 은닉 뉴런마다 한 행의 가중치와 하나의 편향.

output_weights, output_biases: 출력층. 출력마다 한 행과 하나의 편향; 각 행은 은닉 뉴런마다 하나의 가중치를 가집니다.

출력

신경망의 출력 y 리스트를 반환하세요.

제약 조건

1 ≤ 입력 수, 은닉 뉴런 수, 출력 수 ≤ 50

-10 ≤ 각 값 ≤ 10

예시

예시 1
입력:
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]
]

예상 출력:
expected = [0.182426]
입력:
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}
};

예상 출력:
std::vector<double> expected = {0.182426};
입력:
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}
};

예상 출력:
double[] expected = new double[] {0.182426};

설명

은닉층: ReLU(1×1 + 0.5×(-2) + 0) = ReLU(0) = 0, ReLU(1×0.5 + 0.5×1 + 0.5) = 1.5. 출력: sigmoid(0×1 + 1.5×(-1) + 0) = sigmoid(-1.5) ≈ 0.182426.

예시 2
입력:
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]
]

예상 출력:
expected = [0.5, 0.268941]
입력:
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}
};

예상 출력:
std::vector<double> expected = {0.5, 0.268941};
입력:
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}
};

예상 출력:
double[] expected = new double[] {0.5, 0.268941};

설명

은닉층: ReLU(2) = 2, ReLU(-2) = 0. 출력 1: sigmoid(2×0.5 + 0 - 1) = sigmoid(0) = 0.5. 출력 2: sigmoid(2×(-0.5) + 0) = sigmoid(-1) ≈ 0.268941.

접근 방법

먼저 스스로 풀어 본 뒤 힌트를 하나씩 열어 보세요.

힌트 1

먼저 입력으로 hidden activation을 모두 계산한 뒤, 그 hidden 출력으로 마지막 layer를 계산하세요.

힌트 2

각 layer는 dot product와 bias들의 묶음이며, hidden layer에는 ReLU, output에는 sigmoid를 씁니다.

힌트 3

원래 입력을 두 번째 layer에 섞지 마세요. 두 번째 layer는 hidden layer 출력만 봅니다.

예상 복잡도

시간 O(hn + oh), 추가 공간 O(h + o)

참고 자료

이 문제는 CodeUtility에 맞게 수정되었습니다. 위의 설명과 제한 조건을 따르세요.

다른 사람의 풀이 보기

커뮤니티 솔루션

아직 공개된 풀이가 없습니다. 문제를 풀고 첫 풀이를 공유하세요.