코드(깃허브)
https://github.com/LGMpr/Pre-trained-Resnet-with-CIFAR-10-Transfer-Learning-/blob/main/aa
Pre-trained-Resnet-with-CIFAR-10-Transfer-Learning-/aa at main · LGMpr/Pre-trained-Resnet-with-CIFAR-10-Transfer-Learning-
Contribute to LGMpr/Pre-trained-Resnet-with-CIFAR-10-Transfer-Learning- development by creating an account on GitHub.
github.com
들어가며
1. 따라한 모델 : https://velog.io/@pppanghyun/%EC%A0%84%EC%9D%B4%ED%95%99%EC%8A%B5Transfer-Learning (전이학습)
* test accuracy : 약 81%
2. pretrained 된 것이 돌아간다는 것 보는 것 만이 목적임. 성능 목적 X
3. transform(RandomCrop(32, padding=4), Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
4. batch_size = 16, epoch = 20, optim = Adam, lr = 0.0001, weight_decay=0.01, Loss = CELoss
시작
1. 이걸 이제 하나씩 바꾸면서 좀 나아지게 할 것. 단, 데이터 적용 외의 모델 구조 자체는 유지
2. initialization, random은 걱정할 필요 없음. 그대로 불러오는거니까
3. 시간(직장인 ㅠㅠ), GPU(코랩 무료) 관계상 epoch은 좀 줄여서 해보기..
4. 목표는 accuracy 90% 이상으로
초기 모델(Base)
1. batch : 32, epoch : 10
2. 결과 : train_acc 76.9%, test_acc 81.6%(왜 높아???), 8m10s 소요
3. epoch 20으로 올려서 다시 해보자
epoch 20(Base2)
1. 결과 : train_acc 80.3%, test_acc 82.3%(???), 16m22s 소요
2. 해석 : 왜... 여전히 test가 더 잘나오는가
가. epoch1로 했을때 train_acc 59.7%, test_acc 74.9%
나. 아예 학습 안시켰을때(backward, optimizer 주석처리) train_acc 9.9%, test_acc 9.3%
* 근데 왜 어느정도 학습이 될까?(최초 5%까지 나왔는데 점차 개선되서 안정적인 9% 후반대 나옴)
다. train을 아예 안하고 test_acc 10%
* 상식적으로 10개 클래스 있으니까 10%가 합리적이긴함. 각 클래스별 데이터가 동일(5000개씩) 하기도하고.
* 근데 pretrained인데 그냥 10%가 맞나? 싶을 수 있음. 이유는 출력층 layer를 바꿨고 여기 파라미터는 학습 안된거나 마찬가지(initialzation을 하는게 나을까 아닌게 나을까?. 재정의하면 parameter는 다시 임의의 수들로 나오겠지?)
라. Test Accuracy가 train Accuracy보다 높은 이유(perplexity + 구글링)
1) 데이터 : train 데이터셋 작은 경우, train/test데이터 분포 차이, 우연히 테스트 데이터가 더 쉬울때
2) 과도한 정규화, 학습시에만 사용되는(dropout 같은) 것의 문제
3) Data Augmentation이 과할때(train이 너무 어려울때)
4) 코드를 잘못 짰을때!!!
* 이걸 제일 의심해서 data 쪽이랑 Accuracy 구하는쪽 자세히 봤지만 뭐 없음. 애초에 어려운 곳도 아니고 Accuracy는 똑같은 구조..
torchinfo
1. 뭔가 내가 놓치고있나 싶어 torchinfo를 찍어봤다

2. 모르겠다. 코랩 무료 GPU도 끝났고... 일단 여기까지..
3. 코랩 pro 지름.

epoch 1(Base4)
1. epoch 1로해서 train보다 test가 높은 이유 찾기
2. 기본 : train 62.5%, test 74%
가) Data Augmentation에서 RandomCrop 제외 train 65%, test 76%
나) 거기에 Shuffle False : train 66%, test 77%
* test가
다) 거기에 Shuffle True로, lr 0.001로 높이고 epoch 10까지 : Learning Curve가 눈에 띄게 낮아서 중단.
라) lr 돌려놓고 epoch 10 : train 84.6%, test 82.5%
* 정상화됨... epoch 수 문제였던 것 같음. 그냥 언더피팅...
마) RandomCrop 돌려놓고 30 epoch까지 해봄(시간 24분..ㅠㅠ) : train 82%, test 82.4%.........
바) epoch 10, RandomCrop 안한걸로 기본값 잡기. Learning Curve 보고 가장 잘나왔을때 그때 epoch 늘려서 하기
Normalization(0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010) 변경 (mod1)
1. 차이없음!
2. 해석 : 값이 최초 세팅의 0.5와 큰 차이 없기때문에 유의미한 차이가 있기는 힘들었던듯(분산 최대 차이가 0.3정도)

LR 0.01로 변경 (mod2)
1. train 32%, test 33%
2. 해석 : 최악임. 차라리 아무것도 안한게 높을 수준. Learning Curve도 4k 넘어가면서 완만해짐. Local minimum에 빠진거 아닌가 추측
3. LR 0.1로 변경(mod2.1) : 끔찍한 모습에 중단. 가장 처음에 짧고 안좋아보이는게 LR 0.9로 해본 것. 감소함
4. LR 0.1, weight decay 제거(mod2.2) : 유의미한 증가. 이건 epoch 더 늘려야 결과 볼 수 있을 것 같음.
weight decay에 대해 정확히 모르고 있었음.
***** 이래서 이론이 중요하다 *****
* epoch 30까지 해봤을때. train 69.1%, test 70%.

