본문 바로가기
프로그래밍 놀이터/머신러닝, AI, 딥러닝

[머신러닝] #3 신경망 #1

by 돼지왕왕돼지 2018. 7. 3.

[머신러닝] #3 신경망 #1


"Deep Learning from Scratch” 책을 보고 제가 필요한 내용만 정리한 내용입니다.

자세한 내용은 책을 구매해서 보세요~

2층 신경망, 3층 신경망, 3층 신경망 구현하기, activation function, astype, Dot, exp, Matrix, ndim, notation, rectified linear unit, ReLU 함수, Shape, sigmoid function, step function, 가중치 설정, 계단 함수, 다중 클래스 분류, 다차원 배열의 계산, 렐루, 머신러닝, 비선형 함수, 선형 함수, 소프트맥스 함수, 시그모이드 함수, 신경망, 신경망의 내적, 은닉층, 입력층, 출력층, 출력층 활성화 함수, 층의 깊이, 클래스 분류, 퍼셉트론, 퍼셉트론 신경망, 항등 함수, 행렬, 행렬 곱, 행렬의 내적, 활성화 함수, 회귀


-

앞 장에서 배운 퍼셉트론은 좋은 소식과 나쁜 소식이 있다.

좋은 소식은 퍼셉트론으로 복잡한 함수를 표현할 수 있다는 것이고,

나쁜 소식은 가중치 설정은 여전히 사람이 수동으로 한다는 것.


신경망은 이 나쁜 소식을 해결해준다.

가중치 매개변수의 적절한 값을 데이터로부터 자동으로 학습하는 능력이 신경망의 중요한 성질이다.



3.1. 퍼셉트론에서 신경망으로


3.1.1. 신경망의 예.


-

2층 신경망, 3층 신경망, 3층 신경망 구현하기, activation function, astype, Dot, exp, Matrix, ndim, notation, rectified linear unit, ReLU 함수, Shape, sigmoid function, step function, 가중치 설정, 계단 함수, 다중 클래스 분류, 다차원 배열의 계산, 렐루, 머신러닝, 비선형 함수, 선형 함수, 소프트맥스 함수, 시그모이드 함수, 신경망, 신경망의 내적, 은닉층, 입력층, 출력층, 출력층 활성화 함수, 층의 깊이, 클래스 분류, 퍼셉트론, 퍼셉트론 신경망, 항등 함수, 행렬, 행렬 곱, 행렬의 내적, 활성화 함수, 회귀

가장 왼쪽 줄은 입력층,

맨 오른쪽 줄을 출력층,

중간 층을 은닉층이라고 한다.


은닉층의 뉴런은 입력층이나 출력층과 달리 사람 눈에는 보이지 않는다.

이 책에서는 입력층, 은닉층, 출력층을 차례로 0층, 1층, 2층이라고 한다.



-

신경망은 모두 3층으로 구성되지만, 가중치를 갖는 층은 2개뿐이기 때문에 “2층 신경망” 이라고 한다.

문헌에 따라서는 신경망을 구성하는 층수를 기준으로 3층 신경망이라고도 하기도 하니 주의해야 한다.




3.1.2. 퍼셉트론 복습


-

2층 신경망, 3층 신경망, 3층 신경망 구현하기, activation function, astype, Dot, exp, Matrix, ndim, notation, rectified linear unit, ReLU 함수, Shape, sigmoid function, step function, 가중치 설정, 계단 함수, 다중 클래스 분류, 다차원 배열의 계산, 렐루, 머신러닝, 비선형 함수, 선형 함수, 소프트맥스 함수, 시그모이드 함수, 신경망, 신경망의 내적, 은닉층, 입력층, 출력층, 출력층 활성화 함수, 층의 깊이, 클래스 분류, 퍼셉트론, 퍼셉트론 신경망, 항등 함수, 행렬, 행렬 곱, 행렬의 내적, 활성화 함수, 회귀

y = h(b + w1x1 + w2x2)

h(x) = 0 if x <= 0

      = 1 if x > 0




3.1.3. 활성화 함수의 등장


-

h(x) 라는 함수는 입력 신호의 총합을 출력 신호로 변환하는 함수로 일반적으로 활성화 함수(activation function) 이라고 한다.

활성화 함수는 이름처럼 입력 신호의 총합이 활성화를 일으키는지를 정하는 역할을 한다.





3.2. 활성화 함수


-

활성화 함수는 임계값을 경계로 출력이 바뀌는데, 이런 함수를 계단 함수(step function)이라고 한다.

퍼셉트론에서는 활성화 함수로 계단 함수를 이용한다라고 할 수 있다.

활성화 함수를 계단 함수에서 다른 함수로 변경하는 것이 신경망의 세계로 나아가는 열쇠이다.




3.2.1. 시그모이드 함수


-

시그모이드 함수(sigmoid function)

