Skip to content

Yuki-Tanaka-33937424/kaggle-Shopee-Price-Match-Guarantee

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 

Repository files navigation

kaggle-Shopee-Price-Match-Guarantee

Kaggleのshopeeコンペのリポジトリ スクリーンショット 2021-04-12 22 08 49
Kaggleの Shopee - Price Match Guarantee コンペのリポジトリです。
nbというディレクトリに、今回使用したNotebookをおいてあります。
ただし、下の方針にもある通り、今回はKaggle上でほぼ完結させているため、gitは使用していません。ですので、nbの中に全てのversionのNotebookがあるわけではないです。
KaggleのDiscussionに弊チームのsolutionを公開しています。こちらから飛べるので是非ご覧ください!

最終結果

スクリーンショット 2021-05-15 22 27 59

  • Public: 0.750
  • Private: 0.737
  • rank: 57/2426 (Top3%)
  • 銀メダルでした!!

方針

  • 基本的にはKaggle上で実験を行い、quotaが切れたらローカルのGPUで実験を行う。
  • Version名は常にVersion〇〇に統一して、変更などはKaggle日記(このリポジトリのREADME.md)に書き込む。

Paper

  • 参考にした論文の一覧。決して全てを理解してるわけではない。
No Name Detail Date link
01 ArcFace: Additive Angular Margin Loss for Deep Face Recognition CNNの最後の全結合層の代わりにArcMarginProductを入れることで、特徴良マップの距離を各クラスごとに離すことに成功し、顔認証のSOTAを記録した。 9 Feb 2019 link
02 EfficientNetV2: Smaller Models and Faster Training EfficientNetにFused-MBConv(depthwiseとpointwiseではなく普通の畳み込み)も入れて、スケーリングの仕方を変えつつ、progressive-learning(画像サイズと正則化を両方大きくしていく学習方法)を採用して、学習効率と精度の両方を改善した。 1 Apr 2021 link
03 MultiFace: A Generic Training Mechanism for Boosting Face Recognition Performance ArcmarginProductを適用する際に、特徴量を分割して低次元部分空間に射影して、それらのアンサンブルをすることで精度を改善した。 31 Jan 2021
  • そのほかに参考にした論文・サイトなど
    • 今回初めてBERTを使ったので、その論文を読もうとしたがあまり時間が取れず、あまり読めなかった。link

Basics

Overview(Deepl)

あなたは、お得な情報を求めてオンラインショップをチェックしていますか?同じ商品を買うのに、店によって値段が違うのは嫌だと思う人は多いでしょう。小売企業は、自社の商品が最も安いことをお客様に保証するために、さまざまな方法を用いています。中でも、他の小売店で販売されている商品と同等の価格で商品を提供する「プロダクトマッチング」という手法があります。このマッチングを自動的に行うには、徹底した機械学習のアプローチが必要であり、データサイエンスのスキルが役立ちます。

似たような商品の2つの異なる画像は、同じ商品を表している場合もあれば、全く別の商品を表している場合もあります。小売業者は、2つの異なる商品を混同してしまうことで生じる誤表示などの問題を避けたいと考えています。現在は、ディープラーニングと従来の機械学習を組み合わせて、画像やテキストの情報を解析し、類似性を比較しています。しかし、画像やタイトル、商品説明などに大きな違いがあるため、これらの方法は完全には有効ではありません。

Shopeeは、東南アジアと台湾における主要なEコマースプラットフォームです。お客様は、それぞれの地域に合わせた、簡単で安全かつ迅速なオンラインショッピング体験を高く評価しています。また、Shopeeに掲載されている何千もの商品に対して「最低価格保証」機能を提供するとともに、強力な支払いサポートと物流サポートを提供しています。

このコンペティションでは、機械学習のスキルを応用して、どのアイテムが同じ商品であるかを予測するモデルを構築します。

その応用範囲は、Shopeeや他の小売業者をはるかに超えています。商品のマッチングに貢献することで、より正確な商品分類をサポートし、マーケットプレイスのスパムを発見することができます。顧客は、買い物をする際に、同じ商品や似たような商品がより正確にリストアップされることで利益を得ることができます。そして最も重要なことは、あなたやあなたの周りの人たちがお得な商品を探すのに役立つということです。

data(DeepL)

大規模なデータセットの中から重複しているものを見つけることは、多くのオンラインビジネスにとって重要な問題です。Shopeeの場合、ユーザーが自分で画像をアップロードしたり、商品説明を書いたりすることができるので、さらに多くの課題があります。あなたの仕事は、どの商品が繰り返し投稿されているかを特定することです。関連する商品の違いは微妙ですが、同じ商品の写真は大きく異なります。

これはコードコンペなので、テストセットの最初の数行/画像のみが公開され、残りの画像は提出されたノートブックでのみ見ることができます。隠されたテストセットには、約 70,000 枚の画像が含まれています。公開されている数行のテストと画像は、隠しテストセットのフォーマットとフォルダ構造を説明するためのものです。

Files

[train/test].csv - トレーニングセットのメタデータです。各行には、1つの投稿のデータが含まれています。複数の投稿は、画像IDが全く同じでもタイトルが違ったり、その逆の場合もあります。

  • posting_id - 投稿のIDコードです。
  • image - 画像のID/md5sumです。
  • image_phash - 画像のパーセプチュアルハッシュです。
  • title - 投稿の商品説明です。
  • label_group - 同じ商品に対応するすべての投稿のIDコード。テストセットでは提供されていません。

[train/test]images - 投稿に関連する画像。

sample_submission.csv - 正しいフォーマットのサンプル投稿ファイルです。

  • posting_id - 投稿物のIDコードです。
  • matches - この投稿にマッチするすべての投稿IDのスペース区切りのリストです。投稿は常にセルフマッチします。グループサイズの上限は50なので、50以上のマッチを予測する必要はありません。

