ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ๋”ฅ๋Ÿฌ๋‹(11) - VGGNet
    ๋”ฅ๋Ÿฌ๋‹/CNN 2023. 3. 26. 01:07

    ๐Ÿ‘ฉ‍๐Ÿ’ป VGGNet 

     

    ๋ชจ๋“  ํ•ฉ์„ฑ๊ณฑ ์ปค๋„์˜ ํฌ๊ธฐ๋Š” 3×3, ์ตœ๋Œ€ ํ’€๋ง ์ปค๋„์˜ ํฌ๊ธฐ๋Š” 2×2์ด๋ฉฐ, ์ŠคํŠธ๋ผ์ด๋“œ๋Š” 2์ด๋‹ค. 

    -  ํŠน์„ฑ ๋งต : 64๊ฐœ, 224×224 ํฌ๊ธฐ ์ด๋ฏ€๋กœ 224×224×64๋กœ ํ‘œํ˜„๋œ๋‹ค. 

    ๋งˆ์ง€๋ง‰ 16๋ฒˆ์งธ ๊ณ„์ธต์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋ชจ๋“  ๊ณ„์ธต์— ๋ชจ๋‘ ReLU ํ™œ์„ฑํ™” ํ•จ์ˆ˜๊ฐ€ ์ ์šฉ๋จ

     

     

    โœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

    import copy
    import numpy as np
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.optim as optim
    import torch.utils.data as data
    import torchvision
    import torchvision.transforms as transforms
    import torchvision.datasets as Datasets
    
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

     

    ๐Ÿ import copy

    - ๊ฐ์ฒด ๋ณต์‚ฌ๋ฅผ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•จ 

    - ๊ฐ์ฒด ๋ณต์‚ฌ : ๋ฐ์ดํ„ฐ ๋‹จ์œ„์ธ ๊ธฐ์กด์˜ ๊ฐ์ฒด์˜ ์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ ๊ฒฐ๊ณผ๋กœ ๋‚˜์˜ค๋Š” ๊ฐ์ฒด๋ฅผ "๊ฐ์ฒด ์‚ฌ๋ณธ"(object copy)์ด๋ผ๊ณ  ํ•จ

     

    โญ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด ๋ณต์‚ฌ

    original = [1, 2, 3] #original์ด๋ผ๋Š” ๋ณ€์ˆ˜์— [1, 2, 3] ์ €์žฅ
    copy_o = original #copy_o์— original ๋ณต์‚ฌ(shallow copy)
    print(copy_o)
    copy_o[2] = 10 #copy_o์˜ 3์„ 10์œผ๋กœ ๊ฐ’์„ ๋ณ€๊ฒฝ
    print(copy_o)
    print(original)

    copy_o๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์›๋ž˜ ๊ฐ’์ธ original์˜ 3๋„ 10์œผ๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋จ 

     

    โญ ์–•์€ ๋ณต์‚ฌ : ์‚ฌ๋ณธ๋ณ€์ˆ˜ = copy.copy(๋ณต์‚ฌํ•  ๋Œ€์ƒ)

     

    import copy
    
    original = [[1, 2], 3]
    copy_o = copy.copy(original) #original ๊ฐ’์„ copy_o์— ์–•์€ ๋ณต์‚ฌ(copy.copy( )) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ original ๊ฐ’์„ copy_o์— ๋ณต์‚ฌํ•จ 
    print(copy_o)
    copy_o[0] = 100 #copy_o์˜ [1, 2] ๊ฐ’์„ 100์œผ๋กœ ๋ณ€๊ฒฝ
    print(copy_o)
    print(original)
    
    append = copy.copy(original)
    append[0].append(4)#์ฒซ ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ([1, 2])์— 4๋ฅผ ์ถ”๊ฐ€
    print(append)
    print(original)

     append : ๋ฐฐ์—ด์˜ ์›์†Œ ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ์ด๋‹ค. 

     

      -append[๋ฐฐ์—ด์˜ ์›์†Œ ์ธ๋ฑ์Šค].append(์ถ”๊ฐ€ํ•  ๊ฐ’)

     

    copy_o์—์„œ [1, 2] ๊ฐ’์„ 100์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋”๋‹ˆ copy_o๋งŒ ๋ฐ”๋€Œ๊ฒŒ ๋จ

    [1, 2]์— 4๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋”๋‹ˆ original๊ณผ copy_o ๋ชจ๋‘ ๋ฐ˜์˜๋จ

     

    โญ ๊นŠ์€ ๋ณต์‚ฌ : ์‚ฌ๋ณธ๋ณ€์ˆ˜ = copy.deepcopy(๋ณต์‚ฌํ•  ๋Œ€์ƒ)

    import copy
    
    original = [[1, 2], 3]
    copy_o = copy.deepcopy(original) #original ๊ฐ’์„ copy_o์— ๊นŠ์€ ๋ณต์‚ฌ(copy.deepcopy())
    print(copy_o)
    copy_o[0] = 100 #copy_o์˜ [1, 2] ๊ฐ’์„ 100์œผ๋กœ ๋ณ€๊ฒฝ
    print(copy_o)
    print(original)
    
    append = copy.deepcopy(original)
    append[0].append(4) #์ฒซ ๋ฒˆ์งธ ๋ฆฌ์ŠคํŠธ([1, 2])์— 4๋ฅผ ์ถ”๊ฐ€
    print(append)
    print(original)

     

    copy_o์—์„œ [1, 2] ๊ฐ’์„ 100์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋”๋‹ˆ copy_o๋งŒ ๋ฐ”๋€ ๊ฒƒ์€ ๋™์ผํ•จ

    -  original์€ ๊ทธ๋Œ€๋กœ ๋ณด์กด๋จ 

     

    ๐Ÿ“š ์ด ๋ถ€๋ถ„์€ VGG ๋ชจ๋ธ์„ ์ง์ ‘ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ

     

    โœ VGG ๋ชจ๋ธ ์ •์˜ํ•˜๊ธฐ 

    class VGG(nn.Module):
        def __init__(self, features, output_dim):
            super().__init__()
            self.features = features #VGG ๋ชจ๋ธ์— ๋Œ€ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜์—์„œ ๋ฐ›์•„ ์˜จ features ๊ฐ’์„ self.features์— ๋„ฃ์–ด ์ค๋‹ˆ๋‹ค.
            self.avgpool = nn.AdaptiveAvgPool2d(7)
            self.classifier = nn.Sequential(
                nn.Linear(512*7*7, 4096),
                nn.ReLU(inplace=True),
                nn.Dropout(0.5),
                nn.Linear(4096, 4096),
                nn.ReLU(inplace=True),
                nn.Dropout(0.5),
                nn.Linear(4096, output_dim)
            ) #์™„์ „์—ฐ๊ฒฐ์ธต๊ณผ ์ถœ๋ ฅ์ธต์„ ์ •์˜ํ•œ๋‹ค.
    
        def forward(self, x):
            x = self.features(x)
            x = self.avgpool(x)
            h = x.view(x.shape[0], -1)
            x = self.classifier(h)
            return x, h

     

    โœ VGG ๋ชจ๋ธ ์œ ํ˜• ์ •์˜ํ•˜๊ธฐ 

    vgg11_config = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'] 
    # 8(ํ•ฉ์„ฑ๊ณฑ์ธต - ์ •์˜๋œ ์ˆซ์ž ๊ฐœ์ˆ˜) + 3(ํ’€๋ง์ธต - (M๊ฐœ์ˆ˜ -2)) = 11(์ „์ฒด ๊ณ„์ธต) = VGG11
    
    vgg13_config = [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512,  'M'] 
    # 10(ํ•ฉ์„ฑ๊ณฑ์ธต - ์ •์˜๋œ ์ˆซ์ž ๊ฐœ์ˆ˜) + 3(ํ’€๋ง์ธต - (M๊ฐœ์ˆ˜ -2)) = 13(์ „์ฒด ๊ณ„์ธต) = VGG13
    
    vgg16_config = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'] 
    # 13(ํ•ฉ์„ฑ๊ณฑ์ธต- ์ •์˜๋œ ์ˆซ์ž ๊ฐœ์ˆ˜) + 3(ํ’€๋ง์ธต - (M๊ฐœ์ˆ˜ -2)) = 16(์ „์ฒด ๊ณ„์ธต) = VGG16
    
    vgg19_config = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'] 
    # 16(ํ•ฉ์„ฑ๊ณฑ์ธต - ์ •์˜๋œ ์ˆซ์ž ๊ฐœ์ˆ˜) + 3(ํ’€๋ง์ธต - (M๊ฐœ์ˆ˜ -2)) = 19(์ „์ฒด ๊ณ„์ธต) = VGG19

     

    โœ VGG ๊ณ„์ธต ์ •์˜

     

    def get_vgg_layers(config, batch_norm):
        layers = []
        in_channels = 3
    
        for c in config: #vgg11_config ๊ฐ’๋“ค์„ ๊ฐ€์ ธ์˜จ๋‹ค. (for c in config๋ฅผ ํ•˜๋ฉด ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ)
            assert c == 'M' or isinstance(c, int) 
            if c == 'M': #๋ถˆ๋Ÿฌ์˜จ ๊ฐ’์ด ‘M’์ด๋ฉด ์ตœ๋Œ€ ํ’€๋ง(MaxPool2d)์„ ์ ์šฉ
                layers += [nn.MaxPool2d(kernel_size = 2)]
            else: #๋ถˆ๋Ÿฌ์˜จ ๊ฐ’์ด ์ˆซ์ž์ด๋ฉด ํ•ฉ์„ฑ๊ณฑ(Conv2d) ์ ์šฉ
                conv2d = nn.Conv2d(in_channels, c, kernel_size=3, padding=1)
                if batch_norm: #๋ฐฐ์น˜ ์ •๊ทœํ™”(batch normalization)๋ฅผ ์ ์šฉํ• ์ง€์— ๋Œ€ํ•œ ์ฝ”๋“œ
                    layers += [conv2d, nn.BatchNorm2d(c), nn.ReLU(inplace=True)] #๋ฐฐ์น˜ ์ •๊ทœํ™”๊ฐ€ ์ ์šฉ๋  ๊ฒฝ์šฐ ๋ฐฐ์น˜ ์ •๊ทœํ™”+ReLU ์ ์šฉ       
                else:
                    layers += [conv2d, nn.ReLU(inplace=True)] #๋ฐฐ์น˜ ์ •๊ทœํ™”๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ReLU๋งŒ ์ ์šฉ
                in_channels = c
    
        return nn.Sequential(*layers) #๋„คํŠธ์›Œํฌ์˜ ๋ชจ๋“  ๊ณ„์ธต์„ ๋ฐ˜ํ™˜

    ๐Ÿ for c in config: 
            assert c == 'M' or isinstance(c, int)    :์กฐ๊ฑด๋ฌธ - ๊ฐ€์ • ์„ค์ •๋ฌธ 

     

    โญ for c in config : 

    - ์œ„์—์„œ ์ •์˜ํ•œ config(๋ชจ๋ธ์„ ๋ฐฐ์—ด๋กœ ์ •์˜ํ•œ ๊ฒƒ)์—์„œ ์›์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด

     

    โญ assert c == 'M' or isinstance(c, int)

     

    ๐Ÿ“Œ assert 

    - ๊ฐ€์ • ์„ค์ •๋ฌธ

    - ๋’ค์˜ ์กฐ๊ฑด์ด True๊ฐ€ ์•„๋‹ˆ๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค. 

    -  c == 'M'์ด ์•„๋‹ˆ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

     

    ๐Ÿ“Œ isinstance(c, int)

    - ์ฃผ์–ด์ง„ ์กฐ๊ฑด์ด True์ธ์ง€ ํŒ๋‹จํ•จ(๊ฒ€์ฆ)

     

    print(isinstance(1, int)) #1์ด integer์ธ์ง€ ํŒ๋‹จ
    print(isinstance(1.2, int)) # 1.2๊ฐ€ integer์ธ์ง€ ํŒ๋‹จ
    print(isinstance('deep learning', str)) #deep learning์ด string์ธ์ง€ ํŒ๋‹จ

    -  assert c == 'M' or isinstance(c, int) ์˜๋ฏธ๋Š” c๊ฐ€ 'M'์ด ์•„๋‹ˆ๊ฑฐ๋‚˜ int๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋„๋ก ํ•จ

     

    โœ ๋ชจ๋ธ ๊ณ„์ธต ์ƒ์„ฑ

    - get_vgg_layers() ํ•จ์ˆ˜ : VGG ๋ชจ๋ธ์˜ ๊ณ„์ธต์„ ์ƒ์„ฑ

    ๋ฐฐ์น˜ ์ •๊ทœํ™”(batch normalization)์— ๋Œ€ํ•œ ๊ณ„์ธต๋„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ธฐ(get_vgg_layers ์˜ต์…˜์— ์ถ”๊ฐ€)

     

    vgg11_layers = get_vgg_layers(vgg11_config, batch_norm=True)
    print(vgg11_layers)

     

    ๐Ÿ batch_norm = True(๋ฐฐ์น˜ ์ •๊ทœํ™”)

    - ๋ฐ์ดํ„ฐ์˜ ํ‰๊ท ์„ 0์œผ๋กœ, ํ‘œ์ค€ํŽธ์ฐจ๋ฅผ 1๋กœ ๋ถ„ํฌ์‹œํ‚ค๋Š” ๊ฒƒ

    -  ๊ฐ ๊ณ„์ธต์˜ ์ž…๋ ฅ์— ๋Œ€ํ•œ ๋ถ„์‚ฐ์„ ํ‰๊ท  0, ํ‘œ์ค€ํŽธ์ฐจ 1๋กœ ๋ถ„ํฌ์‹œํ‚ค๋Š” ๊ฒƒ

     

    ๐Ÿ‘‹ VGG ๊ณ„์ธต ์ถœ๋ ฅ

     

     

    โœ VGG ์ „์ฒด์— ๋Œ€ํ•œ ๋„คํŠธ์›Œํฌ(vgg11_layers()์™€ VGG์—์„œ ์ •์˜ํ•œ ์™„์ „์—ฐ๊ฒฐ์ธต๊ณผ ์ถœ๋ ฅ์ธต ํฌํ•จ)

    OUTPUT_DIM = 2 #๊ฐœ์™€ ๊ณ ์–‘์ด ๋‘ ๊ฐœ๋ฅผ ํด๋ž˜์Šค ์‚ฌ์šฉ ์ถœ๋ ฅ์ธต์€ 2๊ฐœ์ด๋‹ค. 
    model = VGG(vgg11_layers, OUTPUT_DIM)
    print(model)

     

     

     - vgg11_layers, ์™„์ „์—ฐ๊ฒฐ์ธต๊ณผ ์ถœ๋ ฅ์ธต((classifier): Sequential()) ๋ถ€๋ถ„์ด ํ•ฉ์ณ์ ธ์„œ ์ถœ๋ ฅ๋จ 

     

    - ์œ„์— ๊ฒƒ๊นŒ์ง€๋Š” VGG ๋ชจ๋ธ์„ ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ์ „์ฒด ๋„คํŠธ์›Œํฌ๋ฅผ ์ง์ ‘ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. VGG ๋ชจ๋ธ์€ ์ด๋ฏธ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋Œ€์šฉ๋Ÿ‰์˜ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋กœ ํ•™์Šต์„ ์‹œ์ผฐ์œผ๋ฉฐ, ์ตœ์ƒ์˜ ์ƒํƒœ๋กœ ํŠœ๋‹์„ ๊ฑฐ์ณ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณต์œ ํ•œ ์‚ฌ์ „ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ์ด๋ฏ€๋กœ 

     

     

     

    ๐Ÿ“š VGG ์‚ฌ์ „ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ ์‚ฌ์šฉ

    โœ VGG ์‚ฌ์ „ ํ›ˆ๋ จ ๋ชจ๋ธ ๊ฐ€์ ธ์˜ค๊ธฐ 

    import torchvision.models as models
    pretrained_model = models.vgg11_bn(pretrained=True) 
    print(pretrained_model)

     

    ๐Ÿ pretrained_model = models.vgg11_bn(pretrained=True) 

     

    โญ vgg11_bn

     

    - VGG11 ๊ธฐ๋ณธ ๋ชจ๋ธ์— ๋ฐฐ์น˜ ์ •๊ทœํ™”(bn)๊ฐ€ ์ ์šฉ๋œ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•จ

     

    โญ pretrained = True

     

    - ์‚ฌ์ „ ํ›ˆ๋ จ๋œ ๋ชจ๋ธ์„ ์‚ฌ์šฉ(๋ฏธ๋ฆฌ ํ•™์Šต๋œ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’๋“ค์„ ์‚ฌ์šฉ)

     

    โœ VGG ๋ชจ๋ธ ์œ ํ˜• ์ •์˜ํ•˜๊ธฐ

    vgg11_config = [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'] 
    vgg13_config = [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'] 
    vgg16_config = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'] 
    vgg19_config = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'] 
    My_Vgg = [64, 64, 64, 'M', 128, 128, 128, 'M', 256, 256, 256, 'M']

    โœ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ์ •์˜ํ•˜๊ธฐ

     

Designed by Tistory.