💡 자연어 처리(NLP: Natural Language Processing)의 차원 전제 :
일반적으로 자연어 처리 분야의 딥러닝 모델에서는 문장 데이터를 임베딩하여 주입할 때, 무조건 3차원 텐서 규격 [Batch, Seq, Feature] (단어장 점수의 경우 [Batch, Seq, Vocab])으로 입력을 처리하도록 규격화되어있다.
📊 3차원 텐서 [Batch, Seq, Vocab]의 축(dim) 방향 시각화
📢 일반적으로 자연어 처리(NLP)에서는 위와 같이 입력 규격을 3차원 텐서 형태로 정의하여 연산하지만, 실제 모델의 내부 구동 과정에서는 이 차원 규격을 그대로만 유지하는 것이 아니라 필요에 따라 차원을 인위적으로 줄이거나(Squeeze) 늘리는(Unsqueeze) 조작을 끊임없이 동반하며 활용함. 차원을 줄이고 늘리며 사용하는 구체적인 대표 사례는 다음과 같음.
🤔 텐서 차원(Shape)을 줄이고 늘리는 근본적인 두 가지 목적
1. 최종 결과 도출 및 균형 잡힌 가중치 학습 (비즈니스/수학적 목적) :
• 최종 번역 단어 출력 : 최초 3차원 출력 텐서([1, 1, 30000])에서 squeeze를 거쳐 1차원 점수판([30000])을 얻고, 다시 argmax를 거쳐 최종 0차원 스칼라 정답 단어 딱 1개(예: `15`)를 선출하여 번역기의 최종 텍스트 화면에 보여주기 위해 압축.
• 균형 잡힌 가중치 업데이트 : 32개 문장의 개별 오답 점수들이 나열된 1차원 오차 텐서([32])를 배치 축(dim=0) 방향으로 평균 내어 단 하나의 대표 오차(0차원 스칼라 Loss)로 압축. 32개 문장 모두를 평균적으로 골고루 잘 번역하도록 모델 가중치를 안정적으로 업데이트하기 위해 사용.
2. 레이어 간 행렬곱 규격 매칭 (시스템적 목적) : 데이터 내용물은 똑같아도 다음 신경망 레이어(Embedding, RNN 셀 등)의 연산 입구가 강제하는 엄격한 텐서 차원 규격(예: 반드시 대괄호가 씌워진 2차원으로 입력할 것)에 형상을 맞추기 위해 차원을 늘려 포장(unsqueeze)하는 연산 수행.
배치 전체, 시퀀스 전체의 모든 오차값들을 한 덩어리로 융합하여 평균을 구한 결과물.
• 실제 활용 : 학습 역전파(Backpropagation) 직전에 모델의 전체 오차 대표값 딱 1개를 계산하여 모델 최적화 지표로 활용함.
• 직관적 이해 : 2개 문장(Batch=2) 내의 3개 단어(Seq=3)들이 가진 4개 단어장(Vocab=4) 값들(총 24개)을 축 구분 없이 싹 평균 내어, 전체 데이터의 종합 평균 딱 1개만 남겨 압축하는 개념.
• 핵심 용도 : 학습을 위한 최종 오차 전파
📥 단일 문장(Batch=1) 인코더 내 텐서 차원 변화
인코더(Encoder)의 주 역할은 전체 입력 문장을 통째로 읽어 단 하나의 고정된 크기의 벡터(**문맥 벡터, Context Vector**)로 압축하는 것입니다. 입력된 1차원 토큰 ID 시퀀스는 임베딩과 RNN을 거치면서 차원이 순차적으로 확장되며 문장의 의미 정보를 축적합니다.
💡 인코더 차원 변화 해설
• 입력 ID 시퀀스 : `"나는 학교에 간다."`의 5개 토큰에 대응하는 1차원 텐서 [5]이 인코더에 들어옵니다.
• Embedding : 토큰을 고차원 실수의 벡터 표현으로 변경해 2차원 [5, 768]로 확장합니다.
• nn.RNN : 시퀀스를 따라 순차적으로 정보들을 누적 연산하며 최종적으로 모든 단어의 은닉 상태를 묶은 hidden_states [5, 1024]와 마지막 시퀀스 단계의 최종 요약 상태인 문맥 벡터 context_vector (h_n) [1, 1024]로 출력 분기합니다.
📥 단일 문장(Batch=1) 디코더 내 텐서 차원 변화
디코더(Decoder)의 RNN 루프는 인코더의 최종 요약 은닉 상태인 문맥 벡터(`encoder h_n`)를 초기 기억(`h_0`)으로 주입받아 동작합니다. 매 시점 예측된 `output_token`은 단어장 공간의 점수(`logit`)를 거치고 `argmax`로 디코딩된 후, 다음 시점의 입력으로 순환 피드백됩니다.
💡 디코더 루프 차원 변화 해설
• Squeeze (.squeeze()) : 배치=1 이기 때문에 [1, 30000] 크기의 logit 텐서에서 굳이 필요 없는 크기 1짜리 배치 축을 압축하여 순수 단어 가중치인 1차원 [30000]으로 바꿉니다.
• Argmax (.argmax()) : 1차원 단어장 배열에서 가장 큰 값(가장 확률이 높은 단어)의 인덱스인 0차원의 단일 스칼라(정수)로 최종 단어를 찾아냅니다.
• Unsqueeze (.unsqueeze(0)) : 다음 루프에서 임베딩 레이어로 넘기기 전, PyTorch 모듈의 규격에 맞추어 0차원 스칼라를 다시 대괄호가 씌워진 1차원 텐서 [1]로 포장합니다.