인공지능/밑바닥부터 시작하는 딥러닝

(Chapter 3) 신경망

문_성 2022. 8. 2. 03:01
반응형

 

(퍼셉트론에서 신경망으로)

 

위의 사진은 신경망을 그림으로 나타낸 것 이다. 여기에서 가장 왼쪽 층을 입력층, 가운데 층을 은닉층, 가장 오른쪽 층을 출력층 이라고 한다.

 

그리고, 입력층 은닉층 출력층에 있는 원들을 노드 라고 한다.

 

전 글에서 퍼셉트론을 위와 같이 그림으로 나타내어 설명하지는 않았지만, 퍼셉트론을 굳이 수식이 아닌 그림으로 나타내면, 위와 같은 신경망의 그림과 똑같다는 것을 알 수 있다. (여기서 말하는 퍼셉트론은 단순 퍼셉트론이 아닌 다층 퍼셉트론이다.)

 

위 사진은 퍼셉트론 식이며, 이제는 다들 알 것이라고 생각한다. 

 

위의 식은 신경망에 대한 식이라고 볼 수 있다. 결과적으로 앞서 퍼셉트론의 식과 차이가 없다는것을 알 수 있지만, h(x) 라는 새로운 함수의 개념이 추가되었다.

 

이 함수를 활성화 함수 라고 한다.

 

지금은 활성화 함수의 개념이 추가되었다고 해서 퍼셉트론과 신경망의 차이가 생긴것은 아니지만, 이 활성화 함수가 퍼셉트론과 신경망의 차이를 만들어내는 큰 역할을 한다. 따라서 앞으로 나올 활성화 함수에 대해 잘 기억해두길 바란다.

 

 

(활성화 함수)

 

이제 활성화 함수에 대해 본격적으로 소개하도록 하겠다.

 

먼저, 앞에서 잠깐 알아봤던 활성화 함수인 계단 함수 에 대해서 알아보겠다. 계단 함수는 임계값을 경계로 출력이 바뀌는 함수로, 그래프 상에 나타내면 계단 모양이 나타난다고 해서 계단 함수라고 불린다. 앞서 보았던 h(x) 함수가 대표적인 계단 함수라고 보면 된다.

 

그 다음, 시그모이드 함수에 대해 알아보겠다.

 

위의 수식이 시그모이드 함수이다. 수식만 봐서는 쉽게 느낌(?)이 오지 않으니 그래프상에 나태나어보면

 

이렇게 0과 1 사이의 곡선으로 나타내어 진다는것을 알 수 있다. 따라서 x에 어떠한 값을 넣어도 0과 1 사이의 값을 출력하므로 값의 폭을 줄여주고 크고 작은 값들 사이에 연속성을 가진다.

 

이 두 활성화 함수들을 파이썬으로 나타내어보면

 

# 계단함수

def step_function(x) :
	y = x > 0
    return y.astype(np.int)
   
   
# 시그모이드 함수

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

위와 같이 나타낼 수 있다. (잘못된 tab은 티스토리 자체적인 오류인 것 같다. 무시해도 좋다.)

 

코드에서 흥미로운 점은 계단함수에 관한 부분인데, y = x > 0 의 부분이 numpy 를 많이 다루어보지 않은 사람에게는 의아한 점 일수도 있다. 필자도 numpy를 많이 다루어보지 않아서, 책을 보고 numpy의 편리한 기능(bool 연산) 이라는 것을 알았다. ㅋㅋ

 

 이렇게 대표적인 두가지 활성화 함수들을 알아보았는데, 둘의 공통점에 대해 살펴보면 둘 다 비선형 함수 라는 점이다.

 

비선형 함수는 말 그대로 선형이 아닌 함수를 뜻하며, 선형의 의미 그대로 직선 1개로는 그릴 수 없는 함수를 칭한다.

 

그럼, 선형 함수는 활성화 함수가 될 수 있는지에 관한 의문이 생긴다.

 

선형함수인 h(x) = c * x 가 활성화 함수라고 가정해보자. 이 활성화 함수를 이용한 3층 네트워크(신경망) 을 떠올려보면, y(x) = h(h(h(x))) 와 같은 출력값에 대한 신경망의 수식이 나온다. 

 

그러나, 이 수식은 y = c * c * c * x = c^3 * x 와 같이 하나의 수식으로 나타낼 수 있다. 즉, y  = a * x (a = c^3) 과 똑같은 식인 셈이다. 이러면 신경망의 층을 쌓는 이유가 없어진다. 아무리 층을 많이 쌓아도 출력값을 똑같은 형태의 하나의 선형식으로 나타낼 수 있기 때문이다.

 

따라서 층을 쌓는 혜택을 누리고 싶으면 비선형 함수를 사용하는것이 옳다.

 

