꺼내먹는지식 준
Pytorch nn.Module 총정리 / 모델 만드는 법 본문
nn.Module
nn.Module 클래스는 여러 기능들을 한 곳에 모아놓는 상자 역할을 한다.
nn.Module 내부에는 여러 nn.Module 상자를(nn.Linear ..) 포함할 수도 있다.
nn.Module 상자는 설계자의 의도대로 아래의 예시와 같이 다양하게 사용될 수 있다.
1) nn.Module이라는 상자에 기능들을 가득 모아놓은 경우 basic building block
2) nn.Module이라는 상자에 basic building block인 nn.Module들을 가득 모아놓은 경우 딥러닝 모델
3) nn.Module이라는 상자에 딥러닝 모델인 nn.Module들을 가득 모아놓은 경우 더욱 큰 딥러닝 모델
Pytoch Official 사이트는 다음과 같이 설명한다.
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes:
super(Model, self).__init__()
- 자식클래스에서 부모클래스의 내용을 사용하고 싶은 경우
- nn.Module 상속, overriding 되지 않기 위해서 super 사용
- https://velog.io/@gwkoo/%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%83%81%EC%86%8D-%EB%B0%8F-super-%ED%95%A8%EC%88%98%EC%9D%98-%EC%97%AD%ED%95%A0
클래스 상속 및 super 함수의 역할
파이썬 클래스 상속 및 super 함수의 역할에 대해 정리해 보았습니다.
velog.io
Sequeantial
모듈(Module)들을 하나로 묶어 순차적으로 실행시키고 싶을때 torch.nn.Sequential를 사용
더 자세히 개념을 이해하고 싶으면, Official 사이트에 올라온 개념을 읽어보자.
A sequential container. Modules will be added to it in the order they are passed in the constructor. Alternatively, an OrderedDict of modules can be passed in. The forward() method of Sequential accepts any input and forwards it to the first module it contains. It then “chains” outputs to inputs sequentially for each subsequent module, finally returning the output of the last module.
The value a Sequential provides over manually calling a sequence of modules is that it allows treating the whole container as a single module, such that performing a transformation on the Sequential applies to each of the modules it stores (which are each a registered submodule of the Sequential).
What’s the difference between a Sequential and a torch.nn.ModuleList? A ModuleList is exactly what it sounds like–a list for storing Module s! On the other hand, the layers in a Sequential are connected in a cascading way.
간단 예제
#y = x + 3 + 2 + 5
import torch
from torch import nn
class Add(nn.Module):
def __init__(self, value):
super().__init__()
self.value = value
def forward(self, x):
return x + self.value
calculator = nn.Sequential(
Add(3),
Add(2),
Add(5),
)
x = torch.tensor([1])
output = calculator(x)
if output == 11:
print("Success")
else:
print("Fail")
#Success
foward() 함수는 모델이 학습데이터를 입력받아서 forward 연산을 진행시키는 함수이다.
forward() 함수는 model 객체를 데이터와 함께 호출하면 자동으로 실행이된다.
예를 들어 model이란 이름의 객체를 생성 후, model(입력 데이터)와 같은 형식으로 객체를 호출하면 자동으로 forward 연산이 수행된다.
해당 문제에서는 calculator(x) 로 x 데이터와 함께 model 객체를 생성하자,
forward 가 연속적으로 작동되어 y = x + 3 + 2 + 5가 동작되었다.
ModuleList
파이썬의 list처럼 모아두기만 하고 그때그때 원하는 것만 인덱싱(indexing)을 통해 쓰는방법
#y = ((x + 3) + 2) + 5
import torch
from torch import nn
class Add(nn.Module):
def __init__(self, value):
super().__init__()
self.value = value
def forward(self, x):
return x + self.value
class Calculator(nn.Module):
def __init__(self):
super().__init__()
self.add_list = nn.ModuleList([Add(2), Add(3), Add(5)])
def forward(self, x):
for i, l in enumerate(self.add_list):
x = l(x)
return x
x = torch.tensor([1])
calculator = Calculator()
output = calculator(x)
print(output)
if output == 11:
print("Success")
else:
print("Fail")
for 문을 도는 l 에 Add(2) , Add(3), Add(5) 가 해당되기에 어떻게 사용해야하나 햇갈렸다.
add = Add(x)
add(2); add(3); add(5)
이렇게 혹은 sequential 로 연속 동작이 아니어도, 해결 방법이 다음과 같다.
l(x) 하면 동작한다.
즉, Add(n)(x) 가 동작한다는 것인데,
class Add(nn.Module):
def __init__(self, value):
super().__init__()
self.value = value
def forward(self, x):
return x + self.value
x = torch.tensor([1])
output = Add(2)(x)
print(output)
#3
실제로 바로 initialize 되고, forward가 동작한다.
나중에 시간 될 때 코드를 뜯어보자.
*list 를 두고 ModuleList 를 쓰는 이유는,
list 를 컨테이너 방식으로 neural net의 구성요소를 담고자 하면, nn.Module의 파라미터로 등록이 되어야 하기 때문에, 무조건 nn.ModuleList를 사용해야 한다.
Parameters
nn.Module안에 미리 만들어진 tensor들을 보관할 수 있다
import torch
from torch import nn
from torch.nn.parameter import Parameter
class Linear(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.W = torch.nn.Parameter(torch.ones(3,2))
self.b = torch.nn.Parameter(torch.ones(2,3))
def forward(self, x):
output = torch.addmm(self.b, x, self.W.T)
return output
x = torch.Tensor([[1, 2],
[3, 4]])
linear = Linear(2, 3)
output = linear(x)
if torch.all(output == torch.Tensor([[4, 4, 4],
[8, 8, 8]])):
print("Success")
else:
print("Fail")
Buffer
Parameter vs Torch vs Buffer
Tensor
: gradient 계산 X 값 업데이트 X 모델 저장시 값 저장 X
Parameter
: gradient 계산 O 값 업데이트 O 모델 저장시 값 저장 O
Buffer
: gradient 계산 X 값 업데이트 X 모델 저장시 값 저장 O
import torch
from torch import nn
from torch.nn.parameter import Parameter
class Model(nn.Module):
def __init__(self):
super().__init__()
self.parameter = Parameter(torch.Tensor([7]))
self.tensor = torch.Tensor([7])
self.register_buffer('buffer', self.tensor)
model = Model()
buffer = model.get_buffer('buffer')
if buffer == 7:
print("Success")
print(model.state_dict())
nn.Module 분석
1) 모델 분석
2) 모델 수정
'AI > PyTorch' 카테고리의 다른 글
Tensorboard, Weight & Biases 간단 사용 (0) | 2022.01.26 |
---|---|
Transfer Learning 듀토리얼 - (1) 모델 저장, checkpoint, 불러오기 (0) | 2022.01.26 |
Torch Math Operations (0) | 2022.01.25 |
Torch Tensors (0) | 2022.01.25 |
Torch Indexing (0) | 2022.01.25 |