Neural Network

2 minute read

신경망

퍼셉트론의 단점은 가중치를 설정하는 작업이 수동이라는 것이다.
신경망은 이것까지 자동으로 되도록 (학습하도록) 할 수 있다.

알고리즘 시간의 배운 멀티스테이지 그래프를 떠올려 보자.

한 레벨의 노드에서는 바로 다음 노드로만 가는 경로만 있고
맨 처음과 끝엔 노드가 하나만 있다는 그 그래프말이다.

신경망은 입출력이 하나만 있다는 점을 제외하고는 이 멀티스테이지 그래프와 비슷하게 생겼다.
이때 맨 왼쪽의 입력을 입력층, 오른쪽의 출력을 출력층, 그 사이를 은닉층이라고 한다.

신경망은 여러 입력 x에 가중치를 곱한 값들과 편향의 합을 가지고 출력값이 정해진다는 것은 아까의 퍼셉트론과 동일하다.

단, 퍼셉트론은 그저 그 값이 0보다 크냐 작냐를 가지고 출력값을 정했다면
신경망은 그 값을 어떤 함수에 넣고 돌린 반환값을 출력한다.

이때 쓰이는 함수를 활성화 함수라고 하며
활성화 함수에는 계단 함수, 시그모이드 함수, ReLU 함수 등이 있다.

계단 함수

계단 함수는 매우 간단하게 구현할 수 있다.
이때 입력값 x 는 ndarray라 가정한다.

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

이 함수에 [2, -0.1, 0] 의 값을 가지는 배열을 넣으면
[1, 0, 0] 이라는 값을 돌려줄 것이다.

이 함수는 입력값 x와 출력값 y 에 대해 그래프를 그렸을 때
0보다 작은 지점에선 항상 0이다가 0이 넘어가면 갑자기 1로 수직으로 올라가는 모양이 계단같이 생겼다.

시그모이드 함수

시그모이드 함수는 그 그래프가 S자로 생겼다.

시그모이드 함수는 1/ (1 + e^(-x)) 를 출력한다.

이를 파이썬으로 구현하면

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

가 된다.

ReLU 함수

ReLU 함수는 입력값이 0보다 크면 그대로, 아니면 0을 출력하는 함수이다.

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

위 세 활성화 함수의 공통점으로, 비선형적이라고 할 수 있다.
선형, 즉 y = ax 같은 함수를 활성화 함수로 쓴다면
신경망의 층을 높여서 학습을 하는 (deep learning) 의미가 없다.
5번 하든 100번을 하든 결국 a^n * x 꼴이기 때문이다.

신경망의 층을 이동하는 모습은 다음과 같다.
x라는 초기입력으로 1, 2단계를 거쳐가는 모습이다.

a1 = np.dot(x, W1) + b1  
z1 = sigmoid(a1)  
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
...

출력층

신경망에서 은닉층에서 사용되는 활성화 함수와 달리
출력층에서는 또다른 함수를 쓴다.

출력층에서 사용되는 활성화 함수는 항등 함수, 소프트맥스 함수 등이 있다.

분류 (클래스 구분 등) 작업에서는 소프트맥스 함수를, 회귀 작업에서는 항등 함수를 일반적으로 쓴다.

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

소프트맥스는 그 열의 값들을 다 사용하는 함수이다.

파이썬으로 구현하면 아래와 같다.

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

단 이렇게 단순히 구현하면 오버플로우가 일어나기 쉽다.
따라서 로그를 이용하여 계산과정에서 오버플로우가 일어나지 않게 해주어야 한다.

def softmax(x):
  a = np.max(a)
  b = x - a
  c = np.exp(b)
  return c / np.sum(c)

이 함수를 거쳐 나오는 열의 합을 다 더하면 1이 된다.

이는 확률로서 생각할 수가 있는데

n x 1 짜리 행렬이 결과라면 각각의 엔트리들은 n번째 클래스가 맞을 확률이 된다.

예를 들어 0 ~ 9 의 사진을 주고 그 사진이 나타내는 수가 몇인지 맞추는 학습을 하고 테스트 하는 신경망을 설계한다면
출력시 행의 개수가 10개가 되게 한다.
결과의 10x1 짜리 행렬의 각 엔트리들은 각각 그 사진이 0일 확률을 담고 있다.

이때 이 테스트를 몇 십개씩 묶어서 하면 입출력의 빈도가 줄어서 그 성능이 좋아진다.
10000개의 784x1 벡터 (24x24 픽셀의 사진) 테스트가 있다면 이를 784x1 벡터 하나하나를 만 번 보내는 것이 아니라
784 x 100 의 100개를 묶은 행렬을 한 번에 입력해서 결과를 보는 것이 더 빠르다.

이때 이렇게 묶인 데이터를 배치(batch)라고 한다.