마지막으로, 소개한 두 활성화 함수 이외에 최근에 많이 쓰이는 ReLU 라는 활성화 함수를 소개한다.

 

수식은 이렇다. 그래프는 따로 제공하지 않겠다. 수식만 봐도 머릿속에서 그래프가 자동으로 그려지는 함수이기 때문이다. ㅋㅋ

 

# ReLU 함수

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

위와 같이 파이썬으로도 쉽게 나타낼 수 있다.

 

 

(다차원 배열의 계산)

 

신경망 연산에서는 행렬 연산(곱셈) 이 아주 중요하게 쓰인다(여기서 행렬은, 2차원 배열을 의미한다.) 따라서, 먼저 행렬의 곱에 대해서 자세하게 알아보자.

 

행렬곱에 대한 설명이 잘 되어있는 사진을 들고 와보았다. 그림만 봐서는 이해가 잘 되지 않을 수 있으니 부과 설명을 이어가겠다.

 

위의 그림은 (3, 3) 형태의 a 행렬과 (3, 3) 형태의 b 행렬을 곱하여 (3, 3) 형태의 c 행렬을 결과로 가진다. 밑의 where c 부분을 잘 해석하면 a 행렬의 열 부분(가로) 과 b 행렬의 행 부분(세로) 를 각각 곱하여 세 값을 더한 것이 해당 c 값이 되는것을 알 수 있다.

 

위의 이미지를 보면 이해가 더 빠를 것이다. 해당 이미지는 (2, 3) 의 행렬과 (3, 2) 의 행렬의 곱에 관한 과정을 자세하게 나타내고 있다. 아마 이 이미지로 이해가 충분히 되리라 생각한다.

 

이러한 행렬 곱이 왜 중요하다고 하는지 이제 알아보자.

 

일단, 입력층의 노드가 2개이고 출력층의 노드가 3개인 2층 신경망을 먼저 떠올려보자. 

 

수식으로 나타내면 위와 같이 나타내어 질 것이다. 그러나 입력층과 출력층의 노드 갯수가 늘어날수록 출력값을 위와 같이 일일이 수식으로 나타내는것은 너무 귀찮다. 따라서 이때 행렬곱을 이용하는 것이다.

 

위처럼 행렬곱으로 나타내면 귀찮음 없이 한 연산만에 출력값을 모두 구할 수 있다. 행렬곱에 대한 이해가 충분하다면 위의 수식은 쉽게 이해되리라고 생각한다.

 

 

(출력층 설계하기)

 

출력층에 대해 자세히 알아보기 전, 희귀와 분류에 대한 개념부터 짚고 넘어가겠다.

 

희귀(regression) 는 입력 데이터에 대한 (연속적인) 수치를 예측하는 문제이고, 분류(classification) 는 입력 데이터가 어느 클래스에 해당하는지 구분하는 문제이다.

 

따라서, 신경망의 문제가 희귀인지 분류인지에 따라 출력층의 활성화 함수를 일반적으로 다르게 둔다.

 

먼저 희귀 일때에는 일반적으로 항등 함수를 사용한다. 항등 함수란 그냥 말 그대로 입력값을 그대로 출력하는 함수이다. 따라서 출력층에서의 입력 신호가 그대로 출력 신호가 된다.

 

수치에 대한 예측이 목적인 희귀에서는 값의 크기나 부호 등 특징이 중요하므로 항등 함수를 쓰는 경우가 대부분이다.

 

분류 일때에는 소프트맥스 함수를 사용한다.

 

위의 수식이 소프트맥스 함수이다. 전체 자연상수 제곱의 합 중 k번째의 값을 자연상수에 제곱하여 전체 합으로 나눈 값을 출력한다. 말이 좀 복잡하지만 크게 어렵지 않은 함수이다.

 

# 소프트맥스 함수

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

위의 코드가 소프트맥스를 구현한 코드이다. 코드를 보면 알 수 있듯이 크게 복잡하지는 않다.

 

소프트맥스 함수 또한 입력값에 대해 0 과 1 사이의 출력값을 내보내며, 큰 특징중 하나는 출력값의 총 합이 1이 된다는 것 이다. 따라서, 소프트맥스 함수의 출력값을 확률 개념으로 해석하는 경우도 있다.

 

 

 

 

반응형

'인공지능 > 밑바닥부터 시작하는 딥러닝' 카테고리의 다른 글

(Chapter 6) 학습 관련 기술들  (0) 2022.08.22
(Chapter 5) 오차역전파법  (0) 2022.08.14
(Chapter 4) 신경망 학습  (0) 2022.08.06
(Chapter 2) 퍼셉트론  (0) 2022.08.01
책 읽기 시작  (0) 2022.07.31