728x90
반응형
손실 함수
- 신경망 학습에는 학습이 얼마나 잘 되고 있는지 알기 위한 '척도'가 필요하다.
- 일반적으로 학습 단계의 특정 시점에서 신경망의 성능을 나타내는 척도로 손실(loss)을 사용한다.
- 손실은 학습 데이터(학습 시 주어진 정답 데이터)와 신경망이 예측한 결과를 비교해 예측이 얼마나 나쁜가를 산출한 단일 값(스칼라)이다.
- 신경망 손실은 손실함수(loss function)을 사용해 구한다.
- 다중 클래스 분류(multi-class classification)신경망에서 손실 함수로 흔히 교차 엔트로피 오차(Cross Entropy Error)를 이용한다.
- 교차 엔트로피 오차는 신경망이 출력하는 각 클래스의 '확률'과 '정답 레이블'을 이용해 구할 수 있다.
손실 함수를 적용한 신경망의 계층 구성
미분과 기울기
- 신경망 학습의 목표는 손실을 최소화하는 매개변수를 찾는 것
- 이대 중요한 것이 '미분'과 '기울기'
미분
- 예) y = f(x) 함수
- x에 관한 y의 미분은 dy/dx라고 쓴다. dy/dx가 의미하는 것은 x의 값을 '조금'변화시켰을 때('조금의 변화'를 극한까지 줄일 때) y 값이 얼마나 변하는가 하는 '변화의 정도'
기울기
- 벡터의 각 원소에 대한 미분을 정리한 것
- 행렬에서도 기울기 생각 가능 W가 m*n행렬이라면
- L = g(W) 함수의 기울기는 아래 그림과 같다.
연쇄 법칙
- 학습 시 신경망은 학습 데이터를 주면 손실을 출력한다.
- 각 매개변수에 대한 손실의 기울기를 원한다.
- 신경망의 기울기를 구하는 방법 - 오차역전파(back-propagation)
- 오차역전파법을 이해하는 열쇠는 연쇄 법칙(chain rule)이다.
- 연쇄법칙은 합성함수에 대한 미분의 법칙이다.(합성함수는 여러 함수로 구성된 함수)
- 연쇄 법칙 예)
- y = f(x), z = g(y) 두 함수
- z = g(f(x)) 최종 출력 z는 두 함수를 조합해 계산 가능하다.
- 합성함수의 미분(x에 대한 z의 미분)은 아래 그림과 같다.
- x에 대한 z의 미분은 y = f(x)와 z = g(y)의 미분을 곱하면 구해진다. 이것이 바로 연쇄 법칙
계산 그래프
- 계산 과정 시각적으로 보여준다.
덧셈 노드
- z = x+y
- 역전파 : 상료로부터의 기울기를 흘리기만 한다. (상류로부터 받은 값에 1을 곱해 하류로 기울기를 전파한다.)
덧셈 노드의 순전파(왼쪽)와 역전파(오른쪽)
곱셈 노드
- z = x*y 계산을 수행
- 역전파 : '상류로부터 받은 기울기'에 '순전파 시의 입력을 서로 바꾼 값'을 곱한다.
- '원소별 연산' 수행
곱셈 노드의 순전파(왼쪽)와 역전파(오른쪽)
분기 노드
- 분기 노드는 산순히 선이 두 개로 나뉘도록 그려진다. 이때 같은 값이 복제되어 분기한다.
- '복제 노드'
- 역전파 : '상류에서 온 기울기들의 합'
분기 노드의 순전파(왼쪽)와 역전파(오른쪽)
Repeat 노드
- 2개로 분기하는 분기 노드를 일반화하면 N개로의 분기(복제)가 되는데 이를 Repeat 노드라고 한다.
Repeat 노드의 순전파(위)와 역전파(아래)
import numpy as np
D, N = 8,7
x = np.random.rand(1, D) # 입력
y = np.repeat(x, N, axis = 0) # 순전파
dy = np.random.rand(N, D) # 무작위 기울기
dx = np.sum(dy, axis = 0, keepdims=True) # 역전파
- np.repeat()메서드가 원소 복제
- keepdims = True 설정으로 2차원 배열의 차원 수 유지
Sum 노드
- 범용 덧셈 노드
Sum 노드의 순전파(위)와 역전파(아래)
# Sum 노드
import numpy as np
D, N = 8,7
x = np.random.rand(N, D) # 입력
y = np.sum(dy, axis = 0, keepdims=True) # 역전파
dy = np.random.randn(1, D) # 무작위 기울기
dx = np.repeat(dy, N, axis = 0) # 역전파
- Sum 노드와 Repeat노드는 서로 '반대 관계'
MatMul 노드
- 행렬 곱셈
MatMul 노드의 순전파 : 각 변수 위에 형상을 표시
MatMul 노드의 역전파
# MatMul 클래스
class MatMul:
def __init__(self, W):
self.params = [W]
self.grads = [np.zeros_like(W)]
self.x = None
def forward(self, x):
W, = self.params
out = np.matmul(x, W)
self.x = x
return out
def backward(self, dout):
W, = self.params
dx = np.matmul(dout, W.T)
dW = np.matmul(self.x.T, dout)
self.grads[0][...] = dW
return dx
Sigmoid 계층
- y = 1/1+exp(-x)
Sigmoid 계층의 계산 그래프
# Sigmoid 계층
class Sigmoid:
def __init__(self):
self.params, self.grads = [],[]
self.out = None
def forward(self, x):
out = 1/(1+np.exp(-x))
self.out = out
return out
def backward(self, dout):
dx = dout * (1.0 - self.out) * self.out
return dx
Affine 계층
- 순전파는 y = np.matmul(x, W) + b
Affine 계층 계산 그래프
# Affine 계층 그래프
class Affine:
def __init__(self, W, b):
self.params = [W,b]
self.grads = [np.zeros_like(W), np.zeros_like(b)]
self.x = None
def forward(self, x):
W, b = self.params
out = np.matmul(x, W) + b
self.x = x
return x
def backward(self, dout):
W, b = self.params
dx = np.matmul(dout, W.T)
dW = np.matmul(self.x.T, dout)
db = np.sum(dout, axis = 0)
self.grads[0][...] = dW
self.grads[1][...] = db
return dx
- Affine의 역전파는 MatMul 노드와 Repeat 노드의 역전파를 수행하면 구할 수 있다.
- Repeat 노드의 역전파는 np.sum() 메서드로 계산 가능
Softmax with Loss 계층
Softmax with Loss 계층의 계산 그래프
가중치 갱신
- 오차역전파법으로 기울기 구했다면, 기울기를 사용해 신경망의 매개변수를 갱신
신경망 학습 순서
- 미니배치
- 훈련 데이터 중에서 무작위로 다수의 데이터를 골라낸다.
- 기울기 계산
- 오차역전파법으로 각 가중치 매개변수에 대한 손실 함수의 기울기를 구한다.
- 매개변수 계산
- 기울기를 사용해 가중치 매개변수를 갱신한다.
- 반복
- 1~3단계 필요한 만큼 반복
- 이것이 바로 경사하강법(Gradient Descent)
- 단순한 확률적경사하강법(Stochastic Gradient Descent(SGD))구현, '확률적(Stochastic)'은 무작위로 선택된 데이터(미니배치)에 대한 기울기를 이용한다는 뜻
- SGD는 (현재의) 가중치를 기울기 방향으로 일정한 거리만큼 갱신
SGD수식
class SGD:
def __init__(self, lr=0.01):
self.lr = lr
def update(self, params, grads): # params 신경망 가중치, grads 기울기
for i in range(len(params)):
params[i] -= self.lr * grads[i]
출처 : 밑바닥부터 시작하는 딥러닝2
https://www.hanbit.co.kr/store/books/look.php?p_code=B8950212853
728x90
반응형
최근댓글