본문 바로가기
딥러닝/파이토치 딥러닝

3장 파이토치 튜토리얼

by sonysame 2024. 4. 4.
  • 텐서: 딥러닝에서 가장 기본이 되는 단위 중 하나(3차원 이상의 배열)1. numpy 호환

 

1. numpy <->tensor

import torch 
import numpy as np  

x=np.array([[1,2],[3,4]])
y=torch.from_numpy(x)
x=y.numpy()

 

2. 텐서크기 구하기

x=torch.FloatTensor([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])

print(x.size()) #torch.Size([3, 2, 2])
print(x.shape) #torch.Size([3, 2, 2])

print(x.size(-1)) #2
print(x.shape[-1]) #2

# dimension
print(x.dim()) #3
print(len(x.size())) #3

 

3. 기본연산

a=torch.FloatTensor([[1,2],[3,4]])
b=torch.FloatTensor([[2,2],[3,3]])

print(a+b)
print(a-b)
print(a*b)
print(a/b)

print(a**b)
print(a==b)
print(a!=b)

 

4. 인플레이스 연산: 기존 텐서 메모리 공간에 결과가 저장
underscore가 함수명 뒤에 붙어있는 것이 특징
* 가비지 컬렉터가 있기 때문에 굳이 인플레이스 연산을 사용할 필요는 없음.

#print(a.mul(b)) #print(a)는 기존 a

print(a.mul_(b)) #print(a)와 동일한 결과

 

5. 차원 축소 연산

x=torch.FloatTensor([[1,2],[3,4]])
print(x.sum()) #tensor(10.)
print(x.mean()) #tensor(2.5000)

# 첫번째 차원이 사라짐
print(x.sum(dim=0)) #tensor([4., 6.])

# 두번째 차원이 사라짐
print(x.sum(dim=-1)) #tensor([3., 7.])

 

6. 브로드캐스트 연산

# 텐서+스칼라
x=torch.FloatTensor([[1,2],[3,4]])
y=1
z=x+y
print(z) #tensor([[2., 3.],[4., 5.]])

# 텐서+벡터
x=torch.FloatTensor([[1,2],[4,8]])
y=torch.FloatTensor([3,5])
z=x+y
print(z) #tensor([[ 4.,  7.],[ 7., 13.]])

# 텐서+텐서
x=torch.FloatTensor([[[1,2]]]) #[1,1,2]
y=torch.FloatTensor([3,5]) #[2]
z=x+y
print(z) #tensor([[[4., 7.]]])


x=torch.FloatTensor([[1,2]]) #[1,2]
y=torch.FloatTensor([[3],[5]]) #[2,1]
z=x+y
print(z) #tensor([[4., 5.],[6., 7.]])

 

7. View 함수 : 텐서의 전체 요소 개수는 유지한 채 모양을 바꾸는 방법

: -1이 들어간 차원의 크기는 다른 차원의 값들을 곱하고 남은 필요한 값이 자동으로 채워짐. 

: view함수의 경우 메모리에 순차대로 선언된 contiguous텐서에 대해서만 동작 -> 그렇지 않을 경우 contiguous함수를 view함수 이전에 써줘야 하는데, contiguous+view를 한 것이 reshape함수!

x=torch.FloatTensor([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])

print(x.size()) #[3,2,2]

print(x.view(3,4)) #print(x.view(3,-1))
#tensor([[ 1.,  2.,  3.,  4.],
#        [ 5.,  6.,  7.,  8.],
#        [ 9., 10., 11., 12.]])

print(x.view(3,1,4)) #print(x.view(-1,1,4))
#tensor([[[ 1.,  2.,  3.,  4.]],
#        [[ 5.,  6.,  7.,  8.]],
#        [[ 9., 10., 11., 12.]]])

print(x.reshape(3,4))
#tensor([[ 1.,  2.,  3.,  4.],
#        [ 5.,  6.,  7.,  8.],
#        [ 9., 10., 11., 12.]])

 

8. Squeeze함수/Unsqueeze함수

Squeeze함수: 차원의 크기가 1인 차원을 없애주는 역할. 만약 해당 차원의 크기가 1이 아닌 경우 같은 텐서가 반환

Unsqueeze함수: 크기가 1인 차원을 삽입. 

x=torch.FloatTensor([[[1,2],[3,4]]])

print(x.size()) #torch.Size([1, 2, 2])
print(x.squeeze().size()) #torch.Size([2, 2])
print(x.squeeze(0).size()) #torch.Size([2, 2])

x=torch.FloatTensor([[1,2],[3,4]])

print(x.size()) #torch.Size([2, 2])
print(x.unsqueeze(1).size()) #torch.Size([2, 1, 2])

 

9. 인덱싱/슬라이싱

x=torch.FloatTensor([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])
print(x.size())
print(x[0])
#tensor([[1., 2.],
#        [3., 4.]])
print(x[:,0])
#tensor([[ 1.,  2.],
#        [ 5.,  6.],
#        [ 9., 10.]])
print(x[1:2,1:,:])
#tensor([[[7., 8.]]])

 

