Chapter 03. 신경망(2)

Junho_Mun·2025년 6월 24일

3.4 3층 신경망 구현하기

핵심은 신경망에서의 계산을 행렬 계산으로 처리할 수 있다는 것이다.

(1234)(5678)=(19224350)\begin{pmatrix} 1 & 2 \\ 3 & 4 \\ \end{pmatrix} \begin{pmatrix} 5 & 6 \\ 7 & 8 \\ \end{pmatrix} = \begin{pmatrix} 19 & 22 \\ 43 & 50 \\ \end{pmatrix}
A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])

np.dot(A,B) # 곱 출력
>>>
(
    [19,22],
    [43,50]
)

다음과 같이 행렬의 곱은 왼쪽 행렬의 행과 오른쪽 행렬의 열을 원소별로 곱하고 그 값을 더해서 계산한다.

1×5+2×7=191 \times 5 +2 \times7 = 19
3×5+4×7=433 \times 5 + 4 \times 7 = 43

이때 코드에서 np.dot은 행렬의 곱을 연산하는데 입력이 1차원 배열이면 벡터를, 2차원 배열이면 행렬 곱을 출력한다.

주의할 점은 행렬의 형상이다.
왼쪽행렬의 1번째 차원의 원소 수(열 수)와 오른쪽 행렬의 0번째 차원의 원소수(행 수)가 같아야한다.

즉, A=m×nA = m \times n 행렬이고 B=n×pB = n \times p 이여야지만 A×BA \times B 연산이 가능하며 결과 행렬은 m×pm \times p가 된다.

3.4.1 신경망의 가중치와 편향 표기법

이때 이 그림은 뉴런 x2x_2에서 다음층의 뉴런인 a1(1){a_1}^{(1)}로 향하며 가중치는 w12(1)w_{12}^{(1)}을 가지고 있다. 이 표기법에 대해 알아보자.

가중치의 지수부의 (1)(1)은 1층의 가충치임을 명시하고있다. 또 아래의 숫자 1122는 앞층의 2번째 뉴런에서 다음 층의 1번째 뉴런으로 향함을 의미한다. 가중치 오른쪽 아래의 인덱스 번호는 '다음 층 번호, 앞 층 번호'순으로 적는다.

  • 가중치(WW)
    • 지수부의 (1)(1)1층의 가중치임을 명시한다.
    • 아래첨자 ijijii다음 층의 뉴런 번호, jj앞 층의 뉴런 번호를 의미한다.
    • 입력층의 노두 수(열) X 다음층(1층)의 노드 수(행)이다.
  • 편향(BB)
    • 편향은 다음 층의 각 뉴런에 독립적으로 더해지는 값이다.
    • b11b_{1}^{1}는 1층의 1번째 뉴런에 더해지는 값이다.
    • 뉴런이 얼마나 쉽게 활성화 되는지 조절할 수 있다. 이는 선형 회귀에서 절편과 유사한 역할을 하여, 데이터가 원점을 지나지 않아도 모델이 유연하게 학습할 수 있도록 돕는다.

3.4.2 활성화 전 신호의 계산

그렇다면 a1(1){a_1}^{(1)}를 계산해보도록 하겠다.
a1(1)=w111x1+w121x2+b11a_{1}^{(1)} = w_{11}^{1} x_1 + w_{12}^{1}x_2 + b_{1}^{1}
여기서 행렬 곱을 이용해보자.
A(1)=XW(1)+B(1)A^{(1)} = XW^{(1)}+B^{(1)}
로 간소화할 수 있다.
이때, 가중치부분은 다음과 같다.