Log

20210411

  • join!!!
  • 今度こそ最後まで走り切るぞ。データセットのサイズも良心的だしきっといけるはず。
  • yyamaさんとチームを組む約束をした。yyamaさんが来てくださるまでの間に色々進めておくことにする。
  • nb001(EDA)
    • ver1
      • 画像サイズが意外にも大きい。1000x1000を超えてくるやつもある。最後にsizeを上げるのはアリかもしれない。
      • 画像のペアとしては2が圧倒的に多く、指数的に減少していく感じ。多クラス分類として解くとクラス数が10000を超えてしまうのでかなり多いか。
      • imageが全く同じものもあった。それらは別に学習なんかしなくても自動的に見分けられるので、最後にそれは一応チェックしてもいいかもしれない。ただ、testデータが見えるわけではないのであまり意味はなさそう。
      • shopeeは東南アジア、台湾系のメルカリ的な存在だと思われるので、商品の説明(title)は割と汚い。BERTなどのtransformerを使うのであれば綺麗にしなければいけない。

20210412

  • nb001
    • ver2
      • 公開Notebookを参考にして追加でEDAを行った。titleの前処理がとても綺麗だったので、textで攻める時には参考にできそう。
      • 各カラムのnuniqueの値を調べた。imageとimage_phashでnuniqueの値が違った(前者の方が大きい)。これはimageは違うけどimage_phashが等しいということがあることを意味する。どういうこと...?
  • nb002(training_EfficientNetB3ns)
    • ver1
      • LBが0.714のこの公開NotebookLBが0.728のこの公開Notebookを参考にして、Y.Nakamaさんのパイプライン主体でベースラインを書いた
      • 前者と後者の違いがいまいちよくわからなかった。後者の方がモデルが大きいことと、epochが大きいことに起因しているのか?後は、後者はローカルマシンでbatch_sizeを上げてモデルを作っているっぽい。それも効いているかもしれない。
      • ArcFaceというレイヤーを最後の全結合層の代わりに差し込むことで、各クラスの距離を離すように学習できるらしい。原論文Qiita記事を参考にして理解した。
      • validation_lossが全く下がらなかったので一旦止めた。
    • ver2
      • 原因はfoldの切り方にあると判断したので、foldの切り方を色々調べた。
      • 先程の公開Notebook(前者)Vote数が高いdiscussionを見ると、label_groupでgroupKFoldをするのが支配的っぽい。discussionでは、その上でさらにlabel_groupの数でstratifiedにもしたほうがいいと述べられていた。RANZCRでも最後の最後でPatientIDでstratifiedにした方がいいということに気づいたので、今回はCV戦略は大事にしたい。
      • [このサイト]でStratifiedGroupKFoldについて詳しく書かれていた。実装してみたが、うまく動かせなかったので、とりあえず途中でセーブした。。
    • ver3
      • ひとまずver1に戻して動かした。epochsを10に、max_grad_normを50に変えてある。
      • やはり、train_lossのみが減って、valid_lossは増えてしまった。CVの切り方をもっと調べることにする。

20210413

  • EfficientNetV2のweightが追加されたらしい。原論文Qiita記事を見るとかなり強そうなので、CVの切り方が安定したらモデルをこれに切り替えてみたい。
  • ArcFaceより強いっぽい手法についての論文を見つけた(原論文のリンク)。後で取り入れる。
  • nb002
    • ver4
      • もともとの公開Notebookでは、GroupKFoldが用いられていると思いきやStratifiedKFoldが用いられてた。確かに、今回は11014クラスの多クラス分類で解いているため、全部知らないグループの中では全く予測できないよねと納得した。
      • StratifiedKFloldを用いるとvalid_lossが減少した。foldの切り方も公開されているものと同じっぽいので、これでいいんだと思われる。
      • 最終的には、image_phaseかimageのいずれかをgroupにして、label_groupをstratifiedにするのが良さそうだが、とりあえずは現状のCVとLBのチェックが先。
      • しっかりLossが落ちた。
      • train_loss valid_loss
        0.0652 1.8025
      • かなり過学習している様子なので、何かしらの対策が必要か。ただ、valid_lossは最後まで単調減少していた。
  • nb003(EfficientNetB3ns_inference_with_Tfidf)
    • ver1
      • LB0.712の公開NotebookLB0.728の公開Notebookを参考にして書く。
      • foldごとにCVを計測できるように仕掛けたが、f1スコアが全く上がらない。全体でCVを出したらうまくいくんだけど...
      • 理由がわかった。学習の段階ではlabel_groupを当てにいっていたため、仮にvalidationの中にペアのうちの片方しかなくてもうまく行っていた(というか、stratifiedの対象がlabel_groupだったので故意にそうしていた)。それに対し、CVを計測する段階ではペアを当てなければいけないため、データの中にペアが必ずいなくてはいけない。ということは、foldごとに分けられないということだ。したがって、全体でペアを探した後にvalidationのデータだけを切り取ればいいということか。
      • text_predictionsにはKNNではなくcosine similarityを使っている。
    • ver4(ver2, 3は失敗)
      • 書き終えたが、バッチサイズが大きくて(64)推論の過程でGPUでKNNをやったときにOOMを吐かれたらしい。
    • ver5
      • やっと実行できた。
      • train_ver CV LB
        4 0.7532 0.715
      • CVとLBの乖離が大きい。やはりCVの切り方は考えないといけない。

