dslighting 1.7.1__py3-none-any.whl → 1.7.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dslighting/__init__.py +1 -1
- dslighting/core/agent.py +78 -62
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/METADATA +3 -1
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/RECORD +352 -7
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/top_level.txt +1 -0
- mlebench/README.md +39 -0
- mlebench/__init__.py +0 -0
- mlebench/cli.py +221 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/grade.py +161 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/mAP_evaluation.py +425 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/prepare.py +483 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/prepare_val.py +719 -0
- mlebench/competitions/AI4Code/grade.py +70 -0
- mlebench/competitions/AI4Code/prepare.py +84 -0
- mlebench/competitions/AI4Code/prepare_val.py +159 -0
- mlebench/competitions/__init__.py +0 -0
- mlebench/competitions/aerial-cactus-identification/grade.py +11 -0
- mlebench/competitions/aerial-cactus-identification/prepare.py +71 -0
- mlebench/competitions/aerial-cactus-identification/prepare_val.py +133 -0
- mlebench/competitions/alaska2-image-steganalysis/grade.py +136 -0
- mlebench/competitions/alaska2-image-steganalysis/prepare.py +88 -0
- mlebench/competitions/alaska2-image-steganalysis/prepare_val.py +148 -0
- mlebench/competitions/aptos2019-blindness-detection/grade.py +35 -0
- mlebench/competitions/aptos2019-blindness-detection/prepare.py +75 -0
- mlebench/competitions/aptos2019-blindness-detection/prepare_val.py +123 -0
- mlebench/competitions/bike-sharing-demand/__init__.py +0 -0
- mlebench/competitions/bike-sharing-demand/grade.py +55 -0
- mlebench/competitions/bike-sharing-demand/prepare.py +37 -0
- mlebench/competitions/billion-word-imputation/grade.py +37 -0
- mlebench/competitions/billion-word-imputation/prepare.py +107 -0
- mlebench/competitions/billion-word-imputation/prepare_val.py +179 -0
- mlebench/competitions/bms-molecular-translation/grade.py +40 -0
- mlebench/competitions/bms-molecular-translation/prepare.py +68 -0
- mlebench/competitions/bms-molecular-translation/prepare_val.py +131 -0
- mlebench/competitions/cassava-leaf-disease-classification/grade.py +12 -0
- mlebench/competitions/cassava-leaf-disease-classification/prepare.py +113 -0
- mlebench/competitions/cassava-leaf-disease-classification/prepare_val.py +186 -0
- mlebench/competitions/cdiscount-image-classification-challenge/grade.py +11 -0
- mlebench/competitions/cdiscount-image-classification-challenge/prepare.py +144 -0
- mlebench/competitions/cdiscount-image-classification-challenge/prepare_val.py +205 -0
- mlebench/competitions/chaii-hindi-and-tamil-question-answering/grade.py +67 -0
- mlebench/competitions/chaii-hindi-and-tamil-question-answering/prepare.py +31 -0
- mlebench/competitions/chaii-hindi-and-tamil-question-answering/prepare_val.py +94 -0
- mlebench/competitions/champs-scalar-coupling/grade.py +60 -0
- mlebench/competitions/champs-scalar-coupling/prepare.py +116 -0
- mlebench/competitions/champs-scalar-coupling/prepare_val.py +155 -0
- mlebench/competitions/conways-reverse-game-of-life-2020/__init__.py +0 -0
- mlebench/competitions/conways-reverse-game-of-life-2020/grade.py +40 -0
- mlebench/competitions/conways-reverse-game-of-life-2020/prepare.py +41 -0
- mlebench/competitions/demand-forecasting-kernels-only/__init__.py +0 -0
- mlebench/competitions/demand-forecasting-kernels-only/grade.py +66 -0
- mlebench/competitions/demand-forecasting-kernels-only/prepare.py +27 -0
- mlebench/competitions/demand_forecasting_kernels_only/__init__.py +0 -0
- mlebench/competitions/demand_forecasting_kernels_only/grade.py +66 -0
- mlebench/competitions/demand_forecasting_kernels_only/prepare.py +27 -0
- mlebench/competitions/denoising-dirty-documents/grade.py +44 -0
- mlebench/competitions/denoising-dirty-documents/prepare.py +134 -0
- mlebench/competitions/denoising-dirty-documents/prepare_val.py +178 -0
- mlebench/competitions/detecting-insults-in-social-commentary/grade.py +11 -0
- mlebench/competitions/detecting-insults-in-social-commentary/prepare.py +72 -0
- mlebench/competitions/detecting-insults-in-social-commentary/prepare_val.py +128 -0
- mlebench/competitions/dog-breed-identification/dogs.py +124 -0
- mlebench/competitions/dog-breed-identification/grade.py +42 -0
- mlebench/competitions/dog-breed-identification/prepare.py +55 -0
- mlebench/competitions/dog-breed-identification/prepare_val.py +104 -0
- mlebench/competitions/dogs-vs-cats-redux-kernels-edition/grade.py +43 -0
- mlebench/competitions/dogs-vs-cats-redux-kernels-edition/prepare.py +70 -0
- mlebench/competitions/dogs-vs-cats-redux-kernels-edition/prepare_val.py +143 -0
- mlebench/competitions/ethanol-concentration/grade.py +23 -0
- mlebench/competitions/ethanol-concentration/prepare.py +90 -0
- mlebench/competitions/facebook-recruiting-iii-keyword-extraction/grade.py +60 -0
- mlebench/competitions/facebook-recruiting-iii-keyword-extraction/prepare.py +41 -0
- mlebench/competitions/facebook-recruiting-iii-keyword-extraction/prepare_val.py +92 -0
- mlebench/competitions/feedback-prize-english-language-learning/__init__.py +0 -0
- mlebench/competitions/feedback-prize-english-language-learning/grade.py +60 -0
- mlebench/competitions/feedback-prize-english-language-learning/prepare.py +39 -0
- mlebench/competitions/freesound-audio-tagging-2019/grade.py +64 -0
- mlebench/competitions/freesound-audio-tagging-2019/prepare.py +94 -0
- mlebench/competitions/freesound-audio-tagging-2019/prepare_val.py +175 -0
- mlebench/competitions/freesound-audio-tagging-2019/vocabulary.py +83 -0
- mlebench/competitions/google-quest-challenge/classes.py +32 -0
- mlebench/competitions/google-quest-challenge/grade.py +45 -0
- mlebench/competitions/google-quest-challenge/prepare.py +58 -0
- mlebench/competitions/google-quest-challenge/prepare_val.py +120 -0
- mlebench/competitions/google-research-identify-contrails-reduce-global-warming/grade.py +77 -0
- mlebench/competitions/google-research-identify-contrails-reduce-global-warming/prepare.py +155 -0
- mlebench/competitions/google-research-identify-contrails-reduce-global-warming/prepare_val.py +211 -0
- mlebench/competitions/h-and-m-personalized-fashion-recommendations/grade.py +42 -0
- mlebench/competitions/h-and-m-personalized-fashion-recommendations/prepare.py +102 -0
- mlebench/competitions/h-and-m-personalized-fashion-recommendations/prepare_val.py +132 -0
- mlebench/competitions/handwriting/grade.py +23 -0
- mlebench/competitions/handwriting/prepare.py +179 -0
- mlebench/competitions/herbarium-2020-fgvc7/grade.py +34 -0
- mlebench/competitions/herbarium-2020-fgvc7/prepare.py +251 -0
- mlebench/competitions/herbarium-2020-fgvc7/prepare_val.py +242 -0
- mlebench/competitions/herbarium-2021-fgvc8/grade.py +34 -0
- mlebench/competitions/herbarium-2021-fgvc8/prepare.py +251 -0
- mlebench/competitions/herbarium-2021-fgvc8/prepare_val.py +222 -0
- mlebench/competitions/herbarium-2022-fgvc9/grade.py +31 -0
- mlebench/competitions/herbarium-2022-fgvc9/prepare.py +233 -0
- mlebench/competitions/herbarium-2022-fgvc9/prepare_val.py +213 -0
- mlebench/competitions/histopathologic-cancer-detection/grade.py +12 -0
- mlebench/competitions/histopathologic-cancer-detection/prepare.py +59 -0
- mlebench/competitions/histopathologic-cancer-detection/prepare_val.py +131 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/constants.py +9 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/grade.py +43 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/kaggle_metric_utilities.py +96 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/kullback_leibler_divergence.py +118 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/prepare.py +121 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/prepare_val.py +190 -0
- mlebench/competitions/hotel-id-2021-fgvc8/grade.py +41 -0
- mlebench/competitions/hotel-id-2021-fgvc8/prepare.py +63 -0
- mlebench/competitions/hotel-id-2021-fgvc8/prepare_val.py +132 -0
- mlebench/competitions/hubmap-kidney-segmentation/grade.py +62 -0
- mlebench/competitions/hubmap-kidney-segmentation/prepare.py +108 -0
- mlebench/competitions/hubmap-kidney-segmentation/prepare_val.py +153 -0
- mlebench/competitions/icecube-neutrinos-in-deep-ice/grade.py +111 -0
- mlebench/competitions/icecube-neutrinos-in-deep-ice/prepare.py +127 -0
- mlebench/competitions/icecube-neutrinos-in-deep-ice/prepare_val.py +183 -0
- mlebench/competitions/ili/grade.py +60 -0
- mlebench/competitions/ili/prepare.py +99 -0
- mlebench/competitions/imet-2020-fgvc7/grade.py +54 -0
- mlebench/competitions/imet-2020-fgvc7/prepare.py +77 -0
- mlebench/competitions/imet-2020-fgvc7/prepare_val.py +157 -0
- mlebench/competitions/inaturalist-2019-fgvc6/grade.py +35 -0
- mlebench/competitions/inaturalist-2019-fgvc6/prepare.py +259 -0
- mlebench/competitions/inaturalist-2019-fgvc6/prepare_val.py +304 -0
- mlebench/competitions/instant-gratification/__init__.py +0 -0
- mlebench/competitions/instant-gratification/grade.py +55 -0
- mlebench/competitions/instant-gratification/prepare.py +25 -0
- mlebench/competitions/instant_gratification/__init__.py +0 -0
- mlebench/competitions/instant_gratification/grade.py +55 -0
- mlebench/competitions/instant_gratification/prepare.py +25 -0
- mlebench/competitions/invasive-species-monitoring/grade.py +11 -0
- mlebench/competitions/invasive-species-monitoring/prepare.py +97 -0
- mlebench/competitions/invasive-species-monitoring/prepare_val.py +164 -0
- mlebench/competitions/iwildcam-2019-fgvc6/grade.py +44 -0
- mlebench/competitions/iwildcam-2019-fgvc6/prepare.py +118 -0
- mlebench/competitions/iwildcam-2019-fgvc6/prepare_val.py +194 -0
- mlebench/competitions/iwildcam-2020-fgvc7/grade.py +11 -0
- mlebench/competitions/iwildcam-2020-fgvc7/prepare.py +164 -0
- mlebench/competitions/iwildcam-2020-fgvc7/prepare_val.py +245 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/classes.py +1 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/grade.py +54 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/prepare.py +42 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/prepare_val.py +88 -0
- mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/grade.py +153 -0
- mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/prepare.py +36 -0
- mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/prepare_val.py +117 -0
- mlebench/competitions/kuzushiji-recognition/grade.py +58 -0
- mlebench/competitions/kuzushiji-recognition/kuzushiji_metric.py +118 -0
- mlebench/competitions/kuzushiji-recognition/prepare.py +92 -0
- mlebench/competitions/kuzushiji-recognition/prepare_val.py +149 -0
- mlebench/competitions/leaf-classification/classes.py +101 -0
- mlebench/competitions/leaf-classification/grade.py +44 -0
- mlebench/competitions/leaf-classification/prepare.py +60 -0
- mlebench/competitions/leaf-classification/prepare_val.py +116 -0
- mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/grade.py +44 -0
- mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/prepare.py +51 -0
- mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/prepare_val.py +96 -0
- mlebench/competitions/liverpool-ion-switching/__init__.py +0 -0
- mlebench/competitions/liverpool-ion-switching/grade.py +52 -0
- mlebench/competitions/liverpool-ion-switching/prepare.py +27 -0
- mlebench/competitions/liverpool_ion_switching/__init__.py +0 -0
- mlebench/competitions/liverpool_ion_switching/grade.py +52 -0
- mlebench/competitions/liverpool_ion_switching/prepare.py +27 -0
- mlebench/competitions/lmsys-chatbot-arena/grade.py +63 -0
- mlebench/competitions/lmsys-chatbot-arena/prepare.py +52 -0
- mlebench/competitions/lmsys-chatbot-arena/prepare_val.py +115 -0
- mlebench/competitions/mcm_2024_c_test/grade.py +107 -0
- mlebench/competitions/mcm_2024_c_test/prepare.py +2 -0
- mlebench/competitions/ml2021spring-hw2/grade.py +11 -0
- mlebench/competitions/ml2021spring-hw2/prepare.py +58 -0
- mlebench/competitions/ml2021spring-hw2/prepare_val.py +135 -0
- mlebench/competitions/mlsp-2013-birds/grade.py +11 -0
- mlebench/competitions/mlsp-2013-birds/prepare.py +182 -0
- mlebench/competitions/mlsp-2013-birds/prepare_val.py +241 -0
- mlebench/competitions/movie-review-sentiment-analysis-kernels-only/grade.py +11 -0
- mlebench/competitions/movie-review-sentiment-analysis-kernels-only/prepare.py +58 -0
- mlebench/competitions/movie-review-sentiment-analysis-kernels-only/prepare_val.py +120 -0
- mlebench/competitions/multi-modal-gesture-recognition/grade.py +58 -0
- mlebench/competitions/multi-modal-gesture-recognition/prepare.py +85 -0
- mlebench/competitions/multi-modal-gesture-recognition/prepare_val.py +139 -0
- mlebench/competitions/my-custom-task-01/prepare.py +2 -0
- mlebench/competitions/new-my-task-01/prepare.py +2 -0
- mlebench/competitions/new-my-task-03/grade.py +107 -0
- mlebench/competitions/new-my-task-03/prepare.py +2 -0
- mlebench/competitions/new-york-city-taxi-fare-prediction/grade.py +28 -0
- mlebench/competitions/new-york-city-taxi-fare-prediction/prepare.py +44 -0
- mlebench/competitions/new-york-city-taxi-fare-prediction/prepare_val.py +89 -0
- mlebench/competitions/nfl-player-contact-detection/grade.py +36 -0
- mlebench/competitions/nfl-player-contact-detection/prepare.py +101 -0
- mlebench/competitions/nfl-player-contact-detection/prepare_val.py +186 -0
- mlebench/competitions/nomad2018-predict-transparent-conductors/grade.py +47 -0
- mlebench/competitions/nomad2018-predict-transparent-conductors/prepare.py +77 -0
- mlebench/competitions/nomad2018-predict-transparent-conductors/prepare_val.py +144 -0
- mlebench/competitions/osic-pulmonary-fibrosis-progression/grade.py +74 -0
- mlebench/competitions/osic-pulmonary-fibrosis-progression/prepare.py +95 -0
- mlebench/competitions/osic-pulmonary-fibrosis-progression/prepare_val.py +167 -0
- mlebench/competitions/paddy-disease-classification/grade.py +35 -0
- mlebench/competitions/paddy-disease-classification/prepare.py +69 -0
- mlebench/competitions/paddy-disease-classification/prepare_val.py +122 -0
- mlebench/competitions/petfinder-pawpularity-score/grade.py +41 -0
- mlebench/competitions/petfinder-pawpularity-score/prepare.py +76 -0
- mlebench/competitions/petfinder-pawpularity-score/prepare_val.py +154 -0
- mlebench/competitions/plant-pathology-2020-fgvc7/grade.py +41 -0
- mlebench/competitions/plant-pathology-2020-fgvc7/prepare.py +74 -0
- mlebench/competitions/plant-pathology-2020-fgvc7/prepare_val.py +160 -0
- mlebench/competitions/plant-pathology-2021-fgvc8/grade.py +54 -0
- mlebench/competitions/plant-pathology-2021-fgvc8/prepare.py +65 -0
- mlebench/competitions/plant-pathology-2021-fgvc8/prepare_val.py +130 -0
- mlebench/competitions/plant-seedlings-classification/grade.py +39 -0
- mlebench/competitions/plant-seedlings-classification/prepare.py +91 -0
- mlebench/competitions/plant-seedlings-classification/prepare_val.py +158 -0
- mlebench/competitions/playground-series-s3e1/__init__.py +0 -0
- mlebench/competitions/playground-series-s3e1/grade.py +52 -0
- mlebench/competitions/playground-series-s3e1/prepare.py +25 -0
- mlebench/competitions/playground-series-s3e11/__init__.py +0 -0
- mlebench/competitions/playground-series-s3e11/grade.py +55 -0
- mlebench/competitions/playground-series-s3e11/prepare.py +25 -0
- mlebench/competitions/playground-series-s3e18/grade.py +39 -0
- mlebench/competitions/playground-series-s3e18/prepare.py +36 -0
- mlebench/competitions/playground-series-s3e18/prepare_val.py +89 -0
- mlebench/competitions/playground_series_s3e1/__init__.py +0 -0
- mlebench/competitions/playground_series_s3e1/grade.py +52 -0
- mlebench/competitions/playground_series_s3e1/prepare.py +25 -0
- mlebench/competitions/playground_series_s3e11/__init__.py +0 -0
- mlebench/competitions/playground_series_s3e11/grade.py +55 -0
- mlebench/competitions/playground_series_s3e11/prepare.py +25 -0
- mlebench/competitions/predict-volcanic-eruptions-ingv-oe/grade.py +44 -0
- mlebench/competitions/predict-volcanic-eruptions-ingv-oe/prepare.py +68 -0
- mlebench/competitions/predict-volcanic-eruptions-ingv-oe/prepare_val.py +146 -0
- mlebench/competitions/random-acts-of-pizza/grade.py +14 -0
- mlebench/competitions/random-acts-of-pizza/prepare.py +80 -0
- mlebench/competitions/random-acts-of-pizza/prepare_val.py +144 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/classes.py +11 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/grade.py +31 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/prepare.py +53 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/prepare_val.py +113 -0
- mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/grade.py +124 -0
- mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/prepare.py +219 -0
- mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/prepare_val.py +257 -0
- mlebench/competitions/rsna-breast-cancer-detection/grade.py +65 -0
- mlebench/competitions/rsna-breast-cancer-detection/prepare.py +141 -0
- mlebench/competitions/rsna-breast-cancer-detection/prepare_val.py +201 -0
- mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/grade.py +13 -0
- mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/prepare.py +47 -0
- mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/prepare_val.py +97 -0
- mlebench/competitions/santander-customer-satisfaction/grade.py +10 -0
- mlebench/competitions/santander-customer-satisfaction/prepare.py +41 -0
- mlebench/competitions/sciencebench-001-clintox-nn/__init__.py +0 -0
- mlebench/competitions/sciencebench-001-clintox-nn/grade.py +56 -0
- mlebench/competitions/sciencebench-001-clintox-nn/prepare.py +75 -0
- mlebench/competitions/sciencebench-015-aai/grade.py +37 -0
- mlebench/competitions/sciencebench-015-aai/prepare.py +102 -0
- mlebench/competitions/sciencebench-051-brain-blood-qsar/grade.py +58 -0
- mlebench/competitions/sciencebench-051-brain-blood-qsar/prepare.py +69 -0
- mlebench/competitions/sciencebench-101-experimental-band-gap-prediction/grade.py +55 -0
- mlebench/competitions/sciencebench-101-experimental-band-gap-prediction/prepare.py +88 -0
- mlebench/competitions/see-click-predict-fix/__init__.py +0 -0
- mlebench/competitions/see-click-predict-fix/grade.py +66 -0
- mlebench/competitions/see-click-predict-fix/prepare.py +25 -0
- mlebench/competitions/see_click_predict_fix/__init__.py +0 -0
- mlebench/competitions/see_click_predict_fix/grade.py +66 -0
- mlebench/competitions/see_click_predict_fix/prepare.py +25 -0
- mlebench/competitions/seti-breakthrough-listen/grade.py +11 -0
- mlebench/competitions/seti-breakthrough-listen/prepare.py +71 -0
- mlebench/competitions/seti-breakthrough-listen/prepare_val.py +159 -0
- mlebench/competitions/siim-covid19-detection/grade.py +194 -0
- mlebench/competitions/siim-covid19-detection/prepare.py +123 -0
- mlebench/competitions/siim-covid19-detection/prepare_val.py +164 -0
- mlebench/competitions/siim-isic-melanoma-classification/grade.py +11 -0
- mlebench/competitions/siim-isic-melanoma-classification/prepare.py +127 -0
- mlebench/competitions/siim-isic-melanoma-classification/prepare_val.py +158 -0
- mlebench/competitions/smartphone-decimeter-2022/grade.py +55 -0
- mlebench/competitions/smartphone-decimeter-2022/notebook.py +86 -0
- mlebench/competitions/smartphone-decimeter-2022/prepare.py +143 -0
- mlebench/competitions/smartphone-decimeter-2022/prepare_val.py +199 -0
- mlebench/competitions/spaceship-titanic/grade.py +11 -0
- mlebench/competitions/spaceship-titanic/prepare.py +23 -0
- mlebench/competitions/spaceship-titanic/prepare_val.py +61 -0
- mlebench/competitions/spooky-author-identification/classes.py +1 -0
- mlebench/competitions/spooky-author-identification/grade.py +38 -0
- mlebench/competitions/spooky-author-identification/prepare.py +40 -0
- mlebench/competitions/spooky-author-identification/prepare_val.py +78 -0
- mlebench/competitions/stanford-covid-vaccine/grade.py +65 -0
- mlebench/competitions/stanford-covid-vaccine/prepare.py +129 -0
- mlebench/competitions/stanford-covid-vaccine/prepare_val.py +199 -0
- mlebench/competitions/statoil-iceberg-classifier-challenge/grade.py +41 -0
- mlebench/competitions/statoil-iceberg-classifier-challenge/prepare.py +105 -0
- mlebench/competitions/statoil-iceberg-classifier-challenge/prepare_val.py +157 -0
- mlebench/competitions/tabular-playground-series-dec-2021/grade.py +11 -0
- mlebench/competitions/tabular-playground-series-dec-2021/prepare.py +39 -0
- mlebench/competitions/tabular-playground-series-dec-2021/prepare_val.py +99 -0
- mlebench/competitions/tabular-playground-series-may-2022/grade.py +9 -0
- mlebench/competitions/tabular-playground-series-may-2022/prepare.py +56 -0
- mlebench/competitions/tabular-playground-series-may-2022/prepare_val.py +116 -0
- mlebench/competitions/tensorflow-speech-recognition-challenge/grade.py +11 -0
- mlebench/competitions/tensorflow-speech-recognition-challenge/prepare.py +90 -0
- mlebench/competitions/tensorflow-speech-recognition-challenge/prepare_val.py +148 -0
- mlebench/competitions/tensorflow2-question-answering/grade.py +122 -0
- mlebench/competitions/tensorflow2-question-answering/prepare.py +122 -0
- mlebench/competitions/tensorflow2-question-answering/prepare_val.py +187 -0
- mlebench/competitions/text-normalization-challenge-english-language/grade.py +49 -0
- mlebench/competitions/text-normalization-challenge-english-language/prepare.py +115 -0
- mlebench/competitions/text-normalization-challenge-english-language/prepare_val.py +213 -0
- mlebench/competitions/text-normalization-challenge-russian-language/grade.py +49 -0
- mlebench/competitions/text-normalization-challenge-russian-language/prepare.py +113 -0
- mlebench/competitions/text-normalization-challenge-russian-language/prepare_val.py +165 -0
- mlebench/competitions/tgs-salt-identification-challenge/grade.py +144 -0
- mlebench/competitions/tgs-salt-identification-challenge/prepare.py +158 -0
- mlebench/competitions/tgs-salt-identification-challenge/prepare_val.py +166 -0
- mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/grade.py +11 -0
- mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/prepare.py +95 -0
- mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/prepare_val.py +141 -0
- mlebench/competitions/tmdb-box-office-prediction/__init__.py +0 -0
- mlebench/competitions/tmdb-box-office-prediction/grade.py +55 -0
- mlebench/competitions/tmdb-box-office-prediction/prepare.py +35 -0
- mlebench/competitions/tweet-sentiment-extraction/grade.py +67 -0
- mlebench/competitions/tweet-sentiment-extraction/prepare.py +36 -0
- mlebench/competitions/tweet-sentiment-extraction/prepare_val.py +106 -0
- mlebench/competitions/us-patent-phrase-to-phrase-matching/grade.py +31 -0
- mlebench/competitions/us-patent-phrase-to-phrase-matching/prepare.py +33 -0
- mlebench/competitions/us-patent-phrase-to-phrase-matching/prepare_val.py +71 -0
- mlebench/competitions/utils.py +266 -0
- mlebench/competitions/uw-madison-gi-tract-image-segmentation/grade.py +158 -0
- mlebench/competitions/uw-madison-gi-tract-image-segmentation/prepare.py +139 -0
- mlebench/competitions/uw-madison-gi-tract-image-segmentation/prepare_val.py +193 -0
- mlebench/competitions/ventilator-pressure-prediction/__init__.py +0 -0
- mlebench/competitions/ventilator-pressure-prediction/grade.py +52 -0
- mlebench/competitions/ventilator-pressure-prediction/prepare.py +27 -0
- mlebench/competitions/ventilator-pressure-prediction/prepare_val.py +142 -0
- mlebench/competitions/ventilator_pressure_prediction/__init__.py +0 -0
- mlebench/competitions/ventilator_pressure_prediction/grade.py +52 -0
- mlebench/competitions/ventilator_pressure_prediction/prepare.py +27 -0
- mlebench/competitions/vesuvius-challenge-ink-detection/grade.py +97 -0
- mlebench/competitions/vesuvius-challenge-ink-detection/prepare.py +122 -0
- mlebench/competitions/vesuvius-challenge-ink-detection/prepare_val.py +170 -0
- mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/grade.py +220 -0
- mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/prepare.py +129 -0
- mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/prepare_val.py +204 -0
- mlebench/competitions/whale-categorization-playground/grade.py +41 -0
- mlebench/competitions/whale-categorization-playground/prepare.py +103 -0
- mlebench/competitions/whale-categorization-playground/prepare_val.py +196 -0
- mlebench/data.py +420 -0
- mlebench/grade.py +209 -0
- mlebench/grade_helpers.py +235 -0
- mlebench/metrics.py +75 -0
- mlebench/registry.py +332 -0
- mlebench/utils.py +346 -0
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/WHEEL +0 -0
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import random
|
|
3
|
+
import shutil
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
from sklearn.model_selection import train_test_split
|
|
8
|
+
from tqdm import tqdm
|
|
9
|
+
|
|
10
|
+
from mlebench.utils import get_logger
|
|
11
|
+
|
|
12
|
+
logger = get_logger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _create_dataset_files(
|
|
16
|
+
train_data_by_cat: dict,
|
|
17
|
+
test_data_by_cat: dict,
|
|
18
|
+
base_metadata: dict,
|
|
19
|
+
public_dir: Path,
|
|
20
|
+
private_dir: Path,
|
|
21
|
+
raw_dir: Path,
|
|
22
|
+
dev_mode: bool,
|
|
23
|
+
dev_count: int,
|
|
24
|
+
):
|
|
25
|
+
"""
|
|
26
|
+
Helper function to generate the complete set of dataset files for a given split.
|
|
27
|
+
|
|
28
|
+
This function is responsible for:
|
|
29
|
+
1. Creating the `train` set (metadata.json and image files).
|
|
30
|
+
2. Creating the `test` set (public metadata.json and image files).
|
|
31
|
+
3. Creating the private `answers.csv` for the `test` set.
|
|
32
|
+
4. Creating the public `sample_submission.csv`.
|
|
33
|
+
"""
|
|
34
|
+
public_dir.mkdir(exist_ok=True, parents=True)
|
|
35
|
+
private_dir.mkdir(exist_ok=True, parents=True)
|
|
36
|
+
|
|
37
|
+
# --- Process Train Set ---
|
|
38
|
+
new_train_metadata = base_metadata.copy()
|
|
39
|
+
new_train_metadata.update({"annotations": [], "images": []})
|
|
40
|
+
train_sample_count = sum(len(v) for v in train_data_by_cat.values())
|
|
41
|
+
|
|
42
|
+
with tqdm(
|
|
43
|
+
desc=f"Creating train set for {public_dir.name}",
|
|
44
|
+
total=train_sample_count,
|
|
45
|
+
) as pbar:
|
|
46
|
+
for category_id, annotations_images in train_data_by_cat.items():
|
|
47
|
+
category_subdir = f"{category_id // 100:03d}/{category_id % 100:02d}"
|
|
48
|
+
(public_dir / "nybg2020/train/images" / category_subdir).mkdir(
|
|
49
|
+
exist_ok=True, parents=True
|
|
50
|
+
)
|
|
51
|
+
for idx, annotation_image in enumerate(annotations_images):
|
|
52
|
+
new_train_metadata["annotations"].append(annotation_image["annotation"].copy())
|
|
53
|
+
new_train_metadata["images"].append(annotation_image["image"].copy())
|
|
54
|
+
|
|
55
|
+
if not dev_mode or idx < dev_count:
|
|
56
|
+
src_path = raw_dir / "nybg2020/train" / annotation_image["image"]["file_name"]
|
|
57
|
+
dst_path = public_dir / "nybg2020/train" / annotation_image["image"]["file_name"]
|
|
58
|
+
shutil.copyfile(src=src_path, dst=dst_path)
|
|
59
|
+
|
|
60
|
+
pbar.update(1)
|
|
61
|
+
|
|
62
|
+
with open(public_dir / "nybg2020/train/metadata.json", "w") as f:
|
|
63
|
+
json.dump(new_train_metadata, f, indent=4, sort_keys=True)
|
|
64
|
+
|
|
65
|
+
if not dev_mode:
|
|
66
|
+
assert len(list((public_dir / "nybg2020/train/images").glob("**/*.jpg"))) == len(
|
|
67
|
+
new_train_metadata["images"]
|
|
68
|
+
)
|
|
69
|
+
assert len(new_train_metadata["annotations"]) == len(new_train_metadata["images"])
|
|
70
|
+
|
|
71
|
+
# --- Process Test Set ---
|
|
72
|
+
new_test_metadata = base_metadata.copy()
|
|
73
|
+
del new_test_metadata["categories"]
|
|
74
|
+
del new_test_metadata["regions"]
|
|
75
|
+
new_test_metadata.update({"annotations": [], "images": []})
|
|
76
|
+
|
|
77
|
+
test_annotations_images = [item for sublist in test_data_by_cat.values() for item in sublist]
|
|
78
|
+
random.Random(0).shuffle(test_annotations_images)
|
|
79
|
+
|
|
80
|
+
for idx, annotation_image in tqdm(
|
|
81
|
+
enumerate(test_annotations_images),
|
|
82
|
+
desc=f"Creating test set for {public_dir.name}",
|
|
83
|
+
total=len(test_annotations_images),
|
|
84
|
+
):
|
|
85
|
+
new_image_id = str(idx)
|
|
86
|
+
new_file_name = f"images/{idx // 1000:03d}/{idx}.jpg"
|
|
87
|
+
|
|
88
|
+
new_annotation = annotation_image["annotation"].copy()
|
|
89
|
+
new_annotation["image_id"] = new_image_id
|
|
90
|
+
new_test_metadata["annotations"].append(new_annotation)
|
|
91
|
+
|
|
92
|
+
new_image = annotation_image["image"].copy()
|
|
93
|
+
new_image["id"] = new_image_id
|
|
94
|
+
new_image["file_name"] = new_file_name
|
|
95
|
+
new_test_metadata["images"].append(new_image)
|
|
96
|
+
|
|
97
|
+
if not dev_mode or idx < dev_count:
|
|
98
|
+
src_path = raw_dir / "nybg2020/train" / annotation_image["image"]["file_name"]
|
|
99
|
+
dst_path = public_dir / "nybg2020/test" / new_file_name
|
|
100
|
+
dst_path.parent.mkdir(exist_ok=True, parents=True)
|
|
101
|
+
shutil.copyfile(src=src_path, dst=dst_path)
|
|
102
|
+
|
|
103
|
+
# Save public test metadata (without annotations)
|
|
104
|
+
with open(public_dir / "nybg2020/test/metadata.json", "w") as f:
|
|
105
|
+
public_new_test = new_test_metadata.copy()
|
|
106
|
+
del public_new_test["annotations"]
|
|
107
|
+
assert public_new_test.keys() == {"images", "info", "licenses"}
|
|
108
|
+
json.dump(public_new_test, f, indent=4, sort_keys=True)
|
|
109
|
+
|
|
110
|
+
if not dev_mode:
|
|
111
|
+
assert len(list((public_dir / "nybg2020/test/images").glob("**/*.jpg"))) == len(
|
|
112
|
+
new_test_metadata["images"]
|
|
113
|
+
)
|
|
114
|
+
assert len(new_test_metadata["annotations"]) == len(new_test_metadata["images"])
|
|
115
|
+
|
|
116
|
+
# --- Save Private Test Answers and Public Sample Submission ---
|
|
117
|
+
answers_rows = [
|
|
118
|
+
{"Id": img["id"], "Predicted": ann["category_id"]}
|
|
119
|
+
for img, ann in zip(new_test_metadata["images"], new_test_metadata["annotations"])
|
|
120
|
+
]
|
|
121
|
+
answers_df = pd.DataFrame(answers_rows)
|
|
122
|
+
answers_df.to_csv(private_dir / "answers.csv", index=False)
|
|
123
|
+
|
|
124
|
+
sample_df = pd.DataFrame({"Id": answers_df["Id"], "Predicted": 0})
|
|
125
|
+
sample_df.to_csv(public_dir / "sample_submission.csv", index=False)
|
|
126
|
+
|
|
127
|
+
assert len(answers_df) == len(new_test_metadata["images"])
|
|
128
|
+
assert len(sample_df) == len(answers_df)
|
|
129
|
+
assert answers_df["Id"].equals(sample_df["Id"])
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _split_data_by_category(
|
|
133
|
+
data_by_cat: dict, test_size: float, random_state: int
|
|
134
|
+
) -> tuple[dict, dict]:
|
|
135
|
+
"""Splits data within each category into train and test sets."""
|
|
136
|
+
train_split = {}
|
|
137
|
+
test_split = {}
|
|
138
|
+
for category_id, annotations_images in data_by_cat.items():
|
|
139
|
+
n_samples = len(annotations_images)
|
|
140
|
+
if n_samples == 1:
|
|
141
|
+
train_annotations_images = annotations_images
|
|
142
|
+
test_annotations_images = []
|
|
143
|
+
elif n_samples < 5:
|
|
144
|
+
# Ensure at least 1 sample in test for small categories
|
|
145
|
+
current_test_size = max(1, int(n_samples * test_size))
|
|
146
|
+
train_annotations_images = annotations_images[:-current_test_size]
|
|
147
|
+
test_annotations_images = annotations_images[-current_test_size:]
|
|
148
|
+
else:
|
|
149
|
+
train_annotations_images, test_annotations_images = train_test_split(
|
|
150
|
+
annotations_images, test_size=test_size, random_state=random_state
|
|
151
|
+
)
|
|
152
|
+
train_split[category_id] = train_annotations_images
|
|
153
|
+
test_split[category_id] = test_annotations_images
|
|
154
|
+
return train_split, test_split
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def prepare(raw: Path, public: Path, private: Path):
|
|
158
|
+
"""
|
|
159
|
+
Splits the raw data into public and private datasets with appropriate test/train splits.
|
|
160
|
+
This version also creates a second, parallel split for validation purposes.
|
|
161
|
+
"""
|
|
162
|
+
dev_mode = False
|
|
163
|
+
dev_count = 2 # Copy over n images per category when in dev mode
|
|
164
|
+
|
|
165
|
+
# Create directories for the new validation split
|
|
166
|
+
public_val = public.parent / "public_val"
|
|
167
|
+
private_val = private.parent / "private_val"
|
|
168
|
+
|
|
169
|
+
# Load raw data and organize by category
|
|
170
|
+
json_path = raw / "nybg2020/train/metadata.json"
|
|
171
|
+
with open(json_path, "r", encoding="latin-1") as f:
|
|
172
|
+
old_train_metadata = json.load(f)
|
|
173
|
+
|
|
174
|
+
annotations_images_by_category = {}
|
|
175
|
+
for annotation, image in list(
|
|
176
|
+
zip(old_train_metadata["annotations"], old_train_metadata["images"])
|
|
177
|
+
):
|
|
178
|
+
assert annotation["image_id"] == image["id"]
|
|
179
|
+
category_id = annotation["category_id"]
|
|
180
|
+
if category_id not in annotations_images_by_category:
|
|
181
|
+
annotations_images_by_category[category_id] = []
|
|
182
|
+
annotations_images_by_category[category_id].append(
|
|
183
|
+
{"annotation": annotation, "image": image}
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# --- First Split: Create the main train/test sets (80/20 split of raw data) ---
|
|
187
|
+
logger.info("Performing first split: raw data -> train/test")
|
|
188
|
+
original_test_size = 0.2
|
|
189
|
+
train_data_by_cat, test_data_by_cat = _split_data_by_category(
|
|
190
|
+
annotations_images_by_category,
|
|
191
|
+
test_size=original_test_size,
|
|
192
|
+
random_state=0,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
# Generate the original `public` and `private` outputs
|
|
196
|
+
_create_dataset_files(
|
|
197
|
+
train_data_by_cat,
|
|
198
|
+
test_data_by_cat,
|
|
199
|
+
old_train_metadata,
|
|
200
|
+
public,
|
|
201
|
+
private,
|
|
202
|
+
raw,
|
|
203
|
+
dev_mode,
|
|
204
|
+
dev_count,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# --- Second Split: Create the validation train/test sets from the main train set ---
|
|
208
|
+
# The goal is a validation set (`test_val`) of roughly the same size as the original test set.
|
|
209
|
+
# Original split: train=0.8*N, test=0.2*N
|
|
210
|
+
# Second split on train data: We need a test fraction of (0.2*N)/(0.8*N) = 0.25
|
|
211
|
+
logger.info("Performing second split: train data -> train_val/test_val")
|
|
212
|
+
validation_test_size = 0.25
|
|
213
|
+
train_val_data_by_cat, test_val_data_by_cat = _split_data_by_category(
|
|
214
|
+
train_data_by_cat, # Use the training data from the first split as input
|
|
215
|
+
test_size=validation_test_size,
|
|
216
|
+
random_state=0, # Use same random state for consistency
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Generate the new `public_val` and `private_val` outputs
|
|
220
|
+
_create_dataset_files(
|
|
221
|
+
train_val_data_by_cat,
|
|
222
|
+
test_val_data_by_cat,
|
|
223
|
+
old_train_metadata,
|
|
224
|
+
public_val,
|
|
225
|
+
private_val,
|
|
226
|
+
raw,
|
|
227
|
+
dev_mode,
|
|
228
|
+
dev_count,
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
logger.info("Data preparation complete.")
|
|
232
|
+
if not dev_mode:
|
|
233
|
+
# Final sanity check on total annotations
|
|
234
|
+
total_original = len(old_train_metadata["annotations"])
|
|
235
|
+
total_in_first_split = sum(len(v) for v in train_data_by_cat.values()) + sum(
|
|
236
|
+
len(v) for v in test_data_by_cat.values()
|
|
237
|
+
)
|
|
238
|
+
total_in_second_split = sum(len(v) for v in train_val_data_by_cat.values()) + sum(
|
|
239
|
+
len(v) for v in test_val_data_by_cat.values()
|
|
240
|
+
)
|
|
241
|
+
assert total_original == total_in_first_split
|
|
242
|
+
assert total_in_second_split == sum(len(v) for v in train_data_by_cat.values())
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
from sklearn.metrics import f1_score
|
|
3
|
+
|
|
4
|
+
from mlebench.grade_helpers import InvalidSubmissionError
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def prepare_for_metric(submission: pd.DataFrame, answers: pd.DataFrame):
|
|
8
|
+
"""
|
|
9
|
+
`submission` and `answers` are pd.DataFrame with "Id" and "Predicted" columns
|
|
10
|
+
"""
|
|
11
|
+
if len(submission) != len(answers):
|
|
12
|
+
raise InvalidSubmissionError(
|
|
13
|
+
f"Submission length {len(submission)} != answers length {len(answers)}"
|
|
14
|
+
)
|
|
15
|
+
if "Id" not in submission.columns or "Predicted" not in submission.columns:
|
|
16
|
+
raise InvalidSubmissionError("Submission must have 'Id' and 'Predicted' columns")
|
|
17
|
+
|
|
18
|
+
assert "Id" in answers.columns, "Answers must have 'Id' column"
|
|
19
|
+
assert "Predicted" in answers.columns, "Answers must have 'Predicted' column"
|
|
20
|
+
|
|
21
|
+
# Sort submission and answers by "Id"
|
|
22
|
+
submission = submission.sort_values("Id")
|
|
23
|
+
answers = answers.sort_values("Id")
|
|
24
|
+
if (submission["Id"].values != answers["Id"].values).any():
|
|
25
|
+
raise InvalidSubmissionError("Submission and answers have mismatched 'Id' columns")
|
|
26
|
+
|
|
27
|
+
y_true = [int(y) for y in answers["Predicted"]]
|
|
28
|
+
y_pred = [int(y) for y in submission["Predicted"]]
|
|
29
|
+
return y_true, y_pred
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def grade(submission: pd.DataFrame, answers: pd.DataFrame) -> float:
|
|
33
|
+
y_true, y_pred = prepare_for_metric(submission, answers)
|
|
34
|
+
return f1_score(y_true=y_true, y_pred=y_pred, average="macro")
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import random
|
|
3
|
+
import shutil
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
from sklearn.model_selection import train_test_split
|
|
8
|
+
from tqdm import tqdm
|
|
9
|
+
|
|
10
|
+
from mlebench.utils import get_logger
|
|
11
|
+
|
|
12
|
+
logger = get_logger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def prepare(raw: Path, public: Path, private: Path):
|
|
16
|
+
"""
|
|
17
|
+
Splits the raw data into public and private datasets with appropriate test/train splits.
|
|
18
|
+
|
|
19
|
+
`train/metadata.json` is the "table of contents" for our data, with the following structure:
|
|
20
|
+
(More details at https://www.kaggle.com/competitions/herbarium-2021-fgvc8/data)
|
|
21
|
+
```
|
|
22
|
+
{
|
|
23
|
+
"annotations" : [annotation],
|
|
24
|
+
"categories" : [category],
|
|
25
|
+
"images" : [image],
|
|
26
|
+
"info" : info,
|
|
27
|
+
"licenses" : [license],
|
|
28
|
+
"institutions" : [region]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
- `images` and `annotations` are both N-length lists corresponding to the N samples.
|
|
32
|
+
We'll need to split each of these lists into train and test.
|
|
33
|
+
- The other fields are dataset-wide metadata that we don't need to touch.
|
|
34
|
+
|
|
35
|
+
- test/metadata.json is the same structure as train/metadata.json, but without "annotations", "categories", "institutions"
|
|
36
|
+
|
|
37
|
+
Other notes:
|
|
38
|
+
- train/test splits need to occur per category (each category should be in both train and test).
|
|
39
|
+
- The `test/images` and `train/images` folders have nested subdirs to make it easier to browse
|
|
40
|
+
- `train/images` is structured as `{category_id[:3]}/{category_id[3:]}/{image_id}.jpg`
|
|
41
|
+
- `test/images` is structured as `{image_idx[:3]}/{image_idx}.jpg` (to not reveal the category)
|
|
42
|
+
- When we create the new splits, we re-assign image indices so that we don't give away labels based on the index
|
|
43
|
+
- train images are indexed within their own category
|
|
44
|
+
- test images follow a flat index after shuffling the categories
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
dev_mode = False
|
|
48
|
+
dev_count = 2 # Copy over n images per category when in dev mode
|
|
49
|
+
|
|
50
|
+
# Create train, test from train split
|
|
51
|
+
json_path = raw / "train/metadata.json"
|
|
52
|
+
with open(json_path, "r", encoding="utf-8") as f:
|
|
53
|
+
old_train_metadata = json.load(f)
|
|
54
|
+
|
|
55
|
+
# Organize data by category so that we can split per-category later
|
|
56
|
+
annotations_images_by_category = {} # We'll collect both `annotations` and `images` here
|
|
57
|
+
for annotation, image in list(
|
|
58
|
+
zip(old_train_metadata["annotations"], old_train_metadata["images"])
|
|
59
|
+
):
|
|
60
|
+
assert (
|
|
61
|
+
annotation["image_id"] == image["id"]
|
|
62
|
+
), f"Mismatching image_id in annotation and image: {annotation['image_id']} vs {image['id']}"
|
|
63
|
+
category_id = annotation["category_id"]
|
|
64
|
+
if category_id not in annotations_images_by_category:
|
|
65
|
+
annotations_images_by_category[category_id] = []
|
|
66
|
+
annotations_images_by_category[category_id].append(
|
|
67
|
+
{
|
|
68
|
+
"annotation": annotation,
|
|
69
|
+
"image": image,
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Split train/test
|
|
74
|
+
train_sample_count = 0 # Useful for tqdm later
|
|
75
|
+
train_annotations_images_by_category = {}
|
|
76
|
+
test_annotations_images_by_category = {}
|
|
77
|
+
for category_id, annotations_images in tqdm(
|
|
78
|
+
annotations_images_by_category.items(), desc="Assigning train/test splits"
|
|
79
|
+
):
|
|
80
|
+
test_size = 0.2
|
|
81
|
+
# Create split by "category" (class): Each category needs to be in both train and test (80:20) as per original ratio
|
|
82
|
+
n_samples = len(annotations_images)
|
|
83
|
+
if n_samples == 1:
|
|
84
|
+
# If only one sample, put it in train
|
|
85
|
+
train_annotations_images = annotations_images
|
|
86
|
+
test_annotations_images = []
|
|
87
|
+
elif n_samples < 5: # Minimum 5 samples to ensure at least 1 in test
|
|
88
|
+
# Ensure at least 1 sample in test
|
|
89
|
+
test_size = max(1, int(n_samples * test_size))
|
|
90
|
+
train_annotations_images = annotations_images[:-test_size]
|
|
91
|
+
test_annotations_images = annotations_images[-test_size:]
|
|
92
|
+
else:
|
|
93
|
+
# Original split logic
|
|
94
|
+
train_annotations_images, test_annotations_images = train_test_split(
|
|
95
|
+
annotations_images, test_size=test_size, random_state=0
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
train_annotations_images_by_category[category_id] = train_annotations_images
|
|
99
|
+
test_annotations_images_by_category[category_id] = test_annotations_images
|
|
100
|
+
train_sample_count += len(train_annotations_images)
|
|
101
|
+
|
|
102
|
+
# Add to train set
|
|
103
|
+
new_train_metadata = (
|
|
104
|
+
old_train_metadata.copy()
|
|
105
|
+
) # Keep 'categories', 'info', 'licenses', 'institutions'
|
|
106
|
+
new_train_metadata.update(
|
|
107
|
+
{
|
|
108
|
+
"annotations": [],
|
|
109
|
+
"images": [],
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
with tqdm(
|
|
113
|
+
desc="Creating new train dataset",
|
|
114
|
+
total=train_sample_count,
|
|
115
|
+
) as pbar:
|
|
116
|
+
for category_id, annotations_images in train_annotations_images_by_category.items():
|
|
117
|
+
# Create a nested directory from category_id, e.g. 15504 -> "155/04" or 3 -> "000/03"
|
|
118
|
+
category_subdir = f"{category_id // 100:03d}/{category_id % 100:02d}"
|
|
119
|
+
(public / "train/images" / category_subdir).mkdir(exist_ok=True, parents=True)
|
|
120
|
+
for idx, annotation_image in enumerate(annotations_images):
|
|
121
|
+
new_annotation = annotation_image["annotation"].copy()
|
|
122
|
+
new_train_metadata["annotations"].append(new_annotation)
|
|
123
|
+
|
|
124
|
+
new_image = annotation_image["image"].copy()
|
|
125
|
+
new_train_metadata["images"].append(new_image)
|
|
126
|
+
|
|
127
|
+
# Copy file from raw to public
|
|
128
|
+
if (
|
|
129
|
+
not dev_mode or idx < dev_count
|
|
130
|
+
): # if dev_mode, only copy the first dev_count images
|
|
131
|
+
src_path = raw / "train" / annotation_image["image"]["file_name"]
|
|
132
|
+
dst_path = public / "train" / annotation_image["image"]["file_name"]
|
|
133
|
+
shutil.copyfile(src=src_path, dst=dst_path)
|
|
134
|
+
|
|
135
|
+
pbar.update(1)
|
|
136
|
+
|
|
137
|
+
with open(public / "train/metadata.json", "w") as f:
|
|
138
|
+
json.dump(new_train_metadata, f, indent=4, sort_keys=True)
|
|
139
|
+
|
|
140
|
+
if not dev_mode:
|
|
141
|
+
assert len(list((public / "train/images").glob("**/*.jpg"))) == len(
|
|
142
|
+
new_train_metadata["images"]
|
|
143
|
+
), f"Mismatching number of images in train_images, got {len(list((public / 'train/images').glob('**/*.jpg')))}"
|
|
144
|
+
assert len(new_train_metadata["annotations"]) == len(
|
|
145
|
+
new_train_metadata["images"]
|
|
146
|
+
), f"Mismatching number of annotations in train_metadata, got {len(new_train_metadata['annotations'])}"
|
|
147
|
+
|
|
148
|
+
# Add to test set
|
|
149
|
+
new_test_metadata = old_train_metadata.copy()
|
|
150
|
+
del new_test_metadata["categories"]
|
|
151
|
+
del new_test_metadata["institutions"]
|
|
152
|
+
new_test_metadata.update(
|
|
153
|
+
{
|
|
154
|
+
"annotations": [],
|
|
155
|
+
"images": [],
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
# Flatten and shuffle test set so that we don't have all the same categories in a row
|
|
159
|
+
test_annotations_images = [
|
|
160
|
+
item for sublist in test_annotations_images_by_category.values() for item in sublist
|
|
161
|
+
]
|
|
162
|
+
random.Random(0).shuffle(test_annotations_images)
|
|
163
|
+
for idx, annotation_image in tqdm(
|
|
164
|
+
enumerate(test_annotations_images),
|
|
165
|
+
desc="Creating new test dataset",
|
|
166
|
+
total=len(test_annotations_images),
|
|
167
|
+
):
|
|
168
|
+
|
|
169
|
+
# Make new image id, for test set this is just the index
|
|
170
|
+
new_image_id = str(idx)
|
|
171
|
+
# Make new filename from image id e.g. "000/0.jpg"
|
|
172
|
+
new_file_name = f"images/{idx // 1000:03d}/{idx}.jpg"
|
|
173
|
+
|
|
174
|
+
new_annotation = annotation_image["annotation"].copy()
|
|
175
|
+
new_annotation["image_id"] = new_image_id
|
|
176
|
+
new_test_metadata["annotations"].append(new_annotation)
|
|
177
|
+
|
|
178
|
+
new_image = annotation_image["image"].copy()
|
|
179
|
+
new_image["id"] = new_image_id
|
|
180
|
+
new_image["file_name"] = new_file_name
|
|
181
|
+
new_test_metadata["images"].append(new_image)
|
|
182
|
+
|
|
183
|
+
# Copy file from raw to public
|
|
184
|
+
if not dev_mode or idx < dev_count: # if dev_mode, only copy the first dev_count images
|
|
185
|
+
src_path = raw / "train" / annotation_image["image"]["file_name"]
|
|
186
|
+
dst_path = public / "test" / new_file_name
|
|
187
|
+
dst_path.parent.mkdir(exist_ok=True, parents=True)
|
|
188
|
+
shutil.copyfile(src=src_path, dst=dst_path)
|
|
189
|
+
|
|
190
|
+
# Save new test metadata
|
|
191
|
+
with open(public / "test/metadata.json", "w") as f:
|
|
192
|
+
# The public test data, of course, doesn't have annotations
|
|
193
|
+
public_new_test = new_test_metadata.copy()
|
|
194
|
+
del public_new_test["annotations"]
|
|
195
|
+
assert public_new_test.keys() == {
|
|
196
|
+
"images",
|
|
197
|
+
"info",
|
|
198
|
+
"licenses",
|
|
199
|
+
}, f"Public test metadata keys should be 'images', 'info', 'licenses', but found {public_new_test.keys()}"
|
|
200
|
+
json.dump(public_new_test, f, indent=4, sort_keys=True)
|
|
201
|
+
|
|
202
|
+
if not dev_mode:
|
|
203
|
+
assert len(list((public / "test/images").glob("**/*.jpg"))) == len(
|
|
204
|
+
new_test_metadata["images"]
|
|
205
|
+
), f"Mismatching number of images in test_images, got {len(list((public / 'test/images').glob('**/*.jpg')))}"
|
|
206
|
+
assert len(new_test_metadata["annotations"]) == len(
|
|
207
|
+
new_test_metadata["images"]
|
|
208
|
+
), f"Mismatching number of annotations in test_metadata, got {len(new_test_metadata['annotations'])}"
|
|
209
|
+
assert len(new_train_metadata["annotations"]) + len(
|
|
210
|
+
new_test_metadata["annotations"]
|
|
211
|
+
) == len(old_train_metadata["annotations"]), (
|
|
212
|
+
f"Expected {len(old_train_metadata['annotations'])} annotations in total, but found"
|
|
213
|
+
f"{len(new_train_metadata['annotations'])} in train and {len(new_test_metadata['annotations'])} in test"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Save private test answers
|
|
217
|
+
answers_rows = []
|
|
218
|
+
for image, annotation in zip(new_test_metadata["images"], new_test_metadata["annotations"]):
|
|
219
|
+
assert (
|
|
220
|
+
image["id"] == annotation["image_id"]
|
|
221
|
+
), f"Mismatching image_id in image and annotation: {image['id']} vs {annotation['image_id']}"
|
|
222
|
+
answers_rows.append(
|
|
223
|
+
{
|
|
224
|
+
"Id": image["id"],
|
|
225
|
+
"Predicted": annotation["category_id"],
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
answers_df = pd.DataFrame(answers_rows)
|
|
229
|
+
answers_df.to_csv(private / "answers.csv", index=False)
|
|
230
|
+
|
|
231
|
+
# Create new sample submission that matches raw/sample_submission.csv, but for the new test set
|
|
232
|
+
sample_rows = []
|
|
233
|
+
for image in new_test_metadata["images"]:
|
|
234
|
+
sample_rows.append(
|
|
235
|
+
{
|
|
236
|
+
"Id": image["id"],
|
|
237
|
+
"Predicted": 0,
|
|
238
|
+
}
|
|
239
|
+
)
|
|
240
|
+
sample_df = pd.DataFrame(sample_rows)
|
|
241
|
+
sample_df.to_csv(public / "sample_submission.csv", index=False)
|
|
242
|
+
|
|
243
|
+
assert len(answers_df) == len(
|
|
244
|
+
new_test_metadata["images"]
|
|
245
|
+
), f"Expected {len(new_test_metadata['images'])} rows in answers, but found {len(answers_df)}"
|
|
246
|
+
assert len(sample_df) == len(
|
|
247
|
+
answers_df
|
|
248
|
+
), f"Expected {len(answers_df)} rows in sample submission, but found {len(sample_df)}"
|
|
249
|
+
assert answers_df["Id"].equals(
|
|
250
|
+
sample_df["Id"]
|
|
251
|
+
), "Mismatched 'Id' columns between answers and sample submission"
|