다운로드
작성자: admin 작성일시: 2018-12-03 14:38:03 조회수: 48436 다운로드: 241
카테고리: 기타 태그목록:

파이토치 패키지 소개

파이토치(PyTorch)는 텐서플로와 함께 딥러닝 구현에 가장 많이 사용되는 패키지다. 사용 방법이 텐서플로보다 비교적 쉽다.

설치

PyTorch는 Conda를 이용해 설치하는 것을 추천한다.

conda install PyTorch-cpu torchvision-cpu -c PyTorch

torch라는 이름으로 임포트한다.

In [1]:
import torch
import numpy as np 
import pandas as pd 
torch.__version__
Out:
'1.2.0'

텐서 자료형

PyTorch의 텐서(Tensor) 자료형은 NumPy의 배열(ndarray)과 유사한 자료형이다. 텐서 자료형을 사용하는 방법도 NumPy와 비슷하다. 텐서 자료형 데이터를 만드는 방법은 3 가지가 있다.

  • 리스트나 NumPy 배열을 텐서로 변환
  • 0 또는 1 등의 특정한 값을 가진 텐서를 생성
  • 랜덤한 값을 가지는 텐서를 생성

배열과 리스트를 텐서 자료형으로 변환

리스트를 텐서 자료형으로 바꾸러면 torch.tensor() 또는 torch.as_tensor(), torch.from_numpy() 명령을 사용한다.

  • torch.tensor(): 값 복사(value copy)를 사용하여 새로운 텐서 자료형 인스턴스를 생성한다.
  • torch.as_tensor(): 리스트나 ndarray 객체를 받는다. 값 참조(refernce)를 사용하여 텐서 자료형 뷰(view)를 만든다.
  • torch.from_numpy(): ndarray 객체를 받는다. 값 참조(refernce)를 사용하여 텐서 자료형 뷰(view)를 만든다.
In [2]:
li = np.array([[1, 2], [3, 4]])

li_tensor = torch.tensor(li)
li_as_tensor = torch.as_tensor(li)

print(li_tensor)
print(li_as_tensor)
tensor([[1, 2],
        [3, 4]])
tensor([[1, 2],
        [3, 4]])

torch.tensor() 명령으로 텐서를 만들거나 torch.as_tensor()에 ndarray가 아닌 리스트를 넣었을 때는 이러한 일이 발생하지 않는다.

NumPy 배열을 텐서로 바꿀 때는 torch.from_numpy() 함수를 쓸 수 있다.

In [3]:
arr = np.array([[1, 2], [3, 4]])

arr_tensor = torch.tensor(arr)
arr_as_tensor = torch.from_numpy(arr)
arr_from_numpy = torch.from_numpy(arr)

print(arr_tensor, arr_tensor.dtype)
print(arr_as_tensor, arr_as_tensor.dtype)
print(arr_from_numpy, arr_from_numpy.dtype)
tensor([[1, 2],
        [3, 4]]) torch.int64
tensor([[1, 2],
        [3, 4]]) torch.int64
tensor([[1, 2],
        [3, 4]]) torch.int64

반대로 텐서를 NumPy 배열로 바꿀 때는 torch.numpy() 메서드를 사용한다.

In [4]:
print(arr_tensor.numpy())
print(arr_as_tensor.numpy())
print(arr_from_numpy.numpy())
[[1 2]
 [3 4]]
[[1 2]
 [3 4]]
[[1 2]
 [3 4]]

torch.as_tensor()torch.from_numpy()는 원래의 ndarray 객체를 참조하므로 원래 ndarray 객체의 값을 바꾸면 텐서 자료형의 값도 바뀌고 반대로 텐서 자료형에서 원소의 값을 바꾸면 원래 ndarray 객체의 값도 바뀐다.

In [5]:
arr_as_tensor[0, 0] = 1000
arr
Out:
array([[1000,    2],
       [   3,    4]])
In [6]:
arr_from_numpy  # 같은 객체를 참조한다.
Out:
tensor([[1000,    2],
        [   3,    4]])
In [7]:
arr[0, 1] = 2000
arr_as_tensor
Out:
tensor([[1000, 2000],
        [   3,    4]])

랜덤한 값을 가지는 텐서 생성

랜덤 값으로 채워진 텐서를 생성하는 명령은 다음과 같다.

  • torch.rand() : 0과 1사이의 숫자를 균등하게 생성
  • torch.rand_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
  • torch.randn() : 평균이 0이고 표준편차가 1인 가우시안 정규분포를 이용해 생성
  • torch.randn_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
  • torch.randint() : 주어진 범위 내의 정수를 균등하게 생성, 자료형은 torch.float32
  • torch.randint_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
  • torch.randperm() : 주어진 범위 내의 정수를 랜덤하게 생성