20210415

  • BERTを使った公開Notebook論文があった。参考にしたい。
  • nb002
    • ver6(ver5は失敗)
      • batch_sizeを変えても学習率を変えなくて済むように、lr = Constant * batch_sizeの形式に変更した。値としては若干大きくなっている。
      • train_loss valid_loss
        0.0616 1.7975
      • 両方若干よくなった。
      • ちなみに、CosineAnnealingLRは明らかにダメそうだった。最初に過学習してしまうみたい。
    • ver8(ver7は失敗)
      • foldをGroupKFoldにしてみた。学習の段階では多クラス分類として解かざるを得ないためにvalidation_lossは下がらないが、CVは正確になると踏んだ。
      • train_loss valid_loss
        0.0510 12.4228
      • 予想通りvalid_lossは全く落ちてないが今は気にしない。
    • ver10(ver9は失敗)
      • ver6にSAMを加えてbatch_sizeを12に落とした。
      • train_loss valid_loss
        0.1289 1.9122
      • バッチサイズを落とした影響で、学習率も(線形ではあるが)落ちているので、学習が終わりきっていないように見える。恐らく、十分にバッチサイズを大きくできれば結果は変わると思われる。
  • nb003
    • ver6
      • text_predictionsでKNNを使えるようにコードを書いたが、失敗してver5と全く同じスコアを出してしまった。
    • ver8(ver7は失敗)
      • やっとできた。
      • train_ver CV LB
        4 0.7546 -
      • 再びエラーになった。やはりバッチサイズは16に下げた方がいいっぽい。
    • ver9
      • この公開Notebookを参考に、get_text_embeddingsの中のpcaを外した。
      • 上記の公開Notebookでは、GroupKFoldを使っていた。悩ましい...
      • train_ver CV LB
        4 0.7641 -
      • またエラーになった。今度はtext_embeddingsのmax_featuresが多すぎてメモリがオーバーしてしまうらしい。
      • 今回は21500にしていたが、動作確認が取れた18000にする。
    • ver11(ver10は失敗)
      • train_ver CV LB
        4 0.7647 -
      • 結局エラーを吐かれた。これは諦める。
    • ver12
      • ver8から、バッチサイズを8に落とした。
      • train_ver CV LB
        4 0.7546 0.691
      • 大撃沈したので今後のベースラインはver5になった。
    • ver13
      • CNNのnb002_ver8のものに変えた。
      • ver12が撃沈したのでこっちもボツ。
    • ver14
      • ver5から、EfficientNetをnb002_ver8のものに変えた。
      • train_ver CV LB
        8 0.667 0.662
      • CV、LBともにかなり下がったが、CVとLBがほぼ同じ値になった。方針的としては当たっているように思える。

20210416

  • CVの切り方がよくわからない。このディスカッションこのディスカッションなどでも話されているが、GroupKFoldでCVが0.7~0.8程度出ているのが再現できないのが気になる。恐らくstratifiedよりはgroupの方がいいのだろうが、何が違うのかわからない。
  • nb002
    • ver12
      • ローカルのRTX3090を使った。バッチサイズは24まであげている。
      • train_loss valid_loss
        0.0420 1.7825
      • 一応よくなったが思ったほどはよくなってない。
    • ver13
      • せっかくマシンパワーがあるので、epochを15にした。
      • train_loss valid_loss
        0.0280 1.7847
      • まず過学習をどうにかしないといけない。
    • ver14
      • dropout=0.3にした。
      • train_loss valid_loss
        0.0629 1.7521
    • ver15
      • dropout=0.5にした。
      • train_loss valid_loss
        0.1124 1.7201
      • 過学習がいい感じに防がれている。よく確認したらYYamaさんが既にdropout=0.5も試してくれていた。反省。
  • nb003
    • ver15
      • nb002_ver11のモデルで作ったが、RTX3090で作り直すことにした。
    • ver16
      • train_ver CV LB
        12 0.756 0.716
      • ver5と比べて若干上がってはいるが、誤差と言っていい範囲。

20210417

  • nb002

    • ver16
      • cassavaのNotebookから色々な損失関数を引っ張ってきて動作確認をしてquick saveした。
    • ver17
      • ver15に加えて、GroupKFoldを試した。その時、foldごとにクラス数が変わってしまうため、それに合わせてクラス数も変える必要があった。しかし、それだけだとなぜかcudaのエラーが出てしまっていた。
      • 理由が判明した。foldを切るだけだと、クラス数自体は8811になるけどlabel自体は11014まである(0, 2, 3, 4, 6, 8, ...的な)ので、それを(0, 1, 2, 3, 4, ...)に直さなければいけないことだった。頑張って直した。
      • その代わりとして、validationはできなくなってしまった。
      • train_loss: 0.2121
      • StratifiedKFoldに比べてtrain_lossが高いのはなぜなのだろうか...
    • ver18~
      • RTX3090で様々な損失関数を試してみた
      • foldの切り方はまだstratifiedKFoldになっている。
      • ver train_fn train_loss valid_loss
        18 FocalLoss(gamma=2) 0.2074 1.7763
        19 FocalLoss(gamma=1) 0.1516 1.7412
        20 FocalCosineLoss - -
        21 SymmetricCrossEntropyLoss 0.1125 0.1712
        22 BiTemperedLoss - -
      • FocalCosineLossとBiTemperedLossは挙動がおかしかったので止めた。SymmetricCrossEntropyLossはCrossEntropyLossとほぼ変わらなかった。効くとしたらFocal Lossだが、valid_lossがうまく下がらないので今回は採用しない方がいいかもしれない。
    • ver23
      • ver18にDual Attention Headを入れた。
      • 一旦quick saveしている。
    • ver24
      • RTX 3090で動かした。
      • train_loss: 0.1740
    • ver25
      • GroupKFoldでFocalLoss(gamma=0.5)を試した。
      • train_loss: 0.1206
    • ver26
      • ver17から、margin=0.5にしてepoch=15に変更した。
      • train_loss: 8.0259
  • nb003

    • ver18(ver17は失敗)
      • train_ver CV LB
        17 0.7444 0.716
      • とりあえずGroupKFoldがしっかり機能してくれたことに安心。ここから何度かこのやり方でCVとLBを観察する必要がありそう。
    • ver19
      • train_ver CV LB
        18 0.7562 -
      • Foldの切り方はStriatifiedになっている。
    • ver20
      • train_ver CV LB
        19 0.7579 0.712
      • Foldの切り方はStriatifiedになっている。
      • やはり、CVとLBの相関がよくない。RANZCRでは、FocalLossはCVが下降してもLBが実は一番良かったので、GroupKFoldでも様子を見た方が良さそう。
    • ver22, ver23(ver21は失敗)
      • Dual Attention Headのモデルを試した。その時、oofのみを使うか、全データを使うかでthresholdの値が大きく違ったので、両方試してみた。
      • train_ver threshold CV(oof) CV(all data) LB
        24 11.2 0.7330 - 0.706
        24 13.2 0.7211 0.7941 0.667
      • threshold自体はやはりoofに従うのが良さそう。あとはoofのCVのLBに対する相関を見ればいいだけ。
    • ver24
      • train_ver CV LB
        25 0.7444 -
    • ver25

