일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- rnn
- Django
- 결정계수
- 회귀분석
- 파이썬 pandas
- 히스토그램
- word2vec
- Pandas
- 자연어 처리
- 군집화
- 가설검정
- 기술통계학
- numpy
- 밑바닥부터 시작하는 딥러닝
- 감성분석
- 텐서플로2와 머신러닝으로 시작하는 자연어처리
- F분포
- 텍스트 분류
- 구글 BERT의 정석
- 코사인 유사도
- 다층 퍼셉트론
- 모두의 딥러닝
- 머신러닝
- 최소자승법
- 밑바닥부터 시작하는 딥러닝2
- student t분포
- 오래간만에 글쓰네
- 차원축소
- 은준아 화이팅
- 기초통계
- Today
- Total
데이터 한 그릇
신경망 본문
퍼셉트론의 장점은 복잡한 연산과 함수를 만들 수 있다는 점.
단점은, 가중치 값을 인간이 직접 수정해야 한다는 점.
(일반적으로 다층 퍼셉트론을 신경망이라고 칭한다.)
퍼셉트론에서 신경망으로
퍼셉트론의 이론을 다시 살펴보면,
입력값 x1, x2 를 받으면 각각의 입력값들은 각자의 가중치들과의 곱이 이루어지고 그 값들이 다음 노드로 전달된다. 그리고 전달된 두 개의 데이터와 가중치곱 값들을 서로 합한다. 그리고 마지막으로 편향을 더해준다.
이 값이 0 이상의 값을 가지면 1을 출력하고 0 미만의 값을 가지면 0을 출력한다.
#####
활성화 함수의 등장
앞서 설명에서 입력신호의 총합이 0을 넘으면 1을 출력하게 하고 0미만이면 0을 출력하게 하는 조건부가 있었다.
이 조건부를 따로 h(x) 로 정의 내릴 수 있는데, 이러한 h(x) 를 활성화 함수라고 한다.
즉, 입력신호의 총합을 출력 신호로 변환하는 함수를 `활성화 함수` 라고 한다.
퍼셉트론의 구조를 생각하면서 식을 세우면 다음과 같이 만들 수 있다.
**a = w1 * x1 + w2 * x2 + b**
**y = h(a) (h함수는 a가 0이상이면 1을 0미만이면 0을 출력하게 하는 함수다.)**
활성화 함수
지금까지 살펴본 임계값을 기준으로 출력값을 바꾸는 활성화 함수는 `계단 함수` 라고 부른다.
근데, 활성화 함수를 계단 함수(임계값을 기준으로 출력값을 바꾸는 함수) 이외에 다른 유형의 함수를 사용해도 된다.
시그모이드 함수
공식은 아래와 같다.
h(x) = 1 / 1 + e^(-x)
e는 자연상수를 의미.
계단 함수와 시그모이드 함수를 비교해보자.
계단함수 구현해보기
#임계값을 기준으로 출력을 바꾸는 함수
def step_function(x):
if x > 0:
return 1
else:
return 0
#넘파이도 들어갈 수 있게(배열도)
import numpy as np
def step_function2(x):
y = x > 0
return y.astype(np.int)
#그래프 그리기
import matplotlib.pyplot as plt
def step_function(x):
return np.array(x > 0, dtype = np.int)
x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
plt.plot(x,y)
그래프 모양이 계단 형식이다.
시그모이드 함수 구현해보기
def sigmoid(x):
return 1 / (1 + np.exp(-x))
x = np.array([-1.0,1.0,2.0])
sigmoid(x)
#그래프 그리기
x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x,y)
plt.ylim(-0.1, 1.1)
plt.show()
S자 모양의 그래프 도출
계단 함수와 시그모이드 함수 비교
계단 함수와 다르게 시그모이드 함수는 매끈함의 특징을 가지고 있다.
이 매끈함의 특징이 신경망에서 아주 중요한 역할을 한다.
이 매끈함은 계단 함수는 0과 1 둘 중에 하나의 결과만 출력해서 나타나는 현상이고,
시그모이드 함수는 0과 1도 나오지만 0과 1 사이의 실수도 도출된다.
공통점은 둘 다 입력이 작을 때는 0에 가깝고 입력이 클 때는 1에 가깝다.
비선형 함수
계단 함수와 시그모이드 함수 둘 모두 비선형 함수다.
신경망에서는 활성화 함수로 비선형 함수를 사용해야만 한다.
선형 함수를 사용하면 신경망의 층을 깊게 하는 이유가 없다.
ReLU 함수
ReLU는 입력이 0을 넘으면 그 값 그대로 출력하고 0 이하이면 0을 출력한다.
ReLU 함수를 사용하는 이유는 시그모이드 함수의 기울기 소실 문제 때문이다.
다차원 배열의 계산
배열식을 알면 신경망을 효율적으로 구현할 수 있다.
2 * 2 배열끼리의 곱
A * B 와 B * A 는 결과가 다를 수도 있다.
A = np.array([[1,2],[3,4]])
A.shape
B = np.array([[5,6],[7,8]])
B.shape
np.dot(A,B) #행렬의 곱은 np.dot()
(2 * 3) X (3 * 2) 행렬의 곱
차원이 다른 행렬끼리의 곱은 필수적으로 1번째 행렬의 열과 2번째 행렬의 행이 같아야 한다.
중요한 점은 출력되는 행렬의 형상은 1번째 행렬의 행의 개수와 2번째 행렬의 열의 개수이다.
이 경우에는 2 * 2 행렬 도출
A = np.array([[1,2,3],[4,5,6]])
A.shape
B = np.array([[1,2],[3,4],[5,6]])
B.shape
np.dot(A,B) #행렬의 곱은 np.dot()
(2 * 3) x (3 * 2)
만일 (3 * 2) X (2 * 4) 행렬이면?
행렬곱 계산이 가능하고, 3 * 4 형태의 행렬이 도출된다.
그럼 (3 * 2) X (2) 행렬의 곱은 어떻게 될까?
이는 2 숫자로 동일해서 곱이 가능하면서 3행의 값이 도출된다.
A = np.array([[1,2],[3,4],[5,6]])
B = np.array([1,2])
B.shape
np.dot(A,B)
신경망에서의 행렬 곱
X = np.array([1,2])
X.shape
#(1행 2열)
W = np.array([[1,3,5],[2,4,6]])
print(W)
#2행 3열
#행렬 곱 형식이 곱을 할 수 있는 형식
#결과는 3열이 나와야한다.
Y = np.dot(X,W)
Y
3층 신경망 구현하기
0층 입력층에서 1층 은닉층으로 값이 흐르는 과정
#0층 입력층에서 1층 은닉층으로 값이 흐르는 과정
X = np.array([1.0,0.5])
W1 = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
B1 = np.array([0.1,0.2,0.3])
A1 = np.dot(X,W1) + B1 #가중합
Z1 = sigmoid(A1) #활성화함수로 가중합을 가공
print(Z1) #노드가 세 개 였으므로 3개의 출력값을 출력
1층 입력층에서 2층 은닉층으로 값이 흐르는 과정
#1층에서 2층 은닉층으로 값이 흐르는 과정
W2 = np.array([[0.1, 0.4],[0.2,0.5],[0.3,0.6]])
B2 = np.array([0.1,0.2])
Z1.shape
A2 = np.dot(Z1, W2) + B2 #가중합
Z2 = sigmoid(A2) #가중합 활성화 함수 가공
print(Z2) #노드가 두 개 였으므로 두 개의 출력값을 출력
2층 은닉층에서 3층 출력층으로 값이 흐르는 과정
#2층 은닉층에서 3층 출력층으로 값이 흐르는 과정
def identify_function(x):
return x
W3 = np.array([[0.1,0.3],[0.2,0.4]])
B3 = np.array([0.1,0.2])
A3 = np.dot(Z2, W3) + B3
Y = identify_function(A3)
Y
다른 층과 다른 점은 활성화 함수다.
출력층에서의 활성화 함수는 풀고자 하는 문제의 특성에 따라서 달라진다.
이진 분류 문제를 풀고 싶을 때는 sigmoid 함수를 사용, 다중 분류 문제는 softmax 함수를 사용하고,
선형회귀 문제는 항등함수를 사용한다.(함수를 안써도 된다.)
여기까지 신경망의 순방향(forward) 구현은 끝났다.
출력층 설계하기
앞서 풀려고 하는 문제에 따라서 출력층이 달라짐을 살펴봤다.
항등 함수와 소프트맥스 함수 구현하기
항등함수는 말 그대로 입력값이 그대로 출력값으로 나오는 함수를 의미한다.
소프트맥스 함수(softmax function)
소프트맥스 함수의 분자는 입력신호 지수함수 e^ak(k는 k번째 입력신호를 의미) 를 의미한다.
분모는 입력신호 e지수함수의 합을 의미한다.
그런데 소프트맥스 함수에도 하나의 이슈가 발생한다.
소프트맥스 함수는 자연상수의 지수함수이기 때문에 쉽게 출력값이 커질 수 있다.
숫자가 너무 커지게 되면 결과 수치가 불안정해진다.
(이를 `오버플로` 문제라고 한다.)
따라서 개선된 소프트맥스 함수의 공식이 필요하다.
개선된 소프트맥스 함수 도출하는 과정.
소프트맥스 함수의 분자와 분모에 임의의 상수 C 를 곱한다.
그 다음 상수 C를 지수함수 exp 안에 집어 넣는다. 집어넣으면서 +logC 가 된다.
그리고 logC를 a` 기호로 치환한다.
C` 값에 어떤 값을 넣어도 상관없지만 입력 신호 중 최댓값을 이용하는 게 일반적이다.
(PAGE 93에 공식 정리)
a = np.array([1010,1000,990])
np.exp(a) / np.sum(np.exp(a)) #소프트맥스 함수의 계산
c = np.max(a) #입력값 중 최댓값
a - c
np.exp(a-c) / np.sum(np.exp(a-c))
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
소프트맥스 함수의 특징
소프트맥스 함수의 출력값은 0에서 1사이의 실수 값이다.
또한 소프트맥스 출력의 총합은 1이다.
이 때문에 소프트맥스 함수의 출력을 **확률**로 생각할 수 있다.
이 확률을 전제로 확률이 제일 높은 값을 분류의 결과값으로 생각할 수 있다.
주의점.
소프트맥스 함수는 단조 증가 함수(a>=b, f(a)>=f(b)) 이기 때문에 **원소의 대소 관계는 변하지 않는다.**
신경망을 이용한 분류에서는 일반적으로 가장 큰 출력을 내는 뉴런에 해당하는 클래스로만 인식.
따라서 출력 함수로 소프트맥스를 쓰지 않는 경우도 있음.
출력층의 뉴런 수 정하기
출력층의 뉴런 수는 풀려고 하는 문제에 맞춰서 설정해야한다.
분류에서는 분류하고 싶은 클래스 수로 뉴런 수를 정하는 게 일반적이다.
각각의 출력 노드에 확률이 있을텐데 가장 높은 확률을 기록하는 출력노드의 값을 클래스로 결정
손글씨 숫자 인식
순전파(forward propagation)
모두의 딥러닝에서 라이브러리를 이용해서 해봤기 때문에 생략
배치 처리
앞서 다차원 배열의 곱의 조건이 각 행렬의 열과 행의 숫자가 일치해야한다는 점을 살펴봤다.
입력값 행렬과 가중치 값 행렬의 구조를 살펴보면 다음과 같다.
X | W1 | W2 | W3 | -> | Y |
784 | 784 x 50 | 50 x 100 | 100 * 10 | 10 |
전부 다차원 배열의 곱의 조건에 해당한다.
이때의 계산은 이미지 1개를 집어 넣었을 때의 행렬 곱이다.
즉 입력값 x 를 보면 1 x 784 이다.
100개의 이미지를 한 번에 처리하려면 100 x 784 다. 이를 대입했다 생각하고 다시 계산하면
Y는 100 * 10 으로 나타난다.
x[0] 번째 이미지의 정답 레이블은 Y[0] 에 있다.
여기서 Y[0]은 열 개의 벡터로 이루어진 레이블 확률 중에 가장 큰 확률을 보이는 것을 값으로 가지고 있다.
이처럼 하나로 묶은 입력 데이터를 배치(batch) 라고 한다.
정리
이번 신경망 장에서는 신경망의 순전파(forward propagation) 에 대해서 알아봤다.
앞장의 퍼셉트론처럼 각 층의 뉴런들이 다음 층의 뉴런으로 신호를 보낸다는 점에서 같다.
하지만 퍼셉트론과의 차이점은 활성화 함수에 있다.
퍼셉트론은 활성화 함수로 계단 함수를 사용했다면, 신경망에서는 시그모이드, relu, softmax 그리고 항등함수를 사용했다.
그리고 가중합이 활성화함수로 들어가서 출력값을 만들고 그게 다음 뉴런층으로 가는 과정을 자세히 살펴봤다.
마지막으로 출력층의 활성화 함수와 노드의 개수를 살펴봤다.
풀려고 하는 문제에 따라서 출력층의 활성화 함수는 달라지며 출력층의 개수도 달라진다.
이진 분류일 경우에는 sigmoid 함수와 출력 노드를 1개만 만든다.
다중 분류일 경우에는 softmax 함수를 사용하며 분류 클래스 개수대로 노드 수를 정한다.
이때 소프트맥스 함수의 특징 덕에 각각의 출력노드의 값들을 확률로 생각할 수 있다.
즉, 확률이 가장 높은 출력층의 노드가 결과값으로 도출이 되는 것
'딥러닝 > 밑바닥부터 시작하는 딥러닝' 카테고리의 다른 글
합성곱 신경망(CNN) (0) | 2022.01.09 |
---|---|
학습 관련 기술들 (0) | 2022.01.08 |
오차역전파 (0) | 2022.01.07 |
신경망 학습 (0) | 2022.01.07 |
퍼셉트론 (0) | 2022.01.07 |