본문 바로가기
Lectures/BoostCamp -Naver

1-2. mmdetection faster rcnn의 scheduler 잡지식

by yooom 2024. 1. 20.
목차
1. mmcv 2.x ver code flow 리뷰 ( 순한맛 )
1-1. faster rcnn train/ inference코드 리뷰 & Config 수정 (부스트 캠프 제공)
1-2. faster rcnn의 scheduler 잡지식

2. mmcv 2.x config 파일 사용법 ( 순한맛 )
2-1. cascade rcnn 사용법
2-2. ConvNext 사용법 (mask rcnn, fp16 error)

3. mmcv 외부 라이브러리 사용법 ( 안순한맛 ) // DINO, CoDETR은 MMCV 3.x ver
3-1. swin b / L 사용법
3-2. UniverseNet 사용법
3-3. FocalNet 사용법

4. Optional
4-1. wandb 사용법, 사용 안 하는 법
4-2. val 나누기 (random split, stratified group k fold)
4-3. loss function 바꾸기, cross entropy에 가중치 바꾸기, nms→soft-nms 바꾸기,
4-4. ensemble. nms→wbf로 추론 하기
4-5. correlation matrix hitmap 제작
4-6. val data에 bbox, gt_box 띄우기

 

_base_/schedules에는 3개 파일이 있다

여기서 1x는 12epoch, 2x는 24epoch, 20e는 20epoch을 의미한다.

 

SGD를 사용하고 있고,

policy = 'step'인 걸 보아하니 scheduler를 step으로 선언하여 step이 8epoch, 11epoch에서 0.0001씩 learning rate를 줄일 것이다.

그럼

1~7epoch동안 lr = 2e-2

8~10epoch동안 lr = 2e-6

11~12epoch동안 lr = 2e-10 으로 진행되겠다.

 

optimizer

딕셔너리 안에 type='SGD'가 덩그러니 적혀있다.

이건 torch.optim 에서 정의된 클래스를 가져오는 거다. 즉, 여기서 정의된 건 아니고 pytorch에 정의된 모든 optimizer를 이름만 적으면 가져올 수 있다는 거다.

SGF, Adam, AdamW, Adagrad, Adadelta. LBFGS, SparseAdam, Rprop 이런 것들이 있다.

 

나를 포함한 대부분이 무지성 AdamW를 쓰겠지만, 적어도 Adam과 AdamW의 차이는 무엇인지. Adam과 AdamW의 수식은 어떻게 되고 학습에 어떤 의미를 가지는지, 각각의 파라미터는 어떤 영향력을 행사하는지는 알고 가자. 면접 질문으로 멘탈 파사삭 되기 좋은 영역이다.

 

SGD의 경우 lr=0.02

AdamW의 경우 lr=0.001부터 주로 시작한다.

 

그런데 나의 경우 심할 때는 5e-8에서 시작하기도 했다.

optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
optimizer = dict(type='AdamW', lr=1e-3, betas=(0.9, 0.999), weight_decay=0.0001)

이런 식으로 선언하면 된다.

 

 

scheduler

뿌캠에 와서 멘토님께 제일 잘 배웠다고 생각하는 것이다.

relu를 leaky relu로 바꾸고, sota 모델을 사용하고 이런 거 보다 learning rate 잘 조절하는 게 더 중요하다(물론..되도록 좋은 모델 선택하자..) 

 

지금까지 scheduler로 step만 썼었다. 큰 lr로 학습해서 빠르게 loss를 줄이고 막판에 작은 lr로 최적값 찾기.

하지만 극소값에 갇힐 위험이 있다는 생각을 지금까지 못 했었다.

모델은 아주 고차원에서 복잡한 지형 환경에서 훈련을 받는다. 이때 순진하게 step으로만 접근하면 최솟값에 접근하지 못한 채 val loss는 높으면서 train loss만 0%대를 찍는 과적합인 극소점에서 벗어나질 못한다.

이미 lr이 작아서 극소점을 탈출하려면 큰 힘이 필요하다. 그래서 착안된 게 scheduler다

스케줄러 종류는 아주 많다.

https://gaussian37.github.io/dl-pytorch-lr_scheduler/

 

Pytorch Learning Rate Scheduler (러닝 레이트 스케쥴러) 정리

gaussian37's blog

gaussian37.github.io

나는 초반에 step을 사용하다가 cyclic scheduler를 사용해봤다.

큰 차이는 못 느꼈지만 언젠가 sheduler사용법에 경험이 쌓이고 익숙해지면 잠재력을 깨울 수 있을 것 같다.

 

코드로는 이렇게 사용했다.

# learning policy : step
lr_config = dict(
    policy='step',
    warmup='linear',  # 500 iter까지 lr을 linear하게 서서히 증가시킨다.
    warmup_iters=500, # 이걸 해놔도 처음 grad_norm이 10만을 찍는 걸 보게 될 거다.ㅋㅋ
    warmup_ratio=0.001,
    step=[27, 33])
runner = dict(type='EpochBasedRunner', max_epochs=36)

# learning policy : cyclic
lr_config = dict(
    policy='cyclic',
    by_epoch = False, # epoch단위 말고 iter 단위로 주기를 갖는다.
    target_ratio = (100, 0.1), # 초기 lr선언값보다 100배 증가했다가 0.1배 하락한다.
    cyclic_times = 5, # 전체 epoch중에 5번의 주기를 갖는다.
    step_ratio_up = 0.2, # 한 주기 안에서 0.2주기 동안 상승한다.
    anneal_strategy = 'cos', # lr이 감소할 때 형태다. linear, exp, cos이 있다. exp는 급격하게 감소
    gamma = 0.5, #다음 주기에서 peak값을 *0.5한 값으로 한다.
    warmup_iters=1000 # cos함수를 쓰지만 warmup 때문에 sin처럼 보일 수 있다.
728x90

댓글