20210419

  • nb003
    • ver25
      • train_ver CV LB
        26 0.7549 0.716
      • もう本当に理解し難い。YYamaさんはほぼ同じ条件でLB0.722を出しているので、YYamaさんに画像処理は一任して自分はTextベースのアプローチを試みる。
    • ver27(ver26は失敗)
      • ここにきて、nb002で、defalutでmargin=Falseにしてたのはミスだと気づいた。他のどのNotebookを見てもmargin=0.5になっている。しかも、nb003はしっかりmargin=0.5になっているので、ずっと学習と推論でmarginの値が違うまま使ってた。完全にやらかした。
      • そこで、こちらのmarginもFalseにして、nb002_ver17を改めてサブしてみる。
      • train_ver CV LB
        17 0.7444 0.716
      • 手元のスコアではmarginがあろうと無かろうと変化がない。困った...

20210420

  • NemuriさんとBelugaさんのお二方とマージさせていただいた。自然言語処理担当になったので、気合を入れ直して頑張る。
  • nb002
    • ver27
      • ver26のモデルを、dropout=0.1に戻して、共有用にコメントを付け加えてquick saveした。
  • nb003
    • ver28
      • 共有用に、ver25でdropout=0.1に戻してコメントを付け加えてquick saveした。

20210421

  • 発展ディープラーニングにTransformerとBERTの実装が詳しく掲載されていた。かなりわかりやすかったので、コンペが終わったら原論文を読みつつ自分の手で実装する。
  • nb002
    • ver28
      • ver27を実際に動かした。
      • train_loss: 4.3233
  • nb003
    • ver29
      • ver28を動かした。
      • train_ver CV LB
        28 0.7545 0.715
      • やはり思ったよりは上がらない。コードの中身は0.730弱出てるコードとほぼ同じなはずなので、何か見落としやバグがあると思われる。

20210422

  • nb004(BERT_training)
    • ver1, ver2
      • sentence BERTを使っている公開Notebook(training, inferencce)を参考にしてnb002_ver27にBERTを乗せた。
      • とりあえず書き終えたのでquick saveした。

20210423

  • nb004
    • ver3
      • train_lossがうまく下がらないので、schedulerをget_linear_schedule_with_warmupからCosineAnnealingLRに変えた。また、epochも10に上げた。
      • stratifiedKFoldに切り替えてvalidation_lossが下がっていることが確認できたので、GroupKFoldに戻した。
      • train_loss: 0.43599

