반응형

파이토치 기초 예제

 

정리. 수알치 오상문

(참조: 파이토치 기초 동영상)


import torch

print(torch.__version__)

[결과]
'1.10.0'


x = torch.empty(4, 3)  # 메모리 공간 4x3 텐서 만들기 (초기화 없음)
print(x)

[결과]
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])


x = torch.rand(4, 3)  # 랜덤값(0~1) 채워진 4x3 텐서 
print(x)

[결과]
tensor([[0.2192, 0.9991, 0.7398],
        [0.1423, 0.1617, 0.4878],
        [0.3868, 0.5706, 0.1873],
        [0.4772, 0.2441, 0.4278]])


x = torch.zeros(4, 3, dtype=torch.long)  # long형 0으로 채워진 4x3 텐서
print(x)

[결과]
tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])


x = torch.tensor([[0,1,2],[3,4,5],[6,7,8],[9,10,11]])  # 리스트로 텐서 만들기 
print(x)

[결과]
tensor([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]])


x = torch.tensor([[0,1,2],[3,4,5],[6,7,8],[9,10,11]], dtype=torch.double)  # 리스트로 텐서 만들기 
print(x)

[결과]
tensor([[ 0.,  1.,  2.],
        [ 3.,  4.,  5.],
        [ 6.,  7.,  8.],
        [ 9., 10., 11.]], dtype=torch.float64)


y = x.new_ones(3, 4, dtype=torch.int)  # 기존 텐서 모양과 데이터형 변환하기 
print(y)

[결과]
tensor([[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]], dtype=torch.int32)


x = torch.randn_like(y, dtype=torch.double)  # 텐서 구조는 y처럼 하고 double 랜덤값(0.0~1.0) 초기화
print(x)

[결과][18
tensor([[-0.5836,  0.6246,  0.5739, -0.7952],
        [ 1.2307, -1.6365,  1.0394,  0.9653],
        [-0.3182, -0.0342,  1.2220,  1.1937]], dtype=torch.float64)


print(x.size())  # x 텐서 구조 

[결과]
torch.Size([3, 4])


z = torch.zeros(3, 4)
print(z.size())

[결과]
torch.Size([3, 4])


print(z.size() == x.size())  # 크기 비교도 가능

[결과]
True


y = torch.ones(3,4)
print(x + y)

[결과]
tensor([[ 0.4164,  1.6246,  1.5739,  0.2048],
        [ 2.2307, -0.6365,  2.0394,  1.9653],
        [ 0.6818,  0.9658,  2.2220,  2.1937]], dtype=torch.float64)


# in-place 연산 이용하기 : 이름 뒤 '_' 붙음에 주의 
x.add_(y)
print(x)

[결과]
tensor([[ 0.4164,  1.6246,  1.5739,  0.2048],
        [ 2.2307, -0.6365,  2.0394,  1.9653],
        [ 0.6818,  0.9658,  2.2220,  2.1937]], dtype=torch.float64)


x.copy_(y)  # 텐서 y 값들을 x 텐서에 복사, x += y
print(x)

[결과]
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]], dtype=torch.float64)


x.sub_(y)  # x-y
x.mul_(y)  # x*y 
x.div_(y)  # x/y
print(x)

[결과]
tensor([[-14., -14., -14., -14.],
        [-14., -14., -14., -14.],
        [-14., -14., -14., -14.]], dtype=torch.float64)


# torch.sub(x, y)
# torch.mul(x, y)
# torch.add(x, y)
# torch.div(x, y)
z = torch.add(x, x)
print(z)

[결과]
tensor([[-28., -28., -28., -28.],
        [-28., -28., -28., -28.],
        [-28., -28., -28., -28.]], dtype=torch.float64)


# torch.mm()  내적(dot product) : 행렬 곱 
# z = torch.mm(x,y)  <-- 에러!!!  행렬곱은 형태가 같아야 함
x = torch.ones(3,3) * 3
y = torch.ones(3,3) * 2
z = torch.mm(x, y)
print(z)

[결과]
tensor([[18., 18., 18.],
        [18., 18., 18.],
        [18., 18., 18.]])


# 차원 축소 squeeze 
# 차원 증가 unsqueeze
t = torch.rand(1,3,3)
t1 = t.squeeze()
t2 = t1.unsqueeze(0)  # 0, 1, 2 : 증가할 위치 지정 0은 가장 바깥 차원
                           # t1.unsqueeze(dim=0)
print(t)
print(t1)
print(t2)
print(t2.shape)

[결과]
tensor([[[0.6821, 0.5715, 0.4165],
         [0.6538, 0.5369, 0.5405],
         [0.8553, 0.4417, 0.1882]]])
tensor([[0.6821, 0.5715, 0.4165],
        [0.6538, 0.5369, 0.5405],
        [0.8553, 0.4417, 0.1882]])
tensor([[[0.6821, 0.5715, 0.4165],
         [0.6538, 0.5369, 0.5405],
         [0.8553, 0.4417, 0.1882]]])
torch.Size([1, 3, 3])


x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])
s = torch.stack([x, y, z])     # stack : 수직 연결
print(s)

[결과]
tensor([[1., 4.],
        [2., 5.],
        [3., 6.]])


