ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์ ์ด๋ฏธ์ง ์ ์ฒด๋ฅผ ํ ๋ฒ์ ๊ณ์ฐํ๋ ๊ฒ์ด ์๋ ์ด๋ฏธ์ง์ ๊ตญ์์ ๋ถ๋ถ์ ๊ณ์ฐํจ์ผ๋ก์จ ์๊ฐ๊ณผ ์์์ ์ ์ฝํ์ฌ ์ด๋ฏธ์ง์ ์ธ๋ฐํ ๋ถ๋ถ๊น์ง ๋ถ์ํ ์ ์๋ ์ ๊ฒฝ๋ง์ด๋ค.
์ด๋ฏธ์ง ๋ถ์์ ์๋์ ๊ทธ๋ฆผ ์ผ์ชฝ๊ณผ ๊ฐ์ 3x3 ๋ฐฐ์ด์ ์ค๋ฅธ์ชฝ๊ณผ ๊ฐ์ด ํผ์ณ์ ๊ฐ ํฝ์
์ ๊ฐ์ค์น๋ฅผ ๊ณฑํด ์๋์ธต์ผ๋ก ์ ๋ฌํ๊ฒ ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๋ฆผ์์ ๋ณด์ด๋ ๊ฒ์ฒ๋ผ ์ด๋ฏธ์ง๋ฅผ ํผ์ณ์ ๋ถ์ํ๊ฒ ๋๋ฉด ๋ฐ์ดํฐ์ ๊ณต๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๋ฌด์ํ๊ฒ ๋๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ํฉ์ฑ๊ณฑ์ธต์ด ๋์
๋๋ค.
ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง(Convolutional Neural Network, CNN ๋๋ ConvNet)์ ์์ฑ ์ธ์์ด๋ ์ด๋ฏธ์ง/์์ ์ธ์์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ์ ๊ฒฝ๋ง์ด๋ค. ๋ค์ฐจ์ ๋ฐฐ์ด ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๊ตฌ์ฑ๋์ด ์ปฌ๋ฌ ์ด๋ฏธ์ง ๊ฐ์ ๋ค์ฐจ์ ๋ฐฐ์ด ์ฒ๋ฆฌ์ ํนํ๋์ด ์์ผ๋ฉฐ ๋ค์ฏ๊ฐ์ ๊ณ์ธต
์ผ๋ก ๊ตฌ์ฑ๋๋ค.
CNN์ ํฉ์ฑ๊ณฑ์ธต๊ณผ ํ๋ง์ธต์ ๊ฑฐ์น๋ฉด์ ์ ๋ ฅ ์ด๋ฏธ์ง์
์ฃผ์ ํน์ฑ ๋ฒกํฐ(feature vector)
๋ฅผ ์ถ์ถํ๋ค. ์ฃผ์ ํน์ฑ ๋ฒกํฐ๋ค์ ์์ ์ฐ๊ฒฐ์ธต์ ๊ฑฐ์น๋ฉด์ 1์ฐจ์ ๋ฒกํฐ๋ก ๋ณํ๋๋ฉฐ, ์ถ๋ ฅ์ธต์์ ํ์ฑํ ํจ์๋ฅผ ๊ฑฐ์ณ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ค.
๐๐ป ์ ๋ ฅ ์ด๋ฏธ์ง ๋ฐ์ดํฐ๊ฐ ์ต์ด๋ก ๊ฑฐ์น๊ฒ ๋๋ ๊ณ์ธต
์ด๋ฏธ์ง๋ ๋์ด(height), ๋๋น(width), ์ฑ๋(channel)์ ๊ฐ์ ๊ฐ๋ 3์ฐจ์ ๋ฐ์ดํฐ์ด๋ค.
์ด๋ฏธ์ง ์ฑ๋์ ํ๋ฐฑ์ด๋ฉด 1
, ์ปฌ๋ฌ์ด๋ฉด 3
๊ฐ์ ๊ฐ๋๋ค.
๐๐ป ์ ๋ ฅ ๋ฐ์ดํฐ์์ ํน์ฑ์ ์ถ์ถํ๋ ์ญํ ์ ์ํ
์ด๋ฏธ์ง์ ๋ํ ํน์ฑ์ ๊ฐ์งํ๊ธฐ ์ํด ์ปค๋(kernel)
์ด๋ ํํฐ
๋ฅผ ์ฌ์ฉํ๋ค.
์ปค๋/ํํฐ๋ ์ด๋ฏธ์ง์ ๋ชจ๋ ์์ญ์ ํ์ผ๋ฉฐ ํน์ฑ์ ์ถ์ถํ๋ฉฐ ๋์จ ๊ฒฐ๊ณผ๋ฌผ์ ํน์ฑ ๋งต(feature map)์ด๋ผ๊ณ ํ๋ค.
โถ๏ธ ์ผ๋ฐ์ ์ผ๋ก 3x3,5x5 ํฌ๊ธฐ์ ์ปค๋์ ์ ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ฉฐ,์คํธ๋ผ์ด๋(stride)
๋ผ๋ ์ง์ ๋ ๊ฐ๊ฒฉ์ผ๋ก ์ด๋ํ๋ค.
- ์ ๋ ฅ ๋ฐ์ดํฐ : W x H x D (W : ๊ฐ๋ก, H : ์ธ๋ก, D : ๊น์ด ๋๋ ์ฑ๋)
- ํ์ดํผํ๋ผ๋ฏธํฐ
- ํํฐ ๊ฐ์ : K
- ํํฐ ํฌ๊ธฐ : F
- ์คํธ๋ผ์ด๋ : S
- ํจ๋ฉ : P
- ์ถ๋ ฅ ๋ฐ์ดํฐ
- W = (W - F + 2P) / S + 1
- H = (H - F + 2P) / S + 1
- D = K
- ํจ๋ฉ(Padding)
ํฉ์ฑ๊ณฑ ์ฐ์ฐ์ ๊ฒฐ๊ณผ๋ก ์ป์ ํน์ฑ ๋งต์ ์ ๋ ฅ๋ณด๋ค ํฌ๊ธฐ๊ฐ ์์์ง๋ค๋ ํน์ง์ด ์๋ค. ๋ง์ฝ, ํฉ์ฑ๊ณฑ ์ธต์ ์ฌ๋ฌ๊ฐ ์์๋ค๋ฉด ์ต์ข ์ ์ผ๋ก ์ป์ ํน์ฑ ๋งต์ ์ด๊ธฐ ์ ๋ ฅ๋ณด๋ค ๋งค์ฐ ์์์ง ์ํ๊ฐ ๋๊ธฐ ๋๋ฌธ์ ํฉ์ฑ๊ณฑ ์ฐ์ฐ ์ดํ์๋ ํน์ฑ ๋งต์ ํฌ๊ธฐ๊ฐ ์ ๋ ฅ์ ํฌ๊ธฐ์ ๋์ผํ๊ฒ ์ ์ง๋๋๋ก ํ๊ณ ์ถ๋ค๋ฉด ํจ๋ฉ(padding)์ ์ฌ์ฉํ๋ฉด ๋๋ค.
๐๐ป ํน์ฑ ๋งต์ ์ฐจ์์ ๋ค์ด ์ํ๋งํ์ฌ ์ฐ์ฐ๋์ ๊ฐ์์ํค๊ณ , ์ฃผ์ํ ํน์ฑ ๋ฒกํฐ๋ฅผ ์ถ์ถํ์ฌ ํ์ต์ ํจ๊ณผ์ ์ผ๋ก ํ ์ ์๊ฒ ํ๋ค.
๋ค์ด ์ํ๋ง์ด๋ ์ด๋ฏธ์ง๋ฅผ ์ถ์ํ๋ ๊ฒ์ด๋ค.
ํ๊ท ํ๋ง์ ๊ฐ ์ปค๋ ๊ฐ์ ํ๊ท ํ์์ผ ์ค์ํ ๊ฐ์ค์น๋ฅผ ๊ฐ๋ ๊ฐ์ ํน์ฑ์ด ํฌ๋ฏธํด์ง ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ถ๋ถ์ ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง์์๋ ์ต๋ ํ๋ง์ด ์ฌ์ฉ๋๋ค.
- ์ ๋ ฅ ๋ฐ์ดํฐ : W x H x D
- ํ์ดํผํ๋ผ๋ฏธํฐ
- ํํฐ ํฌ๊ธฐ : F
- ์คํธ๋ผ์ด๋ : S
- ์ถ๋ ฅ ๋ฐ์ดํฐ
- W = (W - F ) / S + 1
- H = (H - F) / S + 1
- D = D
๐๐ป ํฉ์ฑ๊ณฑ์ธต๊ณผ ํ๋ง์ธต์ ๊ฑฐ์น๋ฉด์ ์ฐจ์์ด ์ถ์๋ ํน์ฑ ๋งต์ ์ต์ข ์ ์ผ๋ก ์์ ์ฐ๊ฒฐ์ธต(fully connected layer)์ผ๋ก ์ ๋ฌ๋๋ค. ์ด ๊ณผ์ ์์ ์ด๋ฏธ์ง๋ 3์ฐจ์ ๋ฒกํฐ์์ 1์ฐจ์ ๋ฒกํฐ๋ก ํผ์ณ์น๊ฒ(flatten) ๋๋ค.
๐๐ป ์ถ๋ ฅ์ธต์์๋ ์ํํธ๋งฅ์ค ํ์ฑํ ํจ์๊ฐ ์ฌ์ฉ๋๋๋ฐ ์ ๋ ฅ๋ฐ์ ๊ฐ์ 0 ~ 1 ์ฌ์ด์ ๊ฐ์ผ๋ก ์ถ๋ ฅํ๋ค. ๋ง์ง๋ง ์ถ๋ ฅ์ธต์ ์ํํธ๋งฅ์ค ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง๊ฐ ๊ฐ ๋ ์ด๋ธ(label)์ ์ํ ํ๋ฅ ๊ฐ์ด ์ถ๋ ฅ๋๋ฉฐ, ๊ฐ์ฅ ๋์ ํ๋ฅ ๊ฐ์ ๊ฐ๋ ๋ ์ด๋ธ์ด ์ต์ข ๊ฐ์ผ๋ก ์ ์ ๋๋ค.
class CNN(nn.Module):
def __init__(self):
super(FashionCNN, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2)
)
self.layer2 = nn.Sequential(
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(2)
)
self.fc1 = nn.Linear(in_features=64*6*6, out_features=600)
self.drop = nn.Dropout2d(0.25)
self.fc2 = nn.Linear(in_features=600, out_features=120)
self.fc3 = nn.Linear(in_features=120, out_features=10)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = out.view(out.size(0), -1)
out = self.fc1(out)
out = self.drop(out)
out = self.fc2(out)
out = self.fc3(out)
return out
ํํฐ๊ฐ ์๊ฐ์ ์ถ์ผ๋ก ์ข์ฐ๋ก๋ง ์ด๋ํ ์ ์๋ค.
์ถ๋ ฅ ํํ๋ 1D์ ๋ฐฐ์ด์ด ๋๋ฉฐ, ๊ทธ๋ํ ๊ณก์ ์ ์ํํ ๋ ๋ง์ด ์ฌ์ฉ๋๋ค.
ํํฐ๊ฐ ๋ฐฉํฅ ๋ ๊ฐ๋ก ์์ง์ด๋ ํํ์ด๋ค.
ํํฐ๊ฐ ์์ง์ด๋ ๋ฐฉํฅ์ด ์ธ ๊ฐ ์๋ค. ์ด ๋, d < L์ ์ ์งํ๋ ๊ฒ์ด ์ค์ํ๋ค.
์ ๋ ฅ์ด 3D ํํ์์๋ ์ถ๋ ฅ์ด 2D ํ๋ ฌ์ผ ๋ '3D ์ ๋ ฅ์ ๊ฐ๋ 2D ํฉ์ฑ๊ณฑ'์ด๋ผ๊ณ ํ๋ค. ํํฐ์ ๋ํ ๊ธธ์ด(L)๊ฐ ์ ๋ ฅ ์ฑ๋์ ๊ธธ์ด(L)์ ๊ฐ์์ผ ํ๊ธฐ ๋๋ฌธ์ ์ด์ ๊ฐ์ ํฉ์ฑ๊ณฑ ํํ๊ฐ ๋ง๋ค์ด์ง๋ค.
3D ํํ๋ก ์ ๋ ฅ๋๋ค. 1x1 ํฉ์ฑ๊ณฑ์์ ์ฑ๋ ์๋ฅผ ์กฐ์ ํด์ ์ฐ์ฐ๋์ด ๊ฐ์๋๋ ํจ๊ณผ๊ฐ ์๋ค.
์ ์ด ํ์ต์ด๋ ์ด๋ฏธ์ง๋ท์ฒ๋ผ ์์ฃผ ํฐ ๋ฐ์ดํฐ์ ์ ์จ์ ํ๋ จ๋ ๋ชจ๋ธ์ ๊ฐ์ค์น๋ฅผ ๊ฐ์ ธ์ ์ฐ๋ฆฌ๊ฐ ํด๊ฒฐํ๋ ค๋ ๊ณผ์ ์ ๋ง๊ฒ ๋ณด์ ํด์ ์ฌ์ฉํ๋ ๊ฒ์ ์๋ฏธํ๋ค. ๋น๊ต์ ์ ์ ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ๋ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ณผ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
ํน์ฑ ์ถ์ถ(feature extractor)์ ImageNet ๋ฐ์ดํฐ์
์ผ๋ก ์ฌ์ ํ๋ จ๋ ๋ชจ๋ธ์ ๊ฐ์ ธ์จ ํ ๋ง์ง๋ง์ ์์ ์ฐ๊ฒฐ์ธต ๋ถ๋ถ๋ง ์๋ก ๋ง๋ ๋ค. ํ์ตํ ๋๋ ๋ง์ง๋ง ์์ ์ฐ๊ฒฐ์ธต(์ถ์ถ๋ ํน์ฑ์ ์
๋ ฅ๋ฐ์ ์ต์ข
์ ์ผ๋ก ์ด๋ฏธ์ง์ ๋ํ ํด๋์ค๋ฅผ ๋ถ๋ฅํ๋ ๋ถ๋ถ)๋ง ํ์ตํ๊ณ ๋๋จธ์ง ๊ณ์ธต๋ค์ ํ์ต๋์ง ์๋๋ก ํ๋ค.
model = models.resnet18(pretrained=True) #ResNet18๋ชจ๋ธ์ ์ฌ์ฉ, ์ฌ์ ํ์ต๋ ๊ฐ์ค์น๋ฅผ ์ฌ์ฉํ๋ค.
for param in model.parameters():
param.requires_grad = False # ์์ ์ฐ๊ฒฐ์ธต์ ํ๋ผ๋ฏธํฐ๋ค๋ง ํ์ต์ํฌ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํฉ์ฑ๊ณฑ์ธต๊ณผ ํ๋ง์ธต์ ํ๋ผ๋ฏธํฐ๋ ๊ณ ์
model.fc = nn.Linear(512, 2)
for param in model.fc.parameters(): # ์์ ์ฐ๊ฒฐ์ธต์ ํ์ต์ํฌ ๊ฒ
param.requires_grad = True
optimizer = torch.optim.Adam(model.fc.parameters())
cost = torch.nn.CrossEntropyLoss()
๋ฏธ์ธ ์กฐ์ (fine-tuning) ๊ธฐ๋ฒ์ ํน์ฑ ์ถ์ถ ๊ธฐ๋ฒ์์ ๋ ๋์๊ฐ ์ฌ์ ํ๋ จ๋ ๋ชจ๋ธ๊ณผ ํฉ์ฑ๊ณฑ์ธต, ๋ฐ์ดํฐ ๋ถ๋ฅ๊ธฐ์ ๊ฐ์ค์น๋ฅผ ์ ๋ฐ์ดํธํ์ฌ ํ๋ จ์ํค๋ ๋ฐฉ์์ด๋ค. ์ฌ์ ํ์ต๋ ๋ชจ๋ธ์ ๋ชฉ์ ์ ๋ง๊ฒ ์ฌํ์ต์ํค๊ฑฐ๋ ํ์ต๋ ๊ฐ์ค์น์ ์ผ๋ถ๋ฅผ ์ฌํ์ต์ํค๋ ๊ฒ์ด๋ฉฐ ๋ฐ์ดํฐ์ ์ ์ ๋ง๋๋ก ๋ชจ๋ธ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ ํ๋ ๊ธฐ๋ฒ์ด๋ค.
๋ฏธ์ธ ์กฐ์ ๊ธฐ๋ฒ์ ํ๋ จ์ํค๋ ค๋ ๋ฐ์ดํฐ์ ์ ํฌ๊ธฐ์ ์ฌ์ ํ๋ จ๋ ๋ชจ๋ธ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ ๋ต์ ์ธ์ธ ์ ์๋ค.
์ค๋ช ๊ฐ๋ฅํ CNN์ ๋ฅ๋ฌ๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ์ฌ๋์ด ์ดํดํ ์ ์๋ ๋ฐฉ์์ผ๋ก ํ๋ ๊ธฐ์ ์ด๋ค.
ํน์ฑ ๋งต์ ์
๋ ฅ ์ด๋ฏธ์ง ๋๋ ๋ค๋ฅธ ํน์ฑ ๋งต์ฒ๋ผ ํํฐ๋ฅผ ์
๋ ฅ์ ์ ์ฉํ ๊ฒฐ๊ณผ์ด๋ค. ํน์ฑ ์
๋ ฅ ์ด๋ฏธ์ง์ ๋ํ ํน์ฑ ๋งต์ ์๊ฐํํ๋ค๋ ์๋ฏธ๋ ํน์ฑ ๋งต์์ ์
๋ ฅ ํน์ฑ์ ๊ฐ์งํ ๋ฐฉ๋ฒ์ ์ดํดํ ์ ์๋๋ก ๋๋ ๊ฒ์ด๋ค.
์ค๋ช
๊ฐ๋ฅํ CNN [Colab]
๊ทธ๋ํ ํฉ์ฑ๊ณฑ ๋คํธ์ํฌ๋ ๊ทธ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ํ ์ ๊ฒฝ๋ง์ด๋ค.
๊ทธ๋ํ๋ ๋ฐฉํฅ์ฑ์ด ์๊ฑฐ๋ ์๋ edge๋ก ์ฐ๊ฒฐ๋ node์ ์งํฉ์ด๋ค.
๊ทธ๋ํ ์ ๊ฒฝ๋ง(Graph Neural Network, GNN)์ ๊ทธ๋ํ ๊ตฌ์กฐ์์ ์ฌ์ฉํ๋ ์ ๊ฒฝ๋ง์ด๋ค.
๊ทธ๋ํ ํฉ์ฑ๊ณฑ ๋คํธ์ํฌ(Graph Convolutional Network, GCN)๋ ์ด๋ฏธ์ง์ ๋ํ ํฉ์ฑ๊ณฑ์ ๊ทธ๋ํ ๋ฐ์ดํฐ๋ก ํ์ฅํ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
์ ๋ฆฌ๊ฐ ์ ๋ ๊ธ์ด๋ค์. ๋์์ด ๋์ต๋๋ค.