본문 바로가기

Deep Learning

[Deep Learning] 220808 학습일기

 

밑바닥부터 시작하는 딥러닝 - YES24

직접 구현하고 움직여보며 익히는 가장 쉬운 딥러닝 입문서 이 책은 라이브러리나 프레임워크에 의존하지 않고, 딥러닝의 핵심을 ‘밑바닥부터’ 직접 만들어보며 즐겁게 배울 수 있는 본격 딥

www.yes24.com

 

 

1.

행렬의 곱을 사용해 A1를 구하고 시그모이드 함수를 이용해 Z를 구해보자.(0층 -> 1층)

import numpy as np

def sigmoid(x):
    return 1/(1+np.exp(-x))

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
Z1 = sigmoid(A1)

print(A1)
print(Z1)

<출력값>

[[0.3 0.7 1.1]]
[[0.57444252 0.66818777 0.75026011]]

 

1층-> 2층도 구현해보자.

import numpy as np

def sigmoid(x):
    return 1/(1+np.exp(-x))

#0층 -> 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]])

A1 = np.dot(X,W1) +B1
Z1 = sigmoid(A1)
'''Z1 shape는 1,3'''

#1층 -> 2층
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(A2)
print(Z2)

<출력값>

[[0.51615984 1.21402696]]
[[0.62624937 0.7710107 ]]

1층의 출력 Z1이 2층의 입력이 된다.

 

 

이제 2층에서 출력층으로 신호를 전달해보자.

import numpy as np

def sigmoid(x):
    return 1/(1+np.exp(-x))

#0층 -> 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]])

A1 = np.dot(X,W1) +B1
Z1 = sigmoid(A1)
'''Z1 shape는 1,3'''

#1층 -> 2층
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)
'''Z2의 shape는 1,2'''

#2층 -> 출력층
def identity_function(x):
    return x

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

print(Y)

<출력값>

[[0.31682708 0.69627909]

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

항등함수는 입력을 그대로 출력하는 함수이다.

 

출력층의 활성화 함수는 풀고자 하는 문제의 성질에 맞게 정한다.

회귀함수에는 항등함수를, 2클래스 분류에는 시그모이드 함수를, 다중 클래스 분류에는 소프트맥스 함수를 사용하는 것이 일반적이다.

 

 

위에서 했던 것들을 그림으로 정리하면 다음과 같다.

 

 

 

위의 구현을 다시 정리해보자.

import numpy as np

def sigmoid(x):
    return 1/(1+np.exp(-x))

def identity_function(x):
    return x

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

    return y

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

신경망 구현의 관례에 따르면 가중치만 W1과 같이 대문자로 쓰고, 그 외 편향과 중간 결과는 소문자로 써야한다고 한다.

 

init_network() 함수에는 딕셔너리 변수인 network가 있다. 이 딕셔너리 변수 network에는 각 층에 필요한 매개변수(가중치와 편향)이 저장된다.

 

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

 

뒤에 신경망 학습을 더 배우면 역방향( backward, 출력에서 입력 방향) 처리도 나온다고 한다.

 

 

'Deep Learning' 카테고리의 다른 글

[Deep Learning] 220810 학습일기  (0) 2022.08.10
[Deep Learning] 220809 학습일기  (0) 2022.08.10
[Deep Learning] 220806 학습일기  (0) 2022.08.08
[Deep Learning] 220805 학습일기  (0) 2022.08.05
[Deep Learning] 220803 학습일기  (0) 2022.08.03