[PyTorch] Tensor의 모양 변경

beaver.zip·2024년 8월 10일
0

텐서의 크기 변경 - view(), reshape(), flatten()

view(size)

  • 텐서의 크기를 변경하며, 텐서가 메모리에 연속적으로 할당된 경우에 사용이 가능
  • is_contiguous(): 텐서의 메모리가 연속적으로 할당되었는지 확인
  • contiguous(): contiguous 여부를 True로 변경
    -> is_contiguous() 결과가 True인 경우에만 view() 사용 가능
a = torch.tensor([[1, 2, 3],
                  [4, 5, 6]])
print(a.is_contiguous()) # True

a = a.view(1, -1) # 2x3 텐서 ~> 1x6(자동계산) 텐서
print(a) # tensor([[1, 2, 3, 4, 5, 6]])
b = torch.tensor([[1, 2, 3],
                  [4, 5, 6]])
b = b[:, :2]
print(b.is_contiguous()) # False - 슬라이싱으로 인해 연속성이 깨짐

# b = b.view(1, -1) -> 오류 발생
b = b.contiguous() # b의 contiguous 속성을 True로 변경

b = b.view(1, -1)
print(b) # tensor([[1, 2, 4, 5]])

reshape(size)

  • 텐서의 크기를 변경하며, view()와 달리 메모리가 연속적이지 않아도 사용 가능
  • 안전하고 유연하나, 성능 저하의 단점이 있음
    -> 메모리의 연속성이 확실하고, 성능이 중요하면 view() 사용할 것
x = torch.randn(4, 4)
y = x.reshape(2, 8)  # 4x4 텐서 -> 2x8 텐서
print(y.shape)  # torch.Size([2, 8])

flatten(size)

  • 텐서를 1차원 텐서로 평탄화
  • 다차원 데이터를 신경망 모델에 적합한 형태로 전처리할 때 활용
x = torch.randn(3, 2, 2)
y = x.flatten()  # 3x2x2 텐서 -> 12개 요소를 가진 1차원 텐서
print(y.shape)  # torch.Size([12])

텐서의 차원 변경 - transpose(), permute()

transpose(size)

  • 텐서의 두 축을 바꿈
x = torch.randn(2, 3)
y = x.transpose(0, 1)  # 0번째 축과 1번째 축을 바꿈
print(y.shape)  # torch.Size([3, 2])

permute(size)

  • transpose()의 일반화된 버전
  • 여러 축의 순서를 한 번에 변경
x = torch.randn(2, 3, 4)
y = x.permute(2, 0, 1)  # 축의 순서를 2, 0, 1로 변경
print(y.shape)  # torch.Size([4, 2, 3])

텐서의 차원 추가/제거 - unsqueeze(), squeeeze()

unsqueeze(dim)

  • dim 차원으로 크기가 1인 차원을 추가
x = torch.randn(3, 2)
y = x.unsqueeze(0)  # 0차원으로 크기가 1인 차원 추가
print(y.shape)  # torch.Size([1, 3, 2])

squeeze(dim)

  • dim차원으로 크기가 1인 차원을 제거
x = torch.randn(1, 3, 2)
y = x.squeeze(0)  # 0차원으로 크기가 1인 차원 제거
print(y.shape)  # torch.Size([3, 2])

텐서 합치기 - stack(), cat()

stack(tensors, dim)

  • dim 축을 새로 생성해 텐서를 쌓음
a = torch.tensor([[0, 1],
                  [1, 0]])
b = torch.tensor([[2, 3],
                  [3, 2]])
c = torch.tensor([[4, 5],
                  [5, 4]])
d = torch.stack((a, b, c), dim=0)

print(d)
print(d.shape)

# 출력 결과 #
tensor([[[0, 1],
         [1, 0]],

        [[2, 3],
         [3, 2]],

        [[4, 5],
         [5, 4]]])
torch.Size([3, 2, 2])

cat(tensors, dim)

  • dim 차원을 따라 텐서들을 연결
  • stack()과 달리 새로운 차원을 추가하지 않고 기존 차원을 유지
a = torch.tensor([[0, 1],
                  [2, 3]])
b = torch.tensor([[4, 5]])
c = torch.cat((a, b))
print(c)
print(c.shape)

# 출력 결과 #
tensor([[0, 1],
        [2, 3],
        [4, 5]])
torch.Size([3, 2])

텐서 확장 - expand(), repeat()

expand(size)

  • 텐서의 특정 차원의 크기가 1일 때, 해당 차원의 크기를 확장
x = torch.randn(3, 1)
y = x.expand(3, 4)  # 두 번째 차원을 4로 확장
print(y.shape)  # torch.Size([3, 4])

repeat(size)

  • 텐서를 특정 차원에 대해 반복
  • expand()와 달리 차원 중 일부의 크기가 1이어야 하는 제약 없음
  • 그러나 추가 메모리를 할당하므로 그렇지 않은 expand()보다 메모리 효율이 떨어짐
x = torch.tensor([[1, 2], [3, 4]])
y = x.repeat(2, 1)  # 첫 번째 차원을 2번, 두 번째 차원을 1번 반복
print(y)

Outro

더 읽어볼 것

profile
NLP 일짱이 되겠다.

0개의 댓글