20210424

  • このディスカッションによると、同じlabel_groupに属するべき商品が違うlabel_groupに属していることがあるらしい。その原因として、商品のページで、同じ物なのにも関わらず違うカテゴリーで出品されていることが考えられるらしい。そこまで深く考える必要はなくモデルが処理してくれるとchrisは言っているが、終盤ではこれについて一応考える必要があるかもしれない。

  • nb003

    • ver30
      • YYamaさんのNotebookで、KNNの距離をcosineで測ってさらにthresholdを全データでベストな値から0.15下げたところでサブをすると0.715から0.730まで上がったらしいので、自分も同じようにした。
      • ver28のthresholdを0.30まで落とすと、LBが0.725まで上がった。こんなに上がるのか...
      • GroupKFoldはlabel_groupのリークはないため、リークが原因でthresholdが高く出ていたわけではなさそう。
      • 考えられる原因としては、oofはデータ数が6500なのに対してPublicが28000, Privateが48000なので、ペアをたくさんとりすぎてしまう傾向にあることが考えられる。oofのベストの値よりは低くした方がテストデータではいい結果がでそう。
    • ver31
      • ver30のCVを記録しておいた。
      • train_ver CV LB
        28 0.7448 0.725
    • ver32
      • BERTを組み込んだ。
      • しかし、CVが思った以上に低い。BERTの方のthresholdが0.07ということは、各データがかなり接近していることを意味している。ArcMarginを使わないとこうなるとわかったので、サブせずに記録だけとって、BERTを作り直す。
      • CNN_ver BERT_ver CV LB
        nb002_ver28 nb004_ver3 0.7000
    • ver33
      • ver31のthresholdを0.3から0.25に変更した。
      • train_ver CV LB
        28 0.7365 0.724
      • LBは若干下降したが、恐らくPrivateスコアはこっちの方が良さそう。PrivateデータはPublicデータよりもさらに多いから。そしておそらくLBの最適値はこの間(0.28あたり?)にありそう。
    • ver36, ver37(ver34, ver35はsubmit時にTfidfになってしまっている。)
      • nb004_ver4のBERTのサブを行った。
      • まずCVについて。各epochで最も良いthresholdを抜き出した。なお、CNNはver31と同じ。
      • epoch threshold CV
        10 0.30 0.7534
        15 0.28 0.7489
      • CVは両方上昇している。epoch10の方が結果がいいので、恐らく10以降は過学習していると思われる。
      • 次に、epoch10のBERTを用いてthresholdとLBの関係を見る。
      • | threshold | CV | LB | | 0.25 | 0.7477 | 0.716 | | 0.30 | 0.7534 | 0.706 |
      • CVは高いが、LBは思ったより低い。Tfidfを比べてペアをより積極的に取ってきているように見えるため、一度予測の数を可視化して分布をしっかり見るべきかもしれない。
  • nb004

    • ver4
      • ArcFaceを入れないと特徴量マップの距離が近くなってしまうので、ArcFaceを入れた。batch_sizeを128に上げている。
      • ちなみに、lrをあげるとうまく学習できなかった。バッチサイズをあげるのが一番高速化・安定化の面でよかった。
      • どこまで学習させるのがいいのかよくわからないので、epochは20にして5, 10, 15, 20は保存しておくことにした。
      • epoch train_loss
        5 9.2698
        10 1.9805
        15 0.4178
        20 0.2208
      • 10~15あたりが一番良さそう。間違いなく20まではいらない。
    • ver5
      • BERTはTfidfと比べてペアをたくさん取ってくる傾向があったので、少し控えめにさせるためにmarginを上げることにした。
      • margin=1
      • epoch train_loss
        5 27.0191
        10 24.2476
        15 23.4128
        20 23.1411
      • marginが大きすぎて全く学習が進まなかった。もう少し調べるべきだった。
    • ver6
      • margin=0.6(それより大きくするとうまくいかなかった。)
      • epoch train_loss
        5 11.7476
        10 3.5060
        15 1.0147
        20

20210424

  • nb003
    • ver38
      • CNNやBERT, TFIDFの出力を確認するために、oofをダウンロードした。
      • Text model CNN_threshold Text_threshold CV LB
        BERT 0.3 0.01 0.6945 -
        BERT 0.3 0.05 0.7183 -
        BERT 0.3 0.10 0.7406 -
        BERT 0.3 0.15 0.7311 -
        BERT 0.3 0.20 0.7406 -
        BERT 0.3 0.25 0.7477 0.716
        BERT 0.3 0.3 0.7534 0.706
        Tfidf 0.3 0.75 0.7448 0.725
        Tfidf 0.38 0.75 0.7509 -
      • 一番下のCNN_thrsholdが0.38のものは、CNNのthresholdをCVに最適化したもの。
    • ver39
      • BERTのthresholdを0.2にした。(0.25と0.3は再掲)
      • threshold CV LB
        0.2 0.7406 0.718
        0.25 0.7477 0.716
        0.30 0.7534 0.706
      • EDAした感じでも、閾値を0.10あたりにしてようやくTfidfと予測の個数が同じぐらいになっていた。やはりかなり控え目にしてTfidfとのアンサンブルを試すべきな気がする。
    • ver40
      • BERTをnb004_ver6のmargin=0.6のモデルに書き換えた。
      • epoch10のモデルがthreshold=0.31でCVが0.7547を出したので、こちらの方がいい感じになっているように見える。
    • ver42(ver41は失敗)
      • ver33で、tfidfのthredsholdを0.53まで落として、nb004_ver6のepoch5のBERTを組み込んだ。ただ、調べた感じだと、Tfidfに加えてBERTを入れてもCVは悪化しているだけだった。BERTのthresholdを0.01にしてようやく少し効き目があるぐらい。BERTの望みは薄い感じがする。tfidfのthresholdはCVがベストから0.1下がるぐらいのところを選んだ。
    • ver43
      • Tfidfのthresholdを下げるとCVが上がっていくことに気づいたので、ver30からTfidfの閾値を0.75->0.55に下げてサブしてみた。
      • LBが0.680まで下降した。CVと LBの相関はやはり不安定...本当は全foldで取った方がいいよね。
    • ver44
      • nb006通りに、BERTの予測個数が40を超えたときにTfidfの予測をBERTの予測と置き換えた。CVは若干上がっている。
      • その途中で、BERTのKNNの個数を70まで上げた方がCVの値が良くなることがわかった。確かにtrainingデータの中のペアの個数は最大で51だが、テストデータの中にはもっとある可能性も否定できないので増やすべきかもしれない。
      • LBは0.724だった。元々がver30のLB0.725なので、ほぼ横ばい。CVを取ってるのがたった6500個なので、やはり全foldで再調査したほうがいいっぽい。
  • nb006(EDA_oofdf)
    • ver1
      • EffcientNet, Tfidf, BERTの予測結果を可視化した。
      • その結果分かったのが、やはりTfidfとBERTを比べるとBERTがかなりの個数をとってきていると言うこと。BERTの閾値を0.05ぐらいにして初めてTfidfの閾値0.75と同じぐらいの個数分布になった。BERTの閾値0.2が大体EfficientNetの閾値0.3と同じぐらいなので、BERTはかなり積極的に予測をしていることがわかる。
      • OOFの中にはペアの個数が50を超えるようなデータが存在する。予測結果を見ると、30~50個取ることができているのはBERTだけなので、なんとかこれだけでも生かせればスコアが伸びそう。
    • ver2
      • 正解のペアの個数毎にf1スコアの平均をとってみると、30個以上においてはBERTが一番強い(というかBERTしかそれだけとってくることができない)ことがわかった。ペアが50個のデータで、EfficientNetが1個だけ、Tfidfも一個だけみたいな状況下でもBERTは50個とってきていたりするので、BERTの予測個数が多い時だけBERTに置き換えるといいと考えられる。
      • チーム内の分析で、BERTは実は予測個数が2個や3個の時に明らかに強いことが判明した。実際にその置き換えを行ったところスコアが0.005伸びたので、これは効きそう。

