데이터 스터디/DL

[Pytorch] 파이토치 텐서(tensor) 기초함수, 연산

케이와이엠 2023. 11. 17. 11:27

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

 

torch.autograd를 사용한 자동 미분

파이토치(PyTorch) 기본 익히기|| 빠른 시작|| 텐서(Tensor)|| Dataset과 Dataloader|| 변형(Transform)|| 신경망 모델 구성하기|| Autograd|| 최적화(Optimization)|| 모델 저장하고 불러오기 신경망을 학습할 때 가장

tutorials.pytorch.kr

신경망을 학습할 때 가장 자주 사용되는 알고리즘은 역전파입니다. 이 알고리즘에서, 매개변수(모델 가중치)는 주어진 매개변수에 대한 손실 함수의 변화도(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