퍼셉트론, 신경망, 활성화 함수

GURI·2022년 1월 11일
0

Deep-Learning

목록 보기
1/3

퍼셉트론은 복잡한 함수를 표현할 수 있지만, 가중치를 설정하는 작업은 사람이 수동으로 해야 한다.

신경망은 퍼셉트론과 다르게 가중치 매개변수의 적절한 값을 데이터로부터 자동으로 학습하는 능력이 있다.

1. 신경망

신경망은 입력층, 은닉층, 출력층으로 구성되어 있다.

은닉층의 뉴런은 눈에 보이지 않는다.

은닉층이 1개일 때, 입력층은 0층, 은닉층은 1층, 출력층은 2층이라고 한다.

은닉층이 1개일 때 신경망은 모두 3층으로 구성되지만 가중치를 갖는 층은 2개뿐이기 때문에 ‘2층 신경망’이라고도 한다.

2. 퍼셉트론

신경망의 뉴런이 연결되는 방식은 퍼셉트론과 다른 것이 없다.

퍼셉트론?

퍼셉트론이란?

퍼셉트론은 신경망(딥러닝)의 기원이 되는 알고리즘이다.

퍼셉트론은 다수의 신호를 입력으로 받아 하나의 신호를 출력한다. (신호는 1과 0으로 이루어져 있다. {1 : 신호가 흐른다, 0 : 신호가 흐르지 않는다})

b는 편향을 나타내는 매개변수로, 뉴런이 얼마나 쉽게 활성화되느냐를 제어한다.

w는 각 신호의 가중치를 나타내는 매개변수로, 각 신호의 영향력을 제어한다.

위 그림 퍼셉트론의 동작은 x1,x2x_1, x_2, 1이라는 3개의 신호가 뉴런에 입력되어, 각 신호에 가중치를 곱한 후, 다음 뉴런에 전달된다.

이 신호들의 값을 더하여, 그 합이 0을 넘으면 1을 출력하고 그렇지 않으면 0을 출력한다. 참고로 편향의 입력 신호는 항상 1이다.

위 식을 더 간결한 형태로 다시 작성한다면,

