Skip to main content

ResNet 재조명: 향상된 훈련 및 스케일링 전략

학습 방법이 모델 아키텍처 변경보다 더 중요할까? 이 글에서는 ResNet-RS 논문을 깊이 살펴보며 이 질문에 답해 보려 합니다. 이 글은 AI 번역본입니다. 오역 가능성이 있다면 댓글로 자유롭게 알려 주세요.
Created on September 15|Last edited on September 15

논문 | GitHub | 모델 체크포인트

소개

이상으로 6만 3천 회 인용, 레즈넷 오늘날에도 컴퓨터 비전(CV) 연구의 최전선에 있어 왔습니다. 최근의 대부분 CV 논문은 정확도, 속도, 혹은 둘 다에서의 향상을 보여주기 위해 결과를 ResNet과 비교합니다.
예를 들어, EfficientNet-B4 ResNet-50와 유사한 FLOPs를 가진 아키텍처가 top-1 ImageNet 정확도를 76.3%에서 83.0%까지 향상시켰습니다! [참고자료]
❓: 하지만 ImageNet top-1 정확도의 이러한 향상은 모델 아키텍처에서 비롯된 것일까요, 아니면 개선된 학습 및 스케일링 전략?
바로 이 질문이 Bello 등(2021)은 최근 논문에서 이 질문에 답하려고 시도합니다 ResNet 다시 보기: 개선된 학습 및 스케일링 전략. 그 과정에서 이들은 재스케일된 ResNet 아키텍처의 새로운 계열을 소개하는데, 이는 ResNet-RS!

왜 이 블로그를 읽어야 할까요?

원문 논문을 그냥 다운로드해서, 필요하면 출력해 읽으면 되지 않을까요? 이렇게 하지 말아야 할 이유 4가지를 소개합니다:
  1. 이 블로그의 일환으로, 우리는 새로운 ResNet-RS 이 블로그 글은 원 논문에서 생략되었을 수 있는 개념들의 맥락과 역사까지 포함해 아키텍처를 독자들에게 설명함으로써, 초보자에게도 더 친절한 형태로 제공합니다.
  2. 각 항목마다 해당 논문, 설명, 그리고 블로그로 연결되는 링크를 함께 제공했습니다. 훈련 및 정규화 전략 논문에서 언급된 예시로는 모델 EMA, 라벨 스무딩, 스토캐스틱 깊이, RandAugment, 드롭아웃그리고 더 많은 내용!
  3. 구현하는 방법을 보여줍니다 ResNet-RS 아키텍처에서 PyTorch 사용하여 TIMM.
👉: ResNet-RS 모델은 다음에서도 사용할 수 있습니다 TIMM TensorFlow에서 사전 학습된 가중치와 함께.

사전 준비 사항

ResNet-RS 아키텍처에서 제안된 구조적 변경 사항을 완전히 이해하려면, 독자들이 ResNet 아키텍처에 대해 충분히 이해하고 있는 것이 좋습니다.

ResNet-RS

소개를 마쳤으니 이제 본격적으로 살펴보겠습니다. 이 섹션에서는 다음과 같은 핵심 질문들에 답해 보겠습니다:
  1. 이 논문의 주요 기여는 무엇인가요?
  2. 어떻게 …는지 ResNet-RS 전통적인 아키텍처에서 ResNet 아키텍처인가요?
  3. 개선된 학습 전략은 무엇인가요?
  4. 저자들이 사용하고 권장한 스케일링 전략은 무엇인가요? Is 복합 스케일링 전략을 …에서 EfficientNet 가장 효과적인 연구 논문은 무엇인가요?
  5. 모델 아키텍처 개선과 비교했을 때, 학습 및 스케일링 전략은 성능을 얼마나 향상시킬까?
  6. 저자들은 ResNet-RS 학습 시 어떤 데이터 증강을 사용했나요? 그리고 이것들이 ImageNet top-1 성능에 어떻게 기여하나요?
그림-1: ResNet을 최첨단 성능으로 개선. ResNet-RS 아키텍처는 속도-정확도 파레토 곡선에서 EfficientNet을 능가하며, TPU에서는 1.7x–2.7x, GPU에서는 2.1x–3.3x의 속도 향상을 보인다. ResNet*은 256×256 이미지 해상도로 ImageNet에서 학습한 ResNet-200 아키텍처를 의미한다.
그림-1에서 볼 수 있듯이 [참고], ResNet-RS 아키텍처는 GPU에서 EfficientNet보다 최대 3.3배 더 빠를 수 있다!
개인적으로 이 그림을 분석할 때는 ResNet 아키텍처(초록색 점)를 중심으로 보는 방식을 선호한다. With 개선된 학습 및 정규화 전략 (이 글의 후반에서 논의하겠지만) 저자들은 top-1 정확도를 다음과 같이 향상시킬 수 있었다. 79.0% 까지 82.2%, 아키텍처를 전혀 변경하지 않고도! 추가적인 소규모 아키텍처 변경(이 글의 후반에서 역시 다룬다)을 통해, 저자들은 top-1 정확도를 추가로 끌어올려서 83.4%!
❓: 그렇다면 어떤 학습법과 아키텍처 변경이 있나요?
그렇다면 다음으로 살펴보죠!

