인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

윤지형님의 프로필 이미지

작성한 질문수

딥러닝 이론 + PyTorch 실무 완전 정복

[실습] PyTorch로 구현해보는 Loss Function

[섹션3, PyTorch로 구현해보는 Loss Function] 분류task loss함수 질문입니다.

해결된 질문

작성

·

65

·

수정됨

1

좋은 강의 정말 잘 듣고있습니다. 항상 감사합니다.

다름이 아니라 nn.BCEloss 나 nn.BCEWithLogitsLoss에서 이름에 B(Binary)가 들어가 이진분류 문제에 사용하는 함수인가 싶었는데, 실습 강의때 처럼 다중 분류 문제의 loss 함수로 사용해도 괜찮은 것인지 여쭙고 싶습니다.

generate_onehot 함수는 클래스가 10개인 다중분류 데이터를 생성합니다.

batch_size = 16
n_class=10

def generate_onehot(batch_size=16, n_class=10):
    pred = torch.nn.Softmax()(torch.rand(batch_size, n_class))
    gt = torch.rand(batch_size, n_class)
    gt = torch.tensor(gt == torch.max(gt, dim=1, keepdim=True)[0]).float()  # convert to onehot
    return pred, gt

답변 2

1

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. 윤지형님.

먼저, 강의를 잘 듣고 계신다니 기쁩니다. 지금 질문해 주신 nn.BCELossnn.BCEWithLogitsLoss는 이름에서 B(Binary)가 나오듯이, 주로 이진 분류 문제에서 사용되는 손실 함수입니다. 이러한 함수들은 두 클래스간(주로 YES/NO) 여부를 판단할 때 확률적으로 처리하기 때문에 손실을 계산할 수 있습니다.

다중 분류 문제를 위한 손실 함수로는 보통 nn.CrossEntropyLoss를 사용합니다. 이 함수는 내부적으로 소프트맥스(Softmax)와 로그 확률 계산을 수행하여 클래스 예측에서의 손실을 줄이는 역할을 합니다. 다중 레이블 분류(Multi-label classification)처럼 각 레이블이 독립적인 2진 분류 문제로 취급될 때에는 nn.BCELossnn.BCEWithLogitsLoss를 사용하기도 합니다.

현재 하신 실습에서 generate_onehot 함수는 다중 클래스(one-hot) 레이블로 변환한 데이터셋을 생성합니다. nn.BCELoss 대신 다중 클래스 문제에 적합한 nn.CrossEntropyLoss를 사용하는 것이 더 일반적입니다. 이 함수는 클래스 간 상호 정보 손실을 줄여 정확한 예측을 얻는 데 도움을 줍니다.

이와 관련하여 아래 링크에서 손실 함수와 관련 내용을 좀 더 깊이 이해할 수 있는 관련 질문과 답변을 확인하실 수 있습니다:

해당 링크에서 손실 함수의 종류와 적합성을 판단하는 데 있어 어떤 사항들을 고려해야 하는지에 대한 유용한 정보를 얻으실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

0

변정현님의 프로필 이미지
변정현
지식공유자

안녕하세요

좋은 질문 감사합니다!

네 결론부터 말씀드리자면, nn.BCELoss와 nn.BCEWithLogitsLoss 모두 다중 분류 문제의 Loss 함수로 사용해도 괜찮습니다!

제 실습 강의에서도 class 개수가 10인 예제를 사용해서 nn.BCELos와 nn.BCEWithLogitsLoss을 적용하였습니다.

다만 주의할 점은 nn.BCELoss에서는 Ground Truth 값이 (batch_size, n_class) 크기의 one-hot-vector 로 입력되어야 한다는 것입니다.

즉, nn.BCELoss에서는 모델이 예측한 확률값과 실제 정답(One-Hot Vector) 간의 비교가 이루어집니다.

예를 들어, 클래스 개수가 3개이고, 하나의 데이터 샘플이 있다고 가정해보겠습니다.

모델의 예측값: [0.8, 0.1, 0.1] (각 클래스에 대한 예측 확률)

정답(One-Hot Vector): [1, 0, 0]

이 경우, 첫 번째 클래스(0.8 vs 1), 두 번째 클래스(0.1 vs 0), 세 번째 클래스(0.1 vs 0) 이렇게 개별적으로 비교하면서 Binary Cross Entropy를 계산합니다.

즉, 각 클래스마다 독립적으로 이진 분류 문제를 수행하는 것처럼 작동한다고 보면 됩니다!


nn.BCEWithLogitsLoss도 기본적인 개념은 같습니다. 다만, sigmoid 활성화 함수를 내부적으로 포함하고 있어서 모델의 출력값을 바로 넣어도 된다는 차이가 있습니다. (nn.BCELoss는 예측값을 먼저 sigmoid를 거쳐야 합니다.)

정리해보자면:

  • nn.BCELoss & nn.BCEWithLogitsLoss → 다중 분류 문제에서도 사용 가능!

  • 다만, nn.BCELoss를 사용할 때는 정답 데이터를 One-Hot Vector 형태로 만들어야 함

  • 각 클래스별로 개별적으로 확률값을 비교하는 방식이라 생각하면 이해하기 쉬움

  • BCEWithLogitsLoss는 sigmoid가 포함되어 있어 추가 변환 없이 사용 가능

스크린샷 2025-02-02 오후 2.32.42.png.webp