백터, 행렬, 텐서 (Vector, Matrix, Tensor)
- 벡터 : 1차원으로 구성된 값, 1차원 텐서라고 부르기도 함
- 행렬 : 2차원으로 구성된 값, 2차원 텐서라고 부르기도 함
- 텐서 : 3차원 이상으로 구성된 값, 3,4,5...차원 텐서라고 부를 수 있음
- PyTorch Tensor Shape Convention : 딥러닝에서 다루고 있는 행렬이나 텐서의 크기는 중요함
텐서 | 표기 |
2D Tensor(Typical Simple Setting) | |t| = (Batch size, dim), 2차원 텐서의 크기 |t|를 (batch size × dimension)으로 표현하였을 경우 |
3D Tensor(Typical Computer Vision) | |t| = (batch size, width, height), 비전 분야에서의 3차원 텐서 |
3D Tensor(Typical natural Language Processing) | |t| = (batch size, length, dim), NLP 분야에서의 3차원 센서 |
넘파이로 텐서 만들기(벡터와 행렬 만들기)
1. numpy import
# numpy 임포트
import numpy as np
2. 1D with Numpy
- 넘파이로 1차원 텐서(벡터) 생성
# Numpy로 1차원 텐서(벡터) 생성
t = np.array([0., 1., 2., 3., 4., 5., 6.])
print(t)
[0. 1. 2. 3. 4. 5. 6.]
- 1차원 텐서인 벡터의 차원과 크기 출력
# 1차원 텐서인 벡터의 차원과 크기 출력
print(t.ndim) # 차원 출력
print(t.shape) # 크기 출력
1
(7,)
- 넘파이에서 각 벡터의 원소에 접근, 넘파이 인덱스는 0부터 시작
# Numpy에서 각 벡터의 원소에 접근하는 방법
# Numpy에서 인덱스는 0부터 시작
print(t[0], t[1], t[-1]) # 각 인덱스 원소 출력
0.0 1.0 6.0
- 넘파이에서 범위를 지정해 출력
# 범위 지정
print(t[2:5], t[4:-1]) # 2~4번 인덱스, 4번~끝에서 첫번째까지 인덱스
[2. 3. 4.] [4. 5.]
print(t[:2], t[3:]) # 1번 인덱스까지, 3번부터 끝까지
[0. 1.] [3. 4. 5. 6.]
3. 2D with Numpy
- 넘파이로 2차원 행렬 생성
# 넘파이로 2차원 행렬 생성
t = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.], [10., 11., 12.]])
print(t)
[[ 1. 2. 3.]
[ 4. 5. 6.]
[ 7. 8. 9.]
[10. 11. 12.]]
- 생성한 행렬의 차원과 크기 출력
print(t.ndim) # 2차원
print(t.shape) # 4행 3열의 크기
2
(4, 3)
파이토치 텐서 선언(PyTorch Tensor Allocation)
1. 토치 임포트
# torch 임포트
import torch
2. 1D with PyTorch
- 파이토치 1차원 텐서(벡터) 생성
# 파이토치 1차원 텐서(벡터) 생성
t = torch.FloatTensor([0., 1., 2., 3., 4., 5., 6.])
print(t)
tensor([0., 1., 2., 3., 4., 5., 6.])
- 생성한 1차원 텐서의 차원, 크기 확인
print(t.dim()) # 차원
print(t.shape) # 크기
print(t.size()) # 크기
1
torch.Size([7])
torch.Size([7])
- 생성한 1차원 텐서에 접근
print(t[0], t[1], t[-1]) # 인덱스로 접근
print(t[2:5], t[4:-1]) # 슬라이싱
print(t[:2], t[3:]) # 슬라이싱
tensor(0.) tensor(1.) tensor(6.)
tensor([2., 3., 4.]) tensor([4., 5.])
tensor([0., 1.]) tensor([3., 4., 5., 6.])
3. 2D with PyTorch
- 파이토치로 2차원 텐서(행렬) 생성
# 파이토치로 2차원 텐서(행렬) 생성
t = torch.FloatTensor([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.],
[10., 11., 12.]
])
print(t)
tensor([[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.],
[10., 11., 12.]])
- 생성한 2차원 텐서의 차원 및 크기 확인
print(t.dim()) # 차원
print(t.shape) # 크기
print(t.size()) # 크기
2
torch.Size([4, 3])
torch.Size([4, 3])
- 생성한 2차원 텐서 접근
print(t[:, 1]) # 첫 번째 차원을 전체 선택한 상황에서 두번째 차원의 첫번째 것만 가져옴
print(t[:, 0].size())
tensor([ 2., 5., 8., 11.])
torch.Size([4])
print(t[:, :-1]) # 첫번째 차원을 전체 선택한 상황에서 두번째 차원에서는 맨 마지막에서 첫번째를 제외하고 다 가져온다.
tensor([[ 1., 2.],
[ 4., 5.],
[ 7., 8.],
[10., 11.]])
4. 브로드캐스팅(Brodcasting)
- 원칙적으로 행렬의 크기가 같아야만 행렬의 덧셈, 뺄셈이 가능하지만 파이토치는 자동으로 크기를 맞춰서 연산을 수행하는 브로드캐스팅이라는 기능을 제공
- 두 행렬의 크기가 같은 경우 행렬의 덧셈
# 두 행렬의 크기가 같은 경우
m1 = torch.FloatTensor([[3, 3]])
m2 = torch.FloatTensor([[2, 2]])
print(m1 + m2)
tensor([[5., 5.]])
- 두 행렬의 크기가 다른 경우 행렬의 덧셈
# 두 행렬의 크기가 다른 경우
m1 = torch.FloatTensor([[1, 2]])
m2 = torch.FloatTensor([3]) # [3] -> 파이토치는 [3, 3]으로 자동 변환하여 계산한다.
print(m1 + m2)
tensor([[4., 5.]])
5. 자주 사용되는 기능
1) 행렬 곱셈과 원소별 곱셈의 차이
- 파이토치 텐서로 행렬 곱셈, mautmul() 사용
# 파이토치 텐서로 행렬 곱셈, muatmul() 사용
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)
print(m2)
print(m1.matmul(m2)) # 2 x 1
Shape of Matrix 1: torch.Size([2, 2])
Shape of Matrix 2: torch.Size([2, 1])
tensor([[1., 2.],
[3., 4.]])
tensor([[1.],
[2.]])
tensor([[ 5.],
[11.]])
* 행렬의 곱셈에 대한 개념은 구글링을 해보자.
- 원소별 곱셈, mul() 사용
# element-wise 곱셈: 동일한 크기의 행렬이 동일한 위치에 있는 원소끼리 곱함, mul() 사용
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)
print(m2)
print(m1 * m2) # 2 x 2
print(m1.mul(m2))
Shape of Matrix 1: torch.Size([2, 2])
Shape of Matrix 2: torch.Size([2, 1])
tensor([[1., 2.],
[3., 4.]])
tensor([[1.],
[2.]])
tensor([[1., 2.],
[6., 8.]])
tensor([[1., 2.],
[6., 8.]])
2) 행렬 평균
- 평균은 mean()을 사용
# mean() 사용
t = torch.FloatTensor([1, 2])
print(t)
print(t.mean())
tensor([1., 2.])
tensor(1.5000)
- 2차원 행렬로 평균 값 계산
# 2차원 행렬로 평균 값 구하기
t = torch.FloatTensor([[1, 2], [3, 4]])
print(t)
print(t.mean()) # 4개 원소의 평균이 나옴
tensor([[1., 2.],
[3., 4.]])
tensor(2.5000)
- 차원 dimension을 인자로 주는 경우
# 차원 dimension을 인자로 주는 경우
'''
dim = 0 은 첫번째 차원을 의미, 행렬에서 첫번째 차원은 '행'을 의미, 인자로 dim을 주면 해당 차원을 제거한다는 의미,
이는 행열에서 '열' 만을 남긴다는 의미
'''
print(t.mean(dim=0)) # dim=0은 입력에서 첫번째 차원을 제거, 1과 3의 평균, 2와 4의 평균을 구하게 된다.
tensor([2., 3.])
print(t.mean(dim=1)) # dim=1은 입력에서 열의 차원이 제거, 크기에서 (2,1)이 됨, 1과 2의 평균, 3과 4의 평균을 구함
tensor([1.5000, 3.5000])
print(t.mean(dim=-1)) # dim=-1은 입력에서 마지막 차원을 제거한다는 의미고, 이는 결국 열을 제거한다는 의미
tensor([1.5000, 3.5000])
3) 행렬 덧셈
- 텐서의 덧셈(sum)은 평균(mean)과 연산 방법과 인자가 의미하는 것이 동일
- 2차원 텐서 생성
# 2차원 텐서 생성
t = torch.FloatTensor([[1,2], [3,4]])
print(t)
tensor([[1., 2.],
[3., 4.]])
- 생성한 텐서의 덧셈 및 인자를 활용한 덧셈 수행
print(t.sum()) # 단순히 원소 전체의 덧셈을 수행
print(t.sum(dim=0)) # 행을 제거
print(t.sum(dim=1)) # 열을 제거
print(t.sum(dim=-1)) # 열을 제거
tensor(10.)
tensor([4., 6.])
tensor([3., 7.])
tensor([3., 7.])
4) 최대(Max)와 아그맥스(ArgMax)
- 최대(Max)는 원소의 최대값을 리턴, 아그맥스(ArgMax)는 최대값을 가진 인덱스를 리턴
- (2,2) 크기의 행렬 선언
# 2차원 행렬 생성
t = torch.FloatTensor([[1, 2], [3, 4]])
print(t)
tensor([[1., 2.],
[3., 4.]])
- max 실행
# max 실행
print(t.max())
tensor(4.) # 원소들 중 최대값은 4이다.
- 인자로 dim = 0을 주고 max 실행, max 인자에 dim 인자를 주면 argmax도 함께 리턴된다.
print(t.max(dim=0))
torch.return_types.max(
values=tensor([3., 4.]),
indices=tensor([1, 1]))
# dim 을 0으로 주면 첫번째 차원(행)을 제거한다는 의미, dim 을 1로 주면 두번째 차원(열)을 제거한다는 의미
- dim 인자를 주고 max나 argmax 하나만 리턴받고 싶다면 리턴값에 인덱스 부여
# dim 인자를 주고 max나 argmax 하나만 리턴받고 싶다면 리턴값에 인덱스를 부여
print('Max: ', t.max(dim=0)[0])
print('Argmax: ', t.max(dim=0)[1])
Max: tensor([3., 4.])
Argmax: tensor([1, 1])
- dim = 1로 인자를 주었을 때와 dim = -1로 인자를 주었을 때(열을 제거했을 때)
# dim = 1로 인자를 주었을 때와 dim = -1로 인자를 주었을 때
print(t.max(dim=1))
print(t.max(dim=-1))
torch.return_types.max(
values=tensor([2., 4.]),
indices=tensor([1, 1]))
torch.return_types.max(
values=tensor([2., 4.]),
indices=tensor([1, 1]))
텐서와 차원(dimension) 을 그림으로 이해해 보자.
2차원 텐서와 sum(), dimension
# 2차원 텐서(행렬)
t2 = torch.FloatTensor([
[1,2],
[3,4],
[5,6],
[7,8]
])
print(t2)
print(t2.dim()) # 차원
print(t2.size())# 크기
print(t2.shape) # 크기
- dimention = 0 일 때 sum()
print(t2.sum(dim = 0))
- dimention = 1 일 때 sum()
print(t2.sum(dim = 1))
3차원 텐서와 sum(), dimension
# 3차원 텐서
t3 = torch.FloatTensor([
[[1,2],
[3,4]
],
[[5,6],
[7,8]
]
])
print(t3)
print(t3.dim()) # 차원
print(t3.size())# 크기
print(t3.shape) # 크기
- dimention = 0 일 때 sum()
print(t3.sum(dim = 0))
- dimention = 1 일 때 sum()
print(t3.sum(dim = 1))
- dimention = 2 일 때 sum()
print(t3.sum(dim = 2))
참고:
https://wikidocs.net/book/2788
PyTorch로 시작하는 딥 러닝 입문
이 책은 딥 러닝 프레임워크 PyTorch를 사용하여 딥 러닝에 입문하는 것을 목표로 합니다. 이 책은 2019년에 작성된 책으로 비영리적 목적으로 작성되어 출판 ...
wikidocs.net
'AI > PyTorch' 카테고리의 다른 글
PyTorch #소프트맥스 회귀(Softmax Regression) (0) | 2022.03.24 |
---|---|
PyTorch #로지스틱 회귀(Logistic Regression) (0) | 2022.03.23 |
PyTorch #선형 회귀(Linear Regression) (0) | 2022.03.23 |
PyTorch 텐서 조작 #뷰 #스퀴즈 #언스퀴즈 #타입 캐스팅 #텐서 연결 (0) | 2022.03.22 |
PyTorch #파이토치란? #패키지 기본 구성 (0) | 2022.03.22 |