https://inha-kim.tistory.com/45

 

[논문 리뷰] inception v1, GoogLeNet(2014) 논문리뷰 (Going Deeper with Convolutions)

저는 cs231n을 base로 들어서 자세한 내용까지 설명하지 않았습니다. https://arxiv.org/abs/1409.4842 Going Deeper with Convolutions We propose a deep convolutional neural network architecture codenamed..

inha-kim.tistory.com

pytorch 구현 생각보다 복잡하네요..

https://www.youtube.com/watch?v=uQc4Fs7yx5I&t=39s&ab_channel=AladdinPersson

유튜브의 도움을 받았습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# import package
import torch
import torch.nn as nn
from torchsummary import summary
# https://www.youtube.com/watch?v=uQc4Fs7yx5I&t=39s&ab_channel=AladdinPersson
class Conv_block(nn.Module):
    def __init__(self,in_channels, out_channels,**kwargs):
        super(Conv_block,self).__init__()
        self.conv_layer = nn.Sequential(
            nn.Conv2d(in_channels, out_channels,**kwargs),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(),
        )
    def forward(self,x):
        return self.conv_layer(x)
 
class Inception_block(nn.Module):
    def __init__(self,in_channels,out_1x1,red_3x3,out_3x3,red_5x5,out_5x5,out_1x1pool):
        super(Inception_block,self).__init__()
        self.branch_1 = Conv_block(in_channels,out_1x1,kernel_size=1)
        self.branch_2 = nn.Sequential(
            Conv_block(in_channels,red_3x3,kernel_size=1),
            Conv_block(red_3x3,out_3x3,kernel_size=3,padding=1),
        )
        self.branch_3 = nn.Sequential(
            Conv_block(in_channels,red_5x5,kernel_size = 1),
            Conv_block(red_5x5,out_5x5,kernel_size=5,padding = 2),
        )
        self.branch_4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3,stride=1,padding =1),
            Conv_block(in_channels,out_1x1pool,kernel_size=1),
        )
    def forward(self,x):
        out = torch.cat([self.branch_1(x),self.branch_2(x),self.branch_3(x),self.branch_4(x)],dim=1)
        return out
 
# loss에 0.3곱해짐
class inception_Auxiliary_classifier(nn.Module):
    def __init__(self,in_channels,num_classes):
        super(inception_Auxiliary_classifier,self).__init__()
 
        self.conv = nn.Sequential(
            nn.AvgPool2d(kernel_size=5,stride=3),
            Conv_block(in_channels,128,kernel_size=1),
        )
        self.fc = nn.Sequential(
            nn.Linear(20481024),
            nn.ReLU(),
            nn.Dropout(),
            nn.Linear(1024, num_classes),
        )
    def forward(self,x):
        out = self.conv(x)
        out = out.view(out.shape[0],-1)
        out = self.fc(out)
        return out
 
class GoogLeNet(nn.Module):
    def __init__(self, auxiliary_classifier = True, num_classes = 10):
        super(GoogLeNet,self).__init__()
        # True or False 가 아니면 assert error 발생
        assert auxiliary_classifier == True or auxiliary_classifier == False
        self.auxiliary_classifier = auxiliary_classifier
        self.conv1 = Conv_block(in_channels=3,out_channels=64, kernel_size=7,stride=2,padding=3)
        self.maxpool1 = nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
        self.conv2 = Conv_block(in_channels=64,out_channels=192,kernel_size=3,stride=1,padding=1)
        self.maxpool2 = nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
        self.inception3a = Inception_block(192,64,96,128,16,32,32)
        self.inception3b = Inception_block(256,128,128,192,32,96,64)
        self.maxpool3 = nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
        self.inception4a = Inception_block(48019296208164864)
        # auxiliary classifier
        self.inception4b = Inception_block(512160112224246464)
        self.inception4c = Inception_block(512128128256246464)
        self.inception4d = Inception_block(512112144288326464)
        # auxiliary classifier
        self.inception4e = Inception_block(528,256,160,320,32,128,128)
        self.maxpool4 = nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
        self.inception5a = Inception_block(832,256,160,320,32,128,128)
        self.inception5b = Inception_block(832,384,192,384,48,128,128)
        self.avgpool = nn.AvgPool2d(kernel_size=7,stride=1)
        self.dropout = nn.Dropout(p=0.4)
        self.fc1 = nn.Linear(1024,num_classes)
        if self.auxiliary_classifier:
            self.aux1 = inception_Auxiliary_classifier(512,num_classes)
            self.aux2 = inception_Auxiliary_classifier(528,num_classes)
        else:
            self.aux1 = self.aux2 = None
 
    def forward(self,x):
        out = self.conv1(x)
        out = self.maxpool2(out)
        out = self.conv2(out)
        out = self.maxpool2(out)
        out = self.inception3a(out)
        out = self.inception3b(out)
        out = self.maxpool3(out)
        out = self.inception4a(out)
        if self.auxiliary_classifier and self.training:
            aux1 = self.aux1(out)
        out = self.inception4b(out)
        out = self.inception4c(out)
        out = self.inception4d(out)
        if self.auxiliary_classifier and self.training:
            aux2 = self.aux2(out)
        out = self.inception4e(out)
        out = self.maxpool4(out)
        out = self.inception5a(out)
        out = self.inception5b(out)
        out = self.avgpool(out)
 
        out = out.view(out.shape[0],-1)
        out = self.dropout(out)
        out = self.fc1(out)
 
        if self.auxiliary_classifier and self.training:
            return out,aux1,aux2
        else:
            return out
 
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GoogLeNet(auxiliary_classifier=True, num_classes=10).to(device)
 
summary(model, input_size=(3,224,224), device=device.type)
cs

+ Recent posts