카테고리 없음
밑바닥부터 시작하는 딥러닝 (신경망 구현, 손실함수, 엔트로피)
ROSEV
2021. 10. 28. 16:59
위의 사진은 3층 신경망의 신호전달 과정입니다. 코드로 풀면 아래와 같습니다.
a1 = np.dot(x, W1) + b1 # affine
z1 = sigmoid(a1) # simoid
a2 = np.dot(z1, W2) + b2 affine
z2 = sigmoid(a2) # simoid
a3 = np.dot(z2, W3) + b3 affine
y = softmax(a3) # softmax
- MNIST의 사진 데이터의 경우 데이터가 (28X28)의 데이터이므로 입력층의 뉴런이 784개로 형성됩니다.
- 은닉층은 총 2개로 첫번째 은닉층의 뉴런은 50개, 두번째 은닉층의 뉴런은 100개로 임의로 배치했습니다.
- 파라미터가 위의 사진처럼 나타나는 것을 알 수 있습니다. 사진을 넣기전, 사진데이터(28X28)을 Flatten을 해주고, 0과 255사이로 정규화를 해야 합니다.(재확인)
- Flatten을 해주는 이유는 컴퓨터는 행과 열 두차원으로 읽는 것이 아닌 1개의 행으로 읽기때문입니다. 정규화는 사진의 튀는 부분이 너무 숫자가 큰 문제가 발생하기 때문에 사용합니다.
배치처리
- 배치처리란, 기존 MNIST 데이터인 한장의 사진만 넘기는 것이 아닌 한번에 여러장을 하나의 입력 데이터로 사용하는 것을 말합니다
- 하나로 묶은 입력 데이터를 배치라고 하는 것입니다.
아래는 배치처리 되는 코드 예시입니다.
x, t = get_data()
network = init_network()
batch_size = 100
accuracy_cnt = 0
for i in range(0, len(x), batch_size):
x_batch = x[i:i+batch_size]
y_batch = predict(network, x_batch)
p = np.argmax(y_batch, axis=1)
accuracy_cnt += np.sum(p == t[i:i+batch_size])
print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
손실함수(Loss function)
- 머신러닝의 두가지 학습법 Rule-based와 Data-driven이 있습니다.
- 첫번째 rule-based의 경우 규칙으로 위와 같이 고양이로 구분했습니다. 하지만 다양한 고양이의 품종에 따라서 조건이 맞지 않는 경우가 있었습니다. 그래서 두번째인 Data-driven의 방법론으로 다양하고 많은 사진으로 학습하여 고양이로 분류하기 시작했습니다.
- 손실 함수는 이러한 사진을 인식할 때 보다 잘 인식하기 위한 최적의 매개변수를 찾기 위해 사용됩니다. 손실함수의 방법론은 일반적으로 오차제곱합과 교차 엔트로피 오차를 사용합니다.
손실함수 - 오차제곱합
def sum_squares_error(y, t):
return 0.5 * np.sum((y-t)**2)
t = [0,0,1,0,0,0,0,0,0,0]
y = [0.1, 0.04, 0.7, 0.0, 0.05, 0.15, 0.0, 0.1, 0.0, 0.0]
sum_squares_error(np.array(y), np.array(t))
# 결과 >> 0.0975
y = [0.1, 0.02, 0.2, 0.1, 0.05, 0.15, 0.7, 0.1, 0.0, 0.0]
sum_squares_error(np.array(y), np.array(t))
# 결과 >> 0.4566100
- 정답을 예측하는 경우 오차제곱합(손실함수)가 낮은 반면, 틀린 경우 큰 것을 확인할 수 있습니다.
손실함수 - 교차엔트로피오차
def cross_entropy_error(y, t):
delta = 1e-7
return -np.sum( t * np.log(y+ delta))
t = [0,0,1,0,0,0,0,0,0,0]
y = [0.1, 0.04, 0.7, 0.0, 0.05, 0.15, 0.0, 0.1, 0.0, 0.0]
cross_entropy_error(np.array(y), np.array(t))
# 결과 >> 0.5175
y = [0.1, 0.02, 0.2, 0.1, 0.05, 0.15, 0.7, 0.1, 0.0, 0.0]
cross_entropy_error(np.array(y), np.array(t))
# 결과 >> 2.30
- 식을 간단하게 풀이하자면 t는 정답의 값을 나타내며, y는 예측값을 나타냅니다. 그래서 정답의 확률이 높은 경우, 0과 가까워지며 정답의 확률이 낮은 경우 숫자가 커지는 것을 볼 수 있습니다.
미니배치 학습
- 손실함수를 통해 최적의 매개변수를 찾아내는 과정에서 모든 훈련 데이터를 대상으로 손실 함수 값을 구해야 합니다.
- 즉, 훈련데이터가 100,000개 있으면 100,000개의 손실 함수 값들의 합을 지표로 삼는 것입니다.
- 그런데 지금은 100,000개이지만 빅데이터 수준이 되면 너무 커지는 문제가 있습니다. 이런 경우 데이터의 일부를 추려 전체의 근사치로 이용할 수 있습니다. 신경망 학습에서도 훈련 데이터로부터 일부만 골라 학습을 수행합니다. 이 일부를 미니배치라고 합니다.
- MNIST의 훈련데이터 60,000개 중 100장을 무작위로 뽑아 그 100장만 사용하여 학습하는 것입니다. 이러한 학습방법을 미니배치 학습이라고 합니다.
왜 손실함수를 사용하는가
- 정확도 대신 손실함수를 사용하는 이유는 계단함수 대신 시그모이드를 사용하는 이유와 일맥상통합니다.
- 신경망 학습에서는 최적의 매개변수를 찾기 위해 손실함수를 계산하고 미분을 통해 매개변수의 값을 갱신하여 손실함수를 줄이는 과정을 거칩니다.
- 하지만 정확도를 지표로 삼을 경우, 계단함수와 같이 미분의 대부분의 값이 0이므로 갱신이 되지 않고 중단됩니다. 그렇기 때문에 정확도보다, 손실함수를 사용하는 것입니다.