1. Parameter란
정의로는 매개변수, 머신러닝에서는 모델이 사용할 수 있는 매개변수를 모델 내부에서 저장하는 것을 말한다. 일반적인 변수 지정 방식으로는 모델에서 반복적으로 로드할 수 없기 때문에 torch.nn.parameter.Parameter를 사용하여 torch 내부에 저장한다.
2. 모델 내부에서 Parameter 사용
import torch
from torch import nn
from torch.nn.parameter import Parameter
class Model_Param(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.W = Parameter(torch.ones((out_features, in_features)),requires_grad=True)
self.b = Parameter(torch.ones((out_features)),requires_grad=True)
def forward(self, x):
output = torch.addmm(self.b, x, self.W.T)
return output
class Model_Tensor(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
# torch.Tensor
self.W = torch.ones((out_features, in_features))
self.b = torch.ones(out_features)
def forward(self, x):
output = torch.addmm(self.b, x, self.W.T)
return output
매개변수를 Parameter로 선언한 모델과 일반 텐서로 선언한 모델의 코드이다.
x = torch.Tensor([[1, 2],
[3, 4]])
Model_param = Model_Param(2, 3)
Model_tensor = Model_Tensor(2, 3)
output_param = Model_param(x)
output_tensor = Model_tensor(x)
print(output_param)
>> tensor([[4., 4., 4.],
[8., 8., 8.]], grad_fn=<AddmmBackward0>)
print(output_tensor)
>> tensor([[4., 4., 4.],
[8., 8., 8.]])
또, Parameter() 내부에 requires_grad=True를 명시해두면 해당 parameter도 역전파의 대상이 되어 gradient를 계산하고 업데이트 가능하게 된다. 반면에 Model_Tensor에서처럼 일반 tensor로 선언해둔 항목에 대해서는 gradient가 계산되지 않는다.
model_param.state_dict()
>> OrderedDict([('W', tensor([[1., 1.],
[1., 1.],
[1., 1.]])), ('b', tensor([1., 1., 1.]))])
model_tensor.state_dict()
>> OrderedDict()
Parameter로 선언했을 경우 모델 내부에 값이 저장된다. 이는 모델의 학습과정에서 반복적으로 호출될 수 있으며, gradient를 통해 업데이트 가능하다는 말과 같다.
반면에 일반 텐서로 선언했을 경우, 모델 내부에 저장되지 않으므로 반복적으로 호출이 될 수 없다.
이와 유사한 개념으로는 buffer가 있다.
buffer는 parameter와 유사하게 모델 내부에 값이 저장되지만, gradient를 계산하지 않고 업데이트도 되지 않는다.
class Model(nn.Module):
def __init__(self):
super().__init__()
self.parameter = Parameter(torch.Tensor([6]))
self.tensor = torch.Tensor([7])
self.register_buffer('buffer',self.tensor)
model = Model()
buffer = model.get_buffer('buffer')
print(buffer)
>> tensor([7.])
print(model.state.dict())
>> OrderedDict([('parameter', tensor([6.])), ('buffer', tensor([7.]))])
위와 같이 self.register_buffer를 통해 'buffer'라는 이름으로 self.tensor를 저장하면, model.get_buffer('buffer')를 통해 값을 호출할 수 있다. 또, model.state.dict()를 확인해보면 buffer가 저장되어 있는 것을 볼 수 있다. 이때, buffer 값에 requires_grad가 없으므로 buffer는 업데이트 대상이 아니라는 것도 확인할 수 있다.
'DS | Data Science > ML | Machine Learning' 카테고리의 다른 글
[Pytorch] hook & apply (0) | 2022.09.28 |
---|---|
[Gradient] Autograd - .backward(gradient = external_grad) (0) | 2022.09.28 |
[Pytorch] 파이토치 연산자 : 사칙연산, 인덱싱 (0) | 2022.09.28 |
[ML/DL] SOTA가 뭔가요 (0) | 2022.09.23 |
[RNN] Recurrent Neural Network : 순환신경망 (2) | 2022.09.23 |