4.2 손실 함수

2024. 11. 10. 17:23스터디/24-2 스터디 _ 밑바닥부터 시작하는 딥러닝

 

-신경망에서는 현재의 상태를 '하나의 지표'로 표현한 뒤,

그 지표를 기준으로 최적의 가중치 매개변수 값을 탐색함

 

-신경망 학습에서 사용하는 지표 : 손실 함수(Loss Function)

-손실함수

  • 신경망 학습에서 사용하는 지표
  • 신경망 성능의 '나쁨'을 나타내는 지표
  • 현재 신경망의 훈련 데이터 처리 능력 나타냄
  • 마이너스 곱해주면 '좋음' 지표로도 쓸 수 있음
  • 손실함수의 종류

         1. 임의의 함수

         2. 오차제곱합(4.2.1)

         3. 교차 엔트로피 오차(4.2.2)

 

 

4.2.1 오차제곱합(sum of squres for error, SSE)

: 손실 함수

: 각 원소의 '출력(추정 값) - 정답 레이블(참 값)' 을 제곱한 것의 총 합

오차제곱합 수식

 

-yk : 신경망의 출력(신경망이 추정한 값) <- 소프트맥스 함수의 출력이라서 확률로 해석 가능

-tk : 정답 레이블 <- 원-핫-인코딩

-k : 데이터의 차원 수

 

-(오차제곱합을 파이썬으로 구현한 코드)

: 0.5는 식의 1/2에 해당함

def mean_squared_error(y, t):
    return 0.5 * np.sum((y-t)**2)

 

 

-오차가 작을수록(손실 함수의 출력이 작을수록) 정답에 가깝다!

 

 

4.2.2 교차 엔트로피 오차(Cross Entropy Error, CEE)

: 손실 함수

교차 엔트로피 오차 수식

 

-log : 밑이 e인 자연로그

-yk : 신경망의 출력

-tk : 정답 레이블 <- 원-핫-인코딩

 

-정답일 때의 추정(tk=1 일 떄의 yk)의 자연로그를 계산하는 식

-> 정답일 때의 출력이 전체 값을 정하게 된다!

 

-출력이 커질 수록 0에 다가가다가, 출력이 1이 되면 0이 됨

-> 정답일 때의 출력이 작을수록 오차가 크다!

 

-(교차 엔트로피 오차를 파이썬으로 구현한 코드)

def cross_entropy_error(y, t):
    delta = 1e-7
    return -np.sum(t * np.log(y + delta))
  • delta : 아주 작은 값
  • delta 사용 이유 : 0이 입력되면 마이너스 무한대를 뜻하는 '-inf'가 되어 더 이상 계산을 진행할 수 없게 되므로, 작은 값 더해서 절대 0이 되지 않도록(=마이너스 무한대가 발생하지 않도록) 하기 위해서 사용함.

-오차가 작을수록 정답일 확률이 높다!

 

 

4.2.3 미니배치 학습

: 훈련 데이터 모두에 대한 손실 함수의 합을 구해서, '지표'로 삼기

모든 훈련 데이터(N개)에 대한 교차 엔트로피 오차 식

-N : 데이터 개수

-tnk : n번째 데이터의 k번째 값

-ynk : 신경망의 출력

-tnk : 정답 레이블

 

-기존 식(데이터 하나)을 N개의 데이터로 확장한 것

-N으로 나누어줘서 정규화함

-> '평균 손실 함수' 구함

-> 훈련 데이터 개수와 관계없는 통일된 지표 get 가능

 

-미니배치(mini-batch) : '묶음'

  • 데이터의 일부를 (무작위로) 추려 전체의 '근사치'로 이용하는 것(일부만 골라 학습 수행)
  • 그 '일부'의 단위 : 미니배치
  • 추리는 방식 : 무작위(랜덤)
  • 사용 함수 : np.random.choice(n, k)                                                                                                        - 0 이상 n 미만의 수 중에서 무작위로 k개의 'index'를 꺼내는 것                                          - 이 'index'를 사용해서 미니배치를 뽑아내면 됨 

 

 

4.2.4 (배치용) 교차 엔트로피 오차 구현하기

: 두 가지 경우에 따른 구현이 있음

  • y : 신경망의 출력
  • t : 정답 레이블

 

1. 정답 레이블이 '원-핫-인코딩'으로 주어졌을 때의 교차 엔트로피 오차 구현

: 평균 교차 엔트로피 오차 계산

def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
        
    batch_size = y.shape[0]
    return -np.sum(t * np.log(y)) / batch_size

-reshape() 함수 : 데이터의 형상(mXn) 바꿔줌

-/batch_size : 정규화

 

2. 정답 레이블이 '숫자 레이블'로 주어졌을 때의 교차 엔트로피 오차 구현

: 정답에 해당하는 신경망의 출력만으로 교차 엔트로피 오차 계산 가능

def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
        
    batch_size = y.shape[0]
    return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size

-t=0인 원소는 교차 엔트로피 오차도 0이므로, 계산은 무시해도 됨

-np.arange(batch_size) : 0부터 'batch_size-1' 까지 배열을 생성함

-y[np.arange(batch_size), t] : 각 데이터의 정답 레이블에 해당하는 신경망의 출력을 추출함

 

 

4.2.5 왜 손실 함수를 설정하는가?

 

1. 손실 함수를 사용해야하는 이유

 

-'정확도' 대신 '손실 함수의 값'을 지표로 사용하는 이유

: 미분 값이 대부분의 장소에서 0이 되어 매개변수를 갱신할 수 없기 때문이다. 

 

-신경망 학습에서,

  1. 손실 함수의 값을 가능한 작게 하는 매개변수 값을 찾음.
  2. 그 뒤 매개변수의 미분을 계산하고, 미분 값을 이용해서 매개변수의 값을 갱신하는 걸 반복함.
  3. 갱신은 미분(가중치 매개변수의 손실 함수 미분)값이 0이 될 때까지 함.
  4. 이 과정을 통해서 '최적의 매개변수(가중치와 편향)'을 탐색함.

-근데 '정확도'를 지표로 쓰면

미분 값이 이미 대부분의 장소에서 0이 되므로

매개변수 갱신이 불가능함.

 

 

2.  '정확도'를 지표로 쓰면 미분 값이 이미 대부분의 장소에서 0이 되는 이유

 

-지표가 '정확도' 일 때

: 가중치 값의 작은 변화에는 잘 개선되지 않으며,

개선될 때는 불연속적인 띄엄띄엄한 값으로 바뀜.

: 한순간만, 즉 불연속적으로 변화를 일으키므로 대부분의 장소에서 미분 값(=기울기)이 0임

: 계단 함수를 활성화 함수로 쓰지 않는 이유(3장:신경망 학습이 잘 이뤄지지 않음)와도 연관

 

-지표가 '손실 함수' 일 때

: 가중치 값이 조금 변하여도 그에 반응하여 손실 함수의 값도 연속적으로 변화함.

: 연속적으로 변화하므로 곡선의 기울기도 연속적으로 변하므로 미분 값(=기울기)이 0이 되지 않음

 

 

===>>> 가중치 매개변수의 미소한 변화에도 잘 반응하여야하며, 연속적으로 변하여야함.

그러나 '정확도' 지표에서는 그렇지 못하므로 '정확도'를 지표로 쓸 수 없다.