์•ˆ๋…•ํ•˜์„ธ์š”. ์˜ค๋Š˜์€ Xception ๋ฆฌ๋ทฐ ์„ธ๋ฒˆ ์งธ ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค.

 

1. The Xception architecture

 

in particular the VGG-16 architecture , which is schematically similar to our proposed architecture 
in a few respects.

ํŠนํžˆ VGG-16๊ณ„์ธต์€ ๋ช‡ ๊ฐ€์ง€ ์ธก๋ฉด์—์„œ Xception ๊ณ„์ธต๊ณผ ๊ฐœ๋žต์ ์œผ๋กœ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

 

The Inception architecture family of convolutional neural networks, which first demonstrated the 
advantages of factoring convolutions into multiple branches operating successively on channels and then on 
space.

Inception ๋ชจ๋“ˆ์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉํ–ฅ์œผ๋กœ ์ฑ„๋„๊ณผ ๊ณต๊ฐ„์—์„œ ์ž‘๋™ํ•˜๋Š” ์žฅ์ ์„ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

Depthwise separable convolutions, which our proposed architecture is entirely based upon. ~~

์•ž ์ชฝ์—์„œ ์ด์•ผ๊ธฐํ•œ Depthwise Separable Convolution์˜ ์—ฐ์‚ฐ๋Ÿ‰ ๊ฐ์†Œ๋กœ ์ธํ•œ ์†๋„ ์ฆ๊ฐ€์˜ ์žฅ์ ์„ ์†Œ๊ฐœํ•˜๊ณ 
์žˆ์Šต๋‹ˆ๋‹ค.

coding-yoon.tistory.com/77

 

