콘텐츠로 이동

Shape와 Size

텐서를 다루다 보면 가장 먼저 확인하게 되는 정보가 바로 형태(shape) 입니다. 형태는 각 차원의 크기를 나타내며, 연산 호환성을 판단하는 데 필수적입니다.

import torch
# 1D 텐서 (벡터)
v = torch.tensor([1, 2, 3, 4, 5])
# 2D 텐서 (행렬)
m = torch.tensor([[1, 2, 3],
[4, 5, 6]])
# 3D 텐서
t = torch.zeros(2, 3, 4)
print(v.shape) # torch.Size([5])
print(m.shape) # torch.Size([3, 3]) -- 잘못된 예, 아래 수정
print(m.shape) # torch.Size([2, 3])
print(t.shape) # torch.Size([2, 3, 4])

shape 는 속성(attribute)이고, size() 는 메서드(method)입니다. 두 가지 모두 torch.Size 객체를 반환하며 동일한 결과를 제공합니다.

import torch
x = torch.zeros(3, 4, 5)
# 두 방법 모두 동일한 결과
print(x.shape) # torch.Size([3, 4, 5])
print(x.size()) # torch.Size([3, 4, 5])
# torch.Size는 튜플처럼 동작
print(type(x.shape)) # <class 'torch.Size'>
print(isinstance(x.shape, tuple)) # True

torch.Size 는 파이썬 튜플을 상속하므로 언패킹, 비교, 인덱싱이 모두 가능합니다.

x = torch.zeros(3, 4, 5)
# 튜플처럼 언패킹
batch, rows, cols = x.shape
print(batch, rows, cols) # 3 4 5
# 비교
print(x.shape == (3, 4, 5)) # True

특정 차원의 크기만 필요할 때는 인덱스로 접근합니다.

import torch
x = torch.zeros(8, 16, 32, 64)
# shape 인덱싱
print(x.shape[0]) # 8 (배치 크기)
print(x.shape[1]) # 16
print(x.shape[-1]) # 64 (마지막 차원)
# size() 메서드에 인덱스 전달
print(x.size(0)) # 8
print(x.size(2)) # 32
print(x.size(-1)) # 64

numel()num elements 의 줄임말로, 텐서에 담긴 전체 원소 개수를 반환합니다.

import torch
x = torch.zeros(3, 4, 5)
# 수동 계산: 3 * 4 * 5 = 60
print(x.numel()) # 60
# shape를 이용한 동등한 계산
import math
print(math.prod(x.shape)) # 60
# 스칼라 텐서
s = torch.tensor(42.0)
print(s.numel()) # 1

numel() 은 메모리 사용량을 추정하거나, 모델 파라미터 수를 세는 데 자주 사용됩니다.

# 모델 파라미터 총 수 계산 예시
import torch.nn as nn
model = nn.Linear(128, 64)
total_params = sum(p.numel() for p in model.parameters())
print(f"총 파라미터 수: {total_params:,}") # 총 파라미터 수: 8,256

차원 수(rank)를 확인하는 방법은 두 가지입니다.

import torch
scalar = torch.tensor(1.0)
vector = torch.tensor([1, 2, 3])
matrix = torch.zeros(3, 4)
tensor3d = torch.zeros(2, 3, 4)
# ndim 속성 (읽기 전용)
print(scalar.ndim) # 0
print(vector.ndim) # 1
print(matrix.ndim) # 2
print(tensor3d.ndim) # 3
# dim() 메서드 (동일한 결과)
print(tensor3d.dim()) # 3
메서드 / 속성반환 타입설명예시 결과
tensor.shapetorch.Size각 차원의 크기torch.Size([2, 3])
tensor.size()torch.Sizeshape와 동일torch.Size([2, 3])
tensor.size(dim)int특정 차원의 크기3
tensor.shape[dim]int특정 차원의 크기3
tensor.numel()int전체 원소 수6
tensor.ndimint차원 수2
tensor.dim()int차원 수 (ndim과 동일)2

실전 활용: 배치 처리에서의 shape 확인

섹션 제목: “실전 활용: 배치 처리에서의 shape 확인”

딥러닝에서 입력 텐서의 shape를 확인하는 것은 버그를 찾는 첫 번째 수단입니다.

import torch
# 이미지 배치: (배치 크기, 채널, 높이, 너비)
images = torch.zeros(32, 3, 224, 224)
batch_size = images.shape[0] # 32
channels = images.shape[1] # 3
height = images.shape[2] # 224
width = images.shape[3] # 224
print(f"배치 크기: {batch_size}")
print(f"채널 수: {channels}")
print(f"이미지 크기: {height} x {width}")
print(f"총 픽셀 수: {images.numel():,}")
# 총 픽셀 수: 4,816,896