사물 이미지 분류 AI 해커톤

전처리 및 CNN 코드 설계하기 (0.8808)

2022.02.23 04:36 8,257 조회 language

안녕하세요 lastdefiance20입니다.

코드 공유가 현재 baseline 말고 전무한 상태라 초반에 접근하지 못하는 초보분들을 위해서 작은 도움이라도 주기위해 진행중인 코드를 올립니다.

Resnet 등 유명한 모델들을 요즘에는 쉽게 불러와서 사용할 수 있다고는 하나, 초보 분들은 제 코드처럼 한번 자신만의 cnn 구조를 제작하며 함께 딥러닝의 개념을 적립해갔으면 합니다.

아직 미완성된 코드이며 현재진행형입니다. 추후에는 높은 성능을 달성하기 위해 논문 기법들을 구현해볼까 생각중입니다.

순서는 데이터 불러오기(학습 준비 단계) -> 데이터 전처리(augmentation) -> 모델 생성하기 -> 모델 학습하기 -> 제출하기 순으로 이루어져있습니다.

코드의 틀은 Dacon에서 제공한 baseline을 참고하였습니다.

기본 CNN 구조  -> 0.8058 
기본적인 data augmentation, CNN 깊이 증가-> 0.8578, 0.8654 
Mixup 추가 -> 0.8694
epoch 변경, CNN깊이 증가 -> 0.8764
CNN깊이 증가 -> 0.8808

더이상 추가적인 성능향상이 어려운것 같습니다. (TTA 기법을 사용하면 좋아질수도?)

피드백, 궁금증은 댓글로 남겨주시면 감사하겠습니다.

코드
로그인이 필요합니다
0 / 1000
HyunJin
2022.02.23 14:37

코드공유 감사합니다! 많이 배워갑니다!

lastdefiance20
2022.02.23 20:56

HyunJin님 제 코드를 읽어주셔서 감사합니다!

McNuggetSet
2022.02.23 18:36

공유해 주신 코드로 공부해보겠습니다! 코드공유 감사합니다 ㅎ 다음에 올리실 강의글도 기대하고 있겠습니다 ^^b

lastdefiance20
2022.02.23 20:57

McNuggetSet님 아직 생각하고 있는 기능을 사용해보기 전에 기본 모델을 급하게 올린거라 계속 이 글이 업데이트될 예정입니다! 좀 더 디테일하게 서술해 보겠습니다.

성지코딩
2022.02.23 18:46

대강 봐도 깔끔하게 잘 정리해주신 것 같네요! 이번에도 도움 많이 받겠습니다ㅎㅎ 저는 금요일부터 개발을 해보려고 합니다!
혹시 딥러닝 모델을 개발하실 때, tensorflow를 애용하시나요 pytorch를 애용하시나요?? 그리고 서로의 장단점을 대강 알고계시면 공유해주실 수 있을까요?

lastdefiance20
2022.02.23 21:20

성지코딩님 반갑습니다! tensorflow나 pytorch 둘 모두 좋은 딥러닝 프레임워크입니다. 저는 여기서 무언가를 애용한다기보다는 둘 모두 필요하다고 생각해서 한번씩 한번씩 번갈아가면서 썼습니다.(아직 주로 어떤걸 사용할지 정하지를 못했습니다.) 다만 지금처럼 쉽고 빠르게 기초 모델을 제작할때는 tensorflow의 keras를 사용하면 위의 모델생성 부분처럼 몇줄이면 충분하기 때문에 연습하는 차원에서 keras를 이용하여 학습해보았습니다. 둘의 장단점에 대해서는 이곳에 더 자세하게 나와있다고 생각합니다. 

https://hongong.hanbit.co.kr/딥러닝-프레임워크-비교-텐서플로-케라스-파이토치

geehwo
2022.02.23 19:32

너무 아름다운 코드입니다. 텐서플로우를 처음사용해봤는데 어떤식으로 전처리를 해야하는지 이해는 못했어도 구성은 대강 파악할수있엇습니다!

lastdefiance20
2022.02.23 21:22

geehwo님 텐서플로우를 처음 사용해서 혼란스러울지라도 몇번 예제를 따라하다보면 어느정도 윤곽이 잡히고 쉬워지기 때문에 포기하지 않고 도전하시길 바랍니다!

jinmc
2022.02.24 11:12

멋지네요! 저도 한번 트라이 해보고, 가능하면 다른 식으로도 접근해서 올려보도록 하겠습니다!
감사합니다~

lastdefiance20
2022.02.24 11:52

jinmc님의 코드 공유 기대하겠습니다!

도녁
2022.02.26 14:28

안녕하세요, 처음 데이콘에 참가해보는데요, 공유해주신 코드와 설명 보면서 많이 배우고 있습니다. 감사합니다!
코드 따라가면서 해보는 중인데, 질문이 있습니다! Dataset 나누기 파트에서 training_labels = training_labels.reshape(-1,10) 코드를 수행하게 되면 기존 training_labels의 shape이 (150000, 1) 에서 (15000, 10)으로 변하게 됩니다. (Mixup은 생략하고 위의 aug만 진행했습니다.) 이후 바로 아래 코드에서 에러가 생깁니다.
X_train, X_valid, y_train, y_valid = train_test_split(training_images, 
                                                      training_labels, 
                                                      test_size=0.1, 
                                                      stratify = training_labels, 
                                                      random_state=42)

