본 포스팅은 다음 과정을 정리 한 글입니다.
Custom Models, Layers, and Loss Functions with TensorFlow
www.coursera.org/specializations/tensorflow-advanced-techniques
지난 시간 리뷰
2021.03.18 - [Artificial Intelligence/Keras] - [Tensorflow 2][Keras] Week 2 - Custom loss functions
아래 코드는 지난 시간에 배웠던 custom loss function입니다.
threshold를 그냥 1로 세팅하고 진행을 했었는데요. 그럼 만약에 threshold를 parameter로 custom loss function에 전달하고 싶으면 어떻게 해야될까요? threshold는 튜닝 할 수 있는 굉장히 파워풀한 hyperparameter가 될 것입니다.
이렇게 threshold를 원래 손실함수 my_huber_loss에 전달하려면 my_huber_loss가 포함된 래퍼 함수를 만들어야 합니다.
아래 코드는 my_huber_loss_with_threshold function을 정의하고 매개변수로 threshold를 받았습니다. 밑에 my_huber_loss 함수 코드들은 위와 그대로 동일합니다.
이렇게 하면 threshold 매개 변수를 사용할 수 있으므로 loss를 호출할때 해당 값을 전달할 수 있습니다. 이 값을 받아서 아래 my_huber_loss에서는 하드 코딩된 threshold 대신에 받아온 threshold값을 사용합니다.
my_huber_loss_with_threshold가 불러지면 "return my_huber_loss"이 호출되고 my_huber_loss의 값이 계산되며 그 return 값을 그대로 받아서 return 시키게 됩니다.
model.compile의 parameter인 loss는 y_true와 y_pred를 가지는 함수를 필요로 합니다.
우리는 wrapper(my_huber_loss_with_threshold)를 사용하여 threshold를 포함하면서 y_true, y_pred를 제공하는 custom loss function을 구성할 수 있습니다. loss function 내에서 hyperparameter 조정을 수행하려는 경우 여기 threshold값을 조정하면 됩니다.
오늘은 Loss function을 생성하고 Wrapper function을 사용하여 parameter를 지정하는 방법을 배웠습니다. 또한 모델 학습에서 사용자 정의 손실함수를 어떻게 사용되는지 확인하였습니다. Tensorflow를 이용하여 개발을 많이 해오셨으면 손실 함수를 문자열의 이름을 사용하는 대신 클래스의 개체 인스턴스로 전달될 수 있다는 것을 알아 차렸을지도 모릅니다. 그러기 위해서는 손실 함수를 파이썬 함수가 아닌 파이썬 클래스로 구현해야 합니다.
앞에서 Loss function을 살펴보는 중에 클래스로 구현되는 방법도 확인할 수 있었습니다.
따라서 문자열이나 함수를 전달하는 대신에 여러분의 loss function을 위한 class를 만들 수 있습니다. 어떻게 하면 될지 코드로 살펴보겠습니다.
아래에 Huber loss의 전체 코드가 있습니다. 여기에서 몇가지 살펴보겠습니다.
먼저 파이썬의 class를 구현하는 것과 동일하게 class 코드를 구현하고
부모 클래스(Loss)를 클래스 뒤에 괄호 안에 넣음으로써 상속을 수행하는 것으로 선언합니다.
아래 문법은 MyHuberLoss는 Loss class를 상속한다는 의미 입니다. 이 것은 우리가 MyHuberLoss class를 loss function으로 사용할 수 있게 해줍니다.
그런 다음 클래스 내에서 2가지 함수를 가져야 합니다.
먼저 init function을 가져야 합니다. init함수는 클래스에서 객체가 초기화 될때 호출되는 함수입니다.
그 다음으로 call function을 가져야 하는데 객체가 클래스로 부터 인스턴스화 될 때 실행되는 호출 함수입니다. 연산들을 여기에 정의합니다.
init 함수는 threshold를 받아 옵니다. 앞에서 배웠듯이 mode.compile에서 loss의 parameter로 클래스를 넣고 ()로 threshold를 전달할 때 threshold는 init 함수에서 받을 수 있게 됩니다.
그리고 파이썬 문법을 사용하여 self라는 클래스 변수에 threshold를 저장합니다.
그 저장된 threshold를 가지고 call이 호출 되었을 때 self.threshold의 값을 가지고 계산을 하게 됩니다.
그리고 call 함수는 y_true와 y_pred parameter를 가져옵니다.
이제 model.compile에서 loss에 클래스 이름과 매개변수로 threshold값을 전달할 수 있게 되었습니다.
참 쿨한 것 같네요 ㅎㅎ
여태까지 custom loss function을 클래스로 만들고 매개변수로 hyperparameter를 전달하여 값을 변경할 수 있는 방법을 배웠습니다.
많이 활용해 보시기 바랍니다.
감사합니다.
댓글