y=h(b+w1x1+w2x2)y = h(b + w_1x_1 + w_2x_2) / h(x)={0,(x<=0)1,(x>0)h(x) = \begin{cases}0, & (x <= 0 ) \\1, & (x > 0) \end{cases}

입력 신호의 총합이 h(x)라는 함수를 거쳐 변환되어, 그 변환된 값이 y의 출력이 됨을 보여준다.

3. 활성화 함수

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

a=b+w1x1+w2x2a = b+w_1x_1 + w_2x_2 / y=h(a)y = h(a)

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

활성화 함수의 처리 과정을 명시적으로 표현

즉, 가중치 신호를 조합한 결과가 a라는 노드가 되고, 활성화 함수 hh를 통과하여 y라는 노드로 변환되는 과정이 분명하게 나타나 있다. (뉴런 = 노드)

활성화 함수가 퍼셉트론에서 신경망으로 가기 위한 길잡이이다.

3.1 활성화 함수 알아보기

3.1.1 계단 함수

입력이 0을 넘으면 1을 출력, 그 외에는 0을 출력

# 실수만 받아들이는 함수 (배열 X)
def step(x):
	if x > 0:
		return 1
	else:
		return 0

# 넘파이 배열도 지원되도록 수정
def step(x):
	y = x > 0
	return y.astype(np.int)

3.1.2 시그모이드 함수

시그모이드 함수는 S자형 곡선의 대표 함수이다.

e는 자연 상수로 2.7182... 의 값을 가지며, 시그모이드는 계단 함수와 달리 모든 점에서 미분가능하고 모든 점에서 연속인 값을 가진다.

그래프를 그려보면 계단함수처럼 입력이 음수로 들어오면 0으로 수렴하고, 입력이 양수로 들어오면 1로 수렴하는 모습을 가지고 있다. 시그모이드는 계단함수를 대체해서 사용된 활성 함수이다.

h(x)=11+exh(x) = { 1 \over {1+e^{-x} } }

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

시그모이드는 계단함수를 대체할 좋은 대안이었지만 DNN에서 역전파시에 기울기 소실 문제가 발생한다. DNN은 층을 깊게 해서 학습을 효율을 높이는 방향으로 진행되는데, 층이 깊어지면 깊어질수록 기울기 소실 문제는 더 심해집니다

계단 함수와 시그모이드 함수를 비교했을 때, 가장 먼저 느껴지는 점은 매끄러움의 차이이다.

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

계단 함수는 0을 경계로 출력이 갑자기 바뀌어버린다. 시그모이드 함수의 매끈함이 신경망 학습에서 아주 중요한 역할을 하게 된다.

계단 함수는 0, 1의 값만 반환하는 반면 시그모이드 함수는 실수를 반환하는 점도 다르다.

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

두 함수의 공통점으로는 입력이 작을 때의 출력은 0에 가깝고 입력이 커지면 출력이 1에 가까워진다는 구조가 있다. 또한 입력이 아무리 작거나 커도 출력은 언제나 0에서 1 사이이다.

또한 두 함수는 모두 비선형 함수이다.

신경망에서는 활성화 함수로 비선형 함수를 사용해야 한다.

선형 함수를 사용하면 신경망의 층을 깊게 하는 의미가 없어진다. 선형 함수의 문제는 층을 아무리 깊게 해도 은닉층이 없는 네트워크로도 똑같은 기능을 할 수 있다는 데 있다.

즉, 층을 쌓는 혜택을 얻고 싶다면 활성화 함수로는 반드시 비선형 함수를 사용해야 한다.

3.1.2 ReLU 함수

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

relu(x)={x,(x>0)0,(x0)relu(x) = \begin{cases}x, & (x > 0 ) \\0, & (x \le 0) \end{cases}

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

많은 경우 ReLU 함수를 활성 함수로 사용한다.

ReLU는 음이 아닌 구간에서 기울기가 0이 아니기 때문에 시그모이드나 tanh에 비해 빠른 학습이 가능해진다.

3.1.3 Hyperbolic Tangent(tanh)

Hyperbolic Tangent(tanh, 하이퍼볼릭탄젠트) 함수는 시그모이드의 대체재로 사용되는 활성 함수이다.

Hyperbolic Tangent 함수는 시그모이드와 유사하고 대신 출력 범위가 -1에서 1로 확장되었다.

tanh 함수의 출력 범위가 시그모이드보다 더 넓고 기울기가 큰 범위가 더 넓기 때문에 시그모이드보다 학습에 유리하다는 장점이 있다.

tanh의 수식은 다음과 같고, 대부분의 프로그래밍 언어와 계산기에 tanh() 함수가 제공되어 사용되고 있다.

tanh(x)=1ex1+extanh(x) = {{1-e^{-x}} \over {1+e^{-x}}}

tanh 함수는 시그모이드보다 출력범위가 넓어졌고, 기울기도 커져서 학습에 유리하지만, 여전히 시그모이드가 가지고 있는 한계를 그대로 가지고 있다. DNN에서의 기울기 소실 문제는 여전히 해결되지 않았다.

3.2 출력층 활성화 함수

신경망은 분류와 회귀 모두에 이용할 수 있다. 다만 둘 중 어떤 문제냐에 따라 출력층에서 사용하는 활성화 함수가 달라진다.

일반적으로 회귀에는 항등 함수, 분류에는 소프트맥스 함수를 사용한다.

3.2.1 항등 함수(identity function)

항등 함수는 입력을 그대로 출력한다. 입력과 출력이 항상 같다.

f(x)=yf(x) = y

3.2.2 소프트맥스 함수 (softmax function)

yk=exp(ak)i=1nexp(ai)y_k = {{{ exp(a_k) }} \over \sum^n_{i=1} exp(a_i)}

n은 출력층의 뉴런 수, yky_k는 k번째 출력임을 뜻한다.

소프트맥스 함수의 분자는 입력 신호 aka_k의 지수 함수, 분모는 모든 입력 신호의 지수 함수의 합으로 구성된다.

위 그림과 같이 소프트맥스의 출력은 모든 입력 신호로부터 화살표를 받는다.

식의 분모에서 보듯, 출력층의 각 뉴런이 모든 입력 신호에서 영향을 받기 때문이다.

def softmax(x):
	exp_a = np.exp(a)
	sum_exp_a = np.sum(exp_a)
	y = exp_a / sum_exp_a
	return y

소프트맥스 함수 구현 시 주의할 점

앞선 softmax를 컴퓨터로 계산할 때는 오버플로 문제가 생긴다.

softmax는 지수 함수를 사용하는데, 지수 함수라는 것이 쉽게 아주 큰 값을 낸다.

만약 큰 값끼리 나눗셈을 하면 결과 수치가 불안정해진다.

이를 개선하기 위해 수식을 개선해보자.

yk=exp(ak+C)i=1nexp(ai+C)y_k = {{{ exp(a_k + C') }} \over \sum^n_{i=1} exp(a_i + C')}

softmax의 지수 함수를 계산할 때 어떤 정수를 더해도 (혹은 빼도) 결과는 바뀌지 않는다.

여기서 CC'에 어떤 값을 대입해도 상관없지만, 오버플로를 막을 목적으로는 입력 신호 중 최댓값을 이용하는 것이 일반적이다.

a = np.array([1010, 1000, 990])
np.exp(a) / np.sum(np.exp(a))
#array([nan, nan, nan])

c = np.max(a)  #1010
a - c
#array([0, -10, -20])

np.exp(a-c) / np.sum(np.exp(a-c))
#array([9.99954600e-01, 4.53978686e-05, 2.06106005e-09])

개선된 python 함수

def softmax(a):
	c = np.max(a)
	exp_a = np.exp(a - c) #오버플로 대책
	sum_exp_a = np.sum(exp_a)
	y = exp_a / sum_exp_a
	return y
a = np.array([0.3, 2.9, 4.0])
y = softmax(a)
print(y)
# [0.01821127 0.24519181 0.73659691]
np.sum(y)
# 1.0

위와 같이 소프트맥스 함수의 출력은 0에서 1.0 사이의 실수이다. 또한 출력의 총합은 1이다.

출력 총합이 1이 된다는 점은 소프트맥스 함수의 중요한 성질인데 이로 인해 소프트맥스 함수의 출력을 확률로 해석할 수 있다.

출처

profile
Done is better than Perfect.

0개의 댓글