AI |Computer Vision/Basic Pytorch
[PyTorch] Tensor Manipulation 1
Derrick
2022. 3. 29. 22:11
728x90
반응형
1. Tensor 이해하기

< 딥러닝의 가장 기본적인 단위 >
- 1D : Vector (벡터)
- 2D : Matrix (행렬)
- 3D : Tensor (텐서) - 주로 3차원 이상을 Tensor로 분류
- 4D : 3차원의 텐서를 위로 쌓아 올린 형상 - 이후 차원은 옆/뒤로 확장한 모습
2. Pytorch Tensor Shape Convention
Matrix, Tensor들에 대해 " 크기를 구하는 것 "이 중요하다.
정확한 크기를 고려해야 제대로 구현할 수 있으며, 수식을 쉽게 이해할 수 있다.

< Tensor Size >
- 2D Tensor : |t| = ( batch size, dim )
- 3D Tensor : |t| = ( batch size, width, height )
→ 여기부터는 조금 더 복잡한 형태의 입력과 출력을 다룰 수 있다.
ex) 이미지의 경우, ('가로 X 세로')의 set이 여러 개가 쌓이면 3D Tensor 구성
3. PyTorch로 Tensor 선언
→ PyTorch는 Numpy 방식과 매우 유사하며, 지금부터 간단한 Tensor 선언
1) 1D Tensor
- 1차원의 Tensor인 Vector 생성
import torch
a = torch.FloatTensor([0.1, 1., 2., 3., 4., 5., 6.])
print(a)
print(a.dim()) # dimension
print(a.shape) # Tensor의 size
>>
tensor([0.1000, 1.0000, 2.0000, 3.0000, 4.0000, 5.0000, 6.0000])
1 # 1차원 텐서
torch.Size([7]) # Tensor 사이즈는 7, 원소는 7개
- Indexing과 Slicing 연습!
print(a[-1], a[0], a[1]) # indexing
print(a[1:5], a[3:-1]) # Slicing
print(a[:3], a[3:]) # Slicing`
>>
tensor(6.) tensor(0.1000) tensor(1.)
tensor([1., 2., 3., 4.]) tensor([3., 4., 5.])
tensor([0.1000, 1.0000, 2.0000]) tensor([3., 4., 5., 6.])
→ Slicing : 범위 지정(index)으로 원소를 불러오기
→ [시작 번호 : 끝 번호], 끝 번호는 해당하지 않는다!
2) 2D Tensor
- 2차원의 Tensor인 Matrix 생성
b = torch.FloatTensor([[1., 2., 3.,],
[4., 5., 6.,],
[7., 8., 9.,],
[10., 11., 12.]
])
print(b)
print(b.dim()) # dimension
print(b.size()) # tensor.size
>>
tensor([[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.],
[10., 11., 12.]])
2 # 2차원의 Tensor
torch.Size([4, 3]) # (4, 3)
- Slicing
print(b[:, 2]) # 첫번째 차원을 모두 선택하고, 2번째 차원의 2번째 것만 가져온다
print(b[:, 2].size()) # 위의 결과의 size
print(b[:-1,:]) # 두번째 차원을 모두 선택하고, 1차원의 맨 마지막 것을 제외하고 모두 가져온다
>>
tensor([ 3., 6., 9., 12.])
torch.Size([4])
tensor([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
3. Tensor 연산하기 및 다양한 기능
1) Broadcasting
덧셈/뺄셈의 연산을 수행할 때의 Tensor의 크기는 동일해야 하지만, 불가피하게 다른 크기의
Tensor들을 연산하는 상황에서 Pytorch에서는 자동으로 size을 맞춰서 연산 수행한다.
- Vector + Scalar
# vector + scalar
m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([3]) # [3] -> [3, 3] : Broadcasting
print(m1.size(), m2.size()) # m1, m2의 다른 size 확인
print(m1 + m2)
>>
torch.Size([1, 2]) torch.Size([1])
tensor([[4., 5.]])
- 2x1 Vector + 1x2 Vector
# 2x1 Vector + 1x2 Vector
m1 = torch.FloatTensor([[1, 2]]) # (1, 2) -> (2, 2)
m2 = torch.FloatTensor([[3], [4]]) # (2, 1) -> (2, 2)
print(m1.size(), m2.size())
print(m1 + m2)
print((m1+m2).size())
>>
torch.Size([1, 2]) torch.Size([2, 1])
tensor([[4., 5.],
[5., 6.]])
torch.Size([2, 2])
2) Matrix Multiplication(행렬곱) vs Multiplication(일반곱)
- Matrix Multiplication ( Tensor의 행렬곱셈 - matmul() )
m1 = torch.FloatTensor([[1, 2], [3, 4]])
m2 = torch.FloatTensor([[1], [2]])
print(m1.shape) # m1의 size : (2, 2)
print(m2.shape) # m2의 size : (2, 1)
print(m1.matmul(m2)) # (2, 1)로 size 변경됨
>>
torch.Size([2, 2])
torch.Size([2, 1])
tensor([[ 5.],
[11.]])
- Multiplication ( Tensor 내 각 element의 곱셈 - mul() )
print(m1 * m2) # 2 x 2
print(m1.mul(m2))
print((m1.mul(m2)).size())
>>
tensor([[1., 2.],
[6., 8.]])
tensor([[1., 2.],
[6., 8.]])
torch.Size([2, 2]) # m2의 size : (2, 1) -> (2, 2)
→ 일반 곱셈(mul)을 수행하면, 두 행렬의 크기는 broadcasting된 후에 곱셈 수행
3) 평균 (Mean) - .mean()
a = torch.FloatTensor([1, 2])
b = torch.FloatTensor([[1, 2], [3, 4]])
print(a.mean()) # a의 평균값 = (1+2)/2
print(b.mean(dim=0)) # 첫번째 차원(행)을 제거하고 평균 - [ (1+3)/2 , (2+4)/2 ]
print(b.mean(dim=1)) # 두번째 차원(열)을 제거하고 평균
print(b.mean(dim=-1)) # 마지막 차원(= 열)을 제거하고 평균
>>
tensor(1.5000)
tensor([2., 3.])
tensor([1.5000, 3.5000])
tensor([1.5000, 3.5000])
→ 인자로 dim 값을 준다면, 해당 차원을 제거한다는 의미
→ 2x2 Matrix에서 행(dim = 1)을 제거하면, (1, 2) = (2,)의 Vector가 됨.
4) 합계(Sum)과 최대값(Max, ArgMax)
- 합계(Sum)
a = torch.FloatTensor([[1, 2], [3, 4]])
print(a.sum())
print(a.sum(dim=0)) # 행 제거
print(a.sum(dim=1)) # 열 제거
print(a.sum(dim=-1)) # 마지막 차원(= 열) 제거
>>
tensor(10.)
tensor([4., 6.])
tensor([3., 7.])
tensor([3., 7.])
- Max, ArgMax
a = torch.FloatTensor([[1, 2], [3, 4]])
print(a)
print(a.max()) # 전체 element 중, 최대값 하나 출력
print(a.max(dim=0)) # max, argmax 두 값을 출력 (행 차원 제거)
>>
tensor([[1., 2.],
[3., 4.]])
tensor(4.)
torch.return_types.max(
values=tensor([3., 4.]), # dim = 0을 배제 후, 얻은 최대값
indices=tensor([1, 1])) # 최대값의 해당 index값
→ Max는 원소들 중 최대값을 return하고, ArgMax는 최대값을 가진 index를 return 한다.
→ max와 argmax만 따로 return 받고 싶다면 인덱스를 별도 부여하면 된다.
print('Max :',a.max(dim=0)[0]) # 0번 인덱스 : max 값만
print('ArgMax :',a.max(dim=0)[1]) # 1번 인덱스 : argmax 값만
>>
Max : tensor([3., 4.])
ArgMax : tensor([1, 1])