개선된 학습 및 정규화 방법

이 섹션에서는 ImageNet top-1 정확도를 79.0%에서 82.2%로 끌어올린 최신 학습 및 정규화 방법을 살펴봅니다. 아키텍처를 전혀 변경하지 않고도.
표-1: ResNet-RS 학습 레시피에 대한 누적 추가 실험. 위에서 보라색, 초록색, 노란색은 각각 학습 방법, 정규화 방법, 그리고 아키텍처 개선을 의미합니다.
위의 표-1에서 학습 방법과 정규화 방법은 각각 보라색과 초록색으로 표시되어 있으며, top-1 정확도에 대한 각 방법의 기여도도 함께 제시되어 있습니다.
✅: 표-1에서 주목할 점은, 학습 에폭을 늘리면 top-1 정확도가 실제로는 -0.5% 감소하지만, 논문에 따르면 정규화 기법들을 함께 사용할 때에만 에폭 증가가 유효하다는 것입니다. 그렇지 않으면 과적합으로 이어집니다.
이제 아래에서 각 학습 및 정규화 전략을 자세히 살펴보겠습니다.

정규화 전략

가중치의 EMA

여기서 가중치의 EMA는 무엇을 의미하나요? EMA는 지수 이동 평균을 뜻합니다.
❓: 지수 이동 평균이란 무엇인가요?
예를 들어, 아담이 레모네이드를 판다고 해봅시다. 1일 차에는 레모네이드 5잔을 팔았고, 2일 차에는 3잔을 팔았습니다.
그렇다면 이틀 동안 그가 판 레모네이드의 평균 판매량은 다음과 같습니다. 5+32=4\frac{5+3}{2} = 4.
한편, 감쇠 계수가 0.99라면, 지수 이동 평균e는 0.993+0.0152=3.02\frac{0.99*3 + 0.01*5}{2} = 3.02.
✅: 지수 이동 평균은 본질적으로 최신 데이터에 더 높은 가중치를 부여합니다.
❓: 그렇다면 ResNet-RS의 개선된 정규화 전략에서 EMA는 어떤 의미인가요?
기본적으로 모델 가중치에 대해 지수 이동 평균을 취한다는 뜻입니다. 즉, 마지막 에포크 이후의 모델 가중치에 더 높은 중요도를 부여하는 동시에, 과거 에포크의 가중치도 일정 비율로 반영합니다.
❓: PyTorch에서 EMA는 어떻게 구현하나요?
아래에는 EMA의 구현을 복사해 두었습니다 TIMM.
class ModelEMA(nn.Module):
def __init__(self, model, decay=0.9999, device=None):
super(ModelEmaV2, self).__init__()
# make a copy of the model for accumulating moving average of weights
self.module = deepcopy(model)
self.module.eval()
self.decay = decay
self.device = device # perform ema on different device from model if set
if self.device is not None:
self.module.to(device=device)

def _update(self, model, update_fn):
with torch.no_grad():
for ema_v, model_v in zip(self.module.state_dict().values(), model.state_dict().values()):
if self.device is not None:
model_v = model_v.to(device=self.device)
ema_v.copy_(update_fn(ema_v, model_v))

def update(self, model):
self._update(model, update_fn=lambda e, m: self.decay * e + (1. - self.decay) * m)

def set(self, model):
self._update(model, update_fn=lambda e, m: m)
PyTorch에서 모델 가중치에 EMA를 적용하려면, 주어진 어떤 모델이든 다음과 같이 래핑하면 됩니다 ModelEMA 위에서 공유한 클래스를 사용하고 학습 중에 호출하세요 model.update() 모델 가중치의 EMA를 다음과 같이 얻을 수 있습니다:
train_dataset, eval_dataset = create_datasets()
train_dataloader, eval_dataloader = create_dataloaders()
model = create_model()

# wrap model in ModelEMA class
ema_model = ModelEMA(model)

for epoch in EPOCHS:
batch = next(iter(train_dataloader))
loss = model(**batch)
loss.backward()
# apply EMA to model weights
ema_model.update(model)
👉: 이제 독자 여러분이 위에서 공유한 지수 이동 평균(Exponential Moving Average)의 정의와 구현을 직접 매핑해 보시기 바랍니다. 질문이 있거나, CV에서의 정규화 전략 맥락에서 EMA가 잘 이해되지 않는다면 언제든지 저에게 연락하거나 이 보고서 끝에 댓글을 남겨 주세요.

