Tensor
PyTorch 딥러닝 프레임워크는 현재 활발히 사용되는 프레임워크 중 하나입니다. PyTorch 의 tensor는 numpy의 ndarry와 비슷한 구조를 가지고 실제로 numpy와 tensor간의 변환이 가능하다.
Tensor 생성
- 1차원 텐서
tensor = torch.FloatTensor([0., 1., 2., 3.])
- 2차원 텐서
data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
- numpy nd-array를 tensor로 변경
n_array = np.arange(10).reshape(2,5)
# nd array를 PyTorch tensor로 변환합니다.
t_array = torch.FloatTensor(n_array)
print("ndim :", t_array.ndim, "shape :", t_array.shape)
##ndim : 2 shape : torch.Size([2, 5])
Tensor 연산 operation
- 덧셈(add), 뺄섬(sub), 나눗셈(div), 곱셈(mul)
import torch
x = torch.rand(2,6)
y = torch.rand(2,6)
print(f"{torch.add(x,y)}\n") #덧셈
print(f"{torch.sub(x,y)}\n") #뺄셈
print(f"{torch.div(x,y)}\n") #나눗셈
print(f"{torch.mul(x,y)}\n") #곱셈
- 브로드캐스팅 연산 : 크기가 서로 다른 텐서끼리 연산할 때 파이토치에서 자동으로 크기를 맞춰주는 기능
- 덧셈 : 두 텐서의 크기가 (2, 2)로 동일하게 변경되었고, 따라서 덧셈 결과 텐서의 크기도 (2, 2)가 된다.
t1 = torch.FloatTensor([[1, 4]]) # 크기가 (1, 2)인 텐서
t2 = torch.FloatTensor([[3], [4]]) # 크기가 (2, 1)인 텐서
print(t1 + t2)
print((t1 + t2).size())
tensor([[4., 7.],
[5., 8.]])
torch.Size([2, 2])
[1, 4] ⇒ [[1, 4], [1, 4]]
[[3], [4]] ⇒ [[3, 3], [4, 4]]
-
- 곱셈 : 행렬의 곱이 정의되려면 첫번째 행렬의 열과 두번쨰 행렬의 행이 동일해야 한다.
t1 = torch.FloatTensor([[1, 2], [3, 4]]) # 2 x 2
t2 = torch.FloatTensor([[1], [2]]) # 2 x 1
print(t1 * t2) # 2 x 2, print(t1.mul(t2))와 같다.
torch.mm 과 torch.matmul 사이의 차이
torch.mm 은 torch.matmul과 달리 broadcast가 안 된다.
즉 mm은 정확하게 matrix 곱의 사이즈가 맞아야 사용이 가능하다.
Tensor 조작
- view / reshape
: view 함수를 통해 텐서의 크기를 변경할 수 있다. numpy에서의 reshape의 기능과 같으며 -1로 자동 조정기능도 똑같이 존재한다.
tensor_ex = torch.rand(size=(2, 3, 2)) #행/렬/텐서크기
tensor([[[0.8092, 0.5570],
[0.4375, 0.8827],
[0.7835, 0.2612]],
[[0.4974, 0.9591],
[0.4623, 0.8173],
[0.0795, 0.6424]]])
- tensor가 contiguous한 경우, 인자로 받은 사이즈에 맞춰 tensor의 사이즈를 변경
tensor_ex.view([-1, 6])
tensor([[0.8092, 0.5570, 0.4375, 0.8827, 0.7835, 0.2612],
[0.4974, 0.9591, 0.4623, 0.8173, 0.0795, 0.6424]])
- squeeze
: 텐서를 생성한 후, 크기 1의 차원을 갖는 dimension을 squeeze합니다.
tensor_ex = torch.rand(size=(2, 1, 2))
tensor_ex.squeeze().size() #size : (2,2)
- unsqueeze
: 특정 위치에 크기가 1인 차원을 추가하는 함수
# 새로운 차원에 축을 생성합니다.
tensor_ex = torch.rand(size=(2, 2))
tensor_ex.unsqueeze(0).shape
#torch.Size([1, 2, 2])
tensor_ex.unsqueeze(1).shape
#torch.Size([2, 1, 2])
tensor_ex.unsqueeze(2).shape
#torch.Size([2, 2, 1])
- stacking
: Concatenate와 같은 역할을 하지만 더 직관적인 함수
x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])
print(torch.stack([x, y, z]))
print(torch.stack([x, y, z], dim=1))
tensor([[1., 4.],
[2., 5.],
[3., 6.]])
tensor([[1., 2., 3.],
[4., 5., 6.]])
- Ones-like & Zeros-like
: 텐서를 0이나 1로 채움
Pytorch AutoGrad
https://tutorials.pytorch.kr/beginner/basics/autogradqs_tutorial.html
신경망을 학습할 때 가장 자주 사용되는 알고리즘은 역전파입니다. 이 알고리즘에서, 매개변수(모델 가중치)는 주어진 매개변수에 대한 손실 함수의 변화도(gradient)에 따라 조정됩니다.
이러한 변화도를 계산하기 위해 PyTorch에는 `torch.autograd`라고 불리는 자동 미분 엔진이 내장되어 있습니다.
- data : tensor형태의 데이터
- grad : data가 거쳐온 layer에 대한 미분값 저장
- grad_fn : 미분값을 계산한 함수에 대한 정보 저장
- requires_grad : True설정시 연산을 추적할 수 있음
- .backward() : 자동으로 gradient를 계산하며 .grad에 저장된다.
- .detach() : 연산기록으로부터 분리
- with torch.no_grad(): : gradient를 업데이트 하지 않는다. 평가할때 사용한다.
- Function클래스 : Autograd 구현에 중요한 클래스
# Q에 대한 a의 gradient를 출력합니다.
a = torch.tensor([2., 3.], requires_grad=True)
b = torch.tensor([6., 4.], requires_grad=True)
Q = 3*a**3 - b**2
external_grad = torch.tensor([1., 1.])
Q.backward(gradient=external_grad)
a.grad
'데이터 스터디 > DL' 카테고리의 다른 글
[Pytorch] 파이토치 Dataset, Dataloader (0) | 2023.11.17 |
---|---|
[Pytorch] 파이토치 nn.Module, nn.funcional (parameter, forward, backward연산) (0) | 2023.11.17 |
[논문 읽기] Attention IS All You Need (Transformer) (0) | 2023.11.15 |
[논문 읽기] Neural Machine Translation by Jointly Learning to Align and Translate (Attention) (0) | 2023.11.14 |
[논문 읽기] Sequence to Sequence Learning with Neural Networks (Seq2Seq) (0) | 2023.11.14 |