DL&ML/code.data.tips

Kaggle Shopee 대회 top-solution 정리

식피두 2021. 5. 13. 22:58

얼마 전 종료 되었던 Shoppe - Price Match Guarantee 대회

비록 뒤늦게 참여해서 아쉽게 메달은 획득하지 못했지만, 짧은 기간 동안 즐겁게 팀플레이를 할 수 있었던 대회였다.

 

상품 이미지와 제목이 주어졌을 때 유사한 제품 id를 찾는 멀티모달리티를 이용한 대회였다.

https://www.kaggle.com/c/shopee-product-matching

 

탑솔루션이 몇 개 공개되어, 상위권 사람들이 보여준 핵심 아이디어 몇 가지를 정리해보았다.

 

1등 솔루션 (한국인 yoonsoo님, from embeddings to matches)

  • https://www.kaggle.com/c/shopee-product-matching/discussion/238136
  • eca_nfnet_l1, xlm-roberta-large, xlm-roberta-base, bert-base-indonesian-1.5G, indobert-large-p1, bert-base-multilingual-uncased (인도네시안을 쓰는게 의미가 있을 까 싶었는데, 많이들 썼다)
  • Arcface를 이용해 모델 학습
    • 충분히 큰 마진을 두는 것이 임베딩의 퀄리티를 결정하는 데 있어 중요했음
    • 하지만 convergence 이슈가 있었고 다음의 방법으로 해결
      • 학습이 진행 됨에 따라 margin을 점차적으로 증가 시킴
      • 웜업 스텝을 크게 둠
      • cosine head에는 러닝레잇을 더 크게 둠
      • gradient clipping 적용
    • 이미지 모델의 경우 margin 0.8 ~ 1.0이 적합, 텍스트 모델엔 0.6 ~ 0.8이 적합 (마진이 중요한진 몰랐네...)
      • 0.2 부터 시작해서 학습 도중에 점차적으로 끌어 올림
    • google landmark recognition 솔루션을 참고(https://arxiv.org/abs/2010.05350)하여 class-size-adaptive margin 기법을 도입함 (비슷했던 컴페티션을 참고하는 것이 중요)
    • 임베딩(Gloval Average Pooling 혹은 그냥 Pooling에 의해 생성 된) 이후에 BatchNorm + feature-wise Norm을 적용해주는게 좋았음
  • 이미지와 텍스트 임베딩을 이용해 매칭을 하는 방법. 세 가지를 시도했고, 마지막 방식이 가장 좋았음
    • 텍스트 임베딩만 가지고 매칭, 이미지 임베딩만 가지고 매칭 후 그 둘을 union (보통 사람들이 한 것)
    • 텍스트 임베딩과 이미지 임베딩을 컨캣해서 combinded match를 수행 (첫 번째 방식보다 훨씬 좋음)
      • 각각을 기준으로 distance가 threshold 이하로 떨어지는 것들을 고르고 (strong suggest)
      • combined distance가 좀 더 루즈한 threshold 이하로 떨어지는 것들을 고름(moderately suggest)
    • 세 가지를 union (가장 좋음)
    • image + text model을 jointly 학습했을 땐 별로
  • Iterative Neighbor Blending 방법을 제안 (개별 임베딩을 개선)
    • cosine distance = 1 - cosine similarity
    • K NNS(Nearest Neighbor Search)을 cosine similarity 메트릭을 이용해서 적용. threshold 이하만 이웃으로 취급.
      (+ 모든 매치는 최소 2개는 갖도록 일부 조정, threshold에 아무것도 안걸릴 경우)
    • Neighborhood Blending (다른 솔루션에도 Query Extention이란 이름으로 언급 된 부분)
      • 앞서 구한 이웃 끼리 엣지로 연결, 엣지의 웨잇은 cosine similarity으로 취급하여 그래프화
        • threshold 넘는 애들만 연결 되었다고 가정
      • 특정 노드의 임베딩(Query)을 주변 이웃의 임베딩을 weighted sum 함으로써 업데이트 시켜줌 (Query Extension)
        • 이렇게 함으로써 클러스터를 좀 더 명확히 할 수 있다고 한다
      • 여기에 다시 NNS를 적용해서 새 이웃을 얻을 수 있음.
        • evaluation metric이 개선되는게 멈출 때 까지 반복 (답안 링크의 코드 참고)
  • 그 외에 image 학습시 cutmix (0.1) + horizontal flip only augmentation이 좋았다고 한다.

 

2등 솔루션

  • https://www.kaggle.com/c/shopee-product-matching/discussion/238022
  • 2스테이지 모델을 구현해서
    • 1 스테이지 ; 이미지, 텍스트, 이미지+텍스트에 대한 임베딩을 얻음
    • 2 스테이지 ; meta-model 을 학습 시켜서 각 쌍의 품목이 같은 라벨 그룹에 속하는지 판단하는 모델을 구현함
      • LightGBM & Graph Attention Network
  • NFNet-F0, ViT embeddings을 이용한 코사인 유사도
  • CurricularFace loss (Arcface보다 낫다고 함)
  • SAM 옵티마이저 (공부 필요)
  • indonesian-BERT, multilingual-BERT, paraphrase-XLM
  • Text Similarity / Image Similarity / Text + Image Similarity
    • 특히 마지막의 multimodal similaritysms NFNet-F0와 Indonesian BERT의 마지막 레이어를 컨캣 시켜서 학습함
  • 1등 솔루션 처럼 graph feature를 사용해서 pagerank를 이용해 특정 위치 노드를 업데이트 한 것 처럼 보임
    • + Query Extention ; augmented embedding which weighted averaged neighbors
  • 이웃을 구한 결과 A-B와 B-A가 일치 되도록 후처리 한듯
  • 여러 라벨 그룹에 걸쳐 있는 아이템을 후처리 한듯

 

* 6등 솔루션

  • https://www.kaggle.com/c/shopee-product-matching/discussion/238010
  • multi-modal model을 학습을 시켰는데, 다른 사람과 다른 점은
    • 이미지 임베딩 만으로 arcface 학습
    • 텍스트 임베딩 만으로 arcface 학습
    • 이미지+텍스트 임베딩도 동시에 arcface 학습
      • 우리의 경우엔 이것만 시도하다 학습이 잘 안되서 포기했는데...
    • 세 개의 태스크를 동시에 학습!! (링크에 그림 참고)
  • 따라서 하나의 모델 안에 이미지/텍스트 기반의 백본이 있고 출력으로는 3개의 임베딩이 나오는 구조!
  • 이런식으로 멀티모달 모델을 여러개 만들어 앙상블을 시도함.
    • 이 때, 유클리디언 or 코사인 유사도 둘 중 하나만 쓴게 아니라 둘 다 씀 (왜 둘 중 하나만 쓸 생각만 했을까...)
      • 각각의 결과(4개 모델이라면 12세트x2의 예측 결과)에 대해 voting을 함
    • 모델별 학습 파라미터를 보면 새롭게 추가된 head는 백본 보다 큰 러닝레잇을 부여한 것을 볼 수 있음
    • 스케쥴러는 모델별로 다양하게...
      • linaer+warmup
      • ReduceLROnPlateau
      • ConsineAnnealingWarmRestart
  • 라벨 그룹 개수가 최소 2개가 되게 끔 threshold 보정 (다른 답안과 마찬가지)
  • 제품의 단위를 추출해서(200gram, 200gr) 단위가 다르면 매치에서 제거

 

14등 솔루션