코드 작성 관련 내용은 생략하고 이론 위주로 요약 정리한 글입니다.
Chapter 3. 신경망
3.1 퍼셉트론에서 신경망으로
신경망은 입력층 - 은닉층 - 출력층으로 구성된다.
- 퍼셉트론의 수식
$$ y =\begin{cases}0 & (b + w_{1}x_{1} + w_{2}x_{2} \leq 0) \\1 & (b+ w_{1}x_{1} + w_{2}x_{2} > 0 )\end{cases} $$
이 수식을 더 간결한 형태로 작성하면,
$$ y = h(b+w_{1}x_{1}+w_{2}x_{2}) \\ h(x) =\begin{cases}0 & (x \leq 0)\\ 1 & (x > 0) \end{cases} $$
활성화 함수의 등장
입력 신호의 총합을 출력 신호로 변환하는 함수를 활성화 함수(activation function)라 한다.
입력 신호의 총합이 활성화를 일으키는지를 정하는 역할.
$$ a = b+w_{1}x_{1}+w_{2}x_{2} \\ y = h(a) $$
가중치가 달린 입력 신호와 편향의 총합을 계산하여 a라 하고, a를 함수 $h()$에 넣어 y를 출력한다.
가중치 신호를 조합한 결과가 a라는 노드가 되고, 활성화 함수 $h()$를 통과하여 y라는 노드로 변환된다.
3.2 활성화 함수
시그모이드 함수(sigmoid function)
$ h(x) = \frac{1}{1+\exp(-x)} $
계단 함수(step function)
0을 경계로 출력이 0에서 1(또는 1에서 0)로 바뀐다.
시그모이드 함수와 계단 함수 비교
계단 함수가 0과 1 중 하나의 값만 돌려주는 반면 시그모이드 함수는 실수를 돌려준다는 점이 다르다.
다시 말해, 퍼셉트론에서는 뉴런 사이에 0 혹은 1이 흘렀다면, 신경망에서는 연속적인 실수가 흐른다.
비선형 함수
계단 함수와 시그모이드 함수의 공통점은 비선형 함수이다.
신경망에서는 활성화 함수로 비선형 함수를 사용해야 한다.
그 이유는 선형 함수를 이용하면 신경망의 층을 깊게 하는 의미가 없어지기 때문이다.
ReLU 함수(Rectified Linear Unit function)
신경망 분야에서 최근에 주로 이용되는 함수이다.
ReLU는 입력이 0을 넘으면 그 입력을 그대로 출력하고, 0 이하이면 0을 출력하는 함수이다.
$ h(x) =\begin{cases}x & (x > 0) \\ 0 & (x \leq 0) \end{cases} $
3.3 다차원 배열의 계산
신경망에서의 행렬 곱
X와 W의 대응하는 차원의 원소 수가 같아야 한다.
3.4 3층 신경망 구현하기
각 층의 신호 전달 구현하기
입력층에서 1층으로 신호 전달
편향은 오른쪽 아래 인덱스가 하나밖에 없다는 것에 주의하자.
앞 층의 편향 뉴런이 하나뿐이기 때문이다.
행렬의 곱을 이용하면 1층의 '가중치 부분'을 다음 식으로 간소화할 수 있다.
W1은 2X3 행렬, X는 원소가 2개인 1차원 배열이다. (예시)
이렇게 W1과 X의 대응하는 차원의 원소의 수가 일치해야 한다.
이어서 1층의 활성화 함수에서의 처리를 살펴 보자.
은닉층에서의 가중치 합(가중 신호와 편향의 총합)을 a로 표기하고 활성화 함수 h()로 변환된 신호를 z로 표기한다.
(예시에서는 활성화 함수로 시그모이드 함수를 사용한다.)
1층에서 2층으로 가는 과정
1층의 출력 Z1이 2층의 입력이 된다는 점을 제외하면 조금 전의 구현과 같다.
2층에서 출력층으로의 신호 전달
출력층의 구현도 앞의 구현 과정과 거의 같지만, 활성화 함수만 지금까지의 은닉층과 다르다.
여기에서는 항등함수(identity function)을 출력층의 활성화 함수로 이용한다.
항등 함수는 입력을 그대로 출력하는 함수이다.
출력층의 활성화 함수는 h()가 아닌 $\sigma()$로 표시하였다.
- 출력층의 활성화 함수는 풀고자 하는 문제의 성질에 맞게 정함.
- 예) 회귀 - 항등 함수, 2클래스 분류 - 시그모이드 함수, 다중 클래스 분류 - 소프트맥스 함수
3.5 출력층 설계하기
소프트맥스 함수(softmax function) 구현하기
exp(x)는 지수 함수(exponential function)이다.
n은 출력층의 뉴런 수, $y_{k}$는 그중 k번째 출력임을 뜻한다.
소프트맥스의 출력은 모든 입력 신호로부터 화살표를 받는다. 분모에서 보듯, 출력층의 각 뉴런이 모든 입력 신호에서 영향을 받기 때문이다.
소프트맥스 함수 구현 시 주의점
소프트맥스 함수는 지수 함수를 사용하는데, 지수 함수는 쉽게 큰 값을 내뱉기 때문에, 이런 큰 값끼리 나눗셈을 하면 결과 수치가 '불안정'해지는 오버플로 문제가 생긴다.
이 문제를 해결하도록 개선한 수식
소프트맥스의 지수 함수를 계산할 때 어떤 정수를 더하거나 빼도 결과는 바뀌지 않는다.
오버플로를 막을 목적으로는 입력 신호 중 최댓값을 빼주면 올바른 계산이 가능하다.
소프트맥스 함수의 특징
소프트맥스 함수의 출력은 0에서 1.0 사이의 실수이다. 또한 출력의 총합은 1이다.
이 성질 덕분에 소프트맥스 함수의 출력은 '확률'로 해석할 수 있다.
-
주의점: 소프트맥스 함수를 적용해도 각 원소의 대소 관계는 변하지 않는다. 지수함수가 단조 증가 함수이기 때문이다. a의 원소들 사이의 대소 관계가 y의 원소들 사이의 대소 관계로 그대로 이어진다. 신경망을 이용한 분류에서는 일반적으로 가장 큰 출력을 내는 뉴런에 해당하는 클래스로만 인식한다. 그리고 소프트맥스 함수를 적용해도 출력이 가장 큰 뉴런의 위치는 달라지지 않는다. 결과적으로 신경망을 분류할 때는 출력층의 소프트맥스 함수를 생략하는 것이 일반적이다.
-
기계학습의 문제 풀이는 학습과 추론(inference)의 두 단계를 거쳐 이뤄진다. 추론 단계에서는 출력층의 소프트맥스 함수를 생략하는 것이 일반적. 한편, 학습 단계에서는 출력층에서 소프트맥스 함수를 사용한다.
출력층의 뉴런 수 정하기
분류에서는 분류하고 싶은 클래스 수로 설정하는 것이 일반적이다.
3.6 손글씨 숫자 인식
학습 과정은 생략하고, 추론 과정만 구현한다.
이 추론 과정을 신경망의 순전파(forward propagation)라고도 한다.
MNIST 데이터셋
손글씨 숫자 이미지 집합 데이터셋. 0부터 9까지의 숫자 이미지로 구성된다.
책에서 제공하는 mnist.py 파일의 load_mnist 함수로 MNIST 데이터셋을 읽는다.
load_mnist 함수는 인수로 normalize, flatten, one_hot_label (모두 bool형) 세 가지를 설정할 수 있다.
- normalize : 입력 이미지의 픽셀값을 0.0 ~ 1.0 사이의 값으로 정규화할지 정한다. False로 설정하면 입력 이미지의 픽셀은 원래 값 그대로 0 ~ 255 사이 값을 유지한다.
- flatten : 입력 이미지를 1차원 배열로 만들지를 정한다. False로 설정하면 입력 이미지를 1 X 28 X 28의 3차원 배열로, True로 설정하면 784개의 원소로 이뤄진 1차원 배열로 저장한다.
- one_hot_label : 레이블을 원-핫 인코딩(one-hot-encoding) 형태로 저장할지를 정한다. 정답을 뜻하는 원소만 1이고 나머지는 모두 0인 배열이다.
이미지 표시에는 PIL(Python Image Library) 모듈을 사용한다.
신경망의 추론 처리
이 신경망은 입력층 뉴런 784개, 출력층 뉴런 10개로 구성한다.
입력층 뉴런이 784개인 이유는 이미지 크기가 28 x 28 = 784이기 때문이고,
출력층 뉴런이 10개인 이유는 이 문제가 0에서 9까지의 숫자를 구분하는 문제이기 때문이다.
배치 처리
원소 784개로 구성된 1차원 배열 (원래는 28 x 28인 2차원 배열)이 입력되어 마지막에는 원소가 10개인 1차원 배열이 출력되는 흐름이다.
이는 이미지 1장만 입력했을 때의 처리 흐름이다.
그렇다면 이미지 여러 장을 한꺼번에 입력하는 경우를 보자.
x의 형상을 100 x 784로 바꿔서 100장 분량의 데이터를 하나의 입력 데이터로 표현하면 된다.
100장 분량 입력 데이터의 결과가 한 번에 출력된다.
이처럼 하나로 묶은 입력 데이터를 배치(batch)라 한다.
데이터를 배치로 처리함으로써 효율적이고 빠르게 처리할 수 있다.
'Deep Learning' 카테고리의 다른 글
[밑바닥부터 시작하는 딥러닝] Ch1. 파이썬 & Ch2. 퍼셉트론 (0) | 2021.01.11 |
---|