20210426

  • nb004
    • ver11(ver7, 8, 9, 10は失敗)
      • ver6のBERTを全foldで作った。10epochが一番よかったため、T_maxを20にしたままepoch10で切ることにした。
      • fold0を飛ばすコードを書いたままにしてしまっていた。quotaが余りそうなのでもう一度やり直す。
    • ver12
      • 今度は余計なモデルまでセーブしてしまってoutputが膨大になってしまった。outputのうち選択的に選んでデータセットにする方法ってないのか...?
    • ver13
      • やっと成功した。
      • fold train_loss
        0 3.5060
        1 3.5618
        2 3.6370
        3 3.3603
        4 3.5061
      • stratifiedで回してみたところ、validation_lossは14あたりから下がり方がかなり鈍くなってきて、12あたりが限界だった。それ以降は過学習していることは頭に入れなければいけない。

20210427

  • nb002
    • ver29, 30
      • ver28のモデルを全foldに関して作った。
      • ver29にfold1~4, ver30にfold0のモデルがある。
      • lrをバッチサイズに対して線形に変化させているが、バッチサイズが大きくなるとtrain_lossがより下がってしまうのが少し気になる。これまでのコンペとは違い理論値通りにいかないが、validation_lossも出せないし気にしててもしょうがない気もする。
  • nb003
    • ver45
      • BERTの予測個数が2個の場合にTfidfの出力をBERTの出力で置き換える処理をした時のCVの変化を記録した。
    • ver46
      • nb002_ver29, ver30のモデルを入れた。CVを出す処理はまだ書いていない。
      • LBが0.733まで上がった!やはり全foldを入れるだけでも安定感が違う。
  • nb005
    • ver1, ver2
      • EffNetとBERTとTfidfを合わせるNotebookをnb003と切り離した。
      • nb002_ver29, 30とnb004_ver13のモデルでCVを出そうとしたが、modelを何個もロードしているうちにRAMに収まりきらなくなってしまう。del modelの後にgc.collect()もしているので消えていると思っていたがどうも消えてないらしい。正直どうしてかわからない。循環参照があるようにも見えない。torch.cuda.empty_cache()も試してみたが、そもそもcpu側の問題なのでどうにもならないっぽい。

20210429

  • nb003
    • ver47
      • 全foldを使ってCVを出せるようにコードを色々書いてみたが、まだ書き終わっていない。image_embeddingsとtext_embeddingsを元の順番に戻すのに大苦戦してる。
    • ver48
      • Belugaさんが組んでくれた補完アルゴリズムを入れて、さらに置き換えをTfidfの予測値が一個の場合に切り替えた。
      • LBが0.734->0.724まで下降した。Tfidfが一個の場合に置き換えるのはそもそもSEResNeXtを対象に行なった実験であるから、そのせいなのかもしれない。こっちでも出力を解析する必要がありそう。
    • ver49
      • Nemuriさんが作ってくれた前処理付きBERTに差し替えて実験をした。それ以外はLB0.734の時と同じ。
      • 0CVは0.8001->0.8005でLBは0.734->0.733に落ちてしまった。この辺は正直閾値に依存している部分もあるのであんまり気にしなくていいと思う。
      • あと、あまり本質的ではないけどバッチサイズは8から32に上げても大丈夫だった。次からそうする。
  • nb006
    • ver3, ver4
      • nb006のoofを解析した。すると、一番CVがよくなるのは、Tfidfの出力が1個の場合にBERTで置き換えた時だった。考えてみれば当然で、ペアは2つ以上あるので、1個は必ず間違っているからだろう。
      • pred_matchesが1つしかないデータの個数はは535->492に減った。置き換えをしても、依然として明らかに誤っているデータは残されているため、そこは明示的にアルゴリズムを組んで補完した方がいいと思われる。それにあたって、このディスカッションを参考にしたい。
  • nb007(training_SResNeXt)
    • ver1
      • nb002_ver29を全foldで回せるように修正してモデルをSeResNeXtに書き換えた。
      • Kaggle Notebookのsaveを失敗してそっちではver2になってしまった。
  • nb008(infer_SeResNeXt)
    • ver1, ver2, ver3, ver4
      • nb003を参考に、ひとまずfold0のみで、BERTの予測個数が2の場合にTfidfの出力と入れ替える処理を書いた。
      • oof_dfをpickle形式で保存できるようにした。今回の出力はリストになっているため、csvファイルで保存するとstrとして読み込まれてしまう。pickleファイルにすればそのまま読み込めるので便利。
    • ver5
      • 比較をしやすくするために、BERTのthresholdを0.2に下げた。
    • ver6
      • cnn_threshを0.4, BERTのthreshを0.3にしてサブした。Belugaさんのマッチ補完関数を入れるのを忘れてた。BERTを全fold分入れることができないため、fold0のみでCVを出している
      • CV LB
        0.8227 0.724
      • 結構乖離が大きい。CVに対するbestは0.54だったが、データ数的にもっと思いっきり減らすべきだったか。
    • ver7
      • サブが余ったので、閾値を0.35に落として、マッチ補完関数も入れてサブした。
      • CV LB
        0.8140 0.731
      • だいぶ近づいた。おそらくまだ伸びる。BERTも正直もっと下げた方がいいはずなので、サブが余った時に試してみたい。

