- 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
'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 |