ValueError: Found input variables with inconsistent numbers of samples: [150000, 15000]
표본 수가 일치하지 않는다고 에러가 뜨는데 해결 방안이 있을까요?
reshape 코드를 지우고 진행하면 모델 학습 부분에서 또 shape에러가 떠서 모델 층의 마지막 Dense layer의 10개 라벨을 1개 라벨로 바꾸어보았는데, 학습은 돌아가지만 정확도가 매우 떨어져서 질문 드립니다 ㅠ

lastdefiance20
2022.02.26 20:06

안녕하세요 도녁님, 제가 training_labels = training_labels.reshape(-1,10) 코드를 적용한 이유는 one-hot 기법을 적용해주게 되면 shape가 (150000, 1, 10)으로 변하게 되어서, 이를 (150000, 10)으로 바꾸기 위해서입니다.

mixup 부분에서 'training_labels = tf.one_hot(training_labels, 10)' 이 코드를 통과하게 되면 (150000, 1) -> (150000, 1, 10)으로 변하게 되어 이를 (150000, 10)으로 reshape를 진행해준것이기 때문에 mixup을 진행하지 않았다면 굳이 reshape를 진행해줄 필요가 없습니다. mixup에서 one-hot 기법을 적용하지 않았다면 label encoding만 진행해줬기 때문에 (150000, 1) shape이 맞습니다.

혹시 reshape를 코드를 지우고 진행했을때 어떤 shape error가 나는지 알 수 있을까요? 코드를 지우고 에러가 난다면, reshape 코드 수행 전에  'training_labels = tf.one_hot(training_labels, 10)' 을 추가해 보셔도 해결될것 같습니다.

또한 마지막 Dense layer의 10개 라벨을 1개 라벨로 바꾼다는 것은 부적절한 대처입니다. 우리가 지금 10개의 사물을 구별하는 대회이기 때문에 마지막 레이어에서는 'softmax'라는 함수를 사용하여 10개의 확률 결과로 return하는 것입니다. 따라서 여기서 1로 바꾸게 된다면 아마 전부 'airplane' 등 하나의 사물로만 판단하게 되겠죠... 마지막 Dense layer의 'softmax' 함수의 역할은 이곳에도 잘 나와있습니다. https://yong0810.tistory.com/20

도녁
2022.02.27 01:54

reshape 코드를 지우고 진행했을 때, model.fit 부분에서
 ValueError: Shapes (None, 1) and (None, 10) are incompatible
라는 에러가 생깁니다! 10개 라벨을 1개 라벨로 바꾸는 것은 부적절한 대처라는 것 이해했습니다! 감사합니다!

'training_labels = tf.one_hot(training_labels, 10)' 을 추가하면 잘 작동하네요. 정말 감사합니다!

gs
2022.02.26 17:50

코드 공유에 감사드립니다.
GlobalAveragePooling2D는 처음 보네요. 항상 flatten을 썼었는데 배워갑니다. pytorch에도 있는지 찾아봐야겠습니다. 전 필터의 개수를 256개까지만 해서 70% 정도의 정확도가 나왔는데, 이 코드처럼 512개까지도 한번 늘려봐야겠어요.
그리고 질문이 하나 있는데, 혹시 early stopping을 쓰지 않으신 이유가 있나요?
제 생각에 dropout보단 early stopping이 더 나은 방법인 것 같아서요.

lastdefiance20
2022.02.26 20:00

gs님 저도 처음에는 flatten을 사용했는데, global average pooling을 적용했더니 더욱 성능이 잘 나와서 사용하고 있습니다. 또한 제가 필터의 개수를 선정한 근거는 vggnet에서도 64 -> 128 -> 256 -> 512 순으로 늘어나기 때문에 적용해보았는데, 생각보다 성능이 꽤 좋아서 사용하고 있습니다. 

또한 early stopping은 현재 mixup을 사용하니 loss가 overfitting된것처럼 튀는 반면, 이상하게 성능은 잘나와서 학습중 early stopping이 일어나 underfitting이 되지 않도록 잠시 원인을 파악할때까지 빼뒀습니다. early stopping은 '학습, epoch가 과도하게 진행되어 loss 혹은 accuracy가 낮아질때, 자동으로 멈추겠다' 라는 기법이지, 모델 내부에 직접적으로 영향을 끼치지는 않기 때문입니다.

다만 dropout은 항상 사용하고 있습니다. 오류가 있을수 있지만 쉽게 설명드리자면 dropout은 한 집단에서 목소리 큰 사람이 있다고 가정해봅시다. 그 사람을 그대로 내버려두면 집단에 의견을 물었을때 목소리 큰 사람에게 유리한 편향적인 의견이 나올겁니다. 여기서 dropout를 사용하면 목소리 큰 사람을 잠시 제외해두고 다른 사람이 발언하게 함으로써 나중에는 다른 사람들도 목소리가 커져서(?) 한사람에게 편향적이지 않고 집단지성적으로 의견이 나오게 된다는 거죠... 물론 목소리 큰 사람이 가장 현명했을 확률도 있지만, 항상 모든 상황에서 dropout를 적절하게 적용한 모델의 성능이 높았기 때문에 저는 항상 사용합니다. 자세한 설명은 이곳에 잘 나와있습니다.  https://heytech.tistory.com/127

gs
2022.02.26 21:31

자세한 답변 감사합니다!!
vggnet, dropout에 대해서 더 찾아봐야겠습니다. 감사합니다.

Pobredward
2022.03.12 19:24

코드가 많은 도움 되었습니다 감사합니다