본 포스트는 이수안컴퓨터연구소님의 파이토치 한번에 끝내기 PyTorch Full Tutorial Course 강의를 듣고 작성되었습니다.
- 페이스북이 초기 루아(Lua) 언어로 개발된 토치(Torch)를 파이썬 버전으로 개발하여 2017년도에 공개
- 초기에 토치(Torch)는 넘파이(NumPy) 라이브러리처럼 과학 연산을 위한 라이브러리로 공개
- 이후 GPU를 이용한 텐서 조작 및 동적 신경망 구축이 가능하도록 딥러닝 프레임워크로 발전시킴
torch
: 메인 네임스페이스, 텐서 등의 다양한 수학 함수가 포함torch.autograd
: 자동 미분 기능을 제공하는 라이브러리torch.nn
: 신경망 구축을 위한 데이터 구조나 레이어 등의 라이브러리torch.multiprocessing
: 병럴처리 기능을 제공하는 라이브러리torch.optim
: SGD(Stochastic Gradient Descent)를 중심으로 한 파라미터 최적화 알고리즘 제공torch.utils
: 데이터 조작 등 유틸리티 기능 제공torch.onnx
: ONNX(Open Neural Network Exchange), 서로 다른 프레임워크 간의 모델을 공유할 때 사용
x = torch.empty(4,2)
tensor([[-6.1985e+32, 4.5848e-41],
[ 1.6558e+01, 0.0000e+00],
[ 4.4842e-44, 0.0000e+00],
[ 1.7937e-43, 0.0000e+00]])
x = torch.rand(4,2)
tensor([[0.1663, 0.9950],
[0.8520, 0.5015],
[0.7387, 0.0313],
[0.8601, 0.9957]])
x = torch.zeros(4,2, dtype = long)
tensor([[0, 0],
[0, 0],
[0, 0],
[0, 0]])
x = torch.tensor([3,2,3])
tensor([3.0000, 2.3000])
x = x.new_ones(2,4, dtype = torch.double)
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.]], dtype=torch.float64)
# end만 지정
a = torch.arange(5)
# start, end 지정
a = torch.arange(2, 6)
# start, end, step 모두 지정
a = torch.arange(1, 10, 2)
tensor([0, 1, 2, 3, 4])
tensor([2, 3, 4, 5])
tensor([1, 3, 5, 7, 9])
x = torch.randn_like(x, dtype = torch.float)
tensor([[-0.1523, -0.0642, -0.3455, -0.2723],
[ 1.3314, 1.1569, -0.0211, 0.8774]])
print(x.size())
torch.Size([2, 4])
# float type
ft = torch.FloatTensor([1,2,3])
print(ft)
# type 변환
print(ft.short())
print(ft.int()) # dtype=torch.int16
print(ft.long()) # dtype=torch.int32
tensor([1., 2., 3.])
tensor([1, 2, 3], dtype=torch.int16)
tensor([1, 2, 3], dtype=torch.int32)
tensor([1, 2, 3])
# int type
it = torch.IntTensor([1,2,3])
print(it)
# type 변환
print(it.float())
print(it.double()) # dtype=torch.float64
print(it.half()) # dtype=torch.float16
tensor([1, 2, 3], dtype=torch.int32)
tensor([1., 2., 3.])
tensor([1., 2., 3.], dtype=torch.float64)
tensor([1., 2., 3.], dtype=torch.float16)
x = torch.randn(1)
# cuda가 가능하면(is_available()) gpu, 안되면 cpu로 자동 연결
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
cuda
.to
이용해서 device 보냄# 기존 x 모양으로 1로 전부 차있는 것에 device 정의
y = torch.ones_like(x, device = device)
print(y)
# 랜덤으로 선언했던 x 텐서를 device로 보냄
x = x.to(device)
# z를 cpu로 옮기고 type은 double(float64)로 지정
z = x+y
print(z)
print(z.to('cpu', dtype = tensor.double))
tensor([1.], device='cuda:0')
tensor([2.0479], device='cuda:0')
tensor([3.0479], device='cuda:0')
tensor([3.0479], dtype=torch.float64)
t0 = torch.tensor(0)
print(t0.ndim) # 차원
print(t0.shape) # 크기
print(t0) # 실제값
0
torch.Size([])
tensor(0)
t1 = torch.tensor([1,2,3])
print(t1.ndim)
print(t1.shape)
print(t1)
1
torch.Size([3])
tensor([1, 2, 3])
t2 = torch.tensor([[1,2,3],
[4,5,6],
[7,8,9]])
print(t2.ndim)
print(t2.shape)
print(t2)
2
torch.Size([3, 3])
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
t3 = torch.tensor([[[1,2,3],
[4,5,6],
[7,8,9]],
[[1,2,3],
[4,5,6],
[7,8,9]],
[[1,2,3],
[4,5,6],
[7,8,9]]])
print(t3.ndim)
print(t3.shape)
print(t3)
3
torch.Size([3, 3, 3])
tensor([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]])
import math
a = torch.rand(1,2) * 2 - 1
torch.abs(a)
: 절댓값torch.ceil(a)
: 반올림torch.floor(a)
: 반내림torch.clamp(a, -0.5,0.5)
: 최대최소를 찝어버린다 (clamp)torch.min(a)
: 최소torch.max(a)
: 최대torch.mean(a)
: 평균torch.std(a)
: 분산torch.prod(a)
: 곱torch.unique(torch.tensor([1,2,3,1,2,2]))
: 종류(1.1) dim 인자(max,min) : argmax,argmin 리턴
x = torch.rand(2,2)
print(x)
print(x.max(dim = 0)) # dim=0 : 열 기준 , max() : 더 큰 인덱스
print(x.min(dim = 1)) # dim=1 : 행 기준 , max() : 더 큰 인덱스
tensor([[0.7574, 0.0808],
[0.0846, 0.1804]])
torch.return_types.max(
values=tensor([0.7574, 0.1804]),
indices=tensor([0, 1]))
torch.return_types.max(
values=tensor([0.7574, 0.1804]),
indices=tensor([0, 1]))
x = torch.rand(2,2)
y = torch.rand(2,2)
torch.add(x,y)
: 덧셈
torch.sub(x,y)
: 뺄셈
torch.mul(x,y)
: 곱셈
torch.div(x,y)
: 나눗셈
torch.mm(x,y)
: 내적
## 내적 예시
print(x)
print(y)
print(torch.matmul(x,y))
z = torch.mm(x,y)
print(z)
print(torch.svd(z)) # U,S,V 로 기존의 행렬 값을 분해
tensor([[0.7431, 0.2229],
[0.9548, 0.4806]])
tensor([[0.8347, 0.3137],
[1.3998, 0.7706]])
tensor([[0.9323, 0.4049],
[1.4698, 0.6699]])
tensor([[0.9323, 0.4049],
[1.4698, 0.6699]])
torch.return_types.svd(
U=tensor([[-0.5326, -0.8464],
[-0.8464, 0.5326]]),
S=tensor([1.9084, 0.0154]),
V=tensor([[-0.9120, -0.4101],
[-0.4101, 0.9120]]))
result = torch.empty(2,4)
torch.add(x,y, out = result)
print(result)
x.t_()
print(x)
print(y)
y.add_(x) # _ : inplace => 'x 더한 값'을 y로 다시 지정
print(y)
tensor([[0.7431, 0.2229],
[0.9548, 0.4806]])
tensor([[0.0917, 0.0908],
[0.4450, 0.2899]])
tensor([[0.8347, 0.3137],
[1.3998, 0.7706]])
## 텐서의 특정 위치 값 가져오는 법
x = torch.Tensor([[1,2],
[3,4]])
print(x)
# 행렬 위치로 값 추출
print(x[0,0])
print(x[0,1])
print(x[1,0])
print(x[1,1])
# 슬라이싱
print(x[:,0]) # 행은 다 선택하면서 0번째 컬럼 선택
print(x[:,1])
print(x[0,:]) # 열을 슬라이싱하고 행을 선정
print(x[1,:])
tensor([[1., 2.],
[3., 4.]])
tensor(1.)
tensor(2.)
tensor(3.)
tensor(4.)
tensor([1., 3.])
tensor([2., 4.])
tensor([1., 2.])
tensor([3., 4.])
view
x = torch.randn(4,5)
y = x.view(20) # 20개가 나열된 형태로 변경되어 출력
z = x.view(5,-1) # 행 5개, -1 : 나머지는 알아서 계산해서 넣어 # 5,4로 출력됨
tensor([[ 0.1870, 0.6372, 0.2561, -1.3911, 0.8974],
[ 0.8734, 0.5315, -0.4903, -0.4616, -0.3950],
[ 0.4581, -0.1911, -1.6286, 0.5659, -1.8072],
[-1.9535, 0.2897, -0.4601, 0.5018, 1.1456]])
tensor([ 0.1870, 0.6372, 0.2561, -1.3911, 0.8974, 0.8734, 0.5315, -0.4903,
-0.4616, -0.3950, 0.4581, -0.1911, -1.6286, 0.5659, -1.8072, -1.9535,
0.2897, -0.4601, 0.5018, 1.1456])
tensor([[ 0.1870, 0.6372, 0.2561, -1.3911],
[ 0.8974, 0.8734, 0.5315, -0.4903],
[-0.4616, -0.3950, 0.4581, -0.1911],
[-1.6286, 0.5659, -1.8072, -1.9535],
[ 0.2897, -0.4601, 0.5018, 1.1456]])
item
x = torch.randn(1)
print(x)
print(x.item())
print(x.dtype)
tensor([-1.7272])
-1.7272114753723145
torch.float32
tensor = torch.rand(1,3,3)
print(tensor.shape)
t = tensor.squeeze()
print(t.shape)
torch.Size([1, 3, 3])
torch.Size([3, 3]) ## 차원이 축소됨
tensor = torch.rand(3,3)
print(tensor.shape)
t = tensor.unsqueeze(dim=0)
print(t.shape)
torch.Size([3, 3])
torch.Size([1, 3, 3]) #첫번째 차원을 기준으로 차원이 증가됨
stack
x = torch.FloatTensor([1,4])
y = torch.FloatTensor([2,5])
z = torch.FloatTensor([3,6])
# 텐서 결합
print(torch.stack([x,y,z]))
tensor([[1., 4.],
[2., 5.],
[3., 6.]])
cat
stack
과 유사하지만 쌓을 dim
존재a = torch.randn([1,3,3])
b = torch.randn([1,3,3])
## 차원 기준 텐서 결합 (첫번째 차원)
c = torch.cat((a,b), dim = 0) # dim=0 : 첫번째 차원을 기준으로 결합
print(c)
print(c.size()) # 결과 : torch.Size([2, 3, 3])
tensor([[[ 1.7086, 1.7309, 1.4096],
[ 0.0378, -0.8366, 1.3575],
[ 0.7722, -0.5331, -0.2113]],
[[-0.3134, 1.9430, 1.1301],
[ 0.3056, 1.4749, 1.5296],
[ 0.7489, 0.9423, 0.2366]]])
torch.Size([2, 3, 3])
c = torch.cat((a,b), dim=1) # dim=1 : 두번째 차원을 기준으로 결합
print(c)
print(c.size()) # 결과 : torch.Size([1, 6, 3])
tensor([[[ 1.7086, 1.7309, 1.4096],
[ 0.0378, -0.8366, 1.3575],
[ 0.7722, -0.5331, -0.2113],
[-0.3134, 1.9430, 1.1301],
[ 0.3056, 1.4749, 1.5296],
[ 0.7489, 0.9423, 0.2366]]])
torch.Size([1, 6, 3])
c = torch.cat((a,b), dim=2) # dim=2 : 세번째 차원을 기준으로 결합
print(c)
print(c.size()) # 결과 : torch.Size([1, 3, 6])
tensor([[[ 1.7086, 1.7309, 1.4096, -0.3134, 1.9430, 1.1301],
[ 0.0378, -0.8366, 1.3575, 0.3056, 1.4749, 1.5296],
[ 0.7722, -0.5331, -0.2113, 0.7489, 0.9423, 0.2366]]])
torch.Size([1, 3, 6])
chunk
tensor = torch.rand(3,6)
print(tensor)
t1,t2,t3 = torch.chunk(tensor, 3, dim=1)
# 첫번쨰 차원을 기준으로 3개로 나눔
print(t1)
print(t2)
print(t3)
tensor([[0.5286, 0.2108, 0.0335, 0.2943, 0.8410, 0.4693],
[0.3923, 0.1196, 0.1436, 0.3561, 0.2415, 0.0414],
[0.9088, 0.4601, 0.1271, 0.7551, 0.6036, 0.3934]])
tensor([[0.5286, 0.2108],
[0.3923, 0.1196],
[0.9088, 0.4601]])
tensor([[0.0335, 0.2943],
[0.1436, 0.3561],
[0.1271, 0.7551]])
tensor([[0.8410, 0.4693],
[0.2415, 0.0414],
[0.6036, 0.3934]])
split
tensor = torch.rand(3,6)
t1, t2 = torch.split(tensor, 3, dim=1)
print(tensor)
print(t1)
print(t2)
tensor([[0.0883, 0.4678, 0.1435, 0.6052, 0.9097, 0.4505],
[0.3931, 0.1826, 0.0384, 0.2358, 0.7419, 0.0266],
[0.3956, 0.3721, 0.3204, 0.4135, 0.3338, 0.3091]])
tensor([[0.0883, 0.4678, 0.1435],
[0.3931, 0.1826, 0.0384],
[0.3956, 0.3721, 0.3204]])
tensor([[0.6052, 0.9097, 0.4505],
[0.2358, 0.7419, 0.0266],
[0.4135, 0.3338, 0.3091]])