Pytorch Basic(1)


pytorch 튜토리얼을 보고 개인적으로 정리하는 포스팅입니다

What is PyTorch?

두 청중에게 타겟팅한 도구

  • GPU에서 Numpy의 대체물
  • 굉장히 유연하고 빠르게 제공되는 딥러닝 연구 플랫폼

Tensors

Tensor들은 Numpy의 ndarrays와 유사하며 Tensor는 컴퓨팅 파워를 증가하기 위해 GPU를 사용할 수 있습니다

x = torch.Tensor(5, 3)
y = torch.rand(5, 3)
print(y.size())

Operations

연산에 대해 많은 문법이 있습니다 더하기에 대한 다양한 케이스를 보겠습니다

# 1
print(x + y)
# 2
print(torch.add(x, y))
# 3
result = torch.Tensor(5, 3)
torch.add(x, y, out=result)
print(result)
# 4
y.add_(x)
print(y)
  • _가 post-fixed된 연산들은 텐서를 대체합니다. x.copy_(y)는 x를 변경

인덱싱도 사용 가능합니다

print(x[:, 1])

Resize 텐서의 모양을 변경하고 싶을 경우 torch.view를 사용합니다

x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8)
print(x.size(), y.size(), z.size())

http://pytorch.org/docs/master/torch.html 위 문서에 다양한 연산들이 더 있으니 문서를 참고하면 좋을 것 같습니다

Numpy Bridge

Torch의 Tensor를 Numpy array로 변환 가능합니다

a = torch.ones(5)
b = a.numpy()
print(a)
print(b)
a.add_(1)
print(a)
print(b)

위 연산을 하면 a에 수정했는데 b도 값이 변해있습니다

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)

위 연산도 a와 b의 값이 동일

CUDA Tensors

.cuda method를 통해 Tensor들을 GPU로 보낼 수 있습니다

if torch.cuda.is_available():
	x = x.cuda()
	y = y.cuda()
	x + y

Autograd mechanics

이번 부분은 autograd가 어떻게 작동하고 operations이 어떻게 기록되는지에 대한 개론 부분입니다. 모든 것을 반드시 이해할 필요는 없지만 이 개념에 대해 친숙해지면 좋습니다. 이것을 효율적으로 사용할수록, 깨끗하고 효율적 프로그램을 작성할 수 있고 디버깅을 쉽게 도와줍니다

Excluding subgraphs from backward

모든 Variable은 2가지 flags를 가지고 있습니다. requires_gradvolatile. 둘 다 하위 그래프를 제외한 그래디언트 계산을 통해 효율성을 증가시킵니다

requires_grad

그라디언트가 필요한 Single Input이 있을 경우 이것의 output는 또한 그라디언트가 필요합니다. 반대로, 모든 input에 그래디언트가 필요하지 않은 경우엔 output 또한 필요하지 않습니다. 모든 변수들이 그래디언트가 필요하지 않다면 Backward 연산은 하위 그래프에서 이루어지지 않습니다

>>> x = Variable(torch.randn(5, 5))
>>> y = Variable(torch.randn(5, 5))
>>> z = Variable(torch.randn(5, 5), requires_grad=True)
>>> a = x + y
>>> a.requires_grad
False
>>> b = a + z
>>> b.requires_grad
True

당신의 모델의 부분을 고정하고 싶은 경우나 이미 그래디언트 값을 사용하지 않을 것을 알고 있을 경우 유용합니다. 예를 들어 pretrain된 CNN을 사용하고 싶을 경우, 고정하는 부분의 requires_grad를 바꿔주기만 하면 충분합니다.

model = torchvision.models.resnet18(pretrained=True)
for param in model.parameters():
    param.requires_grad = False
# Replace the last fully-connected layer
# Parameters of newly constructed modules have requires_grad=True by default
model.fc = nn.Linear(512, 100)

# Optimize only the classifier
optimizer = optim.SGD(model.fc.parameters(), lr=1e-2, momentum=0.9)

How Autograd encodes the history

Autograd는 reverse automatic differentiation system입니다. (역 자동 차별화 시스템?) 개념적으로 Autograd는 작업을 진행하면서 데이터를 생성한 모든 작업을 기록한 그래프를 기록합니다. 나뭇잎이 입력 변수고 루트가 출력 변수인 DAG 제공, 이 그래프를 뿌리부터 잎까지 추적하면 Chain Rulte을 통해 자동으로 그래디언트를 계산할 수 있습니다

내부적으로 autograd는 그래프를 Fucntion 객체의 그래프로 나타내며 apply()를 적용해 그래프를 평가한 결과를 계산할 수 있습니다. 전달 경로를 계산할 때 autograd는 요청된 계산을 동시에 수행하고 그라디언트를 계산하는 함수를 나타내는 그래프를 작성합니다. forwards pass가 완료되면 우리는 이 그래프를 backward pass를 통해 평가할 수 있습니다

주목할 것은 매번 이터레이션으로부터 매번 그래프가 재생성된다는 것이며 이것은 모든 반복에서 그래프의 전체 모양과 크기를 변경할 수 있는 Python 제어 흐름문을 사용할 수 있는 것입니다. Train전에 모든 경로를 인코딩할 필요는 없습니다!

In-place operations on Variables

autograd에 있는 대체 연산은 제공되지만 대부분 권장하지 않습니다. Autograd의 공격적인 버퍼 해제 및 재사용은 매우 효율적이기 때문에 내부 작업으로 메모리 사용량이 감소할 경우가 없습니다. 과도한 메모리 사용량이라면 inplace를 사용하고 아니라면 사용하지 않으면 됨

제한하는 이유는 2가지가 있습니다

  1. 그라디언트를 계산하는데 필요한 값을 덮어쓰기 때문에 수치적으로 불안정할 수 있습니다. 추가 작업이 필요할 것입니다
  2. inplace 연산은 그래프를 다시 작성해야 합니다. 동일한 저장 영역을 참조하는 변수가 여러개면 내부 오류 기능이 생길 수 있습니다

이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)




© 2017. by Seongyun Byeon

Powered by zzsza