랜덤 생성에 사용되는 시드(seed)는 torch.manual_seed() 명령으로 설정한다.

In [8]:
torch.manual_seed(0)

a = torch.rand(5)
b = torch.randn(5)
c = torch.randint(10, size=(5,))
d = torch.randperm(5)

print(a)
print(b)
print(c)
print(d)
tensor([0.4963, 0.7682, 0.0885, 0.1320, 0.3074])
tensor([ 0.5507,  0.2704,  0.6472,  0.2490, -0.3354])
tensor([8, 4, 3, 6, 9])
tensor([1, 3, 4, 2, 0])

특정한 값으로 초기화를 하지 않는 행렬을 만들 때는 torch.empty() 함수를 사용할 수 있다.

In [9]:
torch.empty(3, 4)
Out:
tensor([[0.0000e+00, 1.1824e+22, 7.7052e+31, 7.2148e+22],
        [2.5226e-18, 1.6898e-04, 1.0527e-11, 3.0880e-09],
        [1.0258e-08, 4.1656e-11, 2.5931e-09, 2.9571e-18]])

특정한 값의 텐서 생성하기

다음은 특정한 값으로 채워진 텐서를 생성하는 명령들이다.

  • torch.arange() : 주어진 범위 내의 정수를 순서대로 생성
  • torch.ones() : 주어진 사이즈의 1로 이루어진 텐서 생성
  • torch.zeros() : 주어진 사이즈의 0으로 이루어진 텐서 생성
  • torch.ones_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
  • torch.zeros_like() : 사이즈를 튜플로 입력하지 않고 기존의 텐서로 정의
  • torch.linspace() : 시작점과 끝점을 주어진 갯수만큼 균등하게 나눈 간격점을 행벡터로 출력
  • torch.logspace() : 시작점과 끝점을 주어진 갯수만큼 로그간격으로 나눈 간격점을 행벡터로 출력
In [10]:
torch.arange(1, 10)
Out:
tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])
In [11]:
torch.ones((2, 5))
Out:
tensor([[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]])
In [12]:
torch.zeros((3, 5))
Out:
tensor([[0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.]])
In [13]:
torch.linspace(0, 10, 5)
Out:
tensor([ 0.0000,  2.5000,  5.0000,  7.5000, 10.0000])

텐서 자료형 변환

텐서 내부의 데이터를 변환 할 때는 .type() 메서드를 사용한다. 다음 표는 PyTorch가 지원하는 자료형을 정리한 것이다. GPU tensor는 GPU 연산이 가능한 자료형을 뜻한다. GPU에 관련된 내용에서 자세히 설명한다.

Data type dtype CPU tensor GPU tensor
32-bit floating point torch.float32 또는 torch.float torch.FloatTensor torch.cuda.FloatTensor
64-bit floating point torch.float64 또는 torch.double torch.DoubleTensor torch.cuda.DoubleTensor
16-bit floating point torch.float16 또는 torch.half torch.HalfTensor torch.cuda.HalfTensor
8-bit integer (unsigned) torch.uint8 torch.ByteTensor torch.cuda.ByteTensor
8-bit integer (signed) torch.int8 torch.CharTensor torch.cuda.CharTensor
16-bit integer (signed) torch.int16 또는 torch.short torch.ShortTensor torch.cuda.ShortTensor
32-bit integer (signed) torch.int32 또는 torch.int torch.IntTensor torch.cuda.IntTensor
64-bit integer (signed) torch.int64 또는 torch.long torch.LongTensor torch.cuda.LongTensor
표 54.1: PyTorch 자료형
In [14]:
arr_tensor.dtype
Out:
torch.int64
In [15]:
arr_tensor.type(dtype=torch.int32)
Out:
tensor([[1, 2],
        [3, 4]], dtype=torch.int32)

텐서 형상 변환

텐서의 형상을 변환(reshape)하려면 .view() 함수를 사용한다.

In [16]:
t1 = torch.ones(4, 3)
t2 = t1.view(3, 4)
t3 = t1.view(12)

print(t1)
print(t2)
print(t3)
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]])
tensor([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

텐서의 차원을 늘리거나 줄일 때도 .view()함수를 쓴다.

In [17]:
t1.view(1, 3, 4)
Out:
tensor([[[1., 1., 1., 1.],
         [1., 1., 1., 1.],
         [1., 1., 1., 1.]]])

squeeze() 명령이나 unsqueeze()를 사용해도 차원을 변환할 수 있다. squeeze()함수는 차원의 원소가 1인 차원을 없애주고, unsqueeze()함수는 인수로 받은 위치에 새로운 차원을 삽입한다.

In [18]:
t4 = torch.rand(1, 3, 3)
t4.shape
Out:
torch.Size([1, 3, 3])
In [19]:
t4.squeeze()
Out:
tensor([[0.9527, 0.0362, 0.1852],
        [0.3734, 0.3051, 0.9320],
        [0.1759, 0.2698, 0.1507]])
In [20]:
t5 = torch.rand(3, 3)
t5.shape
Out:
torch.Size([3, 3])
In [21]:
t5.unsqueeze(0).shape
Out:
torch.Size([1, 3, 3])
In [22]:
t5.unsqueeze(1).shape
Out:
torch.Size([3, 1, 3])

복수의 텐서를 결합

복수의 텐서를 결합할 때는 torch.cat()을 사용한다.

In [23]:
a = torch.ones(2, 3)
b = torch.zeros(3, 3)

torch.cat([a, b], dim=0)
Out:
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])