2층 신경망, 3층 신경망, 3층 신경망 구현하기, activation function, astype, Dot, exp, Matrix, ndim, notation, rectified linear unit, ReLU 함수, Shape, sigmoid function, step function, 가중치 설정, 계단 함수, 다중 클래스 분류, 다차원 배열의 계산, 렐루, 머신러닝, 비선형 함수, 선형 함수, 소프트맥스 함수, 시그모이드 함수, 신경망, 신경망의 내적, 은닉층, 입력층, 출력층, 출력층 활성화 함수, 층의 깊이, 클래스 분류, 퍼셉트론, 퍼셉트론 신경망, 항등 함수, 행렬, 행렬 곱, 행렬의 내적, 활성화 함수, 회귀

e 는 자연상수로 2.7182... 값을 갖는다.



-

신경망에서는 활성화 함수로 시그모이드 함수를 이용하여 신호를 변환하고, 그 변환된 신호를 다음 뉴런에 전달한다.

기존에 본 퍼셉트론과 앞으로 볼 신경망의 주된 차이는 이 활성화 함수 뿐이다.




3.2.2. 계단 함수 구현하기


-

def step_function(x):

    y = x > 0 # boolean array

    return y.astype(np.int) # boolean 이 0 또는 1 로 매핑된 array return, asType 은 자료형 변환




3.2.3. 계단 함수의 그래프




3.2.4. 시그모이드 함수 구현하기


-

def sigmoid(x):

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




3.2.5. 시그모이드 함수와 계단 함수 비교


-

시그모이드 함수는 부드러운 곡선이며 입력에 따라 출력이 연속적으로 변화한다.

계단 함수는 0을 경계로 출력이 갑자기 바뀌어버린다.

시그모이드 함수의 매끈함이 신경망 학습에서 아주 중요한 역할을 한다.


계단 한수가 0과 1 중 하나의 값만 돌려주는 반면 시그모이드 함수는 실수(0.731.. 0.880... 등)를 돌려준다는 점도 다르다.

이전에 본 퍼셉트론에서는 뉴런 사이에 0 혹은 1이 흘렀다면, 신경망에서는 연속적인 실수가 흐른다.



-

둘의 공통점은 큰 관점에서 같은 모양을 하고 있다.

둘 다 입력이 작을 때의 출력은 0에 가깝고, 입력이 커지면 출력이 1에 가까워진다.

둘 다 입력이 중요하면 큰 값을 출력하고 입력이 중요하지 않으면 작은 값을 출력한다.

입력이 아무리 작거나 커도 출력은 0에서 1사이이다.




3.2.6. 비선형 함수


-

계단 함수와 시그모이드 함수의 공통점은 둘 다 비선형 함수라는 것이다.

시그모이드 함수는 곡선, 계단 함수는 계단처럼 구부러진 직선으로 나타나며, 동시에 비선형 함수로 분류된다.



-

신경망에서는 활성화 함수로 비선형 함수를 사용하고, 선형 함수를 사용해서는 안 된다.

선형 함수를 이용하면 신경망의 층을 깊게 하는 의미가 없어지기 때문이다.


선형의 문제는 층을 아무리 깊게 해도 은닉층이 없는 네트워크로도. 똑같은 기능을 할 수 있다.

예를 들어 선형 함수 h(x) = cx 를 활성화 함수로 사용한 3층 네트워크가 있다고 하자.

y(x) = h(h(h(x))) 는 y(x) = c * c * c * x 처럼 곱셈을 세 번 수행하지만 실은 y(x) = ax 와 똑같다.

즉 은닉층이 없는 네트워크로 표현할 수 있다. 다시 말해 여러 층으로 구성하는 이점을 살릴 수 없다.




3.2.7. ReLU 함수


-

시그모이드 함수는 신경망 분야에서 오래전부터 이용해왔으나, 최근에는 ReLU(Rectified Linear Unit, 렐루) 함수를 주로 이용한다.

ReLU 는 입력이 0 을 넘으면 그 입력을 그대로 출력하고, 0 이하이면 0을 출력하는 함수이다.

2층 신경망, 3층 신경망, 3층 신경망 구현하기, activation function, astype, Dot, exp, Matrix, ndim, notation, rectified linear unit, ReLU 함수, Shape, sigmoid function, step function, 가중치 설정, 계단 함수, 다중 클래스 분류, 다차원 배열의 계산, 렐루, 머신러닝, 비선형 함수, 선형 함수, 소프트맥스 함수, 시그모이드 함수, 신경망, 신경망의 내적, 은닉층, 입력층, 출력층, 출력층 활성화 함수, 층의 깊이, 클래스 분류, 퍼셉트론, 퍼셉트론 신경망, 항등 함수, 행렬, 행렬 곱, 행렬의 내적, 활성화 함수, 회귀

h(x) = x if x > 0

      = 0 if x <= 0



-

def relu(x):

    return np.maximum(0, x)






3.3. 다차원 배열의 계산


3.3.1. 다차원 배열


-

배열의 차원수는 np.ndim() 함수로 확인할 수 있다.

배열의 형상은 인스턴스 변수인 shape 로 알 수 있다. return 값은 튜플이다.


ex)

B = np.array([[1,2], [3,4], [5,6]])

np.ndim(B) # 2

B.shape # (3,2) 이는 3X2 (row X column) 를 이야기함



-

2차원 배열은 특히 행렬(matrix)라고 부른다.

