딥러닝을 크게 나눠서 보면
옵티마이저는 예측과 학습 부분에서 다룰 예정이다.
층은 하나 이상의 텐서를 입력으로 받아 하나 이상의 텐서를 출력하는 데이터 처리 모듈이다.
텐서 : 데이터를 담는 컨테이너이다. 여러 차원(1D, 2D...)으로 구분될 수 있다.
여러개의 텐서(혹은 뉴런(neuron), 노드(node)라고도 한다.)들이 모여 층을 이룬다.
층을 지나면서 데이터에 함수(가중치)가 적용되고, 값이 예측된다.
층은 입력층, 은닉층, 출력층으로 구분할 수 있다.
입력층(input layer) : 데이터를 받아들이는 층, 은닉층으로 데이터를 전달한다.
은닉층(hidden layer) : (이전 층의 있는 모든 혹은 다수의 노드로부터)입력 값을 받아 가중합을 계산, 활성화 함수에 적용하여 다음 층으로 전달한다.
출력층(output layer) : 신경망의 최종 결과값을 가진다. (보통 확률로 나타내기 위해 0~1 사이에 값으로 반환하는 함수들을 많이 사용한다.)
커널(kernel) 이라고도 불린다.
입력 값이 연산 결과에 미치는 영향력을 조절하는 요소이다. 훈련 데이터를 신경망에 노출시켜서 학습된 정보가 담겨 있다. (다른 모델의 가중치를 가져온다는 말도 이런 뜻이다.)
다시 말해, 입력 데이터를 다르게 하기 위해 입력 값에 곱해지는 웨이트가 가중치이다.
입력값과 같은 차원수를 갖게 된다. (입력값과 텐서 곱셈 연산을 수행해야 되니)
상황에 따라 임의로 정할 수도 있고, 난수로 정할 수도 있다. (어차피 학습이 될테니)
그 외에도 여러 가중치 초깃값들이 있다. ex) Xavier 초깃값, He 초깃값 등
가중치와 노드의 곱을 합한 것을 가중합(weight sum) 혹은 전달 함수(transfer function)이라고 한다.
각 노드에서 들어오는 신호에 가중치를 곱해서 다음 노드로 전달되는데, 이 값들을 모두 더한 합계를 가중합이라고 한다. 노드의 가중합이 계산되면 이 가중합을 활성화 함수로 보내기 때문에 Transfer function이라고도 한다.
가중합에 더해지는 상수이다. 활성화 함수의 기준을 조절하는 역할을 한다.
#3층 단위의 신경망, 가중치와 편향 초깃값 포함
def init_network():
network = {}
network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
network['b1'] = np.array([0.1, 0.2, 0.3])
network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
network['b2'] = np.array([0.1, 0.2])
network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
network['b3'] = np.array([0.1, 0.2])
return network
비선형성(non-linearity)이라고도 불리는 이 함수가 없다면 각 층은 선형적인 연산인 점곱과 덧셈 2개로 밖에 구성이 안된다.
그러므로 이 층은 입력에 대한 선형 변환(아핀 변환)만을 학습할 수 있다.
예를 들어 어떤 층의 가설 공간(hypothesis space)은 n개의 차원이 있다고 하면, 이는 n개 차원 공간으로 바꾸는 가능한 모든 선형 변환의 집합니다.
그러나 이 층에 차원을 아무리 많이 추가해도(깊게 만들어도) 의미가 없다. 선형 연산만 할 수 있으니, 그래서 층의 가설 공간을 풍부하게 만들어 층을 깊게 만드는 것에 장점을 살리는 비선형성 또는 활성화 함수를 쓴다.
네트워크의 구조는 가설 공간 정의한다. 네트워크 구조를 선택함으로써 가능성 있는 공간(가설 공간)을 입력 데이터에서 출력 데이터로 매핑하는 일련의 특정 텐서 연산으로 제한하게 된다.
#항등함수
def identity_function(x):
return x
#시그모이드 함수
def sigmoid(x):
return 1 / (1 + np.exp(-x))
#항등함수
def identity_function(x):
return x
#렐루함수
def relu(x):
return np.maximum(0, x)
#리키 렐루함수
def leekyrelu(x):
return np.maximum(0.1 * x, x)
'''
소프트맥스 함수
yk = exp(ak) / sigma(i=1 to n)(exp(ai))
'''
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
이 외에도 여러 활성화 함수들이 존재한다.
예측값과 실제값의 오차를 계산하는 함수, 훈련하는 동안 최소화될 값이다. 주어진 문제에 대한 성공 지표가 된다.
평균 제곱 오차(mean squared error, MSE) : 실제 값과 예측 값의 차이를 제곱하여 평균을 낸 값.
실제 값과 예측 값의 차이가 클수록 MSE도 커진다.
반대로 MSE가 적을수록 예측력이 좋다는 말이 된다.
회귀에서 손실 함수로 주로 사용된다.
#MSE
def mean_squared_error(y, t):
return 0.5 * np.sum((y-t)**2)
#CEE
def cross_entropy_error(y, t):
delta = 1e-7 # 0일때 -무한대가 되지 않기 위해 작은 값을 더함
return -np.sum(t * np.log(y + delta))
이 외에도 여러 손실 함수들이 존재한다.
딥러닝의 입력 데이터들은 여러 층을 지나면서, 가중치와 편향, 여러 활성화 함수에 적용되고, 마지막에는 손실함수로 정답 값과 얼마나 비슷한지 예측되고 수정되서 정답과 가까워지는 구조이다.