레이블 스무딩

❓: 레이블 스무딩이란 무엇인가요?
✅: Microsoft Excel로 이해하는 Label Smoothing Microsoft Excel을 사용해 레이블 스무딩을 아주 명확하게 설명한 훌륭한 블로그 글입니다! 레이블 스무딩에 대한 완전한 입문을 위해 독자 여러분께 그 블로그 글을 참고하시길 권합니다.

스토캐스틱 데pth

그래서 표-1에 따르면, 스토캐스틱 데pth는 top-1 정확도를 약 +0.2% 향상시킵니다. 그런데 스토캐스틱 데pth란 무엇일까요? 그리고 어떻게 구현할 수 있을까요? 이 섹션에서는 이러한 질문에 답해 보겠습니다.
❓: 스토캐스틱 데pth란 무엇인가요?
다음에서 처음 소개되었습니다 스토캐스틱 데pth을 갖춘 딥 네트워크 Huang 등(2016)의 논문.
그림-2: 생존 확률의 선형 감소 plp_l 스토캐스틱 데pth를 적용한 ResNet에서 p0p_0=1 및 plp_l = 0.5.
이 아이디어는 그림-2에 제시되어 있습니다. 각 단계에는 잔차 경로(노란색)와 아이덴티티 경로가 있습니다. 스토캐스틱 데pth는 블록의 “생존” 확률에 따라 전체 잔차 경로의 출력을 무작위로 드롭합니다. 드롭 패스는 잔차 분기에서 가끔 열리거나 닫히는 게이트로 볼 수 있습니다. 게이트가 열려 있으면 출력이 통과되고, 블록은 원래 블록과 동일하게 동작합니다. ResNet 연구 논문.
독자께서는 …을 참고하시기 바랍니다. 논문 자세한 내용은 다음을 참고하세요.
❓: PyTorch에서 Stochastic Depth를 구현하는 방법은?
다시 아래에, Stochastic Depth의 구현을 복사해 두었습니다 TIMM.
def drop_path(x, drop_prob: float = 0., training: bool = False):
if drop_prob == 0. or not training:
return x
keep_prob = 1 - drop_prob
shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device)
random_tensor.floor_() # binarize
output = x.div(keep_prob) * random_tensor
return output


class DropPath(nn.Module):
def __init__(self, drop_prob=None):
super(DropPath, self).__init__()
self.drop_prob = drop_prob

def forward(self, x):
return drop_path(x, self.drop_prob, self.training)
👉: Stochastic Depth의 정의와 구현을 서로 대응시키는 작업은 독자 여러분의 연습으로 남겨두지만, 아래에서 짧게 답하고 싶은 질문이 하나 있습니다.
❓: 왜 입력을 나누나요? x 에서 drop_path 위의 함수로 keep_prob?
이는 드롭아웃과 유사하게 입력 활성화를 스케일링하되, 대신 학습 시점에 적용하기 위한 것입니다. 이러한 “역방향 드롭아웃(inverted dropout)”은 아주 훌륭하게 설명되어 있습니다. 여기 에서 스탠퍼드의 CS231n 강의.

RandAugment

❓: RandAugment이란 무엇인가요?
✅: RandAugment는 처음으로 다음에서 소개되었습니다 RandAugment: 검색 공간을 줄인 실용적인 자동 데이터 증강 그리고 timm 문서의 일부로 설명되어 있습니다 여기.

드롭아웃

❓: 드롭아웃이란 무엇인가요?
✅: 독자 여러분께 다음 자료를 참고하시길 권합니다 정규화 섹션CS231n: 시각 인식을 위한 합성곱 신경망 스탠퍼드의 강좌에서 더 자세한 정보를 확인해 보세요 드롭아웃.

가중치 감쇠 감소

저자들이 언급한 마지막 변경 사항 중 하나는 가중치 감쇠를 줄이는 것이었습니다.
표-2: 더 강한 정규화를 사용할수록 가중치를 더 작게 설정. 드롭아웃(DO), 확률적 깊이(SD), 라벨 스무딩(LS), RandAugment(RA) 등 정규화 방법을 조합했을 때의 다양한 정규화 설정에 대한 ImageNet 탑-1 정확도. 이미지 해상도는 ResNet-50에 224×224, ResNet-200에 256×256.
위의 표-2에서 보이듯, RandAugment와 label smoothing을 사용할 때는 기본 weight decay 값인 1e-4를 변경할 필요가 없습니다. 하지만 여기에 dropout 및/또는 stochastic depth를 추가하면, weight decay를 더 낮추지 않는 한 성능이 떨어질 수 있습니다. 직관적으로, weight decay는 정규화 역할을 하므로 여러 기법을 함께 사용할 때 과도한 정규화를 피하려면 그 값을 줄여야 한다는 뜻입니다.

