ResNet 차원을 늘리고 줄이는 이유

hur-kyuh-leez·2024년 2월 14일
0

트랜스포머

목록 보기
11/11
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


class ResNet(nn.Module):
    def __init__(self, num_classes=10):
        super(ResNet, self).__init__()
        self.in_planes = 16

        self.conv1 = nn.Conv2d(3, 16, kernel_size=3,
                               stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(16)
        self.layer1 = self._make_layer(16, 2, stride=1)
        self.layer2 = self._make_layer(32, 2, stride=2)
        self.layer3 = self._make_layer(64, 2, stride=2)
        self.linear = nn.Linear(64, num_classes)

    def _make_layer(self, planes, num_blocks, stride):
        strides = [stride] + [1]*(num_blocks-1)
        layers = []
        for stride in strides:
            layers.append(BasicBlock(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 = F.avg_pool2d(out, 8)
        out = out.view(out.size(0), -1)
        out = self.linear(out)
        return out

self.conv1 = nn.Conv2d(3, 16, kernel_size=3,
                               stride=1, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(16)
        self.layer1 = self._make_layer(16, 2, stride=1)
        self.layer2 = self._make_layer(32, 2, stride=2)
        self.layer3 = self._make_layer(64, 2, stride=2)

에서 input_planes가 16,32,64 로 바뀌는 이유는...

ResNet 아키텍처에서 평면(채널) 수의 변경은 사용되는 특정 ResNet 변형에 기반합니다. 일반적으로, 한 "레이어"에서 다음으로 넘어갈 때 평면 수가 증가합니다. 예를 들어, ResNet-34에서는 평면 수가 동일한 반면, ResNet-50에서는 평면 수가 두 배가 됩니다. 이 평면 수의 변화는 주로 특징 맵의 공간 차원을 절반으로 줄이면서 발생합니다.
_make_layer 함수의 planes 매개변수는 각 레이어의 출력 채널 수를 결정하며, 일반적으로 구현하는 특정 ResNet 변형에 따라 설정됩니다. 예를 들어, ResNet-34 모델을 생성할 때, planes 매개변수는 모든 레이어에서 64로 일정할 수 있지만, ResNet-50 모델의 경우 다른 레이어에 대해 64에서 128, 256 및 512로 두 배씩 증가할 수 있습니다.
평면 수를 변경하는 목적은 공간 차원이 줄어 들면서 네트워크의 표현 능력을 증가시켜 보다 복잡한 특징을 더 높은 추상 수준에서 학습할 수 있도록 하는 것입니다.
따라서 평면 수를 변경하는 결정은 구현되는 특정 ResNet 변형의 설계와 그 아키텍처적 요구 사항에 기반합니다.
-by perplexity-

profile
벨로그에 생각을 임시로 저장합니다. 틀린건 틀렸다고 해주세요 :) 그래야 논리 학습이 강화됩니다.

0개의 댓글