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-