텐서 분할

텐서를 여러개로 나눌 때는 torch.chunk(), torch.split() 명령을 사용한다.

In [24]:
c = torch.rand(3, 6)
c1, c2, c3 = torch.chunk(c, 3, dim=1)
print(c)
print(c1)
print(c2)
print(c3)
tensor([[0.1387, 0.2422, 0.8155, 0.7932, 0.2783, 0.4820],
        [0.8198, 0.9971, 0.6984, 0.5675, 0.8352, 0.2056],
        [0.5932, 0.1123, 0.1535, 0.2417, 0.7262, 0.7011]])
tensor([[0.1387, 0.2422],
        [0.8198, 0.9971],
        [0.5932, 0.1123]])
tensor([[0.8155, 0.7932],
        [0.6984, 0.5675],
        [0.1535, 0.2417]])
tensor([[0.2783, 0.4820],
        [0.8352, 0.2056],
        [0.7262, 0.7011]])
In [25]:
c1, c2 = torch.split(c, 3, dim=1)
print(c1)
print(c2)
tensor([[0.1387, 0.2422, 0.8155],
        [0.8198, 0.9971, 0.6984],
        [0.5932, 0.1123, 0.1535]])
tensor([[0.7932, 0.2783, 0.4820],
        [0.5675, 0.8352, 0.2056],
        [0.2417, 0.7262, 0.7011]])

텐서 연산

텐서 연산은 파이썬에서 사용하는 연산 기호를 사용하거나 torch의 함수를 사용한다.

  • torch.add: 덧셈
  • torch.sub: 뺄셈
  • torch.mul: 곱셉
  • torch.div: 나눗셈
  • torch.mm: 내적(dot product)
In [26]:
x = torch.from_numpy(np.array([[1, 2], [3, 4]]))
y = torch.from_numpy(np.array([[5, 6], [7, 8]]))

print(x + y)
print(torch.add(x, y))
print(x.add(y))
tensor([[ 6,  8],
        [10, 12]])
tensor([[ 6,  8],
        [10, 12]])
tensor([[ 6,  8],
        [10, 12]])
In [27]:
print(x * y)
print(torch.mul(x, y))
print(x.add(y))
tensor([[ 5, 12],
        [21, 32]])
tensor([[ 5, 12],
        [21, 32]])
tensor([[ 6,  8],
        [10, 12]])
In [28]:
print(torch.mm(x, y))
tensor([[19, 22],
        [43, 50]])

인플레이스 연산

명령어 뒤에 _ 를 붙이면 자기 자신의 값을 바꾸는 인플레이스(inplace) 명령이 된다. 인플레이스 명령은 연산 결과를 반환하면서 동시에 자기 자신의 데이터를 고친다.

In [29]:
x = torch.arange(0, 5)
z = torch.arange(1, 6)

print(x)
print(x.add_(z))
print(x)
tensor([0, 1, 2, 3, 4])
tensor([1, 3, 5, 7, 9])
tensor([1, 3, 5, 7, 9])

1개의 원소를 가진 Tensor를 Python의 Scalar로 만들 때는 .item()함수를 사용한다.

In [30]:
scl = torch.tensor(1)

print(scl.item())
1

질문/덧글

몇가지 오류가 있는것같아 질문드립니다. leey*** 2019년 3월 25일 2:07 오후

몇가지 오류가 있는것같아 질문드립니다.

1. In [2] Cell은 list를 tensor로 변형하는 과정을 보여주려고 하신것같은데, li가 list가 아닌 array로 되었네요 ㅜㅜ
2. In [3] Cell에서 'arr_as_tensor = torch.from_numpy(arr)'가 아니라 'arr_as_tensor = torch.as_tensor(arr)'를 쓰려고 하셨던것 아닌가요?
3. 'torch.tensor() 명령으로 텐서를 만들거나 torch.as_tensor()에 ndarray가 아닌 리스트를 넣었을 때는 이러한 일이 발생하지 않는다.' 이부분은 '배열과 리스트를 텐서 자료형으로 변환' section에서 제일 마지막 부분에 와야하는것 아닌가요?

항상 좋은 자료 잘 보고있습니다. 감사합니다.