배열의 가로 방향을 행(row), 세로 방향을 열(column)이라고 한다.




3.3.2. 행렬의 내적(행렬 곱)


-

 1 2      5 6      19  22

        x         =

 3 4      7 8      43  50


1 * 5 + 2 * 7 = 19

1 * 6 + 2 * 8 = 22

3 * 5 + 4 * 7 = 43

3 * 6 + 4 * 8 = 50

행렬의 내적은 왼쪽 행렬의 행(가로)와 오른쪽 행렬의 열(세로)을 원소별로 곱하고 그 값들을 더해서 계산하며, 그 결과가 새로운 다차원 배열의 원소가 된다.



-

ex)

A = np.array([[1,2], [3,4]])

B = np.array([[5,6], [7,8]])

np.dot(A, B) # 내적은 dot 함수를 사용한다.

np.dot(A,B) 와 np.dot(B,A) 는 다른 값이 될 수 있다.



-

내적을 할 때는 행렬의 형상(shape)에 주의해야 한다.

왼쪽 행렬의 열 수와 오른쪽 행렬의 행 수가 같아야 한다.

2 X 3 행렬과 2 X 2 행렬은 내적을 할 수 없고, 2X2 행렬과 2X3 행렬은 내적을 할 수 있다.


3 X 2  dot   2 X 4   =  3 X 4

내적을 하려면 왼쪽의 뒷녀석과 오른쪽의 앞녀석이 같아야 하고 ( 여기서는 왼쪽의 2와 오른쪽의 2 )

결과 형상은 왼쪽의 앞 녀석, 오른쪽의 뒷 녀석이 된다. ( 여기서는 왼쪽의 3 과 오른쪽의 4. )



-

2차월 행렬과 1차원 배열일 경우도 똑같이 적용된다.


3 X 2 dot 2 = 3


왼쪽의 뒤쪽 녀석과 오른쪽의 값이 같아야 하며 ( 여기서는 왼쪽의 2와 오른쪽 단일 숫자 2 )

결과 형상은 왼쪽의 앞쪽 녀석이 된다. ( 여기서는 3 )

( vector 는 상황에 따라 가로 vector, 세로 vector 모두 가능하다고 본다. )




3.3.3. 신경망의 내적


-

2층 신경망, 3층 신경망, 3층 신경망 구현하기, activation function, astype, Dot, exp, Matrix, ndim, notation, rectified linear unit, ReLU 함수, Shape, sigmoid function, step function, 가중치 설정, 계단 함수, 다중 클래스 분류, 다차원 배열의 계산, 렐루, 머신러닝, 비선형 함수, 선형 함수, 소프트맥스 함수, 시그모이드 함수, 신경망, 신경망의 내적, 은닉층, 입력층, 출력층, 출력층 활성화 함수, 층의 깊이, 클래스 분류, 퍼셉트론, 퍼셉트론 신경망, 항등 함수, 행렬, 행렬 곱, 행렬의 내적, 활성화 함수, 회귀

위의 예제는 bias 와 활성화 함수 생략한 가중치만 갖는 케이스인데, 이를 내적으로 표시하면 아래와 같다.

X  dot  W  = Y


2 dot 2 X 3 = 3


X = np.array([1,2])

W = np.array([[1,3,5], [2,4,6]])

Y = np.dot( X, W )





3.4. 3층 신경망 구현하기


3.4.1. 표기법 설명


-

2층 신경망, 3층 신경망, 3층 신경망 구현하기, activation function, astype, Dot, exp, Matrix, ndim, notation, rectified linear unit, ReLU 함수, Shape, sigmoid function, step function, 가중치 설정, 계단 함수, 다중 클래스 분류, 다차원 배열의 계산, 렐루, 머신러닝, 비선형 함수, 선형 함수, 소프트맥스 함수, 시그모이드 함수, 신경망, 신경망의 내적, 은닉층, 입력층, 출력층, 출력층 활성화 함수, 층의 깊이, 클래스 분류, 퍼셉트론, 퍼셉트론 신경망, 항등 함수, 행렬, 행렬 곱, 행렬의 내적, 활성화 함수, 회귀

x1 -> Layer1 로 가는 weight 를 보면..

[1] 은 1층 내용이라는 이야기.

1 1 은 to 와 from 이다. (from to 가 아님을 주의!) 즉 0층의 1 에서 1층의 1로 간다는 이야기이다.




3.4.2. 각 층의 신호 전달 구현하기


-

편향을 뜻하는 뉴런은 인덱스가 1개밖에 없으며 to 를 가르킨다. (편향은 하나밖에 없기 때문 from 의 의미가 없다)



-

행렬의 내적을 이용하면 1층의 가중치 부분을 다음처럼 표현할 수 있다. ( 위의 그림과 다르게 책에서는 1층에 3개의 노드가 있다. )


A(1) = XW(1) + B(1) // 여기서 1 은 층을 나타냄


ex)

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



-

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



-

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

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




3.4.3. 구현 정리


-

ex)

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’] = …

    network[‘b2’] = …

    network[‘W3’] = …

    network[‘b3’] = …

    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 = sigmod(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)




댓글0