A(1)=(a(1)(1),a(2)(1),a(3)(1))(1층활성화전신호벡터)A^{(1)} = (a_{(1)}^{(1)} , a_{(2)}^{(1)}, a_{(3)}^{(1)}) (1층활성화 전 신호 벡터)
X=(x1,x2)(입력벡터)X = (x_1 , x_2) (입력 벡터)
B(1)=(b1(1),b2(1),b2(1))(1층편향벡터)B^{(1)} = (b_{1}^{(1)} , b_{2}^{(1)} , b_{2}^{(1)}) (1층 편향 벡터)
W(1)=(w11(1)w21(1)w31(1)w12(1)w22(1)w32(1))(1층가중치행렬)W^{(1)} = \begin{pmatrix} w_{11}^{(1)} &w_{21}^{(1)} &w_{31}^{(1)} \\ w_{12}^{(1)} &w_{22}^{(1)} &w_{32}^{(1)} \\ \end{pmatrix} (1층 가중치 행렬)
X = np.array([1.0,0.5])
W1 = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
B1 = np.array([0.1,0.2,0.3])

print(W1.shape) #   (2,3)
print(X.shape)  #   (2,)
print(B1.shape) #   (3,)

A1 = np.dot(X,W1) + B1

3.4.3 활성화 함수의 적용

이어서 1층의 활성화 함수의 처리를 살펴보자면 위와 같이 은닉층에서의 가중치 합을 aa라고 표기하고 활성화 함수 h()h()의 처리결과를 zz로 표기한다.

A1 = np.dot(X,W1) + B1
Z1 = sigmoid(A1)

print(A1)   #   [0.3 0.7 1.1]
print(Z1)   #   [0.57444252 0.66818777 0.75026011]

3.4.4 다음 층으로의 전달 (1층 -> 2층)

이어서 1층에서 2층으로 가는 과정을 구현해본다.

W2 = np.array[[0.1, 0.4],[0.2, 0.5],[0.3, 0.6]]
B2 = np.array([0.1, 0.2])

print(Z1.shape) #   (3,)
print(W2.shape) #   (3,2)
print(B2.shape) #   (2,)

A2 = np.dot(Z1,W2) + B2 # 이전층의 출력은 다시 다음층의 입력이 된다.
Z2 = sigmoid(A2)

3.4.5 출력층으로의 전달

마지막으로, 은닉층에서 출력층으로의 전달을 구현해보자.
이전과의 차이점은 활성화 함수가 다르다.

W3 = np.array([0.1, 0.3],[0.2, 0.4])
B3 = np.array([0.1, 0.2])

A3 = np.dot(Z2,W3) + B3
Y = identity_function(A3) # Y = A3 와 같다.

출력층의 활성화 함수는 풀고자 하는 문제의 성질에 맞게 정한다.
예를 들어 회귀에는 항등함수를, 2클래스 분류에는 시그모이드 함수를, 다중 클래스 분류에는 소프트 맥스를 사용하는 것이 일반적이다.

  • 회귀(Regression)문제 -> 주택 가격 예측
  • 2클래스 분류 -> 합격/불합격
  • 다중 클래스 분류 -> 손글씨 숫자 인식 등

최종 구현 (전체 신경망 순전파)


def init_network() :
    network = {}
    network['W1'] = np.array([[0.1, 0.3, 0.5],[0.2, 0.4, 0.6]])
    network['b1'] = np.array([0.1,0.2,0.3])
    network['W2'] = np.array([[0.1,0.4],[0.2,0.5],[0.3,0.6]])
    network['b2'] = np.array([0.1,0.2])
    network['W3'] = np.array([[0.1,0.3],[0.2,0.4]])
    network['b3'] = np.array([0.1,0.2])

    return network

def forward(network, x):
    W1,W2,W3 = network['W1'],network['W2'],network['W3']
    b1,b2,b3 = network['b1'],network['b2'],network['b3']

    a1 = np.dot(x,W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1,W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2,W3) + b3
    y = a3
    return y

network = init_network()
x = np.array([1.0,0.5])
y = forward(network, x) #   [0.31682708 0.69627909]
print(y)

위 코드는 입력층에서 출력층 까지 신호가 한 방향으로 전달되는 순전파(Forward Propagation)과정을 구현하였다. 이 코드의 출력이 실제 정답과 얼마나 차이나는지 오차를 계산하여 역전파(Backpropagation)를 통해 가중치와 편향을 업데이트하며 학습을 진행한다.

profile
Bioinformatics and Data science

0개의 댓글