AI 스터디 관련 질의응답 기록 (2024 가을학기 1차세션)
나는 현재 Google Developers on Campus(이하 GDGoC)에서 AI 멘토로 활동하며, 멤버들을 대상으로 스터디 자료와 멘토링을 제공하고 있다. 이 과정에서 받은 질문들에 대해 답변하는 글을 작성하고자 한다.

Question #1: 데이터 불균형
Q1. 이번 스터디의 경우, 데이터셋이 img였는데, 주신 자료나 연관 링크를 읽고 분석해 보았을 때, 특정 클래스에 속하는 데이터가 다른 클래스에 비해 월등히 많은 (data imbalance) 한 상황을 보았습니다. 실제 데이터를 분석할 때도 이러한 상황이 많을 것 같은데 이를 어떠한 방식으로 처리할 수 있는지 궁금합니다.
+ 클래스별 데이터 수를 고려하여 augumentaion을 다르게 해 준다던지 혹은 너무 많은 클래스의 데이터를 일부 버린다던지 하는 방법이 유효한지 궁금합니다. 또, 모든 클래스별 데이터 수가 동일 한 것이 모델이 학습하기 가장 이상적인 상황이라고 할 수 있는지도 궁금합니다.
A1. 데이터 불균형은 현업에서도 굉장히 많이 발생하는 문제입니다. 이번 프로젝트 또한 클래스별 개수를 확인해보면, 어떤 클래스는 굉장히 적고, 어떤 클래스는 굉장히 많은 모습을 확인할 수 있습니다. 이런 경우 모델이 한쪽 클래스에 편향될 수 있습니다. 이와 같은 경우 말씀 주신 것처럼 적은 데이터 클래스에 대해 뒤집기, 회전, 크기 조절과 같은 Augmentation을 다양하게 주어 부족한 클래스의 데이터 분포를 보강하거나, 다수 클래스의 데이터를 일부 버림으로써 불균형을 완화하는 방식(이런 기법을 Under-sampling이라고 합니다)을 사용하기도 합니다. 다만 이러한 기법들을 적용할 때는 Augmentation이 전체적인 데이터 특성에 너무 많은 영향을 주거나, Under-sampling을 할 때 중요 정보를 포함한 데이터가 삭제될 수 있어서 주의해야 합니다.
이 때문에, 일반적으로는 불균형을 해소하기 위해 데이터를 직접 건드리는 방식보다는 Focal loss와 같이 불균형을 해소하기 위해 설계된 loss function을 사용하거나 클래스별 가중치를 조정하는 방식을 주로 사용합니다.
추가로, 실제 현업에서는 모든 클래스별 데이터 수가 동일한 것보다 풀고자 하는 실제 문제, 즉 실제 스트림으로 들어오게 될 현실의 분포를 따르는 것이 서비스의 측면에서는 더 좋을 수 있습니다. 다만 이는 목적에 따라 달라질 수 있기 때문에, 개발하고 있는 시스템의 목표를 잘 고려하는 것이 중요합니다.
Question #2: 멀티모달(Multi-modality) feature 처리 방법
Q2. 만약 주어진 데이터셋에서 feature의 종류가 한 종류가 아닐 때에는 어떻게 하는지 궁금합니다. 예를 들어 이번 스터디와 동일한 TASK에서 잎의 크기, 식물물의 서식지, 일광량 같은 정보들이 같이 주어질 경우 어떻게 다루는지 궁금합니다.
+ 제 생각으로는 img 처리는 현재 딥러닝 모델들이 뛰어나니, 딥러닝 모델을 사용하고, 이외의 데이터들은 꼭 딥러닝 모델을 사용할 필요는 없으니 tree-based 모델들이나 다른 모델들을 사용하여 classification 하고 각 모델의 softmax 결과를 가중치를 두어 더하여 한번 더 softmax 돌리는 방법을 사용하면 가능할 것 같다고 생각합니다. 만약, 실제로도 이러한 방법을 사용한다면, 서로 다른 feature로 예측을 하는 모델 간의 가중치는 어떻게 설정하는 것이 좋은지, 아니면 다른 방법이 있는지 궁금합니다.
A2. 이미지 데이터 외에 서식지, 일광량 등의 feature가 주어지는 경우를 'Multi-modal' 데이터라고 합니다. 입력의 Modality가 여러 개 존재한다는 것을 의미하며, 이러한 멀티모달 데이터를 처리하기 위해서는 다양한 모델과 처리 방법론을 사용할 수 있습니다. 이미지 데이터는 CNN으로, 수치형 데이터는 MLP나 FFN으로 각각 인코딩하여 입력하는 경우도 있고, 각 피쳐 그룹을 개별 모델로 처리한 후 결합할 수도 있습니다. 결합 방식은 크게 두 가지로 나눌 수 있는데, 초기에 여러 모달리티 데이터를 하나로 결합하여 모델의 입력으로 넣어주는 초기 결합(Early Fusion) 방식과, 독립적으로 처리한 후 결과를 최종 단계에서 결합하는 후기 결합(Late Fusion) 방식이 존재합니다.
이외에도, CNN-LSTM이나 Attention을 활용한 트랜스포머 구조 등 특수한 모델 아키텍처를 사용해서 각 모달리티 간의 관계를 더 잘 학습하도록 할 수도 있습니다.
이러한 멀티모달 데이터를 처리할 때는 모달리티 별로 스케일이 다를 수 있으므로 정규화 기법을 통해 하나의 모달리티 스케일로 처리하는 것이 필요할 수 있다는 점을 기억하시면 좋습니다.
마지막으로, 질문에서 언급한 softmax 결과에 가중치를 두어 결합하는 방법에 대해 말하자면, 각 모델의 성능 지표(예: validation accuracy)를 기준으로 가중치를 설정하는 방법이 많이 쓰입니다. 또는 단순 grid search나 Bayesian optimization 같은 기법으로 가중치를 최적화하는 것도 가능하고, 각 모델의 softmax 결과를 다시 입력으로 받아 최종 예측을 수행하는 Meta Model을 이용할 수도 있습니다(언급 주신 방법이랑 가장 유사하겠네요). 이런 방법들을 활용해 보면 좋을 것 같습니다.
Question #3: 질적(Qualitative) feature 처리 방법
Q3. 딥러닝 모델을 사용할 때, qualitative feature들을 어떻게 다루어야 하는지 잘 모르겠습니다.
제가 알기로는, labelencoder로 label들을 정수형으로 바꿔주면 딥러닝을 돌릴 수는 있겠지만, 만약 해당 feature에 대응되는 class들이 많아진다면 문제가 될 것 같은데, 어떠한 대안이 있는지 잘 모르겠습니다.
A3. 말씀 주신 것처럼, 딥러닝 모델에서 범주형 데이터를 처리할 때는 단순히 LabelEncoder로 정수형으로 바꾸는 것만으로는 한계가 있을 수 있습니다. 클래스가 많아지면 모델이 정수값을 순서로 오해하거나, 학습이 비효율적일 수 있기 때문인데요. 이런 문제를 해결하기 위해 몇 가지 방법이 있습니다.
1) 먼저, 원-핫 인코딩이라는 방식이 있습니다. 이는 범주형 데이터를 0과 1로 이루어진 벡터로 변환하는 방법인데요. 예를 들어, 'Red', 'Blue', 'Green'이라는 클래스가 있다면 각각 [1, 0, 0], [0, 1, 0], [0, 0, 1]처럼 나타낼 수 있습니다. 이 방법은 클래스가 적을 때는 간단하고 효과적이지만, 클래스 수가 많아지면 벡터 크기가 커지는 문제가 있습니다.
2) 클래스가 많다면 임베딩 레이어를 활용하는 것도 좋은 방법입니다. 임베딩 레이어는 각 클래스를 고정된 크기의 벡터로 변환하는데, 예를 들어 'Red'를 [0.1, 0.8], 'Blue'를 [0.5, 0.3]처럼 표현할 수 있습니다. 이런 벡터는 학습 과정에서 최적화되기 때문에 더 유연하게 데이터를 표현할 수 있죠. 파이토치 같은 프레임워크에서 쉽게 사용할 수 있습니다.
3) 또한, Frequency 인코딩이라는 방식도 있습니다. 이는 각 클래스가 데이터에서 얼마나 자주 등장하는지에 따라 숫자를 부여하는 방법인데요. 예를 들어, 'Red'가 데이터에서 40%, 'Blue'가 35%, 'Green'이 25% 등장한다면 각각 0.4, 0.35, 0.25로 바꿀 수 있습니다. 이 방식은 데이터의 분포를 반영할 수 있어서 유용하지만, 클래스 빈도가 중요하지 않은 경우에는 적합하지 않을 수 있습니다.
4) 마지막으로, Target 인코딩이라는 방법도 있습니다. 이는 클래스별로 타깃 값(예: 정답 레이블)의 평균을 구해 숫자로 변환하는 방식입니다. 예를 들어, 'Red'의 타겟 평균이 0.8, 'Blue'가 0.6이라면 각각 0.8, 0.6으로 변환할 수 있습니다. 하지만 이 방법은 데이터 누출(Data leakage)의 위험이 있기 때문에 검증 데이터셋이나 Cross-validation을 활용하여 신중하게 다뤄야 합니다.
이와 같이, 범주형 데이터를 처리할 때는 데이터의 특성과 모델에 따라 적합한 방식을 선택하는 것이 중요합니다. 클래스가 적으면 원-핫 인코딩이 간단하고 효과적이고, 클래스가 많다면 임베딩 레이어가 효율적입니다. 데이터의 의미를 잘 이해하고 있다면 빈도 인코딩이나 타겟 인코딩도 고려해 볼 수 있습니다. 각 방법을 실험하며 최적의 결과를 찾아보시는 걸 추천드립니다!
+) 추가질문
Q3-2. 만약 주어진 데이터 셋이 feature는 2개로 하나는 quantitative, 나머지 하나는 categorical 해서 one-hot을 적용했다면, 이 두 정보를 한 번에 처리하기 위해 torch에서 어떻게 해야 하는지 궁금합니다.
두 변수를 별개로 처리하여 하나는 embedding layer, 나머지 하나는 linear로 처리하여 concat 하면 될까요?
A3-2. 넵 quantitative feature의 처리는 선형 계층에서 할 수 있고, PyTorch에서는 nn.Linear로 구현할 수 있습니다.
quantitative data는 별도의 전처리 없이 바로 사용할 수 있지만, 학습의 안정성을 위해 보통 정규화(normalization)나 표준화(standardization)를 적용합니다.
1) categorical feature는 one-hot encoding을 수행한 후, 차원을 줄이기 위해 임베딩 레이어를 사용하는 것이 일반적입니다. PyTorch에서는 nn.Embedding을 사용해 임베딩 벡터를 생성할 수 있습니다.
예를 들어, 범주형 데이터의 클래스가 10개라면
embedding_layer = nn.Embedding(num_embeddings=10, embedding_dim=4)
와 같이 구현할 수 있겠네요.
여기서 embedding_dim은 범주형 데이터를 임베딩할 벡터의 크기를 의미합니다.
이와 같이 두 데이터를 각각 처리한 뒤, 두 정보를 하나의 입력 벡터로 결합(Concatenation)하여 처리할 수 있습니다. PyTorch에서 이를 구현하려면 다음과 같은 방식으로 구현할 수 있습니다
combined = torch.cat([embedded, quantitative], dim=1) # (batch_size, embedding_dim + hidden_dim)
'컴퓨터 공학 기본 > GDGoC 멘토 활동 기록' 카테고리의 다른 글
Kaggle API 이용법 (feat. kaggle.json이 뭐예요?) (0) | 2024.11.27 |
---|
댓글