값 하나. 축은 몇 개?
NumPy에서 아래 둘은 네 눈엔 비슷하게 찍혀. 모양은 전혀 다름.
np.array(5) # 0차원 배열, shape ()
np.array([5]) # 1차원 배열, shape (1,)
0차원 배열은 축 없는 스칼라 배열. 1차원 배열은 길이 1인 축을 가져. 그래서 전자는 [0]으로 인덱싱하거나 반복할 수 없고 후자는 가능해. 값 하나라고 모양까지 하나인 건 아님.
0차원이 틀린 건 아니다
축이 없다고 2등 자료형 취급하지 마. 합계, 평균, 손실처럼 결과가 값 하나여야 하는 연산엔 0차원 배열이나 스칼라 텐서가 정확한 표현이야. PyTorch의 loss.backward()도 원소 하나인 스칼라 손실에서 그대로 호출하는 게 보통.
버그는 네가 다음 연산의 모양 계약을 안 보고 섞을 때 나와. 배치 차원이 필요한 층에 넣거나 여러 값과 이어 붙이려면 길이 1인 축 추가. 사람이 읽을 Python 숫자가 필요하면 .item()으로 꺼내기. 목적이 먼저, 모양은 그다음.
의도에 맞춰 모양 바꾸기
unsqueeze(0)또는expand_dims(..., 0): 새 축 하나 추가.squeeze(dim): 길이 1인 특정 축 제거. 차원을 안 적은squeeze()는 네 배치축까지 먹을 수 있으니 조심..item(): 원소 하나인 배열이나 텐서를 Python 스칼라로 꺼내. 로깅엔 이쪽이 자연스러워.
피파의 전쟁 이야기
loss.item(). 끝.
import torch# STEP 1: 0-D 텐서 생성t = torch.tensor(3.14)print(t)print(t.shape)print(t.ndim)# STEP 2: t[0] 인덱싱 시도 - 에러 발생try:print(t[0])# IndexError: invalid index of a 0-dim tensor# 스칼라값은 차원이 없다. 위치를 담을 수 없으니 인덱싱 오류except IndexError as e:print(f"IndexError: {e}")# STEP 3: unsqueeze로 1-D 업그레이드t_1d = t.unsqueeze(0)print(t_1d)print(t_1d.shape)print(t_1d.ndim)# STEP 4: 인덱싱 작동print(t_1d[0])