[๋”ฅ๋Ÿฌ๋‹] Depthwise Separable Covolution with Pytorch( feat. Convolution parameters VS Depthwise Separable Covolution paramet

์•ˆ๋…•ํ•˜์„ธ์š”. Google Coral์—์„œ ํ•™์Šต๋œ ๋ชจ๋ธ์„ ํ†ตํ•ด ์ถ”๋ก ์„ ํ•  ์ˆ˜ ์žˆ๋Š” Coral Board & USB Accelator ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” Coral Board๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด4์— USB Accelator๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ƒ๊ฐ์ž…๋‹ˆ..

coding-yoon.tistory.com

 

Residual connections, introduced by He et al. in [4], which our proposed architecture uses extensively.

Resnet์—์„œ ์‚ฌ์šฉํ•˜๋Š” Residual Connections

https://openaccess.thecvf.com/content_cvpr_2016/papers/He_Deep_Residual_Learning_CVPR_2016_paper.pdf

 

Residual Connections : BottleNeck (x)

Residual Connections๋ฅผ ์งš๊ณ  ๋„˜์–ด๊ฐ€์ž๋ฉด, Resnet์˜ ๋ฐฐ๊ฒฝ์€ ํžˆ๋“ ๋ ˆ์ด์–ด๊ฐ€ ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ํ•™์Šต์ด ๋” ์ž˜๋˜์–ด์•ผ ํ•˜์ง€๋งŒ, ์˜คํžˆ๋ ค ํ•™์Šต์„ ๋ชปํ•˜๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ํ˜„์ƒ์ด vanishing/exploding gradients (๊ธฐ์šธ๊ธฐ ์†์‹ค) ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. Batch Normalization์œผ๋กœ  ์–ด๋Š์ •๋„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ณ ์•ˆ๋œ ๋ฐฉ๋ฒ•์ด Residual Connection(mapping) ์ž…๋‹ˆ๋‹ค. ์ด์ „์˜ ๊ฐ’์„ ๋”ํ•ด์คŒ์œผ๋กœ ๊ธฐ์šธ๊ธฐ ์†์‹ค์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ํšจ๊ณผ๋Š” ๊ต‰์žฅํžˆ ์ข‹์Šต๋‹ˆ๋‹ค. 

 

dataset์€ FastEval14K๋ฅผ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. (299x299x3)

 

2. implemention

2-1 depthwise separable convolution

def depthwise_separable_conv(input_dim, output_dim):
   
    depthwise_convolution = nn.Conv2d(input_dim, input_dim, kernel_size=3, padding=1, groups=input_dim, bias=False)
    pointwise_convolution = nn.Conv2d(input_dim, output_dim, kernel_size=1, bias=False)
   
    model = nn.Sequential(
        depthwise_convolution,
        pointwise_convolution
       
    )
       
    return model

2-2 Entry flow

class entry_flow(nn.Module):
    def __init__(self):
        super(entry_flow, self).__init__()
       
        self.conv2d_init_1 = nn.Conv2d(in_channels = 3,
                                       out_channels = 32,
                                       kernel_size = 3,
                                       stride = 2,
                                      )
       
        self.conv2d_init_2 = nn.Conv2d(in_channels = 32,
                                       out_channels = 64,
                                       kernel_size = 3,
                                       stride = 1,
                                      )
       
       
        self.layer_1 = nn.Sequential(
            depthwise_separable_conv(input_dim = 64, output_dim = 128),
            nn.ReLU(),
            depthwise_separable_conv(input_dim = 128, output_dim = 128),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
           
        )
                                                             
        self.conv2d_1 = nn.Conv2d(in_channels = 64,
                                  out_channels = 128,
                                  kernel_size = 1,
                                  stride = 2
                                  )
       
        self.layer_2 = nn.Sequential(
            depthwise_separable_conv(input_dim = 128, output_dim = 256),
            nn.ReLU(),
            depthwise_separable_conv(input_dim = 256, output_dim = 256),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
           
        )
                                                             
        self.conv2d_2 = nn.Conv2d(in_channels = 128,
                                  out_channels = 256,
                                  kernel_size = 1,
                                  stride = 2
                                  )
       
        self.layer_3 = nn.Sequential(
            depthwise_separable_conv(input_dim = 256, output_dim = 728),
            nn.ReLU(),
            depthwise_separable_conv(input_dim = 728, output_dim = 728),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
           
        )
                                                             
        self.conv2d_3 = nn.Conv2d(in_channels = 256,
                                  out_channels = 728,
                                  kernel_size = 1,
                                  stride = 2
                                  )
       
        self.relu = nn.ReLU()
       
    def forward(self, x):
        x = self.conv2d_init_1(x)
        x = self.relu(x)
        x = self.conv2d_init_2(x)
        x = self.relu(x)
       
        output1_1 = self.layer_1(x)
        output1_2 = self.conv2d_1(x)
        output1_3 = output1_1 + output1_2
       
       
        output2_1 = self.layer_2(output1_3)
        output2_2 = self.conv2d_2(output1_3)
        output2_3 = output2_1 + output2_2
       
       
        output3_1 = self.layer_3(output2_3)
        output3_2 = self.conv2d_3(output2_3)
        output3_3 = output3_1 + output3_2
        y = output3_3
       
        return y

2-2 Middle flow

class middle_flow(nn.Module):
    def __init__(self):
        super(middle_flow, self).__init__()
       
        self.module_list = nn.ModuleList()
       
        layers = nn.Sequential(
                nn.ReLU(),
                depthwise_separable_conv(input_dim = 728, output_dim = 728),
                nn.ReLU(),
                depthwise_separable_conv(input_dim = 728, output_dim = 728),
                nn.ReLU(),
                depthwise_separable_conv(input_dim = 728, output_dim = 728)
            )
       
        for i in range(7):
            self.module_list.append(layers)
           
    def forward(self, x):
        for layer in self.module_list:
            x_temp = layer(x)
            x = x + x_temp
       
        return x

2-3 Exit flow

class exit_flow(nn.Module):
    def __init__(self, growth_rate=32):
        super(exit_flow, self).__init__()
       
        self.separable_network = nn.Sequential(
            nn.ReLU(),
            depthwise_separable_conv(input_dim = 728, output_dim = 728),
            nn.ReLU(),
            depthwise_separable_conv(input_dim = 728, output_dim = 1024),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        )
       
        self.conv2d_1 = nn.Conv2d(in_channels = 728,
                                  out_channels = 1024,
                                  kernel_size = 1,
                                  stride = 2
                                  )
       
        self.separable_conv_1 = depthwise_separable_conv(input_dim = 1024, output_dim = 1536)
        self.separable_conv_2 = depthwise_separable_conv(input_dim = 1536, output_dim = 2048)
       
        self.relu = nn.ReLU()
        self.avgpooling = nn.AdaptiveAvgPool2d((1))
       
        self.fc_layer = nn.Linear(2048, 10)
       
    def forward(self, x):
        output1_1 = self.separable_network(x)
        output1_2 = self.conv2d_1(x)
        output1_3 = output1_1 + output1_2
 
        y = self.separable_conv_1(output1_3)
        y = self.relu(y)
        y = self.separable_conv_2(y)
        y = self.relu(y)
        y = self.avgpooling(y)
       
        y = y.view(-1, 2048)
        y= self.fc_layer(y)
       
       
        return y

2-4 Xception

class Xception(nn.Module):
    def __init__(self):
        super(Xception, self).__init__()
        self.entry_flow = entry_flow()
        self.middle_flow = middle_flow()
        self.exit_flow = exit_flow()
       
       
       
    def forward(self, x):
        x = self.entry_flow(x)
        x = self.middle_flow(x)
        x = self.exit_flow(x)
       
        return x

 

3. Experiment result

 

๋‹ค๋ฅธ ๋ชจ๋ธ์— ๋น„ํ•ด ๋†’์€ accuracy
์—ฐ์‚ฐ๋Ÿ‰ ๊ฐ์†Œ
Residual Connection์˜ ์„ฑ๋Šฅ

4. Conclusions

Depthwise Separable Convolution์ด Inception ๋ชจ๋“ˆ๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ, Standard Convolution ๋งŒํผ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ณ , ๋†’์€ ์„ฑ๋Šฅ๊ณผ ์—ฐ์‚ฐ๋Ÿ‰ ๊ฐ์†Œ์˜ ์žฅ์  ๋•Œ๋ฌธ์— CNN์˜ ์„ค๊ณ„์˜ ๊ธฐ์ดˆ๊ฐ€ ๋  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. Xception ๋…ผ๋ฌธ ๋ฆฌ๋ทฐ๋ฅผ ๋งˆ์น˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋…ผ๋ฌธ ๋ฆฌ๋ทฐ์ธ์ง€๋ผ ๋งํ•˜๊ณ ์ž ํ•˜๋Š” ๋‚ด์šฉ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ง€ ๋ชปํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ˜น์‹œ๋ผ๋„ ๋ณด์‹œ๋‹ค๊ฐ€ ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด๋‚˜ ์ถ”๊ฐ€ํ•ด์•ผํ•  ๋ถ€๋ถ„์ด ๋ณด์ด์‹œ๋ฉด ํ”ผ๋“œ๋ฐฑ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

728x90
๋ฐ˜์‘ํ˜•
18์ง„์ˆ˜