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

Apic·6일 전
0

신경망

아래의 그림은 신경망을 그림으로 표현한 것이다.
여기서 가장 왼쪽을 입력층, 중간을 은닉층, 오른쪽을 출력층이라고 한다.
은닉층 뉴련은 입력층이나 출력층과 달리 사람의 눈에 보이지 않는다.
아래의 그림에서는 0층이 입력층, 1층이 은닉층, 3층이 출력층이 된다.

앞전에 배운 퍼셉트론에서는 편향이 그려지지 않았다.
그래서 편향을 명시한 퍼셉트론을 그림으로 나타낸다면 아래와 같다.

이 신호의 결과값 y가 0 이하면 0을 출력하고 0을 넘으면 1을 출력한다.
이러한 조건식을 하나의 함수로 나타낸다.

y=h(b+w1x1+w2x2)y = h(b+w_1x_1 + w_2x_2)
h(x)={001>0}h(x) = \begin{Bmatrix} 0 \leq 0 \\ 1 > 0 \end{Bmatrix}

수식 1

h(x)의 함수 값이 0을 넘으면 1이고 아니면 0을 출력한다.

활성화 함수

이처럼 h(x)와 같은 함수를 일반적으로 활성화 함수라고 한다.
이름처럼 입력 신호의 총합이 활성화를 일으키는지 정하는 역할을 한다.

그리고 그 식을 가중치가 곱해진 입력 신호의 총합을 계산하고, 그 합을 활성화 함수에 입력해 결과를 내는 2단계로 처리하면 아래와 같이 된다.

a=b+w1x1+w2x2a = b + w_1x_1 + w_2x_2

h(x)={00)1>0)}h(x) = \begin{Bmatrix} 0 \leq 0) \\ 1 > 0) \end{Bmatrix}

수식 2

가중치가 달린 입력 신호와 편향의 총합을 계산하고 이를 a라고 한다.
그리고 그 를 함수 h()에 넣어 y를 출력한다.
그것을 그림으로 나타내면 아래와 같다.

입력이 2개인 퍼셉트론

왼쪽은 일반적인 뉴런, 오른쪽은 활성화 처리 과정을 명시한 뉴런

출처: https://github.com/youbeebee/deeplearning_from_scratch/tree/master

단순 퍼셉트론은 임계값을 경계로 출력이바뀌는 함수를 활성화 함수로 사용한 모델을 가리키고
다층 퍼셉트론은 신경망(여러 층으로 구성되고 시그모이드 함수 등 매끈한 활성화 함수를 사용하는 네트워크)를 가리킨다.

활성화 함수의 종류

수식2와 같은 활성화 함수는 임계값을 기준으로 출력이 0, 1로 바뀌는데 이런 함수를 계단 함수라고 한다. 그래서 퍼셉트론에서는 활성화 함수로 계단 함수를 이용한다 라고 할 수 있다.

시그모이드 함수

신경망에서 자주 이용하는 활성화 함수인 시그모이드 함수를 나타낸 식이다.

h(x)=11+exp(x)h(x) = \frac{1}{1 + \exp(-x)}

수식 3

  • exp(x)exp(-x)exe^{-x}를 뜬하며 자연상수로 2.7182..를 갖는 실수다.

계단 함수 구현하기

계단 함수는 입력이 0을 넘으면 1을 출력하고, 그 외에는 0을 출력하는 함수다.

def step_function(x):
    if x > 0:
        return 1
    else:
        return 0

