본문 바로가기

인공지능/Toy Projects

DeepMC_2 / Multi-Scale Deep Learning

목차

    Introduction

    저번 C)WPD에 이어서 다음 단계인 D)Multi-Scale Deep Learning 부분이다.

    DeepMC 논문에서 설명하고 있는 모델의 추론 방식은 C)WPD(Wavelet Packet Decomposition)을 5 levels로 분리해 기상 데이터를 다양한 scale관점에서 encoding하고 attention을 이용해 분리한 다양한 scale의 데이터중에 예측에 어떤 데이터를 사용할지 가중치를 이용해 결정한다.

    D)Multi-Scale Deep Learning은 전체 모델에서 Encoder 부분으로 CNN stack과 CNN-LSTM스택으로 구분된다.

    각각을 코드로 구현해 동작이 잘 되는지 확인해본다.

    Material & Method

    CNN stack과 CNN-LSTM stack은 기계학습 모델을 만들어본 경험이 한번이라도 있으면 구현하기 어렵지 않다.

    단순히 논문에서 설명한대로 레이어를 쌓으면 된다.

    CNN stack과 CNN-LSTM stack의 설명 및 아키텍쳐는 다음과 같다.

    The CNN stack (Figure 10) uses three 1-D convolutional layers with filter sizes of 4 and ReLU activation function for each layer. Each layer is batch normalized before passing onto the next layer. The last layer flattens the output. The CNN-LSTM (Figure 11) stack uses two 1-D convolutional layers with filter sizes of 4 and ReLU activation function for each layer. Each layer is batch normalized before passing onto the next layer. The output of the last layer is passed through an LSTM layer with ReLU activation function and a dropout rate of 20%.

    Result

    각각 stack의 구현은 논문에서 설명한대로 쌓으면 된다.

    최대한 주석으로 설명을 했으나 혹시 모르는 부분이나 잘못되었다고 생각되는 부분은 알려주세요.

     

    import torch
    
    from torch import nn
    
    class LSTMstack(nn.Module):
    
        def __init__(self, num_encoder_feature : int):
    
            super().__init__()
            
            # Hyper parameter
            self.num_encoder_feature = num_encoder_feature
    
            # CNN stack before LSTM
            self.sequence= nn.Sequential(
                nn.Conv1d(self.num_encoder_feature, self.num_encoder_feature,4),
                nn.ReLU(),
                nn.BatchNorm1d(num_features= self.num_encoder_feature),
                nn.Conv1d(self.num_encoder_feature, self.num_encoder_feature,4),
                nn.ReLU(),
                nn.BatchNorm1d(num_features=7)
            )
    
            # LSTM aftre CNN stack
            self.lstm = nn.LSTM(input_size = self.num_encoder_feature, hidden_size = self.num_encoder_feature, dropout = 0.2, num_layers = 2, batch_first = True, bidirectional = True)
    
        def forward(self, WPD):
            # cnnstack output
            cnn_output = self.sequence(WPD)
    
            # cnn output shape is (batch, feature, seq) / in this case [16, 7, 18]
            # but lstm input must be (batch, seq, feature) / in this case [16, 18, 7]
            # so we change axis of cnn output for match lstm input format
            new_cnn_output = torch.transpose(cnn_output, 1, 2)
    
            # lstm output is (output,(h_n, c_n))
            # output shape is (N,L,D∗H_out) when batch_first=True
            # h_n shape is (D∗num_layers,N,H_out), and it means the final hidden state for each element in the sequence
            # c_n shape is (D∗num_layers,N,H_cell), and it means the final cell state for each element in the sequence
            output, (h_n, c_n) = self.lstm(new_cnn_output)
    
            return output
    
    
    class CNNstack(nn.Module):
    
        def __init__(self, num_encoder_feature : int):
    
            super().__init__()
            
            # Hyper parameter
            self.num_encoder_feature = num_encoder_feature
    
            # CNN stack
            self.sequence= nn.Sequential(
                nn.Conv1d(self.num_encoder_feature,self.num_encoder_feature,4),
                nn.ReLU(),
                nn.BatchNorm1d(num_features=self.num_encoder_feature),
                nn.Conv1d(self.num_encoder_feature,self.num_encoder_feature,4),
                nn.ReLU(),
                nn.BatchNorm1d(num_features=self.num_encoder_feature),
                nn.Conv1d(self.num_encoder_feature,self.num_encoder_feature,4),
                nn.ReLU(),
                nn.Flatten()
            )
    
        def forward(self, WPD):
            return self.sequence(WPD)

    Conclusion & Discussion

    CNN stack과 CNN-LSTM stack은 구현에 큰 어려움이 없었다.

    다만 hidden nodes는 개발자의 자유에 맡기는 건지, 아니면 입력 차원이 데이터마다 다를 것이기 때문에 따로 언급을 하지 않았는지는 모르겠지만 개수가 정해지지 않아서 encoder feature개수에 맞춰서 유지하게 진행했다.

    이부분은 유동적으로 코드를 수정하면 되기 때문에 전체 flow가 완성되면 추후에 수정해보는 것으로 한다.

     

     

    작성중인 git

    https://github.com/wlsdml1114/DeepMC

     

    GitHub - wlsdml1114/DeepMC

    Contribute to wlsdml1114/DeepMC development by creating an account on GitHub.

    github.com