본문 바로가기

boostcamp AI tech/boostcamp AI

PyTorch Basics

728x90

- pytorch의 핵심은 auto grad이다. 자동으로 미분을 해준다.

w = torch.tensor(2.0, requires_grad=True)
y = w**2
z = 10*y + 50
z.backward()
print(w.grad)    # dz/dw = 40
a = torch.tensor([2., 3.], requires_grad=True)
b = torch.tensor([2., 3.], requires_grad=True)
Q = 3*a**3 - b**2
external_gradient = torch.tensor([1,1])
Q.backward(gradient = external_gradient)    # 변수가 a,b두개 이므로 external_gradient추가
print(a.grad)   # [36, 81]

- 이렇게 직접 requires_grad=True를 해서 tensor를 정의하는 일은 자주 있지는 않지만 이미 구현된 많은 모델층이 다 알아서 해준다고 소홀히 이해해서는 안된다.

- a,b같은 경우는 [2.,3.]만을 저장하지 않는다. loss.backward시에 자동미분을 하면서 gradient=external_gradient로 전달 받은 parameter에 대해서 각각 미분한 값들을 저장하기위한 공간을 추가로 잡는다.

- 위의 예시에서 Q.backward() 했을때 Q를 a에 대해 미분한 값, b에 대해 미분한 값을 a.grad, b.grad 에 기록한다.

- 따라서 tensor의 값을 가져오고 싶다면 .detach()를 통해 가져오자


- pytorch는 tensor를 사용한다. numpy array 혹은 list를 가지고 바로 생성이 가능하며 numpy와 많은 면에서 거의 같다.

- tensor_x.device, tensor_x.to('cuda'), torch.cuda_is_available()


- view vs. reshape : view는 contiguous하지 않은 tensor의 차원변환을 못한다. https://jimmy-ai.tistory.com/151

    - view 사용 권장


- squeeze, unsqueeze

    - 2d tensor [[1,2],[3,4]], (2,2)

    - unsqueeze(0)  -> (1,2,2)  -> squeeze()  -> (2,2)

    - unsqueeze(1)  -> (2,1,2)  -> squeeze()  -> (2,2)

    - unsqueeze(2)  -> (2,2,1)  -> squeeze()  -> (2,2)


- mm, matmul  vs. dot

    - matrix 행렬곱 시에는 mm, matmul

    - matmul은 broadcasting 지원(batch연산 때 유용), mm은 지원하지 않음

    - 1d-tensor, 벡터 혹은 스칼라 연산시에는 dot 사용 (내적 계산시, np.inner()와 같이 동작)

    - mm사용 권장

t1 = torch.tensor(np.zeros((3,2)))
t2 = torch.tensor(np.zeros((2,3)))

t2.mm(t1)
t2.matmul(t1)
t2.dot(t1)  # error, expect 1D tensor

indexing

- torch.einsum() : 거의 모든 연산을 구현할 수 있다. 배치 단위의 텐서 계산에 유용 ex 곱, 합, 전치 등

- torch.scatter_() : src의 element 일부를 dst에 원하는 곳에 copy

- torch.gather() : 원하는 위치의 element만 가져오기


Container

nn.ModuleDict : dictionary 형태로 모듈들을 저장. print(module) 하면 moduleDict도 같이 출력 됨

nn.Sequential : 여러 모듈 묶어서 순차 실행 가능하게 함

nn.ModuleList : list형태로 모듈들 저장, print(module) 하면 moduleList도 같이 출력 됨


Parameters

- 모듈의 학습 가능한 파라미터 정의, required_grad=True, backward시에 gradient 자동계산

- 모델 안에서 Parameter declare : gradient 계산, 값 업데이트, 모델 저장 시 값 저장

- 모델 안에서 tensor declare : x, x, x

- 모델 안에서 buffer declare : x, x, 모델 저장 시 값 저장

- named_parameters() : 모델의 파라미터들

- parameters() : 모델의 파라미터들

- named_buffers() : 모델의 버퍼들

- get_parameter('target') : target 이름의 파라미터 반환

- register_buffer() : 버퍼에 추가

- 모듈.state_dict() : 파라미터, 버퍼 출력

- 만약 self.W, self.b가 있다면 : 텐서 접근(model.W, model.b), 값 접근(model.W.data, model.b.data)

- 모듈.__dict__ : 모듈 정보 dict으로 반환


submodule

- 모델이 어떤 구조인지 print해볼 수 있다.

- modules() : 모든 submodule들 반환

- children() : 한 단계 아래 submodule들 반환

- named_modules() : 이름과 함께 한 모든 submodule들 반환

- named_children() : 이름과 함께 한 단계 아래 submodule들 반환

- get_submodule('target') : target 이름의 submodule 반환


hook

- nn.Module에는 hook을 사용할 수 있는 공간이 만들어져 있다.

- 우리는 거기에 hook을 등록해서 이미 만들어진 module의 custom이 가능하다.

- 내부를 들여다 볼 수 없는 모델의 forward, backward 과정에서 값들을 관찰할 수 있다.

- 모델 파라미터에 register_hook을 걸면 해당 파라미터의 값, 그라디언트도 관찰할 수 있다.

- 심지어 어떤 값을 변화시키거나 forward 연산식도 바꿀 수 있다.

- register_forward_pre_hook : (module : forward)

- register_forward_hook : (module : forward)

- register_hook : (tensor : backward)

- register_full_backward_hook (module : backward)


apply

- 변화를 모든 하위 모듈들에게 적용

- ex1. 이미 있는 model에 새로운 파라미터를 추가

- ex2. 이미 있는 model의 파라미터 값 변경 (ex, weight initialization)

- ex3. hook과 함께 활용하면 module의 forward, backward시에 연산식 변경

- ex4. 모듈에 어떤 method 추가 (ex, print method)

- ex5. hook 추가

- extra_repr(self) : module에 extra information을 추가. repr(model) 했을 때, 모델 출력 시 나오는 repr 변경


* functools.partial

728x90
반응형

'boostcamp AI tech > boostcamp AI' 카테고리의 다른 글

Model save, load & Transfer Learning  (0) 2023.11.15
PyTorch Project  (0) 2023.11.13
Maximum Likelihood Estimation  (0) 2023.11.12
Bayes Theorem  (0) 2023.11.10
BPTT for RNN  (0) 2023.08.26