티스토리 뷰

1. 3층 신경망 구현하기


아래 [그림 1]처럼 3층 신경망에서 수행되는, 입력부터 출력까지의 처리(순방향 처리)를 구현했습니다.

입력층(0층)은 2개, 은닉층(1층)은 3개, 두 번째 은닉층(2층)은 2개, 출력층(3층)은 2개 뉴런으로 구성


[그림 1]


[그림 2]를 보면 입력층의 뉴런 x2에서 다음 층의 뉴런 a1 으로 향하는 가중치를 표시하고 있습니다.

[그림 2]


[그림 3]과 같이 편향을 뜻하는 뉴런인 1이 추가되었습니다.

a1 (1)를 수식으로 나타내면

a1 (1) = w11 (1) * x1 + w12 (1) * x2 + b1 (1)


A(1) = XW(1) + B(1)


A(1) = (a1(1), a2(1) a3(1)), X = (x1, x2), B(1) = (b1(1), b2(1), b3(1))


w의 행렬은 아래와 같이 되겠죠.



요것을 numpy로 표현 해보겠습니다.

import numpy as np


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])


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

print(A1)


[그림 3]





[그림 4]는 은닉층에서의 가중치 합(가중 신호와 편향의 총합)을 A로 표기하고 활성화 함수 h()로 변환된 신호를 z로 표기합니다.

파이썬 코드로 보면 아래와 같이 표현할 수 있겠죠

import numpy as np

import torch


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])


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

print(A1)


#시그모이드 함수

def sigmoid(x):

    return 1 / (1 + np.exp(-x))

Z1 = sigmoid(A1)

print(Z1)

    

[0.3 0.7 1.1]

[0.57444252 0.66818777 0.75026011]   


[그림 4]



그렇다면 위의 z1이 또 a1(2), a2(2)에 보내지게 되고 거기서 활성화 함수를 더해줍니다.

아래 코드 처럼요.


import numpy as np

import torch


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])


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

print(A1)


#시그모이드 함수

def sigmoid(x):

    return 1 / (1 + np.exp(-x))

Z1 = sigmoid(A1)

print(Z1)

    

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

B2 = np.array([0.1, 0.2])


A2 = np.dot(Z1, W2) + B2

Z2 = sigmoid(A2)

print(Z2)



이제 마지막으로 은닉층 2에서 출력층으로 신호를 전달하는 [그림 5]입니다.

여기에서는 항등 함수인 identity_function()을 정의하고, 이를 출력층의 활성화 함수로 이용했습니다.

항등함수란, 입력을 그대로 출력하는 함수입니다.


[그림 5]



그렇다면 지금까지 구현해 본 것을 정리해보겠습니다.

여기서는 init_network()와 forward()라는 함수를 정의했습니다.

init_network() 함수는 가중치와 편향을 초기화하고 이들을 딕셔너리 변수인 network에 저장

그리고 forword() 함수는 입력 신호를 출력신호로 변환하는 처리과정을 모두 구현


함수이름을 forword라고 한 것은 신호가 순방향(입력에서 출력 방향)으로 전달됨(순전파)을 알리기 위함입니다.

import numpy as np


def init_network():

    network = {}

   #딕셔너리 형태로 들어감 {'W1' : array, 'b1' : array}

    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 sigmoid(x):

    return 1 / (1 + np.exp(-x))


def identity_function(x):

    return x


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 = identity_function(a3)

    

    return y

    

network = init_network()

x = np.array([1.0, 0.5])

y = forward(network, x)

print(y)   



댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31