Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
CHANGED
|
@@ -19,13 +19,23 @@ import torchvision.transforms as T
|
|
| 19 |
# 1. 모델 정의
|
| 20 |
# ──────────────────────────────────────────────────────────────
|
| 21 |
|
| 22 |
-
class
|
| 23 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
def __init__(self, in_ch, out_ch, kernel_size, stride=1, padding=0,
|
| 25 |
-
use_lrn=False, use_pool=False):
|
| 26 |
super().__init__()
|
| 27 |
self.conv = nn.Conv2d(in_ch, out_ch, kernel_size,
|
| 28 |
-
stride=stride, padding=padding, groups=
|
| 29 |
self.relu = nn.ReLU(inplace=True)
|
| 30 |
self.lrn = nn.LocalResponseNorm(5, alpha=1e-4, beta=0.75, k=2) if use_lrn else None
|
| 31 |
self.pool = nn.MaxPool2d(kernel_size=3, stride=2) if use_pool else None
|
|
@@ -37,21 +47,15 @@ class ParallelConvBlock(nn.Module):
|
|
| 37 |
return x
|
| 38 |
|
| 39 |
|
| 40 |
-
class CrossConvBlock(nn.Module):
|
| 41 |
-
"""Conv3: groups=1 로 cross-GPU 전체 채널 연결."""
|
| 42 |
-
def __init__(self, in_ch, out_ch, kernel_size, padding=0):
|
| 43 |
-
super().__init__()
|
| 44 |
-
self.conv = nn.Conv2d(in_ch, out_ch, kernel_size, padding=padding, groups=1)
|
| 45 |
-
self.relu = nn.ReLU(inplace=True)
|
| 46 |
-
|
| 47 |
-
def forward(self, x):
|
| 48 |
-
return self.relu(self.conv(x))
|
| 49 |
-
|
| 50 |
-
|
| 51 |
class AlexNet(nn.Module):
|
| 52 |
"""
|
| 53 |
논문 Figure 2 완전 재현.
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
레이어별 shape:
|
| 56 |
입력 (B, 3, 224, 224)
|
| 57 |
conv1 + pool (B, 96, 27, 27)
|
|
@@ -63,11 +67,14 @@ class AlexNet(nn.Module):
|
|
| 63 |
"""
|
| 64 |
def __init__(self, num_labels=1000, dropout=0.5):
|
| 65 |
super().__init__()
|
| 66 |
-
|
| 67 |
-
self.
|
| 68 |
-
|
| 69 |
-
self.
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
| 71 |
self.classifier = nn.Sequential(
|
| 72 |
nn.Dropout(p=dropout),
|
| 73 |
nn.Linear(256 * 6 * 6, 4096),
|
|
|
|
| 19 |
# 1. 모델 정의
|
| 20 |
# ──────────────────────────────────────────────────────────────
|
| 21 |
|
| 22 |
+
class ConvBlock(nn.Module):
|
| 23 |
+
"""
|
| 24 |
+
groups 인자로 논문의 GPU 분할 전략을 제어하는 범용 블록.
|
| 25 |
+
|
| 26 |
+
groups=1 : cross-GPU (전체 채널 연결) — Conv1·Conv3·FC
|
| 27 |
+
groups=2 : parallel (채널을 반씩 독립 연산) — Conv2·Conv4·Conv5
|
| 28 |
+
|
| 29 |
+
Conv1이 groups=1인 이유:
|
| 30 |
+
in_channels=3 (RGB)는 groups=2로 나눌 수 없음 (3 % 2 != 0).
|
| 31 |
+
논문도 실제로 Conv1은 3채널 입력 전체를 받아 96채널로 변환한 뒤
|
| 32 |
+
Conv2부터 GPU별로 채널을 분리함.
|
| 33 |
+
"""
|
| 34 |
def __init__(self, in_ch, out_ch, kernel_size, stride=1, padding=0,
|
| 35 |
+
groups=1, use_lrn=False, use_pool=False):
|
| 36 |
super().__init__()
|
| 37 |
self.conv = nn.Conv2d(in_ch, out_ch, kernel_size,
|
| 38 |
+
stride=stride, padding=padding, groups=groups)
|
| 39 |
self.relu = nn.ReLU(inplace=True)
|
| 40 |
self.lrn = nn.LocalResponseNorm(5, alpha=1e-4, beta=0.75, k=2) if use_lrn else None
|
| 41 |
self.pool = nn.MaxPool2d(kernel_size=3, stride=2) if use_pool else None
|
|
|
|
| 47 |
return x
|
| 48 |
|
| 49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
class AlexNet(nn.Module):
|
| 51 |
"""
|
| 52 |
논문 Figure 2 완전 재현.
|
| 53 |
|
| 54 |
+
groups 전략:
|
| 55 |
+
Conv1 groups=1 (in=3, RGB는 2로 나눌 수 없음)
|
| 56 |
+
Conv2·4·5 groups=2 (parallel — GPU 분할)
|
| 57 |
+
Conv3·FC groups=1 (cross-GPU — 전체 채널 연결)
|
| 58 |
+
|
| 59 |
레이어별 shape:
|
| 60 |
입력 (B, 3, 224, 224)
|
| 61 |
conv1 + pool (B, 96, 27, 27)
|
|
|
|
| 67 |
"""
|
| 68 |
def __init__(self, num_labels=1000, dropout=0.5):
|
| 69 |
super().__init__()
|
| 70 |
+
# Conv1: in=3(RGB) → groups=1 필수 (3은 2로 나눌 수 없음)
|
| 71 |
+
self.conv1 = ConvBlock( 3, 96, 11, stride=4, groups=1, use_lrn=True, use_pool=True)
|
| 72 |
+
# Conv2·4·5: in_ch가 짝수 → groups=2 로 GPU 분할 재현
|
| 73 |
+
self.conv2 = ConvBlock( 96, 256, 5, padding=2, groups=2, use_lrn=True, use_pool=True)
|
| 74 |
+
# Conv3: cross-GPU
|
| 75 |
+
self.conv3 = ConvBlock(256, 384, 3, padding=1, groups=1)
|
| 76 |
+
self.conv4 = ConvBlock(384, 384, 3, padding=1, groups=2)
|
| 77 |
+
self.conv5 = ConvBlock(384, 256, 3, padding=1, groups=2, use_pool=True)
|
| 78 |
self.classifier = nn.Sequential(
|
| 79 |
nn.Dropout(p=dropout),
|
| 80 |
nn.Linear(256 * 6 * 6, 4096),
|