20210430

  • ここ数日のものを全て20210427に書いてしまった。まあいいけど。
  • nb003
    • ver50
      • BelugaさんのLB0.734のNotebookを整理して、BERTのthreshfoldを0.3->0.2に落とした。過去にBERTだけでやった時は0.3より0.2の方がスコアが良かったので改善されるかもしれない。
      • CV LB
        0.7913 0.732
      • このBERTの使い方では、thresholdはいじらない方がいいっぽい。
    • ver51
      • CNNの予測値を、一個しかなければ必ずもう一つ取らせるようにコードを変えた。正解は必ず二つ以上なので(ペアは必ず存在するから)、改善される可能性がある。
      • サブするのはやめた。

20210501

  • nb002
    • ver32, ver33
      • ver28から、ArcMarginProductを書き換えてMultiFaceにした。論文を読んで真似しただけなので間違ってるかもしれない。
      • ver32がepoch15, ver33がepoch30になっている。
      • epoch train_loss
        15
        30 4.0297
      • かなりいい感じでは?
    • ver34
      • fold1~4についても回した。
      • fold train_loss
        0 4.0297
        1 5.3985
        2 3.8627
        3 4.2946
        4 3.8995
      • 割と不安定なのが気になるが、実装が間違っていると言うわけではなさそう。
  • nb003
    • ver56(ver52, ver53は失敗)
      • 予測値が一個の場合に一番近い予測値をとってくる処理を付け加えた。
      • 間違えてcnn_threshが0.25のままでサブしてしまった。ver54はこれのquick save。
    • ver57
      • 予測値が一個の場合にもう一つとってくる処理をCNNだけにした。
      • これも間違えてcn_threshが0.25になっている。ver55はこれのquick save。
    • ver58
      • ver56のcnn_threshを0.3に直した。
      • CV LB
        0.8119 -
    • ver59
      • ver57のcnn_threshを0.3に戻した。
      • CV LB
        0.8114 -
    • ver60
      • nb002_ver33のCVを算出した。
      • nb002_ver28のCVが0.7996. nb002_ver33のCVが0.7974で若干下降している。これだけで却下するのは若干心許ない。データ数が少ない故かもしれないで、全て作り切ってみた方がいいかもしれない。
  • nb008
    • ver8
      • ver7まで、fold0のモデルしか使えていないことが判明してしまった。と言うことは、もっと伸びるはず。
      • 全foldのモデルを入れて、cnn_threshを0に落とした。
  • nb009
    • ver1
      • SEResNet152Dのfold0を作った。train_lossの下がり方が未知だったので、15epochと20epochの両方を保存した。
  • nb010
    • ver1
      • nb009_ver1のCVを確かめた。
      • epoch train_loss CV
        15 3.0235 0.8059
        20 2.8534 0.8065
      • 最終epochの方がギリよかった。CVだけをみると他のモデルより強いのでかなり期待できる。

20210502

  • nb003
    • ver61
      • YYamaの0.741のNotebookで、nb002_ver34のモデルに差し替えた。
      • LBは0.741->0.736で降下した。MultiFaceは却下。実装が悪かった可能性は否定できない。

20210503

  • nb004
    • ver14
      • Belugaさんが出力をくれたOCRのtextを使ってBERTを事前学習させた。本当はこれも一緒に学習させたいが、OCRの結果がnullの行も30%ほど存在するので、それらを省かなければならないため、一気に全部を使うことはできない・。また、

20210504

  • チームmtgで、最後までマッチしなかったデータをよく見たところ、タイトルを見れば一目瞭然であるようなデータが散見された。これらに足を引っ張られているとしたら相当の損失なので、そこを重点的に当てていこうという話になった。金圏に辿り着きたい!!!
  • nb003
    • ver62
      • 0.741が出てるNotebookにOCRを付け足した。恐らく推論でかかる時間は45分程度で、CVの伸びは0.001程度コスパは正直あまり良くないっぽいので、LB伸びも0.001程度なのであれば切るべきかもしれない。
      • チームメイトが出したスコアを再現するためにcopy&editをすることが増えて、ここに内容を書きづらくなっている...
    • ver63
      • ver62をデータ数78000で動かして、推論にかかる時間を検証した。
      • 予測個数が1のデータ数次第だが、全体のうち15000個がデータ数が1の場合は2h30mかかった。これでは推論は間に合いそうにない。
    • ver64
      • ver62のモデルをfold0, 1, 2のみにしてサブした。
      • LBは0.740だった。元が0.742なので、有効ではないのだろう。
    • ver65
      • 今日のmtgで出た、マッチしなかったデータは、テキストで共通部分を見ればある程度原始的に予測可能であろうという予想に基づいて、まずはマッチしなかったデータに改めてTfidfをかけてみた。
      • threshはとりあえず0.6にした。0.5にすればもっとCVは上がるがそれは今回の様子を見てまた決める。
      • thresh CV
        Tfidf無し 0.8090
        0.6 0.8191
        0.5 0.8268
      • LBは0.744だった。もっと上がって欲しいな...