학습 전략

저자들이 탑-1 정확도를 높이는 데 유용하다고 확인한 두 가지 주요 학습 전략은 다음과 같습니다 -
  1. 더 많은 에포크 동안 학습하세요(350에포크)

코사인 학습률 감쇠

❓: 코사인 학습률 감쇠란 무엇인가요?
✅: 친애하는 독자 여러분께 이렇게 권하고 싶습니다: "학습률을 다루는 방식 개선하기소개를 위해 Vitaly Bushaev의 글을 참고하세요 SGDR: 워밍 리스타트를 사용하는 확률적 경사 하강법.

ResNet-RS 아키텍처

지금까지 우리는 기본 ResNet의 top-1 정확도를 79.0%에서 82.2%로 끌어올리는 데 도움이 된 학습 및 정규화 전략을 살펴보았습니다. 아키텍처를 전혀 변경하지 않고도하지만 저자들은 소폭의 아키텍처 변경도 도입해 top-1 정확도를 83.4%까지 끌어올렸습니다! 이 섹션에서는 그러한 아키텍처 변경을 자세히 살펴보겠습니다.
본질적으로 저자들은 모든 병목 블록에 ResNet-D 수정과 Squeeze-and-Excitation(SE)을 도입했습니다.

스퀴즈 앤드 엑사이트이션

저자들은 도입했습니다 스퀴즈 앤드 엑사이트이션 기본 ResNet에서도 정확도를 한층 더 끌어올리기 위해!
❓: 그렇다면 스퀴즈 앤드 엑사이트이션은 무엇을 의미하나요?
✅: Squeeze-and-Excitation 네트워크에 대한 완전한 이해와 PyTorch 구현 코드는 다음을 참고하세요 PyTorch 구현으로 설명하는 Squeeze-and-Excitation 네트워크.

ResNet-D

저자들은 또한 도입했습니다 ResNet-D 아래에 언급된(논문 4.1절에서 언급된) 기본 ResNet 네트워크에 대한 수정 사항 ResNet-RS 논문)
  1. 스템의 7×7 컨볼루션은 처음 제안된 바와 같이 더 작은 3×3 컨볼루션 세 개로 대체됩니다. 인셉션V3.
  2. 다운샘플링 블록의 잔차 경로에서 처음 두 개의 컨볼루션에 사용되는 스트라이드 크기가 서로 바뀝니다.
  3. 다운샘플링 블록의 스킵 연결 경로에서 사용되던 스트라이드 2의 1×1 컨볼루션을, 먼저 스트라이드 2의 2×2 평균 풀링으로 대체하고 이어서 스트라이드가 없는 1×1 컨볼루션을 적용하는 방식으로 변경합니다.
  4. 스트라이드 2의 3×3 맥스 풀링 레이어를 제거하고, 다음 병목 블록의 첫 번째 3×3 컨볼루션에서 다운샘플링을 수행합니다.
이러한 수정에 기반하여, 업데이트된 아키텍처는 이제 다음과 같은 형태입니다:

그림-3: ResNet-RS 아키텍처 다이어그램. 출력 크기는 224×224 입력 이미지 해상도를 가정합니다. × 기호는 ResNet-101 아키텍처에서 블록이 반복되는 횟수를 의미합니다.
💭: 앞에서 언급한 아키텍처 변경 사항들이 독자 여러분께 잘 이해되었기를 바랍니다. 다음으로 TIMM을 사용한 PyTorch 구현을 진행할 예정입니다. 궁금한 점이 있으시면 언제든지 연락 주시거나, 이 보고서의 마지막 부분에 댓글을 남겨 주세요.

PyTorch에서의 ResNet-RS

모든 변형을 구현하는 코드를 담은 완전한 학습 노트북 ResNet-RS PyTorch에서의 모델 TIMM 그리고 다음에 대해 학습하고 Imagenette 데이터셋은 제공된 아래 텍스트:

ResNet-RS 모델 구현을 포함한 Colab 노트북

결론

이 블로그를 통해 독자 여러분께 ResNet-RS 아키텍처를 소개할 수 있었기를 바랍니다. 아래에 자유롭게 댓글을 남겨 주세요. 이 논문과 관련한 피드백을 듣거나 궁금한 점에 답변해 드리고 싶습니다. 읽어 주셔서 감사합니다!

이 글은 AI로 번역된 기사입니다. 오역이 의심되는 부분이 있다면 댓글로 알려 주세요. 원문 보고서는 다음 링크에서 확인할 수 있습니다: 원문 보고서 보기