Pytorch 딥러닝 모델 구현에 필요한 기초 지식
[Reference]
Blog
Python Class에 대하여 간략하게(self의 개념, 상속의 개념) 알고있다고 생각하고 진행하는 설명글입니다
- 딥러닝 모델을 구현하기위해 Pytorch를 구현하다보면,
- 대충 Python 문법에 대한 지식, Class에 대한건 알겠는데
- 왜 아래의 코드들같이 구현하는지 의문이 들 때가 있다
- 그럴때를 위해 간단한 몇가지 기초 개념에 대해 정리해보았다
목차
용어 정리
- Overide: 재정의 / 부모클래스에 있는 메소드(함수)를 자식클래스에서 따로 메소드를 제작하는 것
__dict__
: 네임스페이스 내에 저장되어있는 변수와 값을 Dictionary 형태로 표현
설명
1. Class 상속
super().__init__() 은 왜 사용하는 것일까?
import torch
import torch.nn as nn
class ConvBlock(nn.Module):
def __init__(self, kernel_size, stride, padding, pool, pool_stride):
super().__init__() # 또는 super().__init__(ConvBlock, self)
self.kernel_size = kernel_size
self.stride = stride
self.padding = padding
self.pool = pool
self.pool_stride = pool_stride
self.conv_block = nn.Sequential(
nn.Conv2d(3,16,kernel_size=self.kernel_size,stride=self.stride,padding=self.padding),
nn.BatchNorm2d(16),
nn.ReLU(),
nn.MaxPool2d(self.pool, self.pool_stride)
)
ConvBlock Class를 선언할때에 인자로 nn.Module을 받는다.
생성자(
__init__()
)안에super().__init__()
을 사용하고 있으므로nn.Module Class를 부모 Class로 상속받겠다는 의미
상속을 받게되면, nn.Module의 class의 멤버변수와 메소드를 이용할 수 있게되는건 알겠는데
다음과 같은 질문이 생긴다
- 어떨때
super().__init__()
를 사용하고, 어떨때super().__init__(class이름, self)
를 이용하는가? - 왜 nn.Module를 상속받을까?
- 어떨때
1-1. super().__init__()
VS super().__init__(class이름, self)
부모(parent) Class를 Initialization 하여, 부모 클래스의 변수와 메소드를 가져온다
super().__init__()
으로도 가능하지만super().__init__(class이름, self)
를 사용하여- Class이름과 self를 이용하여 현재 클래스가 어떤 클래스인지 명확하게 표시 해 줄 수 있다
nn.Module
을 상속 받고나면,__init__
과forward
메서드는 Overide 해줘야 한다
1-2. nn.Module을 사용하는 이유
- nn.Module은 Neural Network Class들이 있는 nn에서 가장 Base가 되는 Class
- 즉, Neural Network Class들의 부모 Class가 nn.Module이다.
- 따라서 Neural Network Class들을 이용하기전에는 꼭 nn.Module을 상속받아야한다
클래스 내에서 다음과 같이
nn.Linear(input_size, output_size)
를 실행하면class LR(nn.Module): def __init__(self, input_size, output_size): super(LR, self).__init__() self.test = 1 self.linear = nn.Linear(input_size, output_size)
nn.Module에 있는
__setattr__
메서드를 실행하게 됨def __setattr__(self, name: str, value: Union[Tensor, 'Module']) -> None: # [...] modules = self.__dict__.get('_modules') if isinstance(value, Module): if modules is None: raise AttributeError("cannot assign module before Module.__init__() call") remove_from(self.__dict__, self._parameters, self._buffers, self._non_persistent_buffers_set) modules[name] = value
__setattr__
메서드는value = (nn.Linear)
가nn.Module
의 Instance인 경우,modules = _modules라는 속성
이 없는 경우,AttributeError: cannot assign module before Module.__init__() call
에러 출력def __init__(self): """ Initializes internal Module state, shared by both nn.Module and ScriptModule. """ torch._C._log_api_usage_once("python.nn_module") self.training = True self._parameters = OrderedDict() self._buffers = OrderedDict() self._non_persistent_buffers_set = set() self._backward_hooks = OrderedDict() self._forward_hooks = OrderedDict() self._forward_pre_hooks = OrderedDict() self._state_dict_hooks = OrderedDict() self._load_state_dict_pre_hooks = OrderedDict() self._modules = OrderedDict() ## _modules 선언 및 초기화
- 이떄,
_modules
는 nn.Module의__init__()
함수에 존재
- 이떄,
1-2-1. Neural Network의 종류
참조: pytorch.org/docs/stable/nn.html#module
Linear layers
nn.Linear
nn.Bilinear
Convolution layers
nn.Conv1d, nn.Conv2d, nn.Conv3d
nn.ConvTranspose1d, nn.ConvTranspose2d, nn.ConvTranspose3d
nn.Unfold, nn.Fold
Pooling layers
nn.MaxPool1d, nn.MaxPool2d, nn.MaxPool3d
nn.MaxUnpool1d, nn.MaxUnpool2d, nn.MaxUnpool3d
nn.AvgPool1d, nn.AvgPool2d, nn.AvgPool3d
nn.FractionalMaxPool2d
nn.LPPool1d, nn.LPPool2d
nn.AdaptiveMaxPool1d, nn.AdaptiveMaxPool2d, nn.AdaptiveMaxPool3d
nn.AdaptiveAvgPool1d, nn.AdaptiveAvgPool2d, nn.AdaptiveAvgPool3d
Padding layers
nn.ReflectionPad1d, nn.ReflectionPad2d
nn.ReplicationPad1d, nn.ReplicationPad2d, nn.ReplicationPad3d
nn.ZeroPad2d
nn.ConstantPad1d, nn.ConstantPad2d, nn.ConstantPad3d
Normalization layers
nn.BatchNorm1d, nn.BatchNorm2d, nn.BatchNorm3d
nn.GroupNorm
nn.InstanceNorm1d, nn.InstanceNorm2d, nn.InstanceNorm3d
nn.LayerNorm
nn.LocalResponseNorm
Recurrent layers
nn.RNN, nn.RNNCell
nn.LSTM, nn.LSTMCell
nn.GRU, nn.GRUCell
Dropout layers
nn.Dropout, nn.Dropout2d, nn.Dropout3d
nn.AlphaDropout
Sparse layers
nn.Embedding
nn.EmbeddingBag
1-2-2. 활성화 함수 종류
참조: pytorch.org/docs/stable/nn.html#non-linear-activations-weighted-sum-nonlinearity
Non-linear activations
nn.ELU, nn.SELU
nn.Hardshrink, nn.Hardtanh
nn.LeakyReLU, nn.PReLU, nn.ReLU, nn.ReLU6, nn.RReLU
nn.Sigmoid, nn.LogSigmoid
nn.Softplus, nn.Softshrink, nn.Softsign
nn.Tanh, nn.Tanhshrink
nn.Threshold
Non-linear activations (other)
nn.Softmin
nn.Softmax, nn.Softmax2d, nn.LogSoftmax
nn.AdaptiveLogSoftmaxWithLoss
2. 정적메소드 (Static Method, Class Method)
@staticmethod
,@classmethod
는 모두 Instance를 만들지 않아도 Class의 Method를 사용할 수 있다
@staticmethod
class ex_static: n = 30 @staticmethod def calc(x): return x + 60 print(ex_static.calc(90)) # 결과 >> 150
@classmethod
class ex_class: n = 30 @classmethod def calc(cls, x): return x + 60 print(ex_class.calc(90)) # 결과 >> 150
Static Method와 다르게 Method의 인자로 cls가 추가됨
이는 Class의 내의 속성 n에 접근하기 위해, 객체를 Instance하고 접근하는것이 아니기 때문에 self인자를 사용해 접근하는것이 불가능함
self 인자는 Instance된 객체의 주소를 전달할 때 사용
@staticmethod
class ex_static: n = 30 @staticmethod def calc(x): return x + 60 + ex_static.n
@classmethod
class ex_class: n = 30 @classmethod def calc(cls, x): return x + 60 + cls.n
원본 ex_class의 주소를 cls로 전달하여 내부 속성 n에 접근 가능
3. Weight 초기화
딥러닝 모델에서 Network가 깊어질수록, 가중치 초기화 (Weight Initialization)이 중요해진다.
https://jh-bk.tistory.com/10 참고
더 많은 정보
댓글