20210505

  • nb003
    • ver66
      • ver65から、閾値を0.6のままにする代わりにリアス式を0.05刻みにして4回に増やした。CVは0.8275。
      • CV LB
        0.8275 0.746
      • LBが0.746まで上がった。方向性としてはあってるっぽいがTfidfでは限界がある。回数を重ねれば表示桁以下の改善はあるが、それ以上はTfidfでは取れない。
    • ver68(ver67は失敗)
      • ver66にルールベースでマッチングするアルゴリズムを付け加えた。
      • CV LB
        0.8282 0.745
      • CVは微増したがLBは微減した。やはり、CVで行う時はせいぜいデータ数が500であるから機能するのであって、テストデータはその10倍あるためまだルールベースで絞るのは難しいのかもしれない。もっと絞ってからやるといいのかも。
    • ver69
      • 0.746のNotebookで、BERTをver16のものにしてdistance averageした。
      • 0.744まで下がってしまった。とりあえずBERTは元に戻す。
  • nb004
    • ver16
      • slackで話す中で、NearestNeighborSearchにかける前に特徴量を正規化してることが大事であるのではないかと感じた。思えば、EfficientNetではArcmarginLossの前にuse_fc=Trueとすることで最後にBatchNorm層を入れていたため正規化はできていた(正規化というよりは大きさが揃っていた程度の話だ)が、BERTに関しては公開Notebookに沿ってuse_fc=Falseとしていたため、正規化がなされていなかった。そこで、ver13から、use_fc=Trueに変更して学習させた。
      • ver13より学習が進みづらいため、念の為epoch20まで学習させて確認した方がいいか。
    • ver17

20210507

  • nb002
    • ver35
      • SAMを入れ回せるようにした。
      • ローカルのver36で全てのfoldを回している。
    • ver36
      • Siamese kearningを試した。実装は公開Notebookを参考にした。
      • 学習自体はうまくいっているが、使っている人が少なすぎるので最後にアンサンブルで加える程度かもしれない。
  • nb011(ensemble)
    • ver1
      • YYamaさんの0.748のkernelのbertを3つに増やして、さらに最後にマッチしなかったデータに対してbertをかけることでペアを探す過程を追加した。
      • CVは0.8324まで上がった。Tfidfでは取りきれなかったデータの1/3程度をさらにマッチさせることができたので、方針は当たっているはず。
      • submitでsubmission.csv not foundになってしまった。timeoutか、最後のbertでエラーを吐かれているっぽい。
    • ver2
      • EfficientNetを一つ減らしてみたが、再びsubmission.csv not found になってしまった。

20210508

  • nb007
    • ver2
      • ver1から、SAMを入れてaugmentationを厳しくして再実行した。
  • nb011
    • ver3
      • YYamaさんのdebugの状況を聞きながら、bertをひとつ減らしてtrainデータで走らせてみた。
      • ちゃんと最後まで行ったので、bertを3つにしたために最後にoomを吐かれていたのかな、多分。
    • ver4
      • ver3をサブしてみたけど結局ダメだった。泣きそう...
    • ver5
      • 77000データで走らせたところ、TfidfでOOMを吐かれてしまった。バッチサイズが高いのが原因なのかな。
    • ver6
      • バッチサイズを16に落として再実行した。
      • Tfidfでmax_df corresponds to < documents than min_dfと言うエラーを吐かれた。
      • これは仕方なくて、Tfidfの内部ではあまりにもたくさん出てくる単語は無視しているらしいが、今回はデータが重複しているためにそれに該当する単語が出てきすぎて最低単語数を下回ってしまうから。
      • データ数を68000に削ってやり直してみる。
    • ver7
      • ver6からデータ数を削って(train x 2)、text_embeddingに関しては使い回すことでBERTを複数回呼び出すのを避けた。
      • これは仕方なくて、Tfidfの内部ではあまりにもたくさん出てくる単語は無視しているらしいが、今回はデータが重複しているためにそれに該当する単語が出てきすぎて最低単語数を下回ってしまうから。
      • ver3をサブしてみたけど結局ダメだった。泣きそう...

20210509

  • 次回への改善点として、チーム内でNotebookの管理方法はある程度最初にまとめておくべきだったことが挙げられる。自分はこのように先頭に通し番号をつけて管理しているが、他のチームメイトに同じ通し番号で亜種を作られてしまうと、自分がどんなに頑張っても管理が壊れてしまう。今回は何とか自分のNotebookにそのまま乗っけるなりして管理して乗り切ったが、次回もそれで乗り切れるとは限らない。他の人が更新したものをそのまま採用すると差分を把握できなくなっていくので、多分あと少し長引いてたらだんだん壊れ始めてた。
  • nb002
    • ver37
      • augmentationを外して、続きの学習をさせた。前のコンペで論文通りにスコアが上がったため、今回も採用する。
  • nb007
    • ver3
      • augmentationを外して、ver2の学習の続きをさせた。
  • nb009
    • ver4
      • ver3の続きを、augmentationを外して行った。
  • nb011
    • ver8
      • BERTのアンサンブルを諦めて、今あるNotebookにBERTを付け加えるだけにしてサブした。
      • だめでした。何でやねーーーーーーーーーーーーーーーん
    • ver9
      • 追加のTfidfを一回にして、trainデータで回した。しっかり動いた。
      • ただ、最後のBERTで、text_embeddingsを使い回すのではなくもう一度BERTを読み直すとエラーが起こった。やはり、Tfidfが2回あることによってOOMを引き起こしていた可能性は高そう。
    • ver10
      • ver9に CNNの追加処理を加えた。うまくいけば0.755ぐらいはいけそうかな。多分それ以上は無理だな。
      • またエラーだった。なんでなんだろうなあ...
    • ver11 ~ ver22
      • 月曜日までこれのデバックを頑張っていたが結局ダメだった。submission csv not foundから全く変わらなかった。ちなみに、YYamaさんのサブが成功しているNotebookをダウンロードして、ここにあげてコメントを色々書き換えて実行したが結局ダメだった。それは明らかにおかしいので、このNotebookがおかしい可能性はある。そんなことないと思うけど...でも、Notebookごとに計算リソースが割り振られてたらなくはないのか。まあもう気にしないことにする。

About

Kaggleのshopeeコンペのリポジトリ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published