구현은 단순하고 쉽지만 는 실수만 받아들인다.
즉 step_function(3.0)은 되지만 step_function(np.array([1.0], [2.0])은 안된다.

def step_function(x):
    y = x > 0
    return y.astype(np.int)

이렇게 하면 numpy도 지원하는 함수를 만들 수 있다.

한 번 간단하게 테스트 해보자.

x = np.array([-1.0, 1.0, 2.0])
y = x > 0
y	# array([False,  True,  True])

0보다 크면 True, 작으면 False로 변환한 배열 y가 생성된다.

하지만 y bool 타입 배열인데 우리는 int 타입의 배열을 원한다.

y = y.astype(np.int64)
y	# array([0, 1, 1])

참고로 여기서 np.int32와 np.int64의 차이는 표현할 수 있는 값의 범위 차이다.
그리고 그 만큼 사용하는 메모리 양도 다르다.

계단 함수의 그래프

이제 이 함수를 그래프로 그려보자.

import matplotlib.pyplot as plt
import numpy as np

def step_function(x):
    return np.array(x > 0, dtype=np.int64)

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()
입력이 2개인 퍼셉트론

계단 함수 그래프

그림처럼 0을 기준으로 출력이 바뀌는 것을 볼 수 있다.

시그모이드 함수 구현하기

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

여기서 np.exp(-x)는 수식3에서 exp(x)exp(-x)에 해당한다.

x = np.array([-1.0, 1.0, 2.0])
sigmoid(x)	# array([0.26894142, 0.73105858, 0.88079708])

이렇게 잘 처리하는 것을 볼 수 있다.
이 함수가 넘파이 배열도 처리하는 비밀은 브로드 캐스트에 있다.

  • 브로드 캐스트: 넘파이 배열과 스칼라 값의 연산을 넘파이 배열의 원소 각각과 스칼라값의 연산으로 바꿔 수행

그리고 시그모이드 함수를 그래프로 나타내면 아래와 같다.

x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()
입력이 2개인 퍼셉트론

시그모이드 함수 그래프

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

입력이 2개인 퍼셉트론

계단 함수(점선)와 시그모이드 함수(실선)

출처: https://github.com/youbeebee/deeplearning_from_scratch/tree/master

두 그림의 차이점은 매끄러움이다.
시그모이드 함수는 곡선이고, 계단 함수는 직선이다.
시그모이드 함수는 연속적으로 값이 변화하고, 계단 함수는 0 또는 1 이지선다다.

비선형 함수

두 함수의 공통점은 비선형 함수라는 것이다.

신경망에서는 활성화 함수로 비선형 함수를 사용해야 한다.
선형 함수를 사용하면 신경망의 층을 깊게 하는 의미가 없기 때문이다.

선형 함수는 아무리 층을 깊게 해도 은닉층이 없는 네트워크로 똑같은 기능을 만들 수 있다.
그렇기 때문에 층을 쌓아 이득을 얻고 싶다면 비선형 함수를 활성화 함수로 사용해야 한다.

ReLU 함수

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

또한 수식은 아래처럼 쓸 수 있다.

h(x)={x(x0)0(x>0)}h(x) = \begin{Bmatrix} x (x \leq 0) \\ 0 (x > 0) \end{Bmatrix}

수식 4

def relu(x):
    return np.maximum(0, x)

다차원 배열의 계산

행렬의 곱

2x2 행렬의 곱은 아래 그림처럼 계산한다.

a = np.array([[1,2], [3,4]])
b = np.array([[5,6], [7,8]])
np.dot(a, b)	# array([[19, 22],
       			#       [43, 50]])
  • np.dot()은 1차원 배열이면 백터를, 2차원 배열이면 행렬 곱을 계산한다.

신경망에서의 행렬 곱

입력이 2개인 퍼셉트론

행렬 곱으로 신경망의 계산 수행

출처: https://github.com/youbeebee/deeplearning_from_scratch/tree/master

x = np.array([1,2])
w = np.array([[1,3,5], [2,4,6]])
y = np.dot(x, w)
y	# array([ 5, 11, 17])

여기서 x는 1x3, w = 2x3이다.
곱셈 결과 행렬의 크기는 x의 행 * w의 열이기 때문에 1x3이 나와야 한다.

y=[12][135246]y = \begin{bmatrix} 1 & 2 \end{bmatrix} \begin{bmatrix} 1 & 3 & 5 \\ 2 & 4 & 6 \end{bmatrix}

이것을 계산하면
12+22=51*2 + 2*2 = 5
13+24=111*3 + 2*4 = 11
15+26=171*5 + 2*6 = 17
이기 때문에 결과는 [51117]\begin{bmatrix} 5 & 11 & 17 \end{bmatrix}이 나오게 된다.

profile
코딩 공부하는 사람

0개의 댓글