# C++ Libtorch에서 손실 함수 (Loss Functions in Libtorch)

Libtorch는 PyTorch의 C++ API로, C++ 환경에서 신경망을 구축하고 학습하는 데 사용된다. 손실 함수는 Libtorch에서 중요한 역할을 하며, 모델의 예측과 실제 값 간의 차이를 정량화하여 최적화를 가능하게 한다. Libtorch는 다양한 손실 함수를 제공하며, 이를 이용하여 모델을 효과적으로 학습시킬 수 있다.

#### Libtorch에서의 손실 함수 개요

Libtorch에서는 손실 함수를 `torch::nn::functional` 네임스페이스 내에서 제공하며, 이를 통해 손쉽게 다양한 손실 함수를 사용할 수 있다. Libtorch의 손실 함수들은 주로 `torch::Tensor` 객체를 입력으로 받아, 예측값과 실제값 간의 차이를 계산한 후 단일 값(스칼라)을 반환한다. 이 스칼라 값은 최적화 과정에서 사용된다.

손실 함수는 주로 회귀(Regression)와 분류(Classification) 작업에서 사용되며, 각각의 작업에 특화된 다양한 손실 함수들이 제공된다.

#### Libtorch에서 사용되는 주요 손실 함수

**MSELoss (Mean Squared Error Loss)**

`torch::nn::MSELoss`는 회귀 문제에서 주로 사용되는 손실 함수로, 예측값과 실제값 간의 평균 제곱 오차를 계산한다. 이 함수는 모델의 예측이 실제값과 얼마나 가까운지를 측정하는 데 사용된다.

사용 예시는 다음과 같다:

```cpp
torch::nn::MSELoss mse_loss;
auto loss = mse_loss(predicted, target);
```

MSELoss는 기본적으로 reduction 옵션을 통해 반환되는 손실 값의 형태를 조정할 수 있다. 예를 들어, `mean` 또는 `sum` 방식으로 계산된 손실을 반환하도록 설정할 수 있다.

```cpp
torch::nn::MSELoss mse_loss(torch::nn::MSELossOptions().reduction(torch::kSum));
auto loss = mse_loss(predicted, target);
```

**CrossEntropyLoss**

`torch::nn::CrossEntropyLoss`는 분류 문제에서 가장 많이 사용되는 손실 함수 중 하나로, 예측된 클래스 확률과 실제 클래스 간의 교차 엔트로피를 계산한다. 이 함수는 다중 클래스 분류 문제에서 주로 사용된다.

CrossEntropyLoss는 내부적으로 `log_softmax`와 `nll_loss`를 결합하여 사용하므로, 따로 소프트맥스(softmax) 활성화 함수를 적용할 필요가 없다.

```cpp
torch::nn::CrossEntropyLoss cross_entropy_loss;
auto loss = cross_entropy_loss(predicted, target);
```

이 함수는 클래스 불균형이 있는 경우, 가중치(weight)를 부여하여 손실을 조정할 수 있는 기능도 제공한다.

```cpp
auto weight = torch::tensor({1.0, 2.0, 0.5});
torch::nn::CrossEntropyLoss cross_entropy_loss(torch::nn::CrossEntropyLossOptions().weight(weight));
auto loss = cross_entropy_loss(predicted, target);
```

**NLLLoss (Negative Log Likelihood Loss)**

`torch::nn::NLLLoss`는 `log_softmax` 함수와 함께 사용되는 손실 함수로, 예측된 클래스의 로그 확률과 실제 클래스 간의 음의 로그 우도를 계산한다. 이 손실 함수는 특히 확률 분포를 직접 출력하는 모델에서 유용하다.

사용 예시는 다음과 같다:

```cpp
torch::nn::NLLLoss nll_loss;
auto loss = nll_loss(predicted_log_probs, target);
```

`NLLLoss`는 `CrossEntropyLoss`와 유사하지만, 입력값으로 소프트맥스가 적용된 로그 확률을 요구한다는 점에서 차이가 있다.

**L1Loss (Mean Absolute Error Loss)**

`torch::nn::L1Loss`는 예측값과 실제값 간의 절대 오차를 계산하는 손실 함수로, MSELoss와 달리 오차의 절대값을 평균하여 손실을 계산한다. 이 손실 함수는 이상치(outlier)에 덜 민감한 특성을 가지고 있다.

사용 예시는 다음과 같다:

```cpp
torch::nn::L1Loss l1_loss;
auto loss = l1_loss(predicted, target);
```

이 함수 역시 reduction 옵션을 통해 반환되는 손실 값의 형태를 조정할 수 있다.

```cpp
torch::nn::L1Loss l1_loss(torch::nn::L1LossOptions().reduction(torch::kSum));
auto loss = l1_loss(predicted, target);
```

#### Libtorch에서의 사용자 정의 손실 함수

Libtorch에서는 표준 손실 함수 외에도 사용자 정의 손실 함수를 구현할 수 있다. 사용자 정의 손실 함수는 단순히 `torch::Tensor`를 입력으로 받아, 예측값과 실제값 간의 손실을 계산하여 반환하는 함수로 정의된다.

예를 들어, Huber 손실 함수를 Libtorch에서 구현하려면 다음과 같이 할 수 있다:

```cpp
torch::Tensor huber_loss(torch::Tensor predicted, torch::Tensor target, double delta) {
    auto error = predicted - target;
    auto abs_error = torch::abs(error);
    auto quadratic = torch::min(abs_error, torch::tensor(delta));
    auto linear = abs_error - quadratic;
    return 0.5 * quadratic.pow(2) + delta * linear;
}
```

이와 같이 Libtorch에서는 C++의 강력한 기능을 활용하여 다양한 사용자 정의 손실 함수를 구현하고, 이를 최적화 과정에서 사용할 수 있다.

#### 손실 함수와 최적화

Libtorch에서 손실 함수는 최적화 과정의 핵심 요소로 사용된다. 손실 함수로 계산된 값을 경사 하강법(Gradient Descent) 등의 최적화 알고리즘에 입력으로 사용하여, 모델의 파라미터를 업데이트한다. Libtorch의 `torch::optim` 모듈은 이러한 최적화 알고리즘들을 제공하며, 손실 함수와 결합하여 모델 학습을 수행한다.

***
