📚 텐서(Tensor) 조작하기
✅ 브로드캐스팅
m1 = torch.FloatTensor([[3, 3]])
m2 = torch.FloatTensor([[2, 2]])
print(m1)
print(m2)
print(m1 + m2)
텐서 간의 사칙연산을 수행할 때, 텐서의 크기가 동일하면 이상없이 진행된다.
m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([3]) # [3] -> [3, 3]
print(m1)
print(m2)
print(m1 + m2)
m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([[3], [4]])
print(m1)
print(m2)
print(m1 + m2)
텐서의 차원과 크기가 달라도 파이토치에서는 브로드캐스팅을 통해서 차원을 맞춘 후에 연산을 수행한다. 두 번째 예시에서는 (1,2)과 (2,1) 크기인 텐서를 모두 (2,2) 로 변환해서 연산을 수행한 것을 알 수 있다. 브로드캐스팅은 편리하지만, 실수가 있었을 경우 발견하기도 어렵기 때문에 주의할 필요가 있다.
✅ 행렬 곱셈 vs 일반 곱셈
📌 행렬 곱셈 (matrix multiplication )
m1 = torch.FloatTensor([[1,2], [3,4]])
m2 = torch.FloatTensor([[1], [2]])
#행렬 곱셈
m1.matmul(m2)
#일반 곱셈
m1*m2
m1.mul(m2)
행렬 연산은 matmul 함수를 통해서 수행한다. 행렬 간 크기가 일치해야 수행할 수 있다.
일반 곱셈은 * 또는 mul 함수를 통해서 수행 가능하고 자동으로 브로드캐스팅이 수행된다.
✅ mean() 함수
t = torch.FloatTensor([[1, 2], [3, 4]])
#전체 텐서의 평균
t.mean()
#첫번째 차원(행)을 제거
t.mean(dim=0)
#두번째 차원(열)을 제거
t.mean(dim=1)
dim 파라미터에 따라서 행, 열 중에서 어느 방향으로 압축할 지 정할 수 있다. dim=0이면 첫 번째 차원인 행 방향으로 압축한다는 의미이고, dim=1이면 두 번째 파라미터인 열 방향으로 압축한다는 의미이다. 일반 파이썬 파라미터와는 반대라고 생각하면 편함.
✅ View()
원소의 수를 유지하면서 텐서의 크기를 변경하는 역할을 한다.
t = np.array([[[0,1,2],
[3,4,5]],
[[6,7,8],
[9,10,11]]])
ft = torch.FloatTensor(t)
ft.shape
ft.size()
ft.dim()
3차원 텐서를 생성한다.
#2차원으로 변경
ft.view([-1, 3])
#3차원으로 유지하면서 크기 변경
ft.view([-1, 1, 3])
-1은 다른 주어진 인자 값에 따라서 파이토치가 알아서 조절하라는 의미. 첫 번째는 인자의 수가 2개이므로 2차원으로 변경하는 것이고, 두 번째는 3개이므로 3차원 형태를 그대로 유지하는 것이다.
✅ Squeeze() vs Unsqueeze()
ft = torch.FloatTensor([[0], [1], [2]])
ft
ft.shape
ft.squeeze()
ft.squeeze().shape
1인 차원을 제거한다. 위에서 생성한 ft의 두 번째 인자가 1인데, squeeze를 사용하면 이 차원이 없어지낟.
ft = torch.Tensor([0, 1, 2])
ft.shape
#0번째에 1차원 추가
ft.unsqueeze(0).shape
#1번째에 1차원 추가
ft.unsqueeze(1).shape
#인덱스 상으로 마지막 차원 추가
ft.unsqueeze(-1).shape
#view로도 가능함
ft.view(1,-1).shape
반대로 unsqueeze()는 특정 인덱스에 해당하는 차원을 1 늘려주는 역할을 한다. unsqueeze(0)은 0번째 인덱스인 행의 차원을 1늘린다는 의미이다. -1을 입력할 경우 인덱스 상에서 가장 마지막 차원에 1차원을 추가한다는 의미이다.
view() 함수로도 동일한 기능을 수행할 수 있다.
✅ 타입 캐스팅 (Type Casting)
텐서 데이터에도 세부 데이터 유형이 존재한다. 이 자료형을 변환하는 것을 타입 캐스팅이라고 함.
lt = torch.LongTensor([1,2,3,4])
lt.float()
lt.long()
✅ Concatenate vs Stacking
x = torch.FloatTensor([[1, 2], [3, 4]])
y = torch.FloatTensor([[5, 6], [7, 8]])
x
y
#concat
torch.cat([x,y], dim=0)
torch.cat([x,y], dim=0).shape
torch.cat([x,y], dim=0).dim()
torch.cat([x,y], dim=1)
torch.cat([x,y], dim=1).shape
torch.cat([x,y], dim=1).dim()
#stack
torch.stack([x, y], dim=0)
torch.stack([x, y], dim=0).shape
torch.stack([x, y], dim=0).dim()
torch.stack([x, y], dim=1)
torch.stack([x, y], dim=1).shape
torch.stack([x, y], dim=1).dim()
concat의 경우 차원이 그대로 유지되지만, stack 의 경우 차원 자체가 증가하는 방식으로 쌓는다.
✅ In Place Operation (덮어쓰기 연산)
x = torch.FloatTensor([[1, 2], [3, 4]])
#기본연산
x.mul(2)
x
#덮어쓰기 연산
x.mul_(2)
x
mul_ 과 같이 연산 함수 뒤에 _를 붙이면 기존의 값을 덮어쓰기 한다.
📚 Reference
PyTorch로 시작하는 딥러닝 입문, 유원준 외, 2022, https://wikidocs.net/52846
'머신러닝, 딥러닝 > 파이토치' 카테고리의 다른 글
[파이토치 스터디] DataLoader 사용 (0) | 2022.03.02 |
---|---|
[파이토치 스터디] 경사하강법 구현, Class 사용하기 (0) | 2022.03.01 |
[파이토치 스터디] 준지도 학습 (Semi-Supervised Learning) (0) | 2022.02.24 |
[파이토치 스터디] 전이학습, 모델 프리징 (0) | 2022.02.23 |
[파이토치 스터디] 클래스 불균형 다루기 (가중 무작위 샘플링, 가중 손실 함수) (0) | 2022.02.23 |
댓글