Keras에서 Custom Loss Function 만들기

져닝·2024년 12월 6일

tensorflow-keras

목록 보기
2/5

딥러닝 모델을 설계할 때, 기본 제공되는 손실 함수(MSE, MAE 등)로 충분하지 않을 때가 있다. 예를 들어, 데이터의 특정 패턴에 민감한 손실 함수가 필요하거나, 불균형 데이터에서 성능을 극대화하려는 경우들이 있다. 오늘은 keras에서 custom loss function을 설게하고 사용하는 방법을 알아보자.

1. Custom Loss Function이 필요한 이유

기본 제공되는 손실 함수는 대부분의 경우 잘 작동하지만, 연구 도메인이나 문제의 특수성에 따라 맞춤형 손실 함수가 필요할 수 있다.

  • 예측에서 특정 값의 오차를 더 중요하게 취급해야 할 때
  • 데이터 불균형 문제를 해결하고 싶을 때
  • 연구 목적에 맞는 독창적인 평가 지표를 구현할 때

2. Custom Loss Function 구현 방법

Keras에서 커스텀 손실 함수를 만드는 방법은 간단하다.

  • python 함수로 정의하거나
  • Keras의 tf.keras.losses.Loss 클래스를 상속받아 객체로 구현

(1) Python 함수로 정의하기

import tensorflow as tf

def custom_mse(y_true, y_pred):
	squared_difference = tf.square(y_true - y_pred)
    return tf.reduce_mean(squared_difference, axis=-1)

사용법
모델 컴파일 단계에서 loss 매개 변수에 함수 이름을 전달한다.

model.compile(optimizer='adam', loss=custom_mse, metrics=['mae']

(2) Loss 클래스를 상속받아 정의하기

좀 더 복잡한 손실 함수가 필요하다면 tf.keras.losses.Loss 클래스를 상속받아 구현할 수 있다.

예를 들어, 회귀 문제에서 사용되는 Huber Loss를 구현해보자.
데이터에 이상치가 포함된 경우, MSE는 이상치에 매우 민감하게 반응하지만, Huber loss는 이상치의 영향을 줄일 수 있다. Huber loss는 다음과 같이 정의된다.

L(y,y^)={12(yy^)2if yy^δδyy^12δ2if yy^>δL(y, \hat{y}) = \begin{cases} \frac{1}{2}(y - \hat{y})^2 & \text{if } |y - \hat{y}| \leq \delta \\ \delta \cdot |y - \hat{y}| - \frac{1}{2} \delta^2 & \text{if } |y - \hat{y}| > \delta \end{cases}

여기서

  • yy: 실제값
  • y^\hat{y}: 예측값
  • δ\delta: 손실 함수의 전환점(threshold)을 결정하는 하이퍼파라미터

핵심 동작
1) 오차가 작을 때 (yy^δ|y - \hat{y}| \leq \delta)

  • MSE처럼 작동 (12(yy^)2\frac{1}{2}(y - \hat{y})^2)
  • 작은 오차에 대해 민감하게 반응

2) 오차가 클 때 (yy^>δ|y - \hat{y}| > \delta)

  • MAE 처럼 작동 (δyy^12δ2\delta \cdot |y - \hat{y}| - \frac{1}{2} \delta^2)
  • 이상치의 영향을 줄이기 위해 선형적으로 작동

이를 코드로 구현하면 다음과 같다.

class CustomHuberLoss(tf.keras.losses.Loss):
	def __init__(self, threshold=1.0):
    	super(CustomHuberLoss, self).__init__()
        self.threshold = threshold
    
    def call(self, y_true, y_pred):
    	error = y_true - y_pred
        is_small_error = tf.abs(error) <= self.threshold
        small_error_loss = tf.square(error) / 2
        big_error_loss = self.threshold * (tf.abs(error) - 0.5 * self.threshold)
        return tf.where(is_small_error, small_error_loss, big_error_loss)

사용법
객체를 생성하고 loss로 전달한다.

loss_fn = CustomHuberLoss(threshold=1.5)
model.compile(optimizer='adam', loss=loss_fn, metrics=['mae']

요약

keras에서 커스텀 손실 함수를 만들면 기본 제공 손실 함수로 해결할 수 없는 다양한 문제를 다룰 수 있다. 간단한 함수 정의부터 클래스를 활용한 복잡한 구현까지 필요에 따라 맞춤형으로 설계할 수 있다.

profile
태양물리박사 / 코드 공부 끄적끄적하는 공간 / Space weather forecasting

0개의 댓글