일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Set
- 패치분할
- docker
- Python
- geopandas
- python최단거리
- 데이터입수
- GIS
- 도커 레이어
- 그리드분할
- 귀여운고래
- 동명이인찾기
- 도커
- GCN
- 알고리즘
- pyvista
- geojson
- 폴더조사
- 이미지빌드
- GNN
- 컨테이너
- MESH
- 좌표거리
- 지하철역좌표
- osmnx
- 파이썬
- 3d데이터
- STL
- graph
- 3d
- Today
- Total
이것저것 기록
[DL, PyTorch] 텐서 슬라이싱, 브로드캐스팅, 기본 연산 본문
1. 브로드캐스팅
두 행렬 A, B가 있을 때, 원래는 두 행렬의 크기가 같아야지만 덧셈/뺄셈을 수행할 수가 있다.
그리고 두 행렬의 곱셈을 할 때는 (A x B) A의 마지막 차원과 B의 마지막 차원이 일치해야한다.
이를 위해 파이토치에서는 브로드캐스팅 이라는 기능을 제공한다.
브로드캐스팅 기능은 서로 크기가 다른 행렬들이 사칙연산을 수행할 수 있도록 자동으로 크기를 맞춰서 연산을 수행하게 해준다.
import numpy as np
import torch
# Case 1 : 같은 크기의 행렬
m1 = torch.FloatTensor([[3, 3]])
m2 = torch.FloatTensor([[2, 2]])
print(f'shape: m1 = {m1.shape}, m2 = {m2.shape}')
m3 = m1 + m2
print(m3, m3.shape)
# Case 2 : 벡터와 행렬
m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([3]) # [3] -> [3, 3]
print(f'shape: m1 = {m1.shape}, m2 = {m2.shape}')
m3 = m1 + m2
print(m3, m3.shape)
# Case 3 : 크기가 다른 두 개의 행렬
m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([[3], [4]])
print(f'shape: m1 = {m1.shape}, m2 = {m2.shape}')
m3 = m1 + m2
print(m3, m3.shape)
2. 텐서 슬라이싱
import numpy as np
import torch
a = torch.empty(6, 6, dtype=torch.float)
print(a)
print(a.size())
# 첫 번째 행의 네 번째 열에 있는 원소
b = a[0, 3]
print(b)
# 네번째 열과 다섯번째 열에 있는 모든 원소
b = a[:, 3:5]
print(b)
3. 연산
3.1 행렬곱셈, 곱셈
import numpy as np
import torch
# 행렬곱셈 (.matmul)
m1 = torch.FloatTensor([[1, 2], [3, 4]])
m2 = torch.FloatTensor([[1], [2]])
print('Shape of Matrix 1: ', m1.shape) # 2 x 2
print('Shape of Matrix 2: ', m2.shape) # 2 x 1
print(m1.matmul(m2)) # 2 x 1
# 곱셈 (.mul) -- element-wise 곱셈
m1 = torch.FloatTensor([[1, 2], [3, 4]])
m2 = torch.FloatTensor([[1], [2]])
print('Shape of Matrix 1: ', m1.shape) # 2 x 2
print('Shape of Matrix 2: ', m2.shape) # 2 x 1
print(m1 * m2) # 2 x 2
print(m1.mul(m2))
행렬곱셈에서 두 개의 행렬 A와 B가 matmul하게 되면 결과로 나오는 행렬의 크기는 행렬 A의 첫번째 차원, 행렬 B의 마지막 차원을 따르게 된다.
위의 예제에서 m1의 첫번째 차원은 2, m2의 마지막 차원은 1이므로 결과값의 크기는 2 x 1이 된 것이다.
element-wise 곱셈에선 서로 다른 크기의 행렬이 브로드캐스팅 된 후에 곱셈이 수행된다.
이는 동일한 크기의 행렬이 동일한 위치에 있는 원소끼리 곱하는 것과 같은 결과를 얻게 된다.
3.2 평균
import numpy as np
import torch
# 1차원 행렬의 평균
t1 = torch.FloatTensor([2, 3])
print(t1)
print(t1.mean()) # tensor(2.5000)
# 2차원 행렬의 평균
t2 = torch.FloatTensor([[3, 3], [6, 9]])
print(t2)
print(t2.mean()) # tensor(5.2500)
# dim값을 인자로 주기
print(t2.mean(dim=0)) # tensor([4.5000, 6.0000])
print(t2.mean(dim=1)) # tensor([3.0000, 7.5000])
print(t2.mean(dim=-1)) # tensor([3.0000, 7.5000])
.mean()에서 dim을 인자로 주게 되면 어느 차원을 기준으로 평균을 구할지 설정할 수 있다.
아무 것도 설정하지 않으면 전체 평균을 계산하고
dim=0은 첫번째차원 즉 행을 기준으로 평균을 계산한다.
dim=1은 두번째 차원 즉 열을 기준으로 평균을 계산하고 dim=-1은 마지막 차원으로 평균을 계산하는데 위의 예제에선 마지막 차원 = 열이므로 t2.mean(dim=1)과 출력값이 동일하게 되는 것이다.
3.3 덧셈
import numpy as np
import torch
# 1차원 행렬의 합
t1 = torch.FloatTensor([2, 3])
print(t1)
print(t1.sum()) # tensor(5.)
# 2차원 행렬의 합
t2 = torch.FloatTensor([[3, 3], [6, 9]])
print(t2)
print(t2.sum()) # tensor(21.)
print(t2.sum(dim=0)) # tensor([ 9., 12.])
print(t2.sum(dim=1)) # tensor([ 6., 15.])
print(t2.sum(dim=-1)) # tensor([ 6., 15.])
덧셈은 평균과 완전히 동일하다. (평균 대신 덧셈을 하는 것 이외엔 사용 방법이 동일함.)
3.4 최대, 아그맥스
# max & argmax
t = torch.FloatTensor([[1, 3], [6, 9]])
print(t.max())
print(t.max(dim=0))
print('Max: ', t.max(dim=0)[0])
print('Argmax: ', t.max(dim=0)[1])
print(t.max(dim=1))
print(t.max(dim=-1))
최대(max)는 최대값을 반환하고 아그맥스(argmax)는 최대값을 가진 인덱스를 반환한다.
차원을 지정하면 두개의 데이터를 뽑을 수 있다.
t.max(dim=0)[0]이 최대값(max)를 나타내고,
t.max(dim=0)[1]이 최대값을 갖는 데이터 인덱스를 나타내게 된다.
참고 링크: wikidocs.net/52460
'Data Science > ML & DL' 카테고리의 다른 글
[DL, PyTorch] 신경망 모델 정의하기 -- Class, nn.Module (0) | 2020.10.13 |
---|---|
[DL, PyTorch] Autograd: 자동 미분 (0) | 2020.10.13 |
[DL, PyTorch] 차원 재구성 - view(), reshape() (2) | 2020.10.08 |
[DL, PyTorch] 벡터, 행렬, 텐서 (0) | 2020.10.06 |
[DL, PyTorch] 이미지를 텐서(Tensor)로 변환하기 (0) | 2020.09.30 |