콘텐츠로 이동

텐서의 차원 이해하기

차원, 랭크, 축 — 같은 개념의 다른 이름

섹션 제목: “차원, 랭크, 축 — 같은 개념의 다른 이름”

텐서를 공부하다 보면 비슷해 보이는 용어들이 혼용되어 혼란스러울 수 있습니다. 먼저 이들의 관계를 정리합니다.

용어의미PyTorch 속성
차원 (Dimension)텐서가 뻗어있는 방향의 수tensor.ndim
랭크 (Rank)차원과 동일한 개념tensor.ndim
축 (Axis)각 차원을 지칭하는 번호 (0부터 시작)연산의 dim= 인자
형태 (Shape)각 차원의 크기tensor.shape
원소 수 (Numel)전체 원소의 개수tensor.numel()
import torch
t = torch.zeros(4, 3, 2)
print(t.ndim) # 3 ← 3차원 텐서 (랭크 3)
print(t.shape) # torch.Size([4, 3, 2])
print(t.size()) # torch.Size([4, 3, 2]) ← shape와 동일
print(t.size(0)) # 4 ← 0번 축의 크기
print(t.size(1)) # 3 ← 1번 축의 크기
print(t.size(-1)) # 2 ← 마지막 축의 크기
print(t.numel()) # 24 ← 4 × 3 × 2

축은 0번부터 시작하며, 음수 인덱스도 사용할 수 있습니다.

shape: (4, 3, 2)
축 번호: 0 1 2
음수 축: -3 -2 -1
t = torch.zeros(4, 3, 2)
# 양수 축과 음수 축은 동일한 결과
print(t.size(0) == t.size(-3)) # True → 4
print(t.size(1) == t.size(-2)) # True → 3
print(t.size(2) == t.size(-1)) # True → 2

축 번호는 연산에서 자주 등장합니다. 예를 들어 dim=0은 “0번 축 방향으로 연산”을 의미합니다.

t = torch.tensor([
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]
]) # shape: (2, 3)
# dim=0: 행 방향으로 합산 → 각 열의 합
print(t.sum(dim=0)) # tensor([5., 7., 9.])
# dim=1: 열 방향으로 합산 → 각 행의 합
print(t.sum(dim=1)) # tensor([ 6., 15.])

각 차원의 텐서가 실제로 어떤 구조인지 직접 확인해보세요.

0D 스칼라 — shape: ()
5
1D 벡터 — shape: (5,)
1
2
3
4
5
2D 행렬 — shape: (4, 3)
1
2
3
4
5
6
7
8
9
10
11
12
3D 텐서 — shape: (2, 3, 4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
0D (스칼라): [●] shape: ()
1D (벡터): [● ● ● ● ●] shape: (5,)
←── 축 0 ──→
2D (행렬): [● ● ●] ← 축 1 → shape: (3, 4)
[● ● ●]
[● ● ●]
[● ● ●]
↑ 축 0 ↓
3D 텐서: 겹겹이 쌓인 행렬들 shape: (2, 3, 4)
↑ 축 0 (깊이)
축 1 (행), 축 2 (열)

딥러닝에서 이미지를 다룰 때 가장 자주 보는 형태입니다.

shape: (B, C, H, W)
↑ ↑ ↑ ↑
| | | └── Width (너비, 픽셀 수)
| | └───── Height (높이, 픽셀 수)
| └──────── Channel (채널: RGB=3, 흑백=1)
└─────────── Batch (배치 크기: 한 번에 처리할 이미지 수)
차원이름의미예시 값
BBatch한 번에 처리하는 이미지 수32, 64, 128
CChannel색상 채널 수1 (흑백), 3 (RGB)
HHeight이미지 높이 (픽셀)224, 256, 512
WWidth이미지 너비 (픽셀)224, 256, 512
# 실제 코드에서 이미지 텐서 다루기
batch_size = 32
channels = 3 # RGB
height = 224
width = 224
# ImageNet 표준 입력 형태
image_batch = torch.zeros(batch_size, channels, height, width)
print(image_batch.shape) # torch.Size([32, 3, 224, 224])
print(image_batch.ndim) # 4
# 각 차원 접근
B = image_batch.size(0) # 32 ← 배치 크기
C = image_batch.size(1) # 3 ← 채널 수
H = image_batch.size(2) # 224 ← 높이
W = image_batch.size(3) # 224 ← 너비
# 또는 언패킹
B, C, H, W = image_batch.shape
print(f"배치: {B}, 채널: {C}, 높이: {H}, 너비: {W}")

이미지 외에도 다양한 데이터 형태가 있습니다.

# 텍스트 (NLP) — (Batch, Sequence Length, Embedding Dim)
# 예: 32개 문장, 각 문장 50 토큰, 임베딩 차원 512
text_batch = torch.zeros(32, 50, 512)
print(text_batch.shape) # torch.Size([32, 50, 512])
# 시계열 (Time Series) — (Batch, Time Steps, Features)
# 예: 16개 샘플, 100 타임스텝, 특성 8개
time_series = torch.zeros(16, 100, 8)
print(time_series.shape) # torch.Size([16, 100, 8])
# 동영상 — (Batch, Frames, Channels, Height, Width)
# 예: 4개 동영상 클립, 16 프레임, RGB, 112×112
video_batch = torch.zeros(4, 16, 3, 112, 112)
print(video_batch.shape) # torch.Size([4, 16, 3, 112, 112])
print(video_batch.ndim) # 5

실제 코드에서 차원 오류는 매우 흔합니다. 다음 패턴으로 디버깅하세요.

def inspect_tensor(t, name="tensor"):
"""텐서 정보를 한눈에 출력하는 유틸리티"""
print(f"[{name}]")
print(f" shape : {t.shape}")
print(f" ndim : {t.ndim}")
print(f" dtype : {t.dtype}")
print(f" device: {t.device}")
print(f" numel : {t.numel():,}")
print()
# 사용 예
x = torch.randn(8, 3, 64, 64)
inspect_tensor(x, "input_batch")
# [input_batch]
# shape : torch.Size([8, 3, 64, 64])
# ndim : 4
# dtype : torch.float32
# device: cpu
# numel : 98,304

  • 차원 = 랭크 = 축의 수tensor.ndim으로 확인
  • 형태(shape) 는 각 축의 크기 → tensor.shape 또는 tensor.size()
  • 축은 0부터 시작, 음수 인덱스(-1은 마지막 축) 사용 가능
  • 이미지 텐서의 표준 형태: (B, C, H, W)
  • tensor.numel() 로 전체 원소 수 확인