10. split함수

: 첫번째 차원의 크기가 4가 되도록 텐서 등분

x=torch.FloatTensor([[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,31,32],[33,34,35,36],[37,38,39,40]])
splits=x.split(4,dim=0)
print(splits[0])
#tensor([[ 1.,  2.,  3.,  4.],
#        [ 5.,  6.,  7.,  8.],
#        [ 9., 10., 11., 12.],
#        [13., 14., 15., 16.]])
print(splits[-1])
#tensor([[33., 34., 35., 36.],
#        [37., 38., 39., 40.]])

 

11. chunk함수

: 원하는 개수로 나누는 chunk 함수

x=torch.FloatTensor([[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,31,32],[33,34,35,36],[37,38,39,40]])
chunks=x.chunk(3,dim=0)
print(chunks[0])
print(chunks[1])
print(chunks[2])
#tensor([[ 1.,  2.,  3.,  4.],
#        [ 5.,  6.,  7.,  8.],
#        [ 9., 10., 11., 12.],
#        [13., 14., 15., 16.]])
#tensor([[17., 18., 19., 20.],
#        [21., 22., 23., 24.],
#        [25., 26., 27., 28.],
#        [29., 30., 31., 32.]])
#tensor([[33., 34., 35., 36.],
#        [37., 38., 39., 40.]])

 

12. index_select함수

dim으로 차원 변경가능

x=torch.FloatTensor([[[1,1],[2,2]],[[3,3],[4,4]],[[5,5],[6,6]]])
indice=torch.LongTensor([2,1])

y=x.index_select(dim=0, index=indice)
print(y)
#tensor([[[5., 5.],
#         [6., 6.]],
#
#        [[3., 3.],
#         [4., 4.]]])

 

13. concatenate함수
이어붙이고자 하는 차원의 크기가 맞지 않으면 cat함수를 수행할 수 없음.

x=torch.FloatTensor([[1,2,3],[4,5,6],[7,8,9]])
y=torch.FloatTensor([[10,11,12],[13,14,15],[16,17,18]])

print(x.size(), y.size())
z=torch.cat([x,y],dim=0)
print(z)
#tensor([[ 1.,  2.,  3.],
#        [ 4.,  5.,  6.],
#        [ 7.,  8.,  9.],
#        [10., 11., 12.],
#        [13., 14., 15.],
#        [16., 17., 18.]])
z=torch.cat([x,y],dim=1)
print(z)
#tensor([[ 1.,  2.,  3., 10., 11., 12.],
#        [ 4.,  5.,  6., 13., 14., 15.],
#        [ 7.,  8.,  9., 16., 17., 18.]])

 

14. stack함수

새로운 차원을 만든 뒤에 cat함수를 수행한 것과 같음. 

x=torch.FloatTensor([[1,2,3],[4,5,6],[7,8,9]])
y=torch.FloatTensor([[10,11,12],[13,14,15],[16,17,18]])
z=torch.stack([x,y])
print(z)
#tensor([[[ 1.,  2.,  3.],
#         [ 4.,  5.,  6.],
#         [ 7.,  8.,  9.]],
#
#        [[10., 11., 12.],
#         [13., 14., 15.],
#         [16., 17., 18.]]])

z=torch.stack([x,y],dim=1)
print(z)
#tensor([[[ 1.,  2.,  3.],
#         [10., 11., 12.]],
#
#        [[ 4.,  5.,  6.],
#         [13., 14., 15.]],
#
#        [[ 7.,  8.,  9.],
#         [16., 17., 18.]]])

z=torch.stack([x,y],dim=2)
print(z)
#tensor([[[ 1., 10.],
#         [ 2., 11.],
#         [ 3., 12.]],
#
#        [[ 4., 13.],
#         [ 5., 14.],
#         [ 6., 15.]],
#
#        [[ 7., 16.],
#         [ 8., 17.],
#         [ 9., 18.]]])

 

15. 반복되는 작업을 수행한 후 ->반복 작업의 결과물을 하나로 합치기

result=[]
for i in range(5):
    x=torch.FloatTensor(2,2)
    result+=[x]

print(result)
"""[tensor([[7.2208e-23, 3.2294e-41],
        [8.3157e-23, 3.2294e-41]]), 
    tensor([[-1.2487e-32,  4.1516e-41],
        [ 3.5934e-23,  3.2294e-41]]), 
    tensor([[-1.2487e-32,  4.1516e-41],
        [ 8.2386e-23,  3.2294e-41]]), 
    tensor([[-1.2487e-32,  4.1516e-41],
        [-1.2487e-32,  4.1516e-41]]), 
    tensor([[5.7682e-23, 3.2294e-41],
        [7.9345e-23, 3.2294e-41]])]"""
