텐서의 구조적 특성과 차원 조작(Transpose/Permute)

calico·2026년 1월 2일

Artificial Intelligence

목록 보기
156/177

1. 데이터의 수치화: 왜 이미지는 텐서인가?

  1. 이미지는 텐서다: 숫자가 격자 형태로 정렬된 구조적 데이터.
  2. 규격이 다르다: OpenCV(HWC)와 PyTorch(CHW)는 색상 데이터를 쌓는 순서가 반대다.
  3. 변환은 필수다: permutetranspose를 통해 모델이 원하는 규격으로 맞춰야만 연산이 가능하다.
  4. Batch는 4번째 차원이다: 실제 모델은 이미지 한 장이 아니라, 이미지의 묶음인 4차원 텐서를 처리한다.

  • 컴퓨터 비전 모델(CNN)이 학습하려면 모든 데이터를 숫자 묶음인 '텐서'로 변환해야 합니다.

  • 자연어 처리가 단어를 벡터로 변환하는 복잡한 과정(Embedding)을 거치는 것과 달리, 이미지는 태생 자체가 격자 구조의 수치 데이터입니다.



차원(Rank)의 확장 프로세스


  • 2D Tensor (Matrix): 흑백 이미지. 하나의 채널(밝기)만 존재함. Shape: (H,W)\text{Shape: } (H, W)

  • 3D Tensor: 컬러 이미지. R, G, B 세 개의 행렬이 겹쳐진 형태. Shape: (C,H,W) or (H,W,C)\text{Shape: } (C, H, W) \text{ or } (H, W, C)

  • 4D Tensor (Mini-batch): 딥러닝 학습 시 여러 장의 이미지를 묶은 단위. Shape: (N,C,H,W)\text{Shape: } (N, C, H, W)

    • 개념적 이해: "3차원 공간(이미지)을 원소로 가지는 벡터" 혹은 "행렬(2D)을 원소로 가지는 행렬"로 시각화할 수 있습니다.



2. 텐서 레이아웃의 두 진영: CHW vs HWC


  • 가장 헷갈리는 부분은 '채널(C) 정보가 어디에 위치하느냐'입니다. 이는 데이터가 메모리에 저장되는 순서를 결정합니다.

1) HWC (Channel-Last) - "픽셀 중심"


  • 구조: (Height,Width,Channel)(Height, Width, Channel)

  • 설명: 각 픽셀 (x,y)(x, y) 위치에 [R,G,B][R, G, B] 값이 나란히 붙어 있습니다.

  • 사용처: OpenCV, PIL, TensorFlow, 전형적인 이미지 파일(JPG, PNG) 포맷.

  • 특징: 사람이 이미지를 이해하는 방식과 유사하며, 이미지 시각화 라이브러리와 호환성이 좋습니다.



2) CHW (Channel-First) - "색상 판 중심"


  • 구조: (Channel,Height,Width)(Channel, Height, Width)

  • 설명: 빨간색 판(R) 전체, 초록색 판(G) 전체, 파란색 판(B) 전체를 순서대로 쌓습니다.

  • 사용처: PyTorch, NVIDIA cuDNN (GPU 가속 라이브러리).

  • 특징: GPU 연산 시 특정 채널 전체에 동일한 필터를 적용하는 Convolution 연산에 최적화되어 있습니다.



3. 전치(Transpose/Permute)의 메커니즘


프레임워크 간의 데이터를 주고받을 때(예: OpenCV로 읽어서 PyTorch로 모델링), 반드시 축의 순서를 바꿔야 합니다.


인덱스 변환 예시: transpose(2, 0, 1)


  • 이 함수는 기존의 0번, 1번, 2번 축의 위치를 새로운 순서로 재배치하라는 명령입니다.

    • 기존 축 (HWC): 0:H, 1:W, 2:C

    • 명령: (2, 0, 1) 순서로 바꿔라.

    • 결과 (CHW): 0:C, 1:H, 2:W



실제 원소의 이동 (Indexing Logic)


  • 데이터 내부의 한 원소 XX의 좌표가 (2,1,1)(2, 1, 1)이었다고 가정합시다. (2번 채널, 1번 행, 1번 열)

    • 이 원소는 축 변경 규칙에 따라 새로운 인덱스로 매핑됩니다. 단순한 배열 뒤집기가 아니라, 전체 데이터를 새로운 좌표계로 재정의하는 과정입니다.



4. 실무 필수: 이미지 입력 파이프라인 (YOLO 예시)


  • 실제 현업에서 이미지가 모델에 들어가기까지의 텐서 조작 과정입니다.
import cv2
import torch
import numpy as np

# 1. 이미지 로드 (OpenCV: HWC 형식)
img = cv2.imread('image.jpg') # Shape: (640, 480, 3)

# 2. 전처리 (Normalization & Type Conversion)
img = img.astype(np.float32) / 255.0

# 3. HWC -> CHW 변환 (PyTorch 포맷)
# 방식 1: NumPy transpose
img_transposed = img.transpose(2, 0, 1) # Shape: (3, 640, 480)

# 방식 2: PyTorch permute
tensor = torch.from_numpy(img) # (H, W, C)
tensor = tensor.permute(2, 0, 1) # (C, H, W)

# 4. Batch 차원 추가 (3D -> 4D)
# 모델은 항상 (N, C, H, W)를 기대함
input_tensor = tensor.unsqueeze(0) # Shape: (1, 3, 640, 480)

# 5. 모델 입력
# output = model(input_tensor)



5. 엔지니어가 주의해야 할 포인트 (Deep Dive)


1) Contiguous (메모리 연속성) 문제


  • transposepermute를 실행하면 텐서의 논리적 형태(Shape)는 바뀌지만, 실제 메모리상의 물리적 순서는 그대로인 경우가 많습니다.

    • 이 상태에서 특정 연산을 수행하면 에러가 날 수 있습니다.

    • 해결: tensor.permute(2, 0, 1).contiguous()를 호출하여 메모리 레이아웃까지 물리적으로 재정렬해주는 것이 안전합니다.



2) 시각화 시 주의사항


  • PyTorch에서 나온 결과(CHW)를 matplotlib이나 cv2로 다시 보고 싶다면, 반드시 다시 HWC로 되돌려야 합니다.

    • plt.imshow(tensor_output.permute(1, 2, 0)) (CHW -> HWC)



3) 왜 성능 차이가 나는가?


  • NVIDIA GPU의 연산 엔진(cuDNN)은 메모리에서 데이터를 읽을 때 CHW 구조일 때 메모리 대역폭을 더 효율적으로 사용하도록 설계되었습니다.

    • 따라서 PyTorch를 사용할 때 이 변환을 생략하면 안 됩니다.



profile
All views expressed here are solely my own and do not represent those of any affiliated organization.

0개의 댓글