일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
- hacking
- 백엔드
- 웹해킹
- Python
- 경제
- 딥러닝
- 파이썬
- Linux
- ChatGPT
- BOF
- c++
- 러닝 스칼라
- hackerschool
- flask
- webhacking
- BOF 원정대
- deep learning
- Scala
- c
- 리눅스
- mysql
- Shellcode
- 러닝스칼라
- php
- backend
- hackthissite
- Web
- Javascript
- 인공지능
- 챗GPT
- Today
- Total
jam 블로그
Artificial Neural Network 2 본문
신경망 (Artificial Neural Network, ANN)
스터디 용으로 Deep Learning from Scratch 2 책을 참고로 정리한 것입니다.
앞 게시물 에 이어서 신경망의 학습에 대해서 정리하였습니다.
신경망의 성능을 나타내는 척도로는 손실 loss을(를) 사용합니다.
손실은 손실함수 (loss function)를 사용하여 구합니다.
손실 함수로는 아래와 같이 있습니다. (계속 추가 예정)
- 교차 엔트로피 오차 (Cross Entropy Error)
- 평균 제곱 오차 (Mean Squared Error)
- Mean Absolute Error
- Mean Absolute Percentage Error
- Mean Squared Logarithmic Error
- Hinge
- Categorical Cross Entropy
- Sparse Categorical Cross Entropy
- Binary Categorical Cross Entropy
- Kullback Leibler Divergence
- Poisson Loss
- Cosine Proximity
책에서는 교차 엔트로피 오차를 사용합니다.
교차 엔트로피 오차는 신경망이 출력하는 각 클래스의 확률과 정답 레이블을 이용해서 구할 수 있습니다.
위에서 만든 소스에 softmax와 교차 엔트로피 오차 계층을 새로 추가합니다.
소프트맥스 함수 (Softmax function)는 입력값을 0, 1 사이의 값으로 정규화 해주는 함수입니다. 수식은 아래와 같습니다.
$$
y_k = \frac{exp(s_k)}{\displaystyle\sum_{i=1}^{n} exp(s_i)}
$$
출력이 총 n개 일때, k번째의 출력 y를 구하는 계산식 입니다. 분자는 k번째의 output의 지수함수 이고, 분모는 모든 입력신호의 output의 지수 함수의 총합니다.
교차 엔트로피 오차의 공식은 다음과 같습니다.
$$
L = -\displaystyle\sum_{k} (t_k)log(y_k)
$$
t 는 k번째 클래스에 해당하는 정답 레이블 입니다.
log는 오일러의 수 e를 밑으로 하는 로그입니다.
미니배치 처리를 교려하면 위 수식에서 다음과 같이 변경해야합니다.
$$
L = -\frac{1}{N}\displaystyle\sum_{n}\sum_{k} t_{nk}logy_{nk}
$$
N으로 나눈는 이유는 1개당의 평균 손실 함수를 구하기 위함이고 이럴 경우 미니배치의 크기에 관계없이 항상 일관된 값을 구할 수 있습니다.
아래는 Softmax 와 Loss 함수 입니다.
import numpy as np
def softmax(x):
if x.ndim == 2:
x = x - x.max(axis=1, keepdims=True)
x = np.exp(x)
x /= x.sum(axis=1, keepdims=True)
elif x.ndim == 1:
x = x - np.max(x)
x = np.exp(x) / np.sum(np.exp(x))
return x
def corss_entropy_error(y, t):
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
if t.size == t.size
t = t.argmax(axis=1)
batch_size = y.shape[0]
return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size
class SoftmaxWithLoss:
def __init__(self):
self.params, self.grads = [], []
self.y = None
self.t = None
def forward(self, x, t):
self. t = t
self. y = softmax(x)
if size.t.size == self.y.size:
self.t = self.t.argmax(asix=1)
loss = cross_entropy_error(self.y, self.t)
return loss
신경망 학습의 목표는 손실을 최소화 하는 매개변수를 찾는 것입니다.
기울기 (gradient) : 벡터의 각 원소에 대한 미분을 정리한 것. 기울기를 얻을 수 있다면 그것을 사용해 매개변수를 갱신할 수 있습니다.
오차역전파법 (back-propagation) : 신경망의 기울기를 구하는 방법.
- 신경망은 여러 함수가 연결된 것이라고 생각할 수 있으며, 여러 함수에 대해 연쇄 법칙을 효율적으로 적용하여 기울기를 구해낼 수 있습니다.
노드에 따른 계산 방식입니다.
- 덧셈 노드
- 곱셈 노드
Repeat 노드
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, FCN 계층, Softmax with Loss 계층에 역전파를 넣어봅시다.
Sigmoid 함수를 수식으로 나타내면
$$
y = \frac{1}{1 + exp(-x)}
$$
인데, 이것을 미분 하면 다음과 같습니다.
$$
\frac{\partial{y}}{\partial{x}} = y(1 - y)
$$
따라서, 출력쪽으로 부터 넘어오는 기울기($ \frac{\partial{L}}{\partial{y}} $)에 방금 구한 미분 $ y(1 - y) $를 곱해서 입력 계층으로 전파합니다.
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
FCN 계층 같은 경우 순전파는 y = np.matmul(x, W) + b로 구현이 가능합니다.
x, W의 Matmul 노드를 거쳐서 b의 Repeat 노드를 거친 두개를 덧셈 노드로 합치는 형식입니다.
class FCL:
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 out
def backward(self, dout):
W, b = self.params
dx = np.matmul(dout, W.T)
dW = np.matmul(self.xT, dout)
db = np.sum(dout, axis=0)
self.grads[0][...] = dW
self.grads[1][...] = db
return dx
Softmax with Loss 계층는 softmax와 cross entropy error 계층으로 되어 있습니다.
class SoftmaxWithLoss:
def __init__(self):
self.params, self.grads = [], []
self.y = None
self.t = None
def forward(self, x, t):
self. t = t
self. y = softmax(x)
if size.t.size == self.y.size:
self.t = self.t.argmax(asix=1)
loss = cross_entropy_error(self.y, self.t)
return loss
def backward(self, dout=1):
batch_size = self.t.shape[0]
dx = self.y.copy()
dx[np.arange(batch_size), self.t] -= 1
dx *= dout
dx = dx / batch_size
return dx
위에서 오차역전파법으로 기울기를 구하였기 때문에 이걸 사용하여 신경망의 매개변수를 갱신합니다.
학습 순서는 다음과 같습니다.
- 미니배치 : 훈련 데이터 중에서 무작위로 다수의 데이터를 골라낸다.
- 기울기 계산 : 오차역전파법으로 각 가중치 매개변수에 대한 손실 함수의 기울기를 구한다.
- 매개변수 갱신 : 기울기를 사용하여 가중치 매개변수를 갱신한다.
- 반복 : 1 ~ 3 단계를 반복합니다.
매개변수 갱신(Optimizer)에는 다양한 방법이 있습니다.
- 경사하강법 (Gradient Descent)
- 확률적경사하강법 (Stochastic Gradient Descent, SGD)
- 모멘텀 (Momentum)
- NAG (Nesterov Accelerated Gradient)
- Nadam
- AdaGrad
- RMSProp
- AdaDelta
- Adam
이 중 확률적 경사하강법으로 구현합니다.
$$
W \leftarrow W - \eta \frac{\partial L}{\partial W}
$$
$ W $는 매개변수 이며, $ \frac{\partial L}{\partial W} $는 손실 함수의 기울기 , $ \eta $는 학습률 (learning rate)입니다.
class SGD:
'''
lr : learning rate
'''
def __init__(self, lr = 0.01):
self.lr = lr
'''
params : weight
grads : 기울기
'''
def update(self, params. grads):
for i in range(len(params)):
params[i] -= self.lr * grads[i]
'인공지능' 카테고리의 다른 글
DIALOGPT : Large-Scale Generative Pre-training for Conversational Response Generation (0) | 2020.03.31 |
---|---|
Extreme Language Model Compression with Optimal Subwords and Shared Projections (0) | 2019.12.18 |
Deep learning natural language processing nlp 1 (0) | 2019.10.20 |
Deep learning one hot encoding (0) | 2019.10.20 |
Artificial Neural Network 1 (0) | 2019.10.20 |