print(torch.cat(result))
"""tensor([[ 7.2208e-23,  3.2294e-41],
        [ 8.3157e-23,  3.2294e-41],
        [-1.2487e-32,  4.1516e-41],
        [ 3.5934e-23,  3.2294e-41],
        [-1.2487e-32,  4.1516e-41],
        [ 8.2386e-23,  3.2294e-41],
        [-1.2487e-32,  4.1516e-41],
        [-1.2487e-32,  4.1516e-41],
        [ 5.7682e-23,  3.2294e-41],
        [ 7.9345e-23,  3.2294e-41]])"""
print(torch.stack(result))
"""tensor([[[ 7.2208e-23,  3.2294e-41],
         [ 8.3157e-23,  3.2294e-41]],

        [[-1.2487e-32,  4.1516e-41],
         [ 3.5934e-23,  3.2294e-41]],

        [[-1.2487e-32,  4.1516e-41],
         [ 8.2386e-23,  3.2294e-41]],
...
         [-1.2487e-32,  4.1516e-41]],

        [[ 5.7682e-23,  3.2294e-41],
         [ 7.9345e-23,  3.2294e-41]]])"""

 

16. expand함수

차원의 크기가 1인 차원을 원하는 크기로 늘려줌!

x=torch.FloatTensor([[[1,2]],[[3,4]]])
print(x.size())

#y=torch.cat([x]*3,dim=1)
y=x.expand(2,3,2)
print(y)
"""tensor([[[1., 2.],
         [1., 2.],
         [1., 2.]],

        [[3., 4.],
         [3., 4.],
         [3., 4.]]])"""

 

17. random permutation함수

x=torch.randperm(10)
print(x)
#tensor([7, 4, 0, 1, 6, 2, 9, 5, 8, 3])

 

18. argmax함수

f(x)의 값을 최대로 만드는 x

x=torch.randperm(3**3).reshape(3,3,-1)
print(x)
y=x.argmax(dim=-1)
print(y)
"""tensor([[[21, 24, 25],
         [19,  0, 16],
         [26,  7, 20]],

        [[13, 23, 12],
         [22, 10,  8],
         [ 1,  4,  5]],

        [[ 2,  9, 18],
         [11,  3, 14],
         [15,  6, 17]]])
tensor([[2, 0, 0],
        [1, 0, 2],
        [2, 2, 2]])"""

 

19. Top-k 함수

argmax는 가장 큰 한 개의 값의 인덱스를 반환
-> topk함수는 가장 큰 k개의 값과 인덱스를 반환

values, indices=torch.topk(x,k=2,dim=-1)
print(values)
print(indices)
"""tensor([[[25, 24],
         [19, 16],
         [26, 20]],

        [[23, 13],
         [22, 10],
         [ 5,  4]],

        [[18,  9],
         [14, 11],
         [17, 15]]])
tensor([[[2, 1],
         [0, 2],
         [0, 2]],

        [[1, 0],
         [0, 1],
         [2, 1]],

        [[2, 1],
         [2, 0],
         [2, 0]]])"""

 

20. Sort함수

values, indices=torch.topk(x, k=x.size(-1), largest=True)
print(values)
"""tensor([[[25, 24, 21],
         [19, 16,  0],
         [26, 20,  7]],

        [[23, 13, 12],
         [22, 10,  8],
         [ 5,  4,  1]],

        [[18,  9,  2],
         [14, 11,  3],
         [17, 15,  6]]])"""

 

21. masked_fill함수

mask가 true인 값들은 value값으로 치환

x=torch.FloatTensor([i for i in range(3**2)]).reshape(3,-1)
print(x)
"""tensor([[0., 1., 2.],
        [3., 4., 5.],
        [6., 7., 8.]])"""
mask=x>4
print(mask)
"""tensor([[False, False, False],
        [False, False,  True],
        [ True,  True,  True]])"""
y=x.masked_fill(mask, value=-1)
print(y)
"""tensor([[ 0.,  1.,  2.],
        [ 3.,  4., -1.],
        [-1., -1., -1.]])"""

 

22. ones & zeros 함수

print(torch.ones(2,3))
print(torch.zeros(2,3))
"""tensor([[1., 1., 1.],
        [1., 1., 1.]])
tensor([[0., 0., 0.],
        [0., 0., 0.]])"""

x=torch.FloatTensor([[1,2,3],[4,5,6]])
print(torch.ones_like(x))
print(torch.zeros_like(x))
"""tensor([[1., 1., 1.],
        [1., 1., 1.]])
tensor([[0., 0., 0.],
        [0., 0., 0.]])"""

'딥러닝 > 파이토치 딥러닝' 카테고리의 다른 글

8장. 로지스틱 회귀  (1) 2024.05.01
7장 선형회귀(linear regression)  (0) 2024.04.22
6장 경사하강법  (0) 2024.04.22
5장. 손실함수  (0) 2024.04.10
4장. 선형계층  (0) 2024.04.10