x = torch.FloatTensor([1, 4])
y = torch.FloatTensor([2, 5])
z = torch.FloatTensor([3, 6])
s = torch.cat([x, y, z])     # cat : 수평 연결 
print(s)

[결과]
tensor([1., 4., 2., 5., 3., 6.])


x = torch.FloatTensor([[1, 4], [1, 4]])
y = torch.FloatTensor([[2, 5], [2, 5]])
z = torch.FloatTensor([[3, 6], [3, 6]])
s = torch.cat([x, y, z], dim=1)     # cat : 수평 연결, dim 옵션 있음  
print(s)
print(s.size())

[결과]
tensor([[1., 4., 2., 5., 3., 6.],
        [1., 4., 2., 5., 3., 6.]])
torch.Size([2, 6])


t = torch.rand(3,6)
t1, t2, t3 = t.chunk(3, dim=1)  # 텐서 분할하기, 3 --> 3개로 나눠라  
print(t)
print(t1)
print(t2)
print(t3)

[결과]
tensor([[0.6778, 0.6925, 0.1192, 0.5652, 0.4153, 0.8731],
        [0.0759, 0.3633, 0.3581, 0.5334, 0.7021, 0.7634],
        [0.2841, 0.3791, 0.9023, 0.0617, 0.9311, 0.0525]])
tensor([[0.6778, 0.6925],
        [0.0759, 0.3633],
        [0.2841, 0.3791]])
tensor([[0.1192, 0.5652],
        [0.3581, 0.5334],
        [0.9023, 0.0617]])
tensor([[0.4153, 0.8731],
        [0.7021, 0.7634],
        [0.9311, 0.0525]])


t = torch.rand(3,6)
t1, t2 = t.split(3, dim=1)  # 텐서 분할하기, 3개씩 단위로 나눠라  
print(t)
print(t1)
print(t2)

[결과]
tensor([[0.0474, 0.9797, 0.6186, 0.6101, 0.8718, 0.9101],
        [0.5364, 0.4285, 0.3994, 0.5352, 0.4211, 0.1455],
        [0.2816, 0.7838, 0.7972, 0.3157, 0.5165, 0.6601]])
tensor([[0.0474, 0.9797, 0.6186],
        [0.5364, 0.4285, 0.3994],
        [0.2816, 0.7838, 0.7972]])
tensor([[0.6101, 0.8718, 0.9101],
        [0.5352, 0.4211, 0.1455],
        [0.3157, 0.5165, 0.6601]])


# numpy(), from_numpy()
# 텐서는 CPU 상에 있지만 넘파이 배열은 메모리에 존재하고 서로 공유 상태이다
t = torch.ones(7)
print(t)
n = t.numpy()  # 넘파이 배열로 변경 
t.add_(1)  # 텐서에 추가한 값이 넘파이 배열에도 영향을 미침
             # a = a+1 식은 새로운 a에 값이 복사되어 넘파이 배열에 영향을 안 미침 
print(t)
print(n) 

[결과]
tensor([1., 1., 1., 1., 1., 1., 1.])
tensor([2., 2., 2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2. 2. 2.]


import numpy as np

n = np.ones(5)
print(n)
t = torch.from_numpy(n)
print(t)
np.add(n, 1, out=n)  # 넘파이 배열에 1씩 증가하면 토치 텐서에도 영향
print(n)
print(t)

[결과]
[1. 1. 1. 1. 1.]
tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
[2. 2. 2. 2. 2.]
tensor([2., 2., 2., 2., 2.], dtype=torch.float64)


# CUDA 사용 
# to()를 이용하여 장치 지정 가능
import torch

t = torch.randn(1)
print(t)
print(t.item())
print(t.dtype)

[결과]
tensor([1.1568])
1.1567552089691162
torch.float32


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
y = torch.ones_like(x, device=device)  # cuda 사용 가능하면 사용한다.
x = x.to(device)
z = x + y

print(device)
print(z)
print(z.to("cpu", torch.double))  # cuda에서 cpu로 

[결과]
cpu
tensor([[2., 5.],
        [2., 5.]])
tensor([[2., 5.],
        [2., 5.]], dtype=torch.float64)


# Autograd(자동미분)

- 이 패키지는 텐서 모든 연산에 자동 미분 계산을 제공한다 코드 작성에 따라
역전파가 가능하다 backdrop을 위한 미분값을 자동 계산한다,

- 텐서 data: 텐서 형태 데이터이다. 

 

- grad: 데이터가 거쳐온 레이어에 대한 미분값을 저장한다. 


- grad_fn: 미분값을 계산한 함수 정보를 저장한다.(어떤 함수에 대해 백드롭했는지 )  


- required_grad: 속성을 True로 설정하면 해당 텐서에 이루어진 모든 연산을 추적한다. 계산 완료후에 .backward() 호출하면 자동으로 gradient 계산할 수 있으며 .grad 속성에 누적된다. 기록 추적을
중단하려면 .detach()를 호출한다. 기록 추적을 방지하려는 코드를 with torch.no_grad():로 감싸면 gradient는 필요없지만 required_grad=True로 설정되어 학습가능한 매개변수를 갖는 모델 평가에 유용하다. 

 

- Autograd 구현에서 중요한 클래스는 Function 클래스이다.

반응형

+ Recent posts