시험공부빅데이터분석
← 보드Tensor · 7/11

크기 1인 차원 다루기 — squeeze, unsqueeze, cat, stack ★★

딥러닝 코드에서는 크기가 1인 차원(채널, batch)을 붙였다 뗐다 할 일이 많아요.

squeeze와 unsqueeze
교수님 슬라이드 — unsqueeze(0)은 (3,)을 (1, 3)으로, unsqueeze(1)은 (3, 1)로. squeeze는 크기 1인 차원만 제거
u = torch.tensor([10, 20, 30]) print(u.unsqueeze(0).shape) print(u.unsqueeze(1).shape) q = torch.randn(1, 3, 1, 4) print(q.squeeze().shape) print(q.squeeze(0).shape) print(q.squeeze(2).shape) print(q.squeeze(1).shape)
torch.Size([1, 3]) torch.Size([3, 1]) torch.Size([3, 4]) torch.Size([3, 1, 4]) torch.Size([1, 3, 4]) torch.Size([1, 3, 1, 4])
코드 줄무슨 뜻
u.unsqueeze(0)맨 앞(0번 자리)에 1을 끼워요. (3,) → (1, 3)
u.unsqueeze(1)1번 자리에 1을 끼워요. (3,) → (3, 1)
q.squeeze()크기 1인 차원을 모두 제거. (1,3,1,4) → (3, 4)
q.squeeze(0)0번 차원(크기 1)만 제거 → (3, 1, 4)
q.squeeze(2)2번 차원(크기 1)만 제거 → (1, 3, 4)
q.squeeze(1)1번 차원의 크기는 3이라서 제거 못 해요. 아무 일도 안 일어나고 에러도 없어요

왜 크기 3인 차원은 못 지울까요? 지우면 원소 수가 줄어서 정보가 사라지기 때문이에요. 크기 1인 차원은 지워도 원소 수가 그대로예요. (1, 3, 4)와 (3, 4)는 원소가 12개로 같지만, 앞의 것은 "3×4 표 1장", 뒤의 것은 "3×4 표 그 자체"예요.

이미지에 쓰면 이렇게 돼요. 흑백 이미지 (28, 28)에 unsqueeze(0)을 하면 채널 차원이 붙어 (1, 28, 28), 한 번 더 하면 batch 차원이 붙어 (1, 1, 28, 28)이에요. 가운데에 넣어 (28, 1, 28)로 만들면 이미지가 깨지니까 채널은 항상 맨 앞(batch를 빼면)이에요.

여러 Tensor를 하나로 합치는 함수도 둘 있어요.

함수하는 일[1,2,3]과 [4,5,6]에 쓰면
cat기존 차원을 따라 이어 붙여요. 차원 수가 그대로예요[1, 2, 3, 4, 5, 6] (6,)
stack새 차원을 만들어 쌓아요. 차원 수가 하나 늘어요[[1,2,3],[4,5,6]] (2, 3)
c1 = torch.tensor([1, 2, 3]) c2 = torch.tensor([4, 5, 6]) print(torch.cat([c1, c2]).shape) print(torch.stack([c1, c2]).shape) print(torch.stack([c1, c2], dim=1)) images = [torch.randn(28, 28).unsqueeze(0) for _ in range(8)] batch = torch.stack(images) print(batch.shape) print(batch[0].squeeze(0).shape)
torch.Size([6]) torch.Size([2, 3]) tensor([[1, 4], [2, 5], [3, 6]]) torch.Size([8, 1, 28, 28]) torch.Size([28, 28])
코드 줄무슨 뜻
torch.cat([c1, c2])이어 붙여서 길이 6의 한 줄
torch.stack([c1, c2])줄 2개를 위아래로 쌓아 2행 3열
stack(..., dim=1)새 차원을 1번 자리에 만들어요. 각 줄이 열이 돼서 3행 2열
[... for _ in range(8)]28×28 이미지를 8장 만들면서 각각 채널 차원(1, 28, 28)을 붙여 리스트에 모아요
torch.stack(images)(1, 28, 28) 8장을 새 batch 차원으로 쌓아 (8, 1, 28, 28)
batch[0].squeeze(0)첫 이미지 (1, 28, 28)에서 채널 차원만 제거 → (28, 28)
외우기 팁

"cat은 이어 붙이기, stack은 쌓기". 쌓으면 차원이 늘어요. 그리고 squeeze는 "1만 지운다"예요.

시험엔 이렇게 써요 — 이렇게 고르세요

unsqueeze(dim)은 크기 1인 차원을 추가하고 squeeze(dim)은 크기 1인 차원만 제거한다. cat은 기존 차원을 따라 연결하고 stack은 새 차원을 만들며 쌓는다. 결과 shape을 구할 때는 "1이 어디에 생기는지(unsqueeze)", "크기가 1인 자리인지(squeeze)"를 하나씩 확인하세요.

잠깐 확인 — shape (2, 1, 5)에 squeeze()를 하면? 그리고 (5,)에 unsqueeze(1)을 하면?

앞의 것은 크기 1인 가운데 차원이 사라져 (2, 5)예요. 뒤의 것은 1번 자리에 1이 생겨 (5, 1)이에요.

다음 카드 → 연산 — 원소별 곱(*)과 행렬곱(@), 그리고 dim 집계 ★★

자료: 2주차 · Week02_Tensor_and_GPU(pdf, 풀이포함 ipynb) · 빅분02(2주차) 녹취