-
๋ฅ๋ฌ๋(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']
โ ์ด๋ฏธ์ง ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ ์ ์ํ๊ธฐ
'๋ฅ๋ฌ๋ > CNN' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Image Segmentation(1) (0) 2023.03.31 ๋ฅ๋ฌ๋(12) - GoogLeNet (0) 2023.03.26 ๋ฅ๋ฌ๋(10) - AlexNet (0) 2023.03.24 ๋ฅ๋ฌ๋(9) - ํฉ์ฑ๊ณฑ์ ๊ฒฝ๋ง(2) : LeNet-5 (0) 2023.03.23 ๋ฅ๋ฌ๋(8) - ๊ทธ๋ํํฉ์ฑ๊ณฑ (0) 2023.03.23