LR 0.0001로 복귀(weight decay 포함), batch_size 128로 변경 (mod3)
1. train 88.7%, test 81.7%
2. 해석 : 처음부터 이 세팅으로 가야했던 것 같다. batch 사이즈가 커지니까 step 작아지고 속도 빨라지고 정확도 높아지고..
3. epoch 20까지 했을때 train 92.6%, test 80.8%. 이걸로 베이스 변경하자... epoch 10은 유지(test accuracy는 동일)
4. Data Augmentation에서 RandomCrop 다시 적용시 train 79.8%, test 81.9%.
5. batch 256, epoch 20으로 늘려서 다시한번. train 85.3%, test 83.3%.(3.0) - 제일 좋음
6. batch 512, epoch 20 train 85.1%, test 83.1%.(3.0+)
7. batch 1024, epoch 20 train 83.2%, test 81.4%.(3.0+)
8. 시간은 다 비슷함(10분 내외)
Optimizer Momentum(0.9)으로 변경 (mod4)
1. train 58%, test 68.9%
2. 해석 : Adam 최고. 참고 모델들은 모멘텀 사용했지만 내 모델은 아님. 다만 추가적인 조정이 필요했을 수도 있겠음.
Adam 복귀, RandomHorizontalFlip() 추가 (mod5)
1. train 83.4%, test 83.7%
2. 해석 : train이 아직 test보다 낮다는 것은 더 상승 여지가 있다는 것 같음. epoch 30으로 다시. 생각해보니 처음부터 할게 아니라 그냥 epoch 10만 주고 실행 셀만 하면 되는거잖아...
3. epoch 30 train 85.8%, test 84.5%. 가장 좋음. 이대로 유지
layer wise learning rate(fc만 0.01로/weight_decay 미사용) (mod6)
1. train 00%, test 00%
2. Learning Curve 보니까 안됨. 중반부부터는 학습도 거의 못함. Weight_decay 0.01(mod6.1)로 해도 극초반만 잘함. 0.1(mod 6.2)로 다시 조정
3. 해석 : 다만 초기 학습은 확실히 빠름. 그 이후가 문제임.
왜 중반부터는 안될까요????

최종
1. 모델(epoch 100)
가. 튜닝 : Batch size, Adam, Normalize, transforms(transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip())
나. 제거 : layer wise lr, Momentum
다. 안써본거 : learning scheduler
2. 결과 : train 91.1%, test 85.3%
3. 해석
가. 시간이 없으니 Colab A100을 써봤다. 리소스가 어우...
나. 그래도 지금까지중에 가장 잘, 정상적으로 나왔다.
대학원 입시 관련 제도 알아보고 사람 만나고 부대 옮기고 연말 회식 + 전출/전입 회식 하다 2주만에 돌아와서
코드를 다시 뜯어봤다
신선한(?) 뇌가 확인한 것은 train_accuracy 구하는 코드에 문제가 있다는 것!
- epoch마다 초기화해줘야하는데 안해줬음
- 그래서 "누적" train_accuracy가 나왔음. 그러다보니 epoch이 많아져야만 초기의 에러값들이 희석되면서 train>test가 된 것
- 초기화 코드를 넣었더니 epoch 10만 했을때 train 85.9%, test 82.7%
* 다시 빼봤더니 train 78.7%, test 82.8%
- 다만, Learning curve가 좀 더 구불구불함. 누적이 아니어서 안정성이 떨어져서 그럴지도
batch별로 구하기때문에도 안정도가 떨어질 것
헤헿 난 돌이다 헤헿
그래도 모델 개선 프로세스 자체에는 희망을 갖고! 일단 유지. 너무 길어져서 2탄으로...
앞으로 할/배울 것
1. 모델 저장하는 법. 가장 잘나온거 저장했었으면 시간 훨씬 아낌
2. learning scheduler 써보기
3. 작은 데이터셋(Flower 등)
참조1
https://github.com/kuangliu/pytorch-cifar (Train CIFAR10 with PyTorch)
Normalize : ((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))
augmen : transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip()
batch_size : 128(train), 100(test)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=args.lr,
momentum=0.9, weight_decay=5e-4)
lr = 0.1
epoch = 200
참조2
changed number of class, filter size, stride, and padding in the the original code
normalize = [0.4914, 0.4822, 0.4465] [0.2471, 0.2435, 0.2616]
T.RandomCrop(32, padding=4), T.RandomHorizontalFlip(),
batch_size = 256
optimizer = optim.SGD(net.parameters(), lr=args.lr,
momentum=0.9, weight_decay=0.01)
lr = 0.01
epoch = 100
'코드' 카테고리의 다른 글
| Channel-wise dropout 코드 구현 (9) | 2024.12.29 |
|---|---|
| Pre-trained Resnet with Flowers102(Transfer Learning) (8) | 2024.12.29 |
| Pre-trained Resnet with CIFAR-10(Transfer Learning) 2탄 (6) | 2024.12.28 |
| pytorch datasets (11) | 2024.12.10 |
| MNIST 홀짝분류 코드 구현 및 분석(pytorch) (3) | 2024.12.04 |