Skip to main content

ResNet 다시 보기: 향상된 학습과 스케일링 전략

학습 방법이 모델 구조 변경보다 더 중요할까? 이 글에서는 ResNet-RS 논문을 자세히 살펴보며 이 질문에 답해 보려고 합니다. 이 글은 AI 번역본입니다. 오역이 있을 경우 댓글로 알려 주세요.
Created on September 15|Last edited on September 15

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

소개

이상으로 인용 63,000회, ResNet 오늘날에도 컴퓨터 비전(CV) 연구의 최전선에 서 왔습니다. 최근의 대부분 CV 논문은 정확도, 속도, 혹은 둘 다에서의 개선을 보여 주기 위해 결과를 ResNet과 비교합니다.
예를 들어, EfficientNet-B4 ResNet-50와 유사한 FLOPs를 가진 아키텍처가 ImageNet top-1 정확도를 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 아키텍처에 대해 충분히 숙지하고 있는 것이 좋습니다.
제14장 Fastai와 PyTorch로 배우는 딥러닝: 박사 학위 없이 만드는 AI 애플리케이션 작성자 제러미 하워드 그리고 실뱅 구제르 은(는) 다음 내용을 학습하는 데 훌륭한 자료입니다 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 학습 레시피에 대한 누적적(Additive) 연구. 위의 보라색, 초록색, 노란색은 각각 학습 기법, 정규화 기법, 아키텍처 개선을 나타냅니다.
위의 표 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라면, the 지수이동평균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)
👉: 이제 독자 여러분이 위에서 공유한 지수이동평균(EMA)의 정의와 구현을 스스로 대응시켜 보시기 바랍니다. 질문이 있거나, CV의 정규화 전략 맥락에서 EMA가 잘 이해되지 않는다면 언제든지 저에게 연락하시거나 이 보고서 말미에 댓글을 남겨 주세요.

라벨 스무딩

❓: 라벨 스무딩이란 무엇인가요?
✅: Microsoft Excel로 설명하는 라벨 스무딩 Microsoft Excel을 사용해 라벨 스무딩을 설명한 훌륭한 블로그 글입니다! 라벨 스무딩에 대한 완전한 소개는 그 블로그 글을 참고하시길 바랍니다.

스토캐스틱 데pth

표 1에 따르면, 스토캐스틱 데프는 top-1 정확도를 약 +0.2% 정도 향상시킵니다. 그런데 스토캐스틱 데프란 무엇일까요? 또, 어떻게 구현할 수 있을까요? 이 절에서는 이러한 질문에 답해 보겠습니다.
❓: 스토캐스틱 데프란 무엇인가요?
도입된 것은 스토캐스틱 데프를 사용하는 딥 네트워크 Huang 등(2016)의 논문.
그림 2: 생존 확률의 선형 감소 plp_l 스토캐스틱 데프를 적용한 ResNet에서 p0p_0=1 및 plp_l = 0.5
이 아이디어는 그림 2에 제시되어 있습니다. 각 단계마다 잔차 경로(노란색)와 아이덴티티 경로가 있습니다. 스토캐스틱 데프는 블록의 “생존” 확률에 따라 전체 잔차 경로의 출력을 무작위로 드롭합니다. 드롭 패스는 잔차 분기 위에 달린 게이트처럼 볼 수 있으며, 때때로 열리거나 닫힙니다. 게이트가 열려 있으면 출력이 통과하고, 블록은 원래 블록과 동일하게 동작합니다. 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) 드롭아웃”에 대해서는 아주 훌륭한 설명이 있습니다. 여기 에서 스탠퍼드의 CS231n 강의.

RandAugment

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

드롭아웃

❓: 드롭아웃이란 무엇인가요?
✅: 친애하는 독자 여러분께서는 다음을 참고하시기 바랍니다 정규화 섹션CS231n: 시각 인식을 위한 합성곱 신경망 자세한 내용은 스탠퍼드 강의를 참고하세요 드롭아웃.

가중치 감쇠 감소

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

훈련 전략

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

코사인 학습률 감쇠

❓: 코사인 학습률 감쇠란 무엇인가요?
✅: 사랑하는 독자 여러분께 이렇게 권하고 싶습니다: "학습률을 다루는 방식을 개선하기비탈리 부샤예프의 입문 자료를 참고하세요 SGDR: 웜 리스타트를 사용하는 확률적 경사 하강법.

ResNet-RS 아키텍처

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

스크위즈 앤드 엑사이트레이션

저자들은 스크위즈 & 엑사이트레이션 기본 ResNet에 적용해 정확도를 한층 더 끌어올리기 위해서입니다!"
❓: 그렇다면 Squeeze-and-Excitation은 무엇을 의미하나요?
✅: Squeeze-and-Excitation 네트워크의 개념을 완전히 이해하고 PyTorch 코드 구현까지 확인하려면 다음을 참고하세요 PyTorch 구현과 함께 알아보는 Squeeze-and-Excitation 네트워크.

ResNet-D

저자들은 또한 ResNet-D 아래에 언급된(논문 4.1절에서 언급된) 기본 ResNet 네트워크에 대한 수정 사항 ResNet-RS 논문):
  1. 스템의 7×7 합성곱은 처음 제안된 바와 같이 더 작은 3×3 합성곱 세 개로 대체됩니다 InceptionV3.
  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로 번역된 기사입니다. 오역이 있을 수 있으니 댓글로 알려 주세요. 원문 보고서는 아래 링크에서 확인하실 수 있습니다: 원문 보고서 보기