PyTorch에서 torch.stack()과 torch.cat() 함수의 차이점
차원 축 추가:
torch.stack()
: 새로운 차원을 추가하여 텐서를 연결합니다. 마치 여러 텐서를 책처럼 쌓아 올리는 것과 같습니다.torch.cat()
: 기존 차원 중 하나를 기준으로 텐서를 연결합니다. 마치 여러 텐서를 옆으로 나란히 붙이는 것과 같습니다.
사용 예시:
torch.stack()
:- 여러 텐서를 하나의 시퀀스로 만들고 싶을 때
- 모델 입력으로 여러 텐서를 전달하고 싶을 때
- 텐서 리스트를 하나의 배치로 만들고 싶을 때
torch.cat()
:- 여러 이미지를 하나의 이미지로 합치고 싶을 때
- 여러 채널의 데이터를 하나의 텐서로 합치고 싶을 때
- 특정 차원을 기준으로 텐서를 분할하고 싶을 때
코드 예시:
import torch
# 1. `torch.stack()` 예시
# 3개의 텐서 생성
t1 = torch.tensor([1, 2, 3])
t2 = torch.tensor([4, 5, 6])
t3 = torch.tensor([7, 8, 9])
# 새로운 차원(0번째 차원)으로 쌓아서 연결
stacked_tensor = torch.stack([t1, t2, t3])
print(stacked_tensor)
# 결과:
# tensor([[[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]]])
# 2. `torch.cat()` 예시
# 2개의 텐서 생성
t1 = torch.tensor([[1, 2], [3, 4]])
t2 = torch.tensor([[5, 6], [7, 8]])
# 1번째 차원(행) 기준으로 연결
cat_tensor = torch.cat([t1, t2], dim=0)
print(cat_tensor)
# 결과:
# tensor([[1, 2],
# [3, 4],
# [5, 6],
# [7, 8]])
주의 사항:
torch.stack()
과torch.cat()
은 동일한 크기와 형태의 텐서만 연결할 수 있습니다.torch.stack()
은 새로운 차원을 추가하기 때문에 메모리 사용량이 증가할 수 있습니다.torch.cat()
은 연결할 차원을 명시해야 합니다.
예제 코드
torch.stack() 예시
import torch
# 3개의 텐서 생성
t1 = torch.tensor([1, 2, 3])
t2 = torch.tensor([4, 5, 6])
t3 = torch.tensor([7, 8, 9])
# 새로운 차원(0번째 차원)으로 쌓아서 연결
stacked_tensor = torch.stack([t1, t2, t3])
print(stacked_tensor)
# 결과:
# tensor([[[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]]])
# 1.1. 텐서 리스트를 하나의 배치로 만들기
# 텐서 리스트
tensors = [t1, t2, t3]
# 배치 크기 확인
batch_size = len(tensors)
# `torch.stack()`을 사용하여 텐서 리스트를 배치로 변환
batch_tensor = torch.stack(tensors)
# 배치 크기 확인
print(batch_tensor.shape[0])
# 결과:
# 3
# 1.2. 모델 입력으로 여러 텐서 전달하기
class MyModel(torch.nn.Module):
def __init__(self):
super().__init__()
# ...
def forward(self, x1, x2, x3):
# ...
# 모델 생성
model = MyModel()
# 모델 입력으로 3개의 텐서 전달
output = model(t1, t2, t3)
# ...
torch.cat() 예시
import torch
# 2개의 텐서 생성
t1 = torch.tensor([[1, 2], [3, 4]])
t2 = torch.tensor([[5, 6], [7, 8]])
# 1번째 차원(행) 기준으로 연결
cat_tensor = torch.cat([t1, t2], dim=0)
print(cat_tensor)
# 결과:
# tensor([[1, 2],
# [3, 4],
# [5, 6],
# [7, 8]])
# 2.1. 여러 이미지를 하나의 이미지로 합치기
# 이미지 텐서 리스트
image_tensors = [...]
# 이미지 채널 수 확인
num_channels = image_tensors[0].shape[0]
# `torch.cat()`을 사용하여 이미지 텐서 리스트를 하나의 이미지로 합침
combined_image = torch.cat(image_tensors, dim=0)
# 이미지 출력
# ...
# 2.2. 특정 차원을 기준으로 텐서 분할하기
# 텐서 생성
t = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8])
# 2개의 텐서로 분할
split_tensors = torch.split(t, 4)
# 분할된 텐서 확인
print(split_tensors)
# 결과:
# (tensor([1, 2, 3, 4]), tensor([5, 6, 7, 8]))
- 위 코드는 예시이며, 실제 사용 목적에 맞게 수정해야 합니다.
torch.stack()
과torch.cat()
함수의 매개변수에 대한 자세한 내용은 PyTorch documentation을 참고하십시오.
torch.stack()
과 torch.cat()
의 대체 방법
torch.stack() 대체 방법:
torch.unsqueeze()
: 새로운 차원을 추가하기 위해torch.unsqueeze()
를 사용할 수 있습니다.- for 루프: 텐서 리스트를 순회하며 직접 연결할 수 있습니다.
- 람다 함수:
map()
함수와 람다 함수를 사용하여 텐서 리스트를 연결할 수 있습니다.
torch.view()
: 텐서의 형태를 변경하여 연결할 수 있습니다.
선택 기준:
- 텐서의 크기와 형태
- 연결 방식
- 코드 간결성
- 성능
예시:
import torch
# 1. `torch.stack()` 대체 방법
# 1.1. `torch.unsqueeze()`
t1 = torch.tensor([1, 2, 3])
t2 = torch.tensor([4, 5, 6])
# 새로운 차원(0번째 차원) 추가
t1 = torch.unsqueeze(t1, dim=0)
t2 = torch.unsqueeze(t2, dim=0)
# 연결
stacked_tensor = torch.cat([t1, t2], dim=0)
# ...
# 1.2. for 루프
t1 = torch.tensor([1, 2, 3])
t2 = torch.tensor([4, 5, 6])
# 리스트 생성
tensors = [t1, t2]
# 연결
stacked_tensor = torch.Tensor()
for tensor in tensors:
stacked_tensor = torch.cat((stacked_tensor, tensor), dim=0)
# ...
# 1.3. 람다 함수
t1 = torch.tensor([1, 2, 3])
t2 = torch.tensor([4, 5, 6])
# 리스트 생성
tensors = [t1, t2]
# 연결
stacked_tensor = torch.cat(list(map(lambda x: torch.unsqueeze(x, dim=0), tensors)), dim=0)
# ...
# 2. `torch.cat()` 대체 방법
# 2.1. `torch.view()`
t1 = torch.tensor([[1, 2], [3, 4]])
t2 = torch.tensor([[5, 6], [7, 8]])
# 2개의 행으로 연결
cat_tensor = torch.view(torch.cat([t1, t2], dim=0), (-1, 4))
# ...
# 2.2. for 루프
t1 = torch.tensor([[1, 2], [3, 4]])
t2 = torch.tensor([[5, 6], [7, 8]])
# 연결
cat_tensor = torch.Tensor()
for i in range(t1.shape[0]):
cat_tensor = torch.cat((cat_tensor, torch.cat([t1[i], t2[i]], dim=0)), dim=0)
# ...
# 2.3. 람다 함수
t1 = torch.tensor([[1, 2], [3, 4]])
t2 = torch.tensor([[5, 6], [7, 8]])
# 연결
cat_tensor = torch.cat(list(map(lambda x, y: torch.cat([x, y], dim=0), t1, t2)), dim=0)
# ...
참고:
torch.stack()
과torch.cat()
함수의 대체 방법을 선택하기 전에 각 방법의 장단점을 고려해야 합니다.
python machine-learning deep-learning