resnet에 대해서 먼저 언급해야할 것 같다. resnet은 마이크로소프트에서 만들어낸 알고리즘이다.
이걸 쓰게 된 계기는 전보다 더욱 정교한 판정이 필요하다고 생각했기 때문이었다.
나동빈의 유튜브를 참고하여 구조를 공부했다. 굉장히 도움이 많이 되었다.
https://github.com/ndb796/Deep-Learning-Paper-Review-and-Practice
GitHub - ndb796/Deep-Learning-Paper-Review-and-Practice: 꼼꼼한 딥러닝 논문 리뷰와 코드 실습
꼼꼼한 딥러닝 논문 리뷰와 코드 실습. Contribute to ndb796/Deep-Learning-Paper-Review-and-Practice development by creating an account on GitHub.
github.com
https://www.youtube.com/watch?v=671BsKl8d0E
이걸 참고하여 코드를 작성했다.
# 5. ResNet 모델 정의
class BasicBlock(nn.Module):
def __init__(self, in_planes, planes, stride=1):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.shortcut = nn.Sequential()
if stride != 1 or in_planes != planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, planes, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(planes)
)
def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = F.relu(out)
return out
BasicBlock은 skip connection 구조를 이렇게 짰다.
컨볼루션층은 2개로 만들고 3x3 컨볼루션층이다.
shortcut는 입력을 바로 더해주기 위한 경로다.
forward의 역할
입력 x를 conv1, bn1, ReLU를 거쳐 out으로 만든다.
out을 conv2, bn2를 거치고, 입력 x와 out을 더해준다.
최종적으로 ReLU를 적용하여 리턴하게 된다.
ResNet:
여러 Residual Block을 쌓아 전체 네트워크를 구성한다.
ResNet18은 [2, 2, 2, 2] 구성으로 총 18개의 레이어를 가진다.
class ResNet(nn.Module):
def __init__(self, block, num_blocks, num_classes=10):
super(ResNet, self).__init__()
self.in_planes = 64
self.conv1 = nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
self.linear = nn.Linear(512, num_classes)
def _make_layer(self, block, planes, num_blocks, stride):
strides = [stride] + [1] * (num_blocks - 1)
layers = []
for stride in strides:
layers.append(block(self.in_planes, planes, stride))
self.in_planes = planes
return nn.Sequential(*layers)
def forward(self, x):
out = F.relu(self.bn1(self.conv1(x)))
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = F.avg_pool2d(out, 4)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out
def ResNet18():
return ResNet(BasicBlock, [2, 2, 2, 2])
근데 문제가 생겼다. 우리가 만들어낸 데이터셋은 너무나 부족했다. 그래서 정확하게 거북목 판단을 하지 못했다. 봤던 논문들을 봤을때 적어도 1000장은 필요해 보였는데 우리가 만들기엔 너무 많았다. 그래서 결국 resnet은 사용하지 않기로 했다.
'개인공부' 카테고리의 다른 글
[flask] flask 간단 사용 (0) | 2024.05.22 |
---|---|
dlib library 설치 (0) | 2024.05.21 |
[springboot] 회원가입 (0) | 2024.05.19 |
[SpringBoot] SpringBoot + Maven (0) | 2024.05.15 |
졸업 작품 주제 (0) | 2024.05.09 |