code competition ãæ¥œããã KaggleOps
ã¯ããã«
è¿å¹Žéå¬ãããã³ã³ããã£ã·ã§ã³ã¯ãã»ãŒå šãŠ code competition ãšèšã£ãŠããã§ããããkaggle platform ã§ã¯ãcsv æåºåã®ã³ã³ããã£ã·ã§ã³ã§ã¯ãªããåŠç¿æžã¿ã¢ãã«ãæšè«ã³ãŒãèªäœãæåºãããã¹ãããŒã¿ã«å¯Ÿããæšè«ã¯ kaggle åŽã§å®è¡ããæè¬ãcode competitionã圢åŒã®ã³ã³ããäž»æµã«ãªã£ãŠããŠããŸãã
åŸæ¥ã® csv æåºåã«æ¯ã¹ãŠåå é£æåºŠã¯å€å°é«ããæè¿ã§ã¯ evaluation api ãªããã®ãç»å Žããããã«ãªããŸããã
é£æåºŠãé«ãæããããèŠå ãšããŠã kaggle ã®æåºåœ¢åŒã«åãããç°å¢ãšã³ãŒããäœæããã®ãããã©ããããšããã®ã倧ããã®ã§ã¯ãªãã§ããããã
code competition ã«ããããµãããã·ã§ã³ã«å¿ èŠãªèŠçŽ ã¯ä»¥äžã®äºã€ã§ãã
- æšè«ã«å¿ èŠãªã¢ãã«ããã¡ã€ã«ã®ã¢ããããŒã
- å®éã«æšè«ãå®è¡ããããã®ã³ãŒãã®äœæ
ä»åäœã£ã KaggleOps ã¯ãã®èŸºããèªååãªããæè»œã«ããããšãããã®ã§ãã
KaggleOps
æŠèŠ
MLOps ã¯ãã¢ãã«ã®ç¶ç¶çãªåŠç¿ããããã€ãç£èŠãªã©ã®æ©æ¢°åŠç¿ã¢ãã«éçºããéçšãŸã§ã®ã©ã€ããµã€ã¯ã«å šäœãå¹çåã»èªååããæ çµã¿ã®ãã®ãããã§ãã æ±ºãŸã£ãåŠç¿ãã€ãã©ã€ã³ãã¢ãã¿ãªã³ã°ããŒã«ã䜿ã£ãããç¹å®ã®ã¯ã©ãŠããµãŒãã¹ã掻çšããããšå ·äœçãªäžèº«ã¯å人ãäŒæ¥ã»ããŒã ããšã«ç°ãªãã®ã§ã¯ãªãã§ããããã
ãã®èãæ¹ã¯ Kaggle ãªã©ã®ã³ã³ããã£ã·ã§ã³ã«ã倧ãªãå°ãªãå¿çšã§ãããã©ã€ããµã€ã¯ã«å šäœããšãŸã§ã¯ãããªããã®ã®ããªãªãžãã«ã®åŠç¿ãã€ãã©ã€ã³ãäœæããããèªå奜ã¿ã®å®éšç®¡çãæŽåããããããåå è ãå€ããšæããŸã (ç§ããã®1人ã§ã)
KaggleOps ã§ã¯ãããçšåºŠå®éšç°å¢ã®åŒ·å¶ããããã®ã®ãåŠç¿ã³ãŒããæšè«ã³ãŒãèªäœã¯èªç±ã«äœãããã®ãšããŠããŸãã
ãã®äžã§ã code competition ãã§ããã ãå¿«é©ã«åãçµãããããªå·¥å€«ãé 匵ã£ãŠå ¥ããŠã¿ãŸãããå®ã¯ Ops ãšèšããã»ã©ã®ãã®ã§ã¯ãªããšæããããå¶çŽãå€ããããšæããæ¹ããããšæããŸãããäœãã®åèã®äžã€ã«ã§ããªãã°å¬ããã§ã
æŽå²
code competition ãæ¥œã«ããæ§ã ãªåãçµã¿ã¯éå»ã«ãããããããŸããäžéšã§ããä»ååèã«ãããã®ãèŒããŠããŸãã
local ã§éçºããã³ãŒãã kaggle dataset ãšããŠäœ¿ã£ãããbase64 ã§ãšã³ã³ãŒããããã®ãæšè«æã«ãã³ãŒãããŠäœ¿çšããããšãæ§ã ãªåãçµã¿ãè¡ãããŠããŸããã
KaggleOps 㯠smly ããã® ãå¹ççãªã³ãŒãã³ã³ããã£ã·ã§ã³ã®äœæ¥ãããŒããããªãåèã«ããŠããŸãã
ã¢ãŒããã¯ãã£

Github Actions ã䜿ã submission ãèªååãããšããæ§æã§ããmodel ãäºæž¬çµæãªã©ã®ã¢ãŒãã£ãã¡ã¯ã㯠Cloud Storage ã«ä¿åããŠãããVertex Custom Training Job 䜿ãã¢ãŒãã£ãã¡ã¯ãã Kaggle Models ã«ã¢ããããŒããããšãããããŒã§ãã
æå ã ãã§ (Cloud Service 䜿ããã«) cli ã ãã§åæ§ã®åŠçãè¡ãããšãã§ããã®ã§ãåãåãããããããšã¯æããŸãã
Github Actions æåºãããŒ
ãµãããããŸã§ã®ãããŒãèŠãŠãããŸãã
1. ããŒã«ã«ç°å¢ã§ã®éçº
åŠç¿ã³ãŒããšæšè«ã³ãŒããæžããŸãããã®é src/settings.py ã§å®çŸ©ããã Path ã䜿çšããããšã§ãããŒã«ã«ç°å¢ãš Kaggle æåºç°å¢ã§åããã¹ã䜿ãããšãã§ããŸãã
COMP_DATASET_DIR: åã³ã³ããã£ã·ã§ã³ã®å ¥åããŒã¿ã®ãã¹ãåŸè¿°ããŸãããããŒã¿ã®ååŸãªã©ãã³ãã³ãããŒã¹ã§ç°¡åã«å®è¡ã§ããããã«ããŠããããã®ãã¹ãèªåçã«èšå®ãããŸããOUTPUT_DIR: åŠç¿ã»æšè«æã®åºåå ã kaggle ç°å¢ã«ããã/kaggle/workingARTIFACT_EXP_DIR: æšè«æã®ã¢ãã«ããŒãå ãkaggle ç°å¢ã«ãããŠãKaggle Models ã«ãã䜿çšå¯Ÿè±¡ã®ã¢ãŒãã£ãã¡ã¯ããããŒããããšãã«äœ¿ããŸã
2. åŠç¿ã®å®è¡ãšã¢ãŒãã£ãã¡ã¯ãã®ä¿å
åŠç¿ã³ãŒãã¯ããŒã«ã«ãŸã㯠Vertex AI Custom Training Job ã§å®è¡ããããšãã§ããŸããåŸè ã®å Žå㯠Artifact Registry ã«ã€ã¡ãŒãžãããã·ã¥ããŠããå¿ èŠããããŸãã
ããŒã«ã«ã§å®è¡ããå Žåã¯ãå®è¡åŸã«çæç© (ã¢ãŒãã£ãã¡ã¯ã) ã Cloud Storage ã«ã¢ããããŒãããå¿ èŠããããŸãããTraining Job ã®å Žå㯠Cloud Storage ãš mount ãããŠããã®ã§ç¹ã«ã¢ãŒãã£ãã¡ã¯ãã®ç§»åãªã©ã®åŠçãè¡ããã« Cloud Storage ã«ä¿åããããšãã§ããŸãã
Vertex AI Custom Training Job ã¯èªç±åºŠé«ããã·ã³ã®èšå®ãã§ããå®è¡åã®éé¡ããããããªãã®ã§ã³ã¹ããæããããšãã§ããŸããå®éšã®éãã«ãã£ãŠ A100 / H100 ã䜿ã£ãããšåãæ¿ãããããšæããŸãã
3. Github Actions ã«ããèªåãµãããã·ã§ã³
Pull Request ãŸãã¯æåå®è¡ã«ãã Actions ã®å®è¡ã«ããã
- Cloud Storage ã«ããã¢ãŒãã£ãã¡ã¯ã â
Kaggle Model - Github äžã®ã³ãŒã â
Kaggle Dataset - 远å ã®äŸåé¢ä¿ â
Kaggle Code
ã« push ãããããã input ãšããæåºçšã®ã³ãŒãã Kaggle Code ã« push ããŸãã
ãã®ææåºçšã®ã³ãŒãã¯èªåå®è¡ãããã®ã§ãå®è¡å®äºããã¿ã€ãã³ã°ã§ web äžã§ Submit to Competition ãã¿ã³ãæŒããŸãã

å®éã«æåºããŠã¿ã
察象ã®ã³ã³ããã£ã·ã§ã³ã¯ Spaceship Titanic ã§ã www.kaggle.com
code competition 圢åŒã§ã¯ãªãã§ãããæµãã¯ã»ãŒåãã¯ãã§ããå®éã®ãªããžããªã¯ãã¡ãã§ã
1. Repository ã®äœæ

- Repository name ã¯ãªãã§ãè¯ãã§ãããurl ã«å«ãŸããã³ã³ãåã«ããŠããŸã
- Start with template ã§
KaggleOpsãéžæããŸã

äœæã§ããã clone ããŸã
2. ã€ã³ãã©ã®ã»ããã¢ãã
docs/infrastructure.md ãåèã«ã€ã³ãã©æ§ç¯ãèšå®ãè¡ããŸããæå
ã®localç°å¢ã§ãåé¡ãªããšæããŸããã gcloud sdk ãªã©å
šãŠå
¥ã£ãŠã devcontainer äžã®äœæ¥ãããããã§ãã Dev Containers: Reopen in Container ãªã©ã§å
¥ããŸãããååå®è¡æã¯ Kaggle docker image ãè¶
éãã®ã§æéããããŸã (å¥ã® docker image ã䜿ã£ãŠãåé¡ãªãã§ã)ã
.envã®äœæKAGGLE_USERNAMEãªã©ã® kaggle é¢é£ã®èªèšŒæ å ±PROJECT_IDãREGIONãªã© Google Cloud é¢é£ã®æ å ±
make init-infra/make setup-infra: terraform ã䜿ã£ãã€ã³ãã©ç®¡çãš github actions ã®èªèšŒæ å ±ã®èšå®
å®è¡ã«æåãããšä»¥äžã®æåã衚瀺ãããŸã!
Infrastructure setup completed
3. å®éšã®ã»ããã¢ãã
docs/experiment_flow.md ã§å®éšé¢é£ã®ã»ããã¢ãããšå®éšãããŒã確èªã§ããŸã
make setupãå®è¡ãã

远å ã©ã€ãã©ãªã®ã€ã³ã¹ããŒã« (deps) ãšæåº (submission) ã«å¿ èŠãª metadata ãš ipynb ãã¡ã€ã«ãèªåçæãããŸãã
åŸè¿°ã® codes/submission/kernel-metadata.json ã® model_sources ã«æåºæã«äœ¿çšãããã¢ãŒãã£ãã¡ã¯ããæå®ããããšãã§ããŸãã
make dl-compã§ããŒã¿ã»ãããããŠã³ããŒããã
data/input/spaceship-titanic ã«ã³ã³ããã£ã·ã§ã³ããŒã¿ãããŠã³ããŒããããŸã

4. å®éš
å®éšçš branch ã®äœæ
git checkout -b exp001 ãªã©ã§å®éšçšã® branch ãäœæããŸã
åŠç¿ã³ãŒããšæšè«ã³ãŒãã®äœæ
ä»å㯠src/train.py ã«åŠç¿ã³ãŒããå®è£
ããŸããsrc/settings.py ã® DirectorySettings ã import ããæå®ãããŠãã Path ã䜿ãããšä»¥å€ã«ã¯ç¹ã«å¶çŽã¯ãªãã§ãã
çè
㯠#%% ã䜿ã£ãŠã€ã³ã¿ã©ã¯ãã£ãã¢ãŒãã§æžãããšãå€ãã§ãã
æšè«ã³ãŒã㯠src/inference.py ã«å®è£
ããŸããOUTPUT_DIR ã« submission.csv ãä¿åããŠçµäºã§ã
config = Config(name="spaceship-titanic") settings = DirectorySettings(exp_name=config.name) test_df = pl.read_csv(settings.COMP_DATASET_DIR / "test.csv") test_df = preprocess(config, test_df) pred_df = test_fn(config, test_df, out_dir=settings.ARTIFACT_EXP_DIR) sample_df = pl.read_csv(settings.COMP_DATASET_DIR / "sample_submission.csv") assert len(sample_df) == len(pred_df), "Sample submission and prediction dataframe must have the same length" submission_df = _build_submission(sample_df, pred_df) submission_df.write_csv(settings.OUTPUT_DIR / "submission.csv") print("âïž Submission saved to: ", settings.OUTPUT_DIR / "submission.csv")
åŠç¿èªäœã¯ local ããã㯠vertex ç°å¢ã§å®è¡å¯èœã§ã
make train-localãããã¯make train-vertexã§å®è¡ãã- local å®è¡ã®å Žåã¯
python src/train.pyã§ãå®è¡å¯èœã§ãã make push-dataã§ææç©ã GCS ã« push ãã (vertex ç°å¢ã§ã¯èªåçã« gcs bucket ã mount ãããããäžèŠ)make vertexå®è¡åã« image ã® push (æŽæ°) ãå¿ èŠ
Cloud Storage ã«ä»¥äžã®ããã«ã¢ãŒãã£ãã¡ã¯ããä¿åãããŸã

5. æåºã®æºå
æåºã®ããã® metadata ãæºåããŸãã 䞻㫠codes/submission/kernel-metadata.json ã® model_sources ãåããŸããä»å㯠spaceship-titanic ãšããå®éšåã ã£ãã®ã§
{ "id": "mst8823/spaceship-titanic-submission", "title": "spaceship-titanic-submission", "code_file": "code.ipynb", "language": "python", "kernel_type": "notebook", "is_private": "true", "enable_gpu": "false", "enable_tpu": "false", "enable_internet": "false", "dataset_sources": ["mst8823/spaceship-titanic-codes"], "competition_sources": ["spaceship-titanic"], "kernel_sources": ["mst8823/spaceship-titanic-deps"], "model_sources": [ "mst8823/spaceship-titanic-artifacts/other/spaceship-titanic/1" ] }
ãã®ããã«èšå®ããŸããã远å ã®ã©ã€ãã©ãªãªã©ã¯ codes/deps/requirements.txt ã«æžãããšã§ãèªåçã«æåºæã«äœ¿ããããã«ãªããŸããä»åã¯ç¹ã«å¿
èŠãªãã®ã§ãã¡ã€ã«ã«å€æŽã¯ãªãã§ãã
6. æåº
PR ã®äœæãããã¯æåã§ GitHub Actions ãå®è¡ã§ããŸãã workflow ã®èšå®ã¯ããå°ããããããããããã§ããããšãããããšããæãã§ã
PR ãäœæãããš CI ããŸãããã¢ãŒãã£ãã¡ã¯ãã®ã¢ããããŒããæšè«ã³ãŒãã®æåºã®å®è¡ããããŸã

- ã¢ãŒãã£ãã¡ã¯ãã®ã¢ããããŒã: Cloud Storage â Kaggle Models ãžã®ã¢ãŒãã£ãã¡ã¯ãã®ã¢ããããŒããžã§ãã Vertex Custom Training Job ã§å®è¡ããã
- æšè«ã³ãŒãã®æåº: kaggle api ã䜿ã
codes/submission/code.ipynbãcodes/submission/kernel-metadata.jsonã®èšå®ã§ push ããã
Kaggle ã«ã¢ããããŒãããããã®ã¯ä»¥äžã®éãã§ã
spaceship-titanic-artifacts: åŠç¿æžã¿ã¢ãã«ãªã©ã Kaggle Model ã«ã¢ããããŒããããspaceship-titanic-codes: æšè«ã§å¿ èŠãªã³ãŒãã Kaggle Dataset ã«ã¢ããããŒããããspaceship-titanic-deps: 远å ã®äŸåé¢ä¿çšãä»åã¯äžèŠãªã®ã§çæãããŠããªãã Kaggle Code ãšããŠäœæãããspaceship-titanic-submission: æšè«çšã®ã³ãŒããäžèšäžã€ã input ãšããŠããã Kaggle Code ãšããŠçæããã

deps ãååšããªãã®ã§ 1cell ç®ããšã©ãŒã§ãããåŠçã¯æ¢ãŸãã 2cell ç®ã«è¡ããŸãã 2cell ç®ã§ã¯ src/inferece.py ãå®è¡ããŠãã submission.csv ãä¿åãããããšãããããŸãã
å®éã®ã³ã³ããã£ã·ã§ã³ã§ã¯ããã® spaceship-titanic-submission ãæŽæ°ãç¶ããããæšè«ã³ãŒãã¯ããäžã€ã§ãã version ãç©ã¿éãªã£ãŠãããŸãã
æåŸã« Submit to Competition ãå®è¡ããŠã¹ã³ã¢ã確èªããããšãã§ããŸã

ãããã«
code competition ãå°ãã§ã楜ã«ããããšæãä»åã® template ãäœã£ãŠã¿ãŸããã
å®éã«ããã€ãã®ã³ã³ãã§äœ¿ã£ãŠã¿ãŠãŸãããã çè 㯠GitHub Actions ã¯ã»ãšãã©äœ¿ãã CLI ã§ã¢ããããŒããæåºãæžãŸããããšãå€ãã§ãããCI åããŠæåºããããšãåæãšãããšã 1 branch = 1 å®éšãšããæ§æã«ãªãããã§ãããè€æ°ã®å°ããªå®éšã管çããå Žåã«åãåãã«ããããªãšããæ°æã¡ã§ããããã¡ãã git worktree ãªã©ã䜿ãããªãããã§ããã°å¥ããã§ãããç§èªèº«ã®ç·ŽåºŠããããŸã§é«ããªãã£ãã§ãã
ãŸã kaggle api ã䜿ãã¢ããããŒãåŠçã¯ãããã¯ãŒã¯ã®é¢ä¿ãªã©ã§äžå®å®ã«ãªãããããæã 倱æããããšã«ã泚æã§ãã
ã¢ãŒãã£ãã¡ã¯ããã³ãŒãã®ã¢ããããŒããŸããã® utils ã®æŽåããã³ãŒãã® push æ¹æ³ãªã©ãç¥ãããšãã§ããŸãããããžã§ããæãããè²ã ãšèªåå? ããããšãã§ãå人çã«ã¯æºè¶³ã§ããã
ããäœãã®åèã«ãªãã°å¬ããéãã§ã
Hydra ãš DVC ã§å®éšç®¡çã¡ã¢
æŠèŠ
Hydra ã䜿ã£ãŠ config 管çã¯ã§ãããã®ã®ãäžéçæç©ã®ãã£ãã·ã¥ãäžæã«ç¡é§ãªã管çã§ããªãã§ããŸãããã€ãŸã hydra ã§ãã€ãã©ã€ã³ããã¯ãªãã®ãäžæãäœãããã§ãããã§ããã°æ¢åã®ããŒã«ã§å®çŸãããã§ããã€ã¡ãŒãžã¯ãã¡ãã®èšäºã®ãããªæãã
- preprocess
- feature_extract
- train
ãšããããã»ã¹ããããåããã»ã¹ã§äžéçæç©ãçæããã±ãŒã¹ãèããã äžéçæç©ãçæããããšã®ã¡ãªããã¯ãååŠçã§åãåŠçïŒçµæãåãã«ãªãåŠçïŒãè€æ°åå®è¡ããªãããšã§èšç®ã³ã¹ããåæžã§ããããšã§ããã
åããã»ã¹ã«ãããåŠçã¯å ¥åããŒã¿ãšã³ã³ãã£ã°ã®å€ã®ã¿ã«äŸåãããšããïŒã€ãŸããåçŸæ§ãããïŒã ãã®åæã§ããã°ãåããã»ã¹ã®äžéçæç©ã®çæçµæã«éããçããã®ã¯å ¥åããŒã¿ãã³ã³ãã£ã°ã®ãã©ã¡ãŒã¿ã倿Žãããå Žåã®ã¿ã§ããã
ä»åå®çŸãããã®ã¯æ£ããããã§ãconfig 㯠hydra ã§ç®¡çããpreprocess.py ã train.py ãªã©ã®å®è¡å¯Ÿè±¡ã®ãã¡ã€ã«èªäœããã€ãã©ã€ã³ã®åã¹ããããšããŠæ±ããæçµçãªãã€ãã©ã€ã³ãäœããŸãã
ä»åäœã£ããã€ãã©ã€ã³ã¯ãã¡ãã§ãã
DVC (Data Version Control)
dvc ãšã¯ãããŒã¿ã®ããã·ã¥ãããã¹ããã¡ã€ã«ã§ä¿æã git ã§ããŒãžã§ã³ç®¡çãããã®ã§ãããŸãããã€ãã©ã€ã³ãäœæããããšãã§ããŸãããã®èŸºãã¯ä»¥äžã®èšäºã詳ããã®ã§ãã¡ããåç §ãã ãã
DVC x Hydra
Hydra ã§ config 管çãã€ã€ã DVC ã§ãã€ãã©ã€ã³ã®äœæãšããŒãžã§ã³ç®¡çãããæ¹æ³ã¯ãå®ã¯å ¬åŒããæäŸãããŠããŸããããã¡ãã®èšäºãš ããã¥ã¡ã³ããããã«åœãããŸãã
ãã¡ããèšäºãããã¥ã¡ã³ããåèã«ããŠäœã£ãç°¡åãªãã€ãã©ã€ã³ã§ãã
.
âââ README.md
âââ conf
â âââ config.yaml
â âââ model
â â âââ logistic_regression.yaml
â â âââ random_forest.yaml
â âââ paths
â âââ default.yaml
âââ dvc.lock
âââ dvc.yaml
âââ params.yaml
âââ pyproject.toml
âââ requirements-dev.lock
âââ requirements.lock
âââ src
âââ hydra_dvc_practice
âââ __init__.py
âââ eval.py
âââ load_data.py
âââ preprocess.py
âââ train.py
conf ã«ã¯ hydra ã䜿ãåæã®èšå®ãã¡ã€ã« config.yaml ãé
眮ããsrc/hydra_dvc_practice ã«ãã€ãã©ã€ã³ã®æ§æèŠçŽ ãšãªãåãã¡ã€ã«ãé
眮ããŸããã
äžè¬çã« hydra ã䜿ãå Žåã
python load_data.py python preprocess.py python train.py python eval.py
ã®ããã«ããã¡ã€ã«ããšã®å®è¡ãåæãšãªããŸãã
ããã dvc ã䜿ãããšã§
dvc exp run
ã³ãã³ãäžçºã§ããã£ãã·ã¥ç®¡çãå«ããã€ãã©ã€ã³ã®å®è¡ãèµ°ããŸãã
ãããŠããã®ãã€ãã©ã€ã³ã®èšèšå³ã dvc.yaml ã§ãã
stages: load_data: cmd: rye run python src/hydra_dvc_practice/load_data.py deps: - src/hydra_dvc_practice/load_data.py outs: - data/train.csv - data/test.csv params: - test_size - target - seed - paths preprocess: cmd: rye run python src/hydra_dvc_practice/preprocess.py deps: - data/train.csv - data/test.csv - src/hydra_dvc_practice/preprocess.py outs: - data/train_scaled.csv - data/test_scaled.csv params: - scaler
load_data step ãš preprocess stage ã«ã€ããŠåãåºããŠããŸãã
- cmd : å stage ã§å®è¡ããã³ãã³ã
- deps : ãã® stage ãäŸåãã察象ã®ãã¡ã€ã«ãäžèšã®äŸã§ã¯ãå®è¡å¯Ÿè±¡ã®ãã¡ã€ã«ã«äœã倿Žãçºçããå Žåã«ã¯ãã£ãã·ã¥ã䜿çšãããªãããšãæå³ããŠããŸãããã¡ããã§ããã倿Žãçºçãã stage 以éã® stage ãåå®è¡ãããŸã (ãã®èŸºãã¯æè»ã«å€æŽã§ããã¯ãã§ã)
- outs : äžéçæç©ãããã§æå®ããäžéçæç©ã¯ dvc ã®ç®¡ç察象ãšãªããŸã
- params : äŸåé¢ä¿ãæã¡ããèšå®ãã©ã¡ã¿ãã€ãŸã deps ã«ããã hydra ã§ç®¡çããŠããå€ããŒãžã§ã³ã§ãããããã§ã¯äŸãã°ã
seedã®å€ã倿Žããå Žåã¯ãdeps åæ§ã«åå®è¡ãçºçããŸãã
ãããäž»ãªèšå®ã§ãããä»ã«ããããããªèšå®ãããããã§ãã
params.yaml ãš dvc.lock ã¯ãã€ãã©ã€ã³ã®å®è¡ããšã«çæãããŸãã
ããšããš dvc 㯠params.yaml ã«ãã€ãã©ã€ã³å®è¡ã«é¢ããå
šãŠã®ãã©ã¡ã¿èšå®ãæžãããšãåæãšããŠããŸãããä»åã¯ãã®èšå®èªäœã hydra ã§ãã£ãŠãããããå®è¡æã« params.yaml ãçæããå¿
èŠããããŸãã
dvc.lock ã«ã¯ stage åäœã§ã®å®è¡ã«é¢ããæ
å ±ãèšèŒããããããåç
§ããããšã§ cache å€å®ãè¡ãããŠããã¯ãã§ãã
ãŸããhydra ã§ãã䜿ããã³ãã³ãã©ã€ã³ã䜿ã£ãèšå®ãã©ã¡ã¿ override ã«ã察å¿ããŠããã䜿ãåæã»ãŒãã®ãŸãŸåçŸãããŠããŸãã
dvc exp run -S model=random_forest -S seed=42
å®éšçµæã®åç §ã容æã«è¡ãããšãã§ããŸãã
ãããã«
hydra ãš dvc ã䜿ã£ããã€ãã©ã€ã³ã®äœæãããŠã¿ãŸããããã¡ã€ã«åäœã§ã®ç®¡çããæ¢åã®ãã€ãã©ã€ã³ããŒã«ãšã¯ç°ãªããŠããŒã¯ãªæ©èœãªã®ããªãšæã£ãŠããŸãããããŠããã hydra ãšãçžæ§ãããç¹ã§ã¯ãããããªæ°ãããŸãã
ãŸããä»åã¯ããããã® dvc ã®æ©èœã€ããŠã¯ããŸãè§ŠããŠã¯ããªãã®ã§ããã¡ããæ©äŒãããã°ãšãããšããã§ãã
調æ»äžã«ééãã DagsHub ãšããã®ã«ãå°ãèå³ããã£ãã®ã§ããããæ©äŒããã°è§Šã£ãŠã¿ãããšæããŸããã
ä»åŸäœ¿ã£ãŠãããã¯äžæã§ãããããããããšã¯ãšããããã§ããã®ã§ãšã·!
åèè³æ
Hydra ã䜿ã£ãŠã¿ã
ã¯ããã«
ä»å㯠Hydra ã䜿ã£ãèšå®ç®¡çã«ã€ããŠèª¿ã¹ãŠã¿ãŸããïŒ
Hydra ãšããã®ã¯ Meta ãéçºããŠãã python ã®ãã¬ãŒã ã¯ãŒã¯ã®äžã€ã§ãããäž»ã«èšå®ãã¡ã€ã«ã®ç®¡çã«é·ããŠãããã®ã§ãã
ãã®èšäºã§ã¯ãããã€ãã®åºæ¬çã¯ã·ãã¥ãšãŒã·ã§ã³ã«ããã Hydra ãã¿ãŠãããããšæã£ãŠããŸã ð² ð² ð²
1. yaml ã§èšå®ç®¡çããã
ãã¡ãã®èšäºã«ããããã«ãargparse ã䜿ãããã°ã©ã å®è¡æã®åŒæ°ãåãåãæ¹æ³ã¯ãã䜿ãããŠãããšæããŸããããããèšå®ãããã©ã¡ãŒã¿æ°ãå€ããšããªã©ã«ã¯èŠãããæããããšãå€ã
ãããŸãã
以äžã®äŸã§ãç¹ã«èšå®æ°ã¯å€ããªãã§ãã hydra ã䜿ã£ãŠã¿ãããšæããŸã! hugguingface trainer ãçšãã fine-tuning ã®ãµã³ãã«ã³ãŒããåèã«ããŠäŸãäœæããŠããŸãã
import argparse import transformers from datasets import load_dataset from transformers import AutoModelForSequenceClassification, AutoTokenizer def main(): parser = argparse.ArgumentParser(description="huggungface transformers training") # transformers parser.add_argument("--model_name", type=str, default="bert-base-uncased") parser.add_argument("--num_labels", type=int, default=2) parser.add_argument("--per_device_train_batch_size", type=int, default=8) parser.add_argument("--per_device_eval_batch_size", type=int, default=8) parser.add_argument("--evaluation_strategy", type=str, default="epoch") parser.add_argument("--num_epochs", type=int, default=3) parser.add_argument("--learning_rate", type=float, default=5e-5) parser.add_argument("--warmup_ratio", type=float, default=0.1) parser.add_argument("--gradient_accumulation_steps", type=int, default=1) parser.add_argument("--eval_accumulation_steps", type=int, default=1) parser.add_argument("--weight_decay", type=float, default=0.01) parser.add_argument("--save_strategy", type=str, default="epoch") parser.add_argument("--fp16", type=bool, default=False) # paths parser.add_argument("--logging_dir", type=str, default="logs") parser.add_argument("--output_dir", type=str, default="output") args = parser.parse_args() # model, tokenizer ã®ããŒã tokenizer = AutoTokenizer.from_pretrained(args.model_name) model = AutoModelForSequenceClassification.from_pretrained( args.model_name, num_labels=args.num_labels ) # example ããŒã¿ã»ããã®ããŒã raw_datasets = load_dataset("glue", "mrpc") def tokenize_function(example): return tokenizer(example["sentence1"], example["sentence2"], truncation=True) tokenized_datasets = raw_datasets.map(tokenize_function, batched=True) # ãã¬ãŒãã³ã°ã®èšå® training_args = transformers.TrainingArguments( output_dir=args.output_dir, per_device_train_batch_size=args.per_device_train_batch_size, per_device_eval_batch_size=args.per_device_eval_batch_size, evaluation_strategy=args.evaluation_strategy, logging_dir=args.logging_dir, num_train_epochs=args.num_epochs, learning_rate=args.learning_rate, warmup_ratio=args.warmup_ratio, gradient_accumulation_steps=args.gradient_accumulation_steps, eval_accumulation_steps=args.eval_accumulation_steps, weight_decay=args.weight_decay, save_strategy=args.save_strategy, fp16=args.fp16, ) trainer = transformers.Trainer( model, training_args, train_dataset=tokenized_datasets["train"], eval_dataset=tokenized_datasets["validation"], tokenizer=tokenizer, ) trainer.train() if __name__ == "__main__": main()
ããã©ã«ãå€ã¯èšå®ããŠããŸãããå šåŒæ°ãèšå®ãããšä»¥äžã®ããã«ãªããŸãã
rye run python src/main_argparse.py --model_name bert-base-uncased --num_labels 2 --per_device_train_batch_size 8 --per_device_eval_batch_size 8 --evaluation_strategy epoch --num_epochs 3 --learning_rate 5e-5 --warmup_ratio 0.1 --gradient_accumulation_steps 1 --eval_accumulation_steps 1 --weight_decay 0.01 --save_strategy epoch --fp16 False --logging_dir logs --output_dir output
äžèšã®ãããªèšå®ã yaml ãã¡ã€ã«ã«æžããhydraã䜿ãããšã§ argparse ããè±åŽããããšãã§ããŸãããŸããèšå®ãã¡ã€ã«èªäœã«éå±€æ§é ãæããããã€ãŸãã°ã«ãŒãåããããšã§ããããããããã管çãããã圢ã§èšå®ãã¡ã€ã«ãæ±ãããšãã§ããŸãã
ä»å㯠configs ãã£ã¬ã¯ããªãäœæããããã«ãã®äžã« paths ãš transformers ãäœããããããã«å¯Ÿå¿ããèšå®ãã¡ã€ã«ãäœãããšæããŸãã
âââ configs
â âââ config.yaml
â âââ paths
â â âââ default.yaml
â âââ transformers
â âââ default.yaml
âââ src
âââ __init__.py
âââ main_hydra.py
default.yaml ã«ã¯å¯Ÿå¿ãããã£ã¬ã¯ããªåã«é¢ããããã©ã«ãå€ãèšèŒããconfig.yaml ã¯ãããããã®èšå®ãã¡ã€ã«ããŸãšãã圹å²ãæã£ãŠããŸãã
model_name: bert-base-uncased num_labels: 2 per_device_train_batch_size: 8 per_device_eval_batch_size: 8 evaluation_strategy: epoch num_epochs: 3 learning_rate: 2e-5 warmup_ratio: 0 gradient_accumulation_steps: 1 eval_accumulation_steps: 1 weight_decay: 0.01 save_strategy: epoch fp16: False
logging_dir: logs output_dir: output
defaults: - paths: default - transformers: default - _self_
defaults: ã«é¢ããŠã¯å
¬åŒããã¥ã¡ã³ããåç
§ãã ããããã£ã¬ã¯ããªå:èšå®ãã¡ã€ã«å ãšãã圢åŒã§èšå®ãèªã¿èŸŒã¿ãæå®ããèšå®ã䜿çšã§ããããã«ããŸãã
ãŸã config.yaml èªäœã«ã paths ã transformers ã®èšå®ä»¥å€ã®èšå®ãªã©ãæžãããšãã§ããŸãã- _self_ ã¯ãconfig.yaml èªèº«ã®èšå®ãæç€ºçã«è¡šããŠãããã®ã«éããŸããã
ãã ãåãèšå®ãååšããå Žåã¯ãªã¹ãã®ããåŸã®ãã®ãåªå
ãããŸããä»åã®å Žåã ãš _self_ ãæåªå
ãšããããšã«ãªããŸãã
å®è¡å¯Ÿè±¡ã®ãã¡ã€ã«ã¯ä»¥äžã®ããã«ãªããŸãã main() ã«å¯Ÿã㊠@hydra.main ãã³ã¬ãŒã¿ã®è¿œå ããããŸããæçµçã«äœ¿ãèšå®ãã¡ã€ã«ãšããã®èšå®ãã¡ã€ã«ãååšãããã£ã¬ã¯ããªã®ãã¹ãããã§æå®ããããšã§ããã®èšå®ã䜿ããããã«ãªããŸãã
import hydra import transformers from datasets import load_dataset from omegaconf import DictConfig from transformers import AutoModelForSequenceClassification, AutoTokenizer @hydra.main(config_path="../configs", config_name="config", version_base="1.3") def main(cfg: DictConfig): # model, tokenizer ã®ããŒã tokenizer = AutoTokenizer.from_pretrained(cfg.transformers.model_name) model = AutoModelForSequenceClassification.from_pretrained( cfg.transformers.model_name, num_labels=cfg.transformers.num_labels ) # example ããŒã¿ã»ããã®ããŒã raw_datasets = load_dataset("glue", "mrpc") def tokenize_function(example): return tokenizer(example["sentence1"], example["sentence2"], truncation=True) tokenized_datasets = raw_datasets.map(tokenize_function, batched=True) # ãã¬ãŒãã³ã°ã®èšå® training_args = transformers.TrainingArguments( output_dir=cfg.paths.output_dir, per_device_train_batch_size=cfg.transformers.per_device_train_batch_size, per_device_eval_batch_size=cfg.transformers.per_device_eval_batch_size, evaluation_strategy=cfg.transformers.evaluation_strategy, logging_dir=cfg.paths.logging_dir, num_train_epochs=cfg.transformers.num_epochs, learning_rate=cfg.transformers.learning_rate, warmup_ratio=cfg.transformers.warmup_ratio, gradient_accumulation_steps=cfg.transformers.gradient_accumulation_steps, eval_accumulation_steps=cfg.transformers.eval_accumulation_steps, weight_decay=cfg.transformers.weight_decay, save_strategy=cfg.transformers.save_strategy, fp16=cfg.transformers.fp16, ) trainer = transformers.Trainer( model, training_args, train_dataset=tokenized_datasets["train"], eval_dataset=tokenized_datasets["validation"], tokenizer=tokenizer, ) trainer.train() if __name__ == "__main__": main()
cfg.transformers.model_name ã cfg.paths.output_dir ã®ããã« ãã£ã¬ã¯ããªå.ãã©ã¡ã¿å ãšããæãã§ã¢ã¯ã»ã¹ã§ããŸãã
åŒæ°ãã€ããã«å®è¡ãããšããã¡ãã yaml ãã¡ã€ã«ã«æžããéãã®èšå®ã§å®è¡ãããŸãã
åŒæ°èšå®ã®äŸã¯ä»¥äžã§ãã
python src/main_hydra.py transformers.fp16=true
ãŸããå®è¡æã«ã¯ããã©ã«ãã§ outputs ãã©ã«ããäœæãããŸãããã®äžã«ã¯ log ãã¡ã€ã«ããå®è¡æã®ãã¹ãŠã® hydra ã®èšå®ãã¡ã€ã«ãå®è¡æ¥/å®è¡æéã®ãã©ã«ãã«ä¿åãããŸãã
2. ã¯ã©ã¹åäœã§èšå®ããã
èšå®ãã©ã¡ã¿ãåãåããããã¯ã©ã¹ã颿°ã®åŒæ°ãšããŠäœ¿çšããå Žåããªããšãªãåé·ãªæ°ãããŸãããŸãããã©ã¡ã¿ã®å€ã«ãã£ãŠå¯Ÿè±¡ã®ã¯ã©ã¹ã»é¢æ°ã倿Žãããæããã¡ãã¡å¯Ÿè±¡ã®ã¯ã©ã¹ã»é¢æ°ã import ãæ¡ä»¶æã§åå²ãäœããªã©ãå°ããã«ã€æãããããŸãã
hydra ã«ã¯ Instantiating ãšããã·ã¹ãã ãããããããåè¿°ã®åé¡ã解決ããŠãããŸãã
ããã䜿ãããšã§æçµç㪠main.py ã¯ä»¥äžã®ããã«ãªããŸãã
import hydra from datasets import load_dataset from omegaconf import DictConfig @hydra.main(config_path="../configs", config_name="config", version_base="1.3") def main(cfg: DictConfig): # model, tokenizer ã®ããŒã model = hydra.utils.get_method(cfg.transformers.model)( cfg.transformers.model_name, num_labels=cfg.transformers.num_labels, ) tokenizer = hydra.utils.get_method(cfg.transformers.tokenizer)(cfg.transformers.model_name) # example ããŒã¿ã»ããã®ããŒã raw_datasets = load_dataset("glue", "mrpc") def tokenize_function(example): return tokenizer(example["sentence1"], example["sentence2"], truncation=True) tokenized_datasets = raw_datasets.map(tokenize_function, batched=True) trainer = hydra.utils.instantiate( cfg.transformers.trainer, model=model, train_dataset=tokenized_datasets["train"], eval_dataset=tokenized_datasets["validation"], tokenizer=tokenizer, ) trainer.train() if __name__ == "__main__": main()
泚ç®ãã¹ã㯠trainer = hydra.utils.instantiate( ãã¡ãã§ãããconfigs/transformers/default.yaml ã«ãã trainer ã instantiate ããŠããŸãã
ããã«ã¯ model ã tokenizer ããã yaml ã§èšå®ã§ããŸããä»å㯠AutoTokenizer ãªã©ã® Auto ç³»ã®ã¯ã©ã¹ãããã®ã§ããã§ãããç¹å®ã®ã¯ã©ã¹ã䜿ããšããªã©ã«ã¯ get_method ã get_class ã䜿ããŸãã
configs/transformers/default.yaml ã¯ãããªæãã§ãã
model_name: bert-base-uncased num_labels: 2 model: transformers.AutoModelForSequenceClassification.from_pretrained tokenizer: transformers.AutoTokenizer.from_pretrained trainer: _target_: transformers.Trainer args: _target_: transformers.TrainingArguments output_dir: ${paths.output_dir} logging_dir: ${paths.logging_dir} per_device_train_batch_size: 8 per_device_eval_batch_size: 8 evaluation_strategy: epoch num_train_epochs: 3 learning_rate: 2e-5 warmup_ratio: 0 gradient_accumulation_steps: 1 eval_accumulation_steps: 1 weight_decay: 0.01 save_strategy: epoch fp16: False
_target_ ã« instantiate 察象ãžã®ãã¹ãæžãããã®äžã«åŒæ°ãæžãããšãã§ããŸããããã«ãã¹ãŠã®åŒæ°ãæžãããšãåè¿°ã®ããã«
trainer = hydra.utils.instantiate(
cfg.transformers.trainer,
model=model,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
tokenizer=tokenizer,
)
ã€ã³ã¹ã¿ã³ã¹åã®ã¿ã€ãã³ã°ã§è¿œå ã§åŒæ°ãèšå®ã§ããŸãããŸããfunctools.partial ãšåæ§ã®ãã®ãäœæããããšãã§ããŸãã(åè)
hydra.utils.get_class ã hydra.utils.get_method ã䜿ãããšã§ãã¯ã©ã¹ããã®ã¡ãœããã颿°ãã®ãã®ãåŒã³åºãããšãã§ããŸãã
3. èšå®ãã«ã¹ã¿ãã€ãºããã
bert ç³»ã®ã¢ãã«ã䜿ãæãªã©ãlarge ã¢ãã«ã䜿ããšãã¯ãã·ã³ã®é¢ä¿äžããããµã€ãºãå°ãããããã«åŠç¿çãå°ããããããªã©ã察象ã®ã¢ãã«ã«å¿ããŠåèšå®ã®ããã©ã«ãã倿Žãããå ŽåããããŸãããã¡ããã³ãã³ãã©ã€ã³äžã§ transformers.model_name=roberta-large transformers.trainer.args.learning_rate=1e-5 ãªã©ã®ããã« override ããããšãã§ããŸãããèšå®ãã¡ã€ã«ãšããŠæ®ãããæ°æã¡ããããŸãã
âââ configs
â âââ config.yaml
â âââ paths
â â âââ default.yaml
â âââ transformers
â |ââ default.yaml
| |ââ roberta-base.yaml
| âââ roberta-large.yaml
âââ src
âââ __init__.py
âââ main.py
ãã®ããã« roberta-base.yaml ãš roberta-large.yaml ã®èšå®ãã¡ã€ã«ã远å ããŠã¿ãŸãã
defaults: - default model_name: roberta-base
defaults: - default model_name: roberta-large trainer: args: num_train_epochs: 2 learning_rate: 1e-5 gradient_accumulation_steps: 4
defaults: - default ã¯ãåãé局㮠default.yaml ã overriede ããããã«è¿œå ããŸããããããã®èšå®ãã¡ã€ã«ããã¿ãŠåããããã«ã倿Žç¹ (override 察象) 以å€ã¯ã defaults ã§æå®ããå€ã®ãã©ã¡ã¿ãé©çšãããŸãããã®å Žåã ãš defaults.yaml ãããã§ããã
ããããããšã§ã倿Žç®æä»¥å€ã®äœèšãªèšå®ãçç¥ãã€ã€èšå®ãè¡ãããšãã§ããŸããã
次ã«ãã®èšå®ãé©çšããæ¹æ³ã«ã€ããŠã§ãã
configs/config.yamlãæžãæãã- å®è¡æã®ã³ãã³ãã©ã€ã³åŒæ°ã§æå®ãã
1 ã«ã€ããŠã¯ã以äžã®ããã« config.yaml ãä¿®æ£ããŸããdefault ã ã£ãéšåã roberta-large ã«ããã ãã§ãã
defaults: - paths: default - transformers: roberta-large - _self_
2 ã«ã€ããŠã¯ä»¥äžã®ã³ãã³ãã©ã€ã³åŒæ°ã䜿ããŸããtransformers ã®èšå®ã倿Žããæãã§ãã
python run src/main.py transformers=roberta-large
話ã¯ãããŸãããhydra ã§ã¯ããã©ã«ãã®å€ãèšå®ãããã³ãã³ãã©ã€ã³åŒæ°ãšããŠå¿
ãèšå®ãããã©ã¡ã¿ã¯ ??? ãšæžãããšãã§ããŸãã??? ã«åœããéšåãæªæå®ã ãšãšã©ãŒãçºçããŸãã
defaults: - paths: default - transformers: ??? - _self_
äŸãã°äžã®ããã«æžãã°ãpython run src/main.py transformers= ãã³ãã³ãã©ã€ã³ããæå®ããå¿
èŠããããŸã (ã³ãã³ãã©ã€ã³ä»¥å€ãããæå®ããæ¹æ³ã¯ãããŸã)ã
4. ãã®ä»
ç°å¢å€æ°ã䜿ã
ãã¡ãã®èšäºãåèã«ãªããŸãã
root_dir: ${oc.env:PROJECT_ROOT}
output_dir: ${hydra:runtime.output_dir}
work_dir: ${hydra:runtime.cwd}
ç°å¢å€æ°ä»¥å€ã«ããå®è¡æã®ãã°ä¿åãã£ã¬ã¯ããªãªã©ã® hydra ç¹æã®ãã¹ã«ãã¢ã¯ã»ã¹ã§ããŸãããã¡ãã倿Žãå¯èœãªã®ã§ãäŸãã°æå®ããåŒæ°ãšåãååã®åºåãã£ã¬ã¯ããªãäœãããšãªã©ãå¯èœã§ãã
notebook ã§äœ¿ã
with hydra.initialize(version_base=1.3, config_path="../configs"): CFG = hydra.compose( config_name="config.yaml", return_hydra_config=True, overrides=OVERRIDES, ) # use HydraConfig for notebook to use hydra job HydraConfig.instance().set_config(CFG)
OVERRIDES ã«ã¯ transformers=default ãªã©ã®ããã«ã³ãã³ãã©ã€ã³åŒæ°ã§ã®èšå®ã«çžåœããéšåãæžãã° OK ã§ãã
multirun
ä»åã¯ç¹ã«è§ŠããŠãªãã£ãã§ãããhydra ã®ç®çæ©èœã®äžã€ã§ãã
è€æ°ã®ç°ãªãèšå®ã§å®è¡ããå Žåã«äœ¿ããŸããäŸãã°ãåŠç¿çãå€ããå®éšãè¡ãããå Žåãªã©ã§ãããçŽåã§ã®å®è¡ã«ãªããŸãããLauncher ã倿Žããããšã§äžŠåã®å®è¡ãå¯èœã«ããŸãã
ãããã«
hydra ã䜿ã£ãèšå®ç®¡çã«ã€ããŠããã䜿ãã·ãã¥ãšãŒã·ã§ã³ãšå®éã®ã³ãŒããäœã£ãŠã¿ãŸããããã®èšäºã«æžããäœ¿ãæ¹ä»¥å€ã«ããŸã ãŸã è²ã ãªããšãã§ãããã§ãããããããããšã¯ã»ãŒã§ãããšäœ¿ã£ãŠã¿ãŠæããŸããã
å ¬åŒ github ã«ããã Hydra Ecosystem ãªãããåèã«ãªãããã§ãã
ä»å䜿çšããã³ãŒãã¯ãã¡ãã«ãããŸãã
GCE ã€ã³ã¹ã¿ã³ã¹å ã®ã³ã³ããã§ Git ã䜿ã
ã¯ããã«
ãã¡ãã®èšäºã§ GCP ã䜿ã GPU ã€ãã®ã€ã³ã¹ã¿ã³ã¹ãäœãããã®äžã§ vecode ã® Dev Container ã䜿ãç°å¢ãæŽããŸãããä»åã¯ããã¡ãã§äœã£ãã³ã³ããã®äžã§ Git ã䜿ãã³ãŒã管çãããGitHub ãšé£æºã§ããããã«ããããšæããŸãã
ã€ã³ã¹ã¿ã³ã¹å ãã³ã³ããå ã§ SSH éµãäœãããšã¯ãããããŒã«ã«ã®PCã§éµãäœæããããã䜿ãããã«ããããšæããŸãã
SSHéµã®äœæ
é©åœãªéµãé©åœãªå Žæã«äœããŸãããã¡ãã®èšäºãªã©ãåèã«ãªããŸãã
ssh-keygen -t ed25519
ä»åã¯ãã¡ãã®ã³ãã³ãã§éµãäœæããŸããã
SSHã§ã€ã³ã¹ã¿ã³ã¹ã«æ¥ç¶ãã
ãã¡ãã®èšäºãåèã«ãªããŸããèšäºã«å£ã£ãŠé²ããŠã¿ãŸãããïŒ
ãŸãéµãç»é²ããŠã¿ãŸããçè 㯠Mac ã䜿ã£ãŠããã®ã§ä»¥äžã®ã³ãã³ããå®è¡ããŸããã
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
ä»åã¯ãã® SSH éµã GitHub ãš GCE ããããã® ssh-key ãšããããšæããŸããGCE ã«ã€ããŠã¯ãã¡ãã®èšäºã®éãå ¬ééµãæå®ããŸããGitHub ã«é¢ããŠã¯ãå ã»ã©ã®ãã¡ãã®èšäºã«ããããŸãã®ã§åèã«ããŠãã ããã*1
次㫠config ãã¡ã€ã«ãä¿®æ£ããŸãã~/.ssh/config ã®å€æŽç®æãšããŠãForwardAgent ãèšå®ããŠããŸãã*2
Host {é©åœãªåå: instance-1ãªã©}
Hostname {å€éšIPã¢ãã¬ã¹}
User {SSHéµã®ãŠãŒã¶ãŒå}
ForwardAgent yes
ã€ã³ã¹ã¿ã³ã¹ã®äžã«å
¥ã£ãŠãssh -T git@github.com ã§ GitHub ãšã®æ¥ç¶ç¢ºèªãããŠã¿ãŸãã
Hi (accountå)! You've successfully authenticated, but GitHub does not provide shell access.
ç¡äºæ¥ç¶ã§ããŠãŸãã ð
ãªããžããªã clone ãã
ã€ã³ã¹ã¿ã³ã¹ã®äžã§ GitHub ãšæ¥ç¶ã§ããã®ã§ããã¡ãã®ãªããžããªã SSH ã§ã¯ããŒã³ããŠã¿ãŸãã
git clone git@github.com:osushinekotan/gcp-pytorch-project.git
/gcp-pytorch-project ãäœãããã®ã§ãdocker ãã€ã³ã¹ããŒã«ãããã®ã¡ Dev Container ãèµ·åãã³ã³ããã«å
¥ã£ãŠã¿ãŸãã
cd gcp-pytorch-project sh gcp/install_docker.sh
docker ã®ã€ã³ã¹ããŒã«ãçµããã° Reopen in Container ãªã©ã§ã³ã³ããã«å
¥ãããšãã§ããŸãã
ã³ã³ããå
ã§å床 GitHub ãšã®æ¥ç¶ã確èªããŠã¿ãŸãã
ssh -T git@github.com
Hi (accountå)! You've successfully authenticated, but GitHub does not provide shell access.
å®ç§ã§ãã ð
ã³ã³ããå ã®å€æŽã GitHub ã« push ãã
ã³ã³ãããªãã§ Git ã䜿ãããšãã§ããããã« GitHub ãšã®æ¥ç¶ã確èªããããšãã§ããŸãããæåŸã« vscode ã§ Manage Unsafe Repositories ãããããšããŸãããã

user name ãš email ãèšå®ãããŠããšããªãã¡ã€ã«ãäœæã㊠push ãŸã§ããŠã¿ãŸãã
git config --global user.email "you@example.com" git config --global user.name "Your Name"
touch test_push.txt git add test_push.txt git commit -m "test" git push origin main

èŠäº push ã«æåããŸãã ð
ããã§ã¯ãã³ã³ããå ã§ git ã®ã¿ãåè£ã䜿ããããã«èšå®ããŠããªããã€å人çã«å¥œããšããã®ããããç§ã¯ãã vscode ã® GUI ã§ããããã㊠git æäœãããŠããŸãããã¡ããGUIæäœã§ãåé¡ãªã push ãŸã§ããããšãã§ããŸãã
ãããã«
ååã®èšäºã«åŒãç¶ãç°å¢æ§ç¯ã«ã€ããŠã§ãããã€ã³ã¹ã¿ã³ã¹å ã§ã®ã³ãŒãã®å€æŽãšç®¡çã« Git / GitHub ã䜿ãããšã§ãããŒã«ã«ãå¥ã®ç°å¢ãšåæãã¯ããããšãã§ããŸãã
ç°å¢æ§ç¯ã«ã¯ Dev Container ã䜿ããã³ãŒã㯠Git / GitHub ã§ç®¡çããããšã§è€æ°ã®ãã·ã³ãè€æ°äººã§ã®éçºãå®éšã«ãããå·®ç°ãæžããããšãã§ããã®ã§ã¯ãªãã§ããããã *3
*1:GitHubãšGCEã§åãéµã䜿ãåããŠããŸããããã¯æšå¥šãããæ¹æ³ã§ã¯ãªããšæããŸããã䟿å®äžãã®ããã«ããŠããŸã
*2:--apple-load-keychain ã䜿ãã®ãšåãããã
*3:ä»å䜿çšãã ssh-agent ãŸããã«ã€ããŠã¯ ころんびあ (@colum2131) / X ããã«æããŠããã ããŸãããããããšãããããŸãã!
Google Cloud (GCP) ã䜿ã£ã kaggle ã®ç°å¢æ§ç¯ã¡ã¢
ã¯ããã«
GCE (Google Compute Engine) ã§ kaggle çšã®ç°å¢æ§ç¯ãããããšæããèªåãªãã®ç°å¢æ§ç¯ãããŠã¿ãŸããããã®éã«ããã€ãããŒãã«ããã£ãã®ã§åå¿é²ãšããŠãã®èšäºãæžããŸããã kaggle çšãšãããŸãããkaggle docker image ãªã©ã¯ç¹ã«äœ¿ãããªã®ã§ããã®èŸºãã¯ç®çã»çšéã«åãããŠé©åœã«å€æŽãã ããã
ä»åã¯ä»¥äžã®ãããªã€ã¡ãŒãžã®ç°å¢ãäœããããšæã£ãŠããŸãã
- instance å
ã§ vscode ã®
devcontainerã䜿ã£ãŠç°å¢ãäœã poetryã䜿ãpytorchã GPU ã§åãã- kaggle ããã®ããŒã¿ã®ããŒããšããŒã¿ã»ããã®ã¢ããããŒã㯠kaggle api ã䜿ã
- åŠç¿æžã¿ã¢ãã«ããã®ä»ããŒã¿ã¯å šãŠ GCS (google cloud storage) ã«ãã
ã€ã³ã¹ã¿ã³ã¹ã®äœæ
æåã«ã€ã³ã¹ã¿ã³ã¹ã®äœæãããŸããä»åã¯GPUã䜿ãããã®ã§ãäºåã«ãGPUã®å²ãåœãŠç³è«ããè¡ãå¿ èŠããããŸãããã¡ãã®èšäºãªã©ãåèã«ãªãããšæããŸãã zenn.dev
1. GCP ã«å
¥ãã Compute Engine ãã ã€ã³ã¹ã¿ã³ã¹ã®äœæ ãå®è¡ãã

ã€ã³ã¹ã¿ã³ã¹åã¯é©åœã«å€æŽããŠäžãããããã§ã¯ããã©ã«ãã® instance-1 ãèšå®ãããŠããŸãããŸãä»å㯠asia-northeast1-a ã« NVIDIA T4 ãã·ã³ãã¹ãããã§åããŸããã ã¹ãããã®æ¹ãã財åžã«åªããã§ãããã
2. ããŒããã£ã¹ã¯ã®éžæ

Deep Learning VM with CUDA 11.8 ãéžæããŸãããnvidia driver ãªã©ã® GPUäœ¿çšæã«å¿
èŠãªãã®ãå
šãŠå
¥ã£ãŠããã®ã§ãæéãçããŠæ¥œã§ãã䜿ããã pytorch ãå¿
èŠãšããŠãã cuda ã®ããŒãžã§ã³ã確èªããéžæããã®ãåã§ããç§ã¯ pytorch=2.0.0 ã䜿ã£ãŠããã®ã§ããã¡ããéžæããŠããŸãããµã€ãº ã¯ããã©ã«ã 50GB ã§ãããdirver ãªã©ãå
¥ããšãããã³ãã³ã«ãªãã®ã§äœè£ãæãã㊠100GB ã«ããŸããã
3. API ãšãã¡ã€ã¢ãŠã©ãŒã«ã®èšå®
ããã©ãããã®ã§ãšããããå
šèš±å¯ã§ãããŸãããå¿
é ãªã®ã¯ Storage ãžã®ãã«ã¢ã¯ã»ã¹æš©ãªã®ã§ãã以å€ã¯ãããªã«èšå®äžããã

4. 詳现èšå®
詳现èšå®ã¯ãããã¯ãŒã¯ ã€ã³ã¿ãŒãã§ãŒã¹ãšã»ãã¥ãªãã£éšåã ãèšå®ããŸãã
ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ãŒã¹ã¯å€éš IPv4 ã¢ãã¬ã¹ã ãšãã§ã¡ã©ã« (ã€ã³ã¹ã¿ã³ã¹ãç«ã¡äžããããšã«å€ãå€ãã) ã«èšå®ããŸããéçIPã¢ãã¬ã¹ãäºçŽããããšã§å€ãå€ããããšã¯ãªããªããŸããã以äžã®ç¹ããããã§ã¯ãšãã§ã¡ã©ã«ã«èšå®ããŸããã
- ãéãããã
- éçIPã¢ãã¬ã¹ãèšå®ãããš kaggle api ã䜿ããªã
äºç¹ç®ã«é¢ããŠãkaggle api ã§ã®ã¢ã¯ã»ã¹æã«ãšã©ãŒãçºçããŠããŸããŸããã©ãã«ãããã°ãªããšãã§ãããã§ããããéãããããšããããšãããéç IP ã¯äžæ¡çšãšããŸããã

ä»åã¯ããŒã«ã«ã®PCãã SSH æ¥ç¶ã§ã€ã³ã¹ã¿ã³ã¹ã«ã¢ã¯ã»ã¹ããã®ã§ãããã§ SSH å
¬ééµãèšå®ããŸãããããžã§ã¯ãå
šäœã® SSH èªèšŒéµ ã§ãåé¡ãªãæ¥ç¶ã§ãããããªã®ã§ãããåœæã®ç§ã®èšå®æ¹æ³ãæªãã£ãã®ã倱æããã®ã§ãããã§éµãèšå®ããŠããŸãã(ä»ãªãã§ããã®ããªïŒ)

SSH ã§ã€ã³ã¹ã¿ã³ã¹ã«æ¥ç¶ãã
ã€ã³ã¹ã¿ã³ã¹ãäœæãéå§ãããšã以äžã®ããã«ãªããŸããç·ã®ãã§ãã¯ããŒã¯ãèµ·åäžã®ãµã€ã³ã§ãããèµ·åäžã¯èª²éãçºçããã®ã§ã忢å¿ãã«ã¯æ³šæãå¿
èŠã§ãã

vscode ãããã®ã€ã³ã¹ã¿ã³ã«æ¥ç¶ããŸãããvscode ã« Dev Containers (ms-vscode-remote.remote-containers) ãš Remote SSH (ms-vscode-remote.remote-ssh) ã®æ¡åŒµæ©èœãå
¥ããŠããå¿
èŠããããŸã (Dev Containers ãå
¥ããã° Remote SSH ãã€ããŠãã?)
ãŸãã~/.ssh/config ã«èšå®ãæžããŠãããŸãããããªããã°äœæããŠäžããã
Host {é©åœãªåå: instance-1ãªã©}
Hostname {å€éšIPã¢ãã¬ã¹}
User {SSHéµã®ãŠãŒã¶ãŒå}
IdentityFile {ç§å¯éµã®å Žæ: ~/.ssh/id_ed25519 ãªã©}
èšèŒããå
容 (Hostname ã User ) 㯠GCP ã®ã³ã³ãœãŒã«ã«æžããŠãããšæããŸãã
config ãã¡ã€ã«ãæžããŠä¿åããvscode ãéããšä»¥äžã®ããã«ã¢ã¯ã»ã¹ã§ãã圢ã«ãªã£ãŠããŸãã

ãã ååæ¥ç¶æã«ã¯ nvidia-driver ãã€ã³ã¹ããŒã«ãããã©ããèããããããäœæ
ã vs code ããã ãšããŸãè¡ããŸããã§ãããã¿ãŒããã«ãã ssh instance-1 ã§æ¥ç¶ããnvidia-driver ã®ã€ã³ã¹ããŒã«ãå®è¡ã§ããŸãã
Would you like to install the Nvidia driver? [y/n] y
ã€ã³ã¹ããŒã«å®äºåŸ nvida-smi ãå®è¡ãããšç¡äºGPUãèªèã§ããŸãããŸããsudo /opt/deeplearning/install-driver.sh ã§ åã€ã³ã¹ããŒã«ãå¯èœã§ãã
ããšã¯ãdocker compose ã䜿ããããã«å
¬åŒãµã€ãã®æé éãã«ã€ã³ã¹ããŒã«ããŸããã³ããïŒã³ããã§OKã§ãã
docs.docker.com
Dev Container ã§ç°å¢æ§ç¯
ã€ã³ã¹ã¿ã³ã¹ã«ç¡äºå ¥ãããšãã§ããã®ã§ãdev container ã§ç°å¢ãäœããŸãã dev container ã«ã€ããŠã¯ãã¡ãã®èšäºãªã©ãåèã«ãªããŸãã
1. Dockerfile ãš compose.yml ã®äœæ
ãŸã Dockerfile ã§ãããä»åã¯ãšãŠãç°¡åã«ä»¥äžã®ããã«ããŸãããpython 㯠3.11 ãã poetry 㯠1.6 ãæå®ããŠããã ãã§ãã
FROM python:3.11 WORKDIR /workspace RUN pip install poetry==1.6.0
compose.yml ã¯ãã¡ãã§ãã
version: "3"
services:
workspace:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/workspace
- /workspace/.venv
ports:
- 8888:8888
tty: true
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
deploy:
resources:
reservations:
devices:
- driver: nvidia
capabilities: [gpu]
deply ã§ GPUã ã³ã³ããå
ã§èªèããããã«ããŠããŸãããã®èŸºãã®æžãæ¹ã«ã¯ç¹ã«èªä¿¡ããªãããåèçšåºŠã«èŠãŠäžããã
devcontainer.json ã®äœæ
次㫠devcontainer.json ãäœããŸãããã㯠devcontainer ãšã㊠vscode ã®æ¡åŒµæ©èœãªã©ãå«ããç°å¢ãäœãããã®èšèšå³ãšãªããã®ã§ããã
devcontainer/devcontainer.json ãäœããäžèº«ãèšè¿°ããŠã¿ãŸãããã
{
"name": "gcp_pytorch_project",
"dockerComposeFile": ["../compose.yml"],
"service": "workspace",
"workspaceFolder": "/workspace",
"runServices": ["workspace"],
"containerEnv": {
"TZ": "Asia/Tokyo"
}
}
å®éã«ã¯ã䜿ãããæ¡åŒµæ©èœããã©ãŒããã¿ãŒã®èšå®ãªã©ãå šãŠããã«æžãããšãã§ããŸãããããæžããªããš devcontainer ã䜿ãæå³ãã ãã¶èãã¡ãããŸãããä»åã¯é·ããªãã®ã§ã·ã³ãã«ã«ããã ãæžããŠããŸããæžãæ¹ãå 容ã«é¢ããŠã¯ãã¡ããåèã«ãªããŸãã
GCS ãããŠã³ããã
ããŠãä»åäœæãããç°å¢ã®èŠä»¶ãšã㊠åŠç¿æžã¿ã¢ãã«ããã®ä»ããŒã¿ã¯å
šãŠ GCS (google cloud storage) ã«ãã ãšãããã®ããããŸããããããç°¡åã«å®çŸããããã« GCSFUSE ã䜿ã£ãŠ GCS ã®ãã±ãããããŠã³ãããã¹ãã¬ã¹ãªãã¢ãã«ãããŒã¿ã®ä¿åããããã§ãã
å®è¡ããã¹ã¯ãªããã¯ä»¥äžã®ãããªæãã§ãã
MOUNT_DIR="./data" PROJECT_ID=YOUR_PROJECT_ID BUCKET_NAME="gcp-pytorch-project" gcloud config set project $PROJECT_ID gcloud auth login # ãã±ããããªããã°ãäœæãã if ! gsutil ls gs://$BUCKET_NAME; then gcloud storage buckets create gs://$BUCKET_NAME --location=us-central1 fi # install gcsfuse export GCSFUSE_REPO=gcsfuse-`lsb_release -c -s` echo "deb http://packages.cloud.google.com/apt $GCSFUSE_REPO main" | sudo tee /etc/apt/sources.list.d/gcsfuse.list curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - sudo apt-get update sudo apt-get install -y fuse gcsfuse sudo gcsfuse -o allow_other -file-mode=777 -dir-mode=777 $BUCKET_NAME $MOUNT_DIR
MOUNT_DIR , PROJECT_ID, BUCKET_NAME ãããããæå®ããå¿
èŠããããŸããMOUNT_DIR ã¯é©åœãªãã£ã¬ã¯ããªãäœæãããã®ãã¹ãæå®ããã°OKã§ããä»å㯠gcp-pytorch-project ãã±ãããã€ã³ã¹ã¿ã³ã¹äžã® ./data ã«ããŠã³ãããŸããããŠã³ããè§£é€ãããå Žå㯠sudo fusermount -u {mountpoint: ããã§ã¯ data} ã§ã§ããŸãã
ããŠã³ããã data ãã©ã«ãã devcontainer ã§ããã«ããŠã³ãããããšã§ãçæç©ã GCS ã«ä¿åããããã«ããŸãã
ã³ã³ããã«å ¥ã
åæºåã¯çµãã£ãã®ã§ãã€ãã«ã³ã³ããã«å
¥ã£ãŠäœæ¥ããŠã¿ãŸãããïŒ
ã³ãã³ããã¬ãããã Dev Containers: Reopen in Container ãªã©ã䜿ããšã³ã³ããã«å
¥ãããšãã§ããŸããdevcontainer.json ã«æžããå
容 (æ¡åŒµæ©èœã formatter ãªã©ã®èšå®) ãåæ ãããç°å¢ããã§ã«åºæ¥äžãã£ãŠããŸããç§ã®å Žåãpython ã® black ã ruff ãªã©ã®èšå®ãæã
ç¯å²ãããªãã®ã§ãªããŒãããå ŽåããããŸããã
GPUã®ç¢ºèªãš poetry ã³ãã³ãã®äœ¿çšã確èªã§ããã pytorch ãã€ã³ã¹ããŒã«ã㊠GPU ãèªèã§ãããã¿ãŠã¿ãŸãã
poetry init poetry add torch=">=2.0.0, !=2.0.1"
ããã§ torch=">=2.0.0, !=2.0.1" ãã®ããã«æå®ããŠããçç±ã¯ãã¡ãã§ãããæ£çŽæ·±ãèãã䜿ã£ã¡ãã£ãŠããŸããã
>>> import torch >>> torch.cuda.is_available() True
è¯ãããã§ããïŒð
kaggle api ã§ããŒã¿ãããŠã³ããŒããã
æåŸã« kaggle api ã䜿ã£ãŠäœãããŒã¿ãããŠã³ããŒãããŠã¿ãŸããããããŠã³ããæåããŠããã°ãããŠã³ããŒãããããŒã¿ã¯ã€ã³ã¹ã¿ã³ã¹ã®ãã£ã¹ã¯ã§ã¯ãªã GCS ã«ä¿åãããã¯ãã§ãããŸã kaggle ãã€ã³ã¹ããŒã«ããèªèšŒæ
å ±ã®èšå®ãããŸãããã®åŸ titanic ã®ããŒã¿ãããŠã³ããŒããä¿åããŠã¿ãŸãã
poetry add kaggle
kaggle api ã®äœ¿ãæ¹ã«é¢ããŠã¯ãã¡ãã®èšäºãªã©ãåèã«ãªãããšæããŸãã
èªèšŒæ
å ±ã¯ kaggle.json ãšããŠä¿åã䜿ãããšãã§ããŸãããå®ã¯ç°å¢å€æ°ãšããŠäœ¿ãããšãã§ããŸããKAGGLE_USERNAME ãš KAGGLE_KEY ãããããèšå®ããã°OKã§ãã
from kaggle import KaggleApi
client = KaggleApi()
client.authenticate()
client.competition_download_files(
competition="titanic",
path="./data",
quiet=False,
)
ãã¡ãã®ã³ãŒããå®è¡ãããšãGCS ã®æå®ãããã±ããã«ããŒã¿ãä¿åãããŸãã

ãããã«
以äžã§äœãããç°å¢ãäœããŸããïŒDockerfile ã devcontainer ãªã©ãã«ã¹ã¿ã ããŠãªãªãžãã«ã®èšå®ãåæ ããç°å¢ãäœãããšããã¡ããå¯èœã§ããdevcontainer ã䜿ãããšã§è€æ°ã®ã€ã³ã¹ã¿ã³ã¹ã§åãç°å¢ãç°¡åã«äœããGCSã«ããŒã¿ãããããšã§å ±æãç°¡åã«ããããšãã§ããããã«ãªã£ããšæããŸãã
ä»å䜿çšããã³ãŒãã¯ãã¡ãã«ãããŸã
HuMob Challenge 2023 ã«åå ããŸããïŒ
HuMob Challenge 2023 ãšã¯
The Human Mobility Prediction Challenge (HuMob Challenge) 2023 is a competition aiming at testing state-of-the-art computational models for the prediction of human mobility patterns, using an open source, urban scale (100K individuals), longitudinal (90 days) trajectory dataset.
HuMob Challenge 2023 㯠SIGSPATIAL ãšããåœéåŠäŒã®ã¯ãŒã¯ã·ã§ããã®äžç°ãšããŠè¡ãããã³ã³ããã£ã·ã§ã³ã§ãã
2023幎7æ10æ¥ãã 2023幎9æ15æ¥ ã®çŽ2ã¶æééå¬ãããŸãããäžäœTOP10 ã®åå è 㯠2023幎11æã«ãã€ãã§éå¬äºå®ã® SIGSPATIAL ã®ã¯ãŒã¯ã·ã§ããã«æåŸ ããè§£æ³çãçºè¡šããTOP3 ã«ã¯äœããPRIZEãçšæãããŠããããã§ãã
ã³ã³ããã£ã·ã§ã³è©³çްã«ã€ããŠã¯ãã¡ããåç §ãã ããã
ã³ã³ãæŠèŠ
ãã®ã³ã³ããã£ã·ã§ã³ã®ã¿ã¹ã¯ã¯ãããããNext Place PredictionããšåŒã°ãããã®ã§ãã ãã人ç©ãããæç¹ã«ãããŠã©ãã«ããããäºæž¬ãããã®ã§ããã
ãŸããä»åã®ã³ã³ããã£ã·ã§ã³ã§ã¯ task1 ãš task2 ã®2çš®é¡ã®ããŒã¿ã»ãããäžããããŸãããããã平垞æãšã³ããçŠã«ãããç·æ¥äºæ æã®ãã®ã§ãããããã®æéã«ããã Next Place Prediction ã®ç²ŸåºŠã§æçµçãªè©äŸ¡ãè¡ãããŸãã
äžéè©äŸ¡ã¯ãããã®ã®ãªãŒãããŒãã¯ååšãããæçµè©äŸ¡ã¯ 1submission ã§çµæã決ãŸãã³ã³ããã£ã·ã§ã³ã§ããã
ããŒã¿
䜿çšããããŒã¿ã«ã€ããŠç°¡åã«èª¬æããŸããããŒã¿ã»ããã®è©³çްã«ã€ããŠã¯ãã¡ããåç §ãã ããã
æ¥æ¬ã®ãšããäžèŠæš¡éœåžã«ãããŠãããæéã®è€æ°ã®äººç©ã®ç§»åã 500m x 500m ã®ã¡ãã·ã¥ã〠30ååäœã§èšé²ãããŠããŸããå ·äœçã«ã¯ä»¥äžã®ãããªããŒãã«ãæ³å®ã§ããŸãã
| user ID | day | timeslot | x | y |
|---|---|---|---|---|
| 1 | 1 | 13 | 10 | 13 |
| 1 | 1 | 18 | 11 | 15 |
| ... | ... | ... | ... | ... |
| 2 | 3 | 15 | 31 | 19 |
| 2 | 3 | 28 | 35 | 33 |
| ... | ... | ... | ... | ... |
| 99999 | 74 | 10 | 999 | 999 |
| 99999 | 74 | 15 | 999 | 999 |
| 99999 | 74 | 20 | 999 | 999 |
user ID: å¿ååãããå人day: ã«ã¬ã³ããŒã¯ããããªãããéå§æç¹ã 0 ãšãããšãã®æ¥ä» (0 ~ 74ã®ã©ãã«ãäžãããã)timeslot: 0 ããã day ã® 0æãšãããšãã® 30ååäœã®ã©ãã« (0~47ã®ã©ãã«ãæ¯ããã)x,y: ããããã¡ãã·ã¥ã®åº§æšã衚ã (æ£è§£ããŒã¿ã«ã¯ 1~200 ã®ã©ãã«ãäºæž¬å¯Ÿè±¡ã«ã¯ 999 ãäžããããŠãã)ã
ã¡ãã·ã¥ã®åº§æšãšããã®ã¯ã以äžã®å³ã§è¡šãããšãã§ããŸãã

å·Šäžããé ã«x, y æ¹åããããã«å¯ŸããŠçªå·ãæ¯ããã圢ã§ããã1ã¡ãã·ã¥500mãªã®ã§ã察象ã®å°åã¯å šäœã¯ 10km åæ¹ã®æ£æ¹åœ¢ãšããããšã«ãªããŸããã©ããã¯äžæã§ãããæ¥æ¬ã®äžèŠæš¡éœåžã® 10km x 10km ãšãªã¢ã«ããã人ã ã®ç§»åã衚ãããŒã¿ã«ãªããŸãã
ãã®ã³ã³ãã§ã¯åŠç¿ããŒã¿ãšãã¹ãããŒã¿ã®ãããªåºå¥ã¯ãªããäºæž¬å¯Ÿè±¡ã® user ID ãš day ã«ããã x, y ã 999 ãšããŠãã¹ã¯ãããŠããŸããtask1ãtask2 ããããã®äºæž¬å¯Ÿè±¡ã¯ä»¥äžã®éãã§ãã

次㫠PoI Features ã«ã€ããŠã§ãããã¡ãã¯ä»¥äžã®ãããªããŒã¿ã§ãã
| x | y | POI category (dim) | # of POIs |
|---|---|---|---|
| 1 | 1 | 13 | 10 |
| 1 | 1 | 18 | 11 |
| 1 | 1 | 24 | 11 |
| 1 | 1 | 27 | 12 |
| ... | ... | ... | ... |
| 2 | 2 | 15 | 31 |
| 2 | 2 | 28 | 35 |
| 2 | 2 | 12 | 35 |
x,y: ã¡ãã·ã¥ã衚ã座æš- POI category : å¿ååããã PoI (ã¬ã¹ãã©ã³ãå ¬åãªã©ã衚ãã©ãã« 0~84)
- # of POIs : ããã¡ãã·ã¥ã«ååšãã PoI ã®æ°
ãã®ã³ã³ãã§ã¯ãå人æ å ±ä¿è·ã®ãã PoI Feature ãšçã® PoI ã®ãããã³ã°ã¯æäŸãããŠããŸããã誰ããã€ã©ãã«è¡ã£ãã®ããé ãããã§ããããããé瀺ãããŠããã°ããé¢çœããšæããŸãããå人æ å ±çµ¡ãã®ã§ã¡ãã£ãšé£ããã§ããããã
äžããããããŒã¿ã»ããã¯ä»¥äžã«ãªããŸãã
åèãŸã§ã«ã task1 ã«ããã user ããšã® x, y ã® line plot ã§ããæšªè»žãæéã瞊軞ã座æšãšãªã£ãŠããŸããèŠåæ£ãã人ãããã°ããã§ã¯ãªã人ãããã®ãããã£ãŠé¢çœãã§ããã

è©äŸ¡ææš
次ã«è©äŸ¡ææšã«ã€ããŠã§ãã
ãã®ã³ã³ãã§ã¯ GEO-BLEU ãš DTW ãšããäºã€ã®è©äŸ¡ææšã§æçµçãªé äœã決ããŸãã
ãŸã GEO-BLEU ã§ãããããã¯ãæ©æ¢°ç¿»èš³ãæç« çæã¿ã¹ã¯ã®åºåãè©äŸ¡ããããã®ææšã§ããBLEU (Bilingual Evaluation Understudy) ã® geo çãšããæãã§ãã
user ID ããšã® x, y ããããã®æéæ¹åã®ã·ãŒã±ã³ã¹ ã® n-gram ã®äžèŽãåºã«ã¹ã³ã¢ãã€ããŠããã®ã ãšæããŸãã詳ããã¯ãã¡ããåç §ãã ãããä»åã®ã³ã³ãã§ã¯ 0~1 ã®å€ããšãã倧ããã»ã©è¯ãã¹ã³ã¢ãšããããšã«ãªããŸãã
次㫠DTW (Dynamic Time Warping) ã«ã€ããŠã§ãããããã¯æç³»åã§éŠŽæã¿æ·±ãææšããšæããŸããæç³»åããŒã¿å士ã®è·é¢ã»é¡äŒŒåºŠã枬ãéã«çšããææ³ã§ããã
DTW ã¯2ã€ã®æç³»åã®åç¹ã®è·é¢ãç·åœããã§å
šãŠæ±ãã2ã€ã®æç³»åãæçãšãªããã¹ãèŠã€ããããã®çޝç©ããšããŸãã
ç»åã¯ãã¡ãããæåããŸããã ä»åã®ã³ã³ãã§ã¯ã0以äžã®å€ããšããå°ããã»ã©è¯ãã¹ã³ã¢ãšããããšã«ãªããŸãã
ãã®äºã€ã®ææšã¯ãããã user ID åäœã§èšç®ããæåŸã«å¹³åããšãããããæçµçãªææšãšããŠããŸãã
以äžãŸãšãã§ãã
- task1 (éåžžæ) ãš task2 (ç·æ¥æ) ã®æ¥æ¬ã®ããå°åã«ãããã¡ãã·ã¥åäœã§ã®äººã ã®ç§»åãäºæž¬ãã
- äžå®å šãªããã«ããŒã¿ã§ãã
- åã¡ãã·ã¥ã«ãããå¿ååããã PoI ã®æ°ã¯äžããããŠãã
- è©äŸ¡ææšã¯ GEO-BLEU ãš DTW ã§ãã
è§£æ³ç޹ä»
ã³ã³ãæŠèŠãšããŒã¿ã®èª¬æãæžãã ã®ã§ãåŒããŒã ã®è§£æ³ã玹ä»ããããšæããŸããæåã«ããè§£æ³ã玹ä»ããæåŸã«æçµãµãããã·ã§ã³ãšããŠéžãã è§£æ³ã玹ä»ããããšæããŸããç¹ã«ã²ããã®ãªãè§£æŸã«ãªã£ãŠããŸã£ãäºãæåã«èšã£ãŠãããŸããã
ã¢ãã«ããŒã¹
äžçªæéããããŠåãçµã¿ãŸããããæçµçãªãµãããã·ã§ã³ã«ã¯éžã°ãªãã£ããã®ã§ããåŸè¿°ããã«ãŒã«ããŒã¹ã®ãã®ãæçµãµãã«ãªã£ãã®ã§ããã¡ãã§ã¯æ©æ¢°åŠç¿ããŒã¹ã®è§£æ³ã玹ä»ããããšæããŸããå šäœã®æµãã¯äžã®å³ã®ãããªæãã§ãã

ãããã seq2seq ã§ãããday 60~74 ã®ç¯å²ã®ç®ç倿° (x, y) ãäºæž¬ããéãday 0~59 ã®ç¹åŸŽéã LSTM Encoder ã«ãday 60~74 ã®ç¹åŸŽéã LSTM Decoder ã«æž¡ããEncoder ã§åŸãããç¶æ ãåŒãç¶ãã Decoder ãæçµçãªäºæž¬ã·ãŒã±ã³ã¹ãåºåããç®æ®µã§ããLSTM 以å€ã«ã Transformer ã GraphLSTM ãªã©ã詊ãããããŸãããå šãŠåãããã« seq2seq ã§ç³»åãäžçºã§åºåããããã«ããŠããŸãã
Encoder ã«æž¡ãç¹åŸŽéãš Decoder ã«æž¡ãç¹åŸŽéã¯ãããããªãŒã¯ããªãããã«äœã£ãŠããŸãã
Encoder ã«æž¡ãç¹åŸŽéãšããŠã¯ãå³ã«ããéããx, y, day time slot ãªã©ã®çã®å€ããx y ãéçŽãããã®ãªã©ã䜿ã£ãŠããŸãããã®éçŽæã«time slot ã ææ¥ã鱿«ç¥æ¥ãã©ã°ãªã©ãçµã¿åãããŠããŸããæäŸãããããŒã¿ã«ã¯ ææ¥ãç¥æ¥ãªã©ã®æ
å ±ã¯ãããŸããããçããŒã¿ãããªããŒã¹ãšã³ãžãã¢ãªã³ã°ããŸããããŸããPoI feature ãããŒãžããäºã§ãå°ççãªç¹åŸŽãæããããšãæåŸ
ããŠããŸãã
Decoder ã«æž¡ãç¹åŸŽéãšããŠã¯ãç®ç倿°ã®ç¯å²å€ (day 0~59) ã®ããŒã¿ã䜿ãéçŽããç¹åŸŽéã䜿ã£ãŠããŸããäŸãã°ãday 0~59 ã®ããŒã¿ã䜿ããuser id ããšã«åææ¥ã®åæéã§ååšãã座æšã®å¹³åå€ãäžå€®å€ãªã©ãéèšããããã day 60~74 ã«ããŒãžããããšã§ç¹åŸŽéãšããŠããŸãã
ãŸã Target Engineering ã€ãŸãç®ç倿°ã® x, y ãããã£ãŠããŸãããŸããä»åã¯åé¡ã§ã¯ãªãååž°ã§è§£ããŠããŸãããã®æãregression ã®ç®ç倿°ã«å¯Ÿã㊠day 0~59 ã®ç¯å²ã§éçŽãã user id ããšã® x , y ããããã®äžå€®å€ãåŒããæšæºåå·®ã§å²ãåŠçãæœããŸãããã€ãŸãäžå€®å€ãšåæ£ãäžå®ã§ãããšããä»®å®ã眮ããŠããŸãã
å šäœçãªæµãã®ãæ°æã¡ãšããŠã¯ãå šãŠã®æ å ±ãããæãã«äœ¿ããäžçºã§ç³»åãåºåããäžå€®å€ãããããŸãå€ããªããããªäºæž¬ãããŠã»ãããšããæãã§ããäžçºã§ç³»åãåºåããŠæ¬²ããã£ãçç±ã¯ãt ãæ¯èŒçé·ããã€ãããŸã§ãããªãã£ãããã§ããã
çµæãšããŠã¯ãã«ãŒã«ããŒã¹ã«åã°ãã§ãã...ããšã§ã«ãŒã«ããŒã¹ã®ãã®ãšã®ç²ŸåºŠæ¯èŒãè¡ããŸããããŸããŸããããŒãã£ãã§ããçç±ãšããŠã¯ä»¥äžãèãããããªãšæã£ãŠããŸãã
ãã€ãã©ãã¥ãŒãã³ã°ãããªãã£ãïŒæéçãªäœè£ããªãã£ãã®ããããŸãããã»ãŒãããã¡ã®ãã€ãã©ã§å®éšããŠããŸããã
loss ã®å·¥å€«ïŒè©äŸ¡ææšã§ãã GEO-BLEU ã DTW ãèæ ®ã§ãã loss (ãããã調ã¹ãŠããªãã§ãã)ã¯äœ¿ããããšãããã RMSE ã§è¡ã£ãŠããŸãããæ¯èŒççžé¢ããã£ãã®ã§ãŸãããããªãšæã£ãŠäœ¿ãç¶ããŠããŸããã
ããå°ãäžå¯§ã«äœããã°ãã«ãŒã«ããŒã¹ã«è² ããå£ããã«ãªã£ããšä¿¡ãããã§ãã
以äžãæ©æ¢°åŠç¿ããŒã¹ã®è§£æ³ã«ãªããŸãã
ã«ãŒã«ããŒã¹
以äžãæ¡çšããã«ãŒã«ã«ãªããŸãã

ãã®åŠçã§ãŸãå®å
šãªããã«ããŒã¿ãäœããŸããuser ID x t x t_label x weekend åã®ã¬ã³ãŒããæã€æ¬ æã®ãªãããã«ããŒã¿ãäœãã€ã¡ãŒãžã§ããã
predict 察象ã«ãããŠæ¬ æã®éšåã ãæ¬ æå€è£å®ãããã°ããã®ã§ãããããã©ãããã£ãã®ã§å®å
šããã«ããŒã¿ãäœããŸãããããããŠäœæãããæ¬ æã®ãªãããã«ããŒã¿ãš predict 察象ã®ããŒã¿ãããŒãžãã (å¿
èŠãªéšåã ããæœåºãã) ããšã§æçµçãªãµãããã·ã§ã³ãã©ãŒãããã«æŽããŠããŸãããã€ãã©ã§ãã T ã¯æåã§è»œããã¥ãŒãã³ã°ãããã®ã䜿ããŸããã
çµæ
task1 ã ãã§ããæå ã®çµæãèŒããŠãããŸãã
| ã«ãŒã«ããŒã¹ | ã¢ãã«ããŒã¹ | |
|---|---|---|
| geobleu | 0.291 | 0.116 |
| dtw | 33.935 | 40.356 |
ããããŠãªãµã³ãã«ã§äºæž¬ãå¯èŠåããŠã¿ããšãããªæãã«ãªããŸãããtask 1 ã«é¢ããŠã¯äººã ã®ç§»åã¯ããªãèŠåæ£ããã§ããäœè«ã§ãããtask2 ã ãš task1 ãšåæ§ã®ã«ãŒã«ã䜿ã£ãŠãã¹ã³ã¢ãå šç¶äœãçµæãšãªããŸãããã¯ãç·æ¥äºæ æã«ã¯éåžžæãšã¯ç°ãªãåãæ¹ãããŠããã®ã§ãããããtask2 ã ãšã¢ãã«ããŒã¹ã®æ¹ã dtw ã«é¢ããŠã¯ã«ãŒã«ããŒã¹ãããè¯ãçµæããããããŠããŸããã

çç±ã¯ããã©ãæåŸã«ã«ãŒã«ããŒã¹ã®ãµãããã·ã§ã³ãäœãã ãäœããç§ã¯ãã®ã³ã³ããã£ã·ã§ã³ããéèµ°ããŸãããã§ãã®ã§ãã¢ã³ãµã³ãã«ããã€ãã©ãã¥ãŒãã³ã°ãè©°ãããšãã£ãããšãããã§ãããããã§ãTOP10 ã«æ®ããã®ã¯éãè¯ãã£ãã ãã ãšæããŸãããã€ãã®ã¯ãŒã¯ã·ã§ããã¯ä»åã¯æ®å¿µãªããèŠéãããšã«ããŸããããHuMob Challenge 2024 ãéå¬ãããã°ãŸãåå ãããã§ããïŒ
ãããã«
ä»å㯠HuMob Challenge 2023 åå èšãšããŠãã³ã³ãã®æŠèŠãšè§£æ³ã®ç޹ä»ãè¡ããŸãããNext Place Prediction ã¯å€§åŠã®æããèå³ããåéã ã£ãã®ã§ãã³ã³ããšããŠè§Šããããšãã§ãããã£ãã§ããæ¥œããåãçµãããšãã§ããŸãããæ¬²ãèšãã°ãªãŒããŒããŒããæ¬²ããã£ãã§ããããŸããPoI ã®é瀺ã user ããšã®ãã¢ã°ã©ãã£ãã¯ããŒã¿ãªã©ãããšããé¢çœãã®ã§ã¯ãªãããšæã£ãŠããŸãã
æäŸãããããŒã¿ã¯å°æ¥çã«ã¯ãªãŒãã³ã«ãªããããã®ã§ãæ©äŒãããã°æ¯éãšãã£ããšããã§ãã
ã³ãŒãã¯ãã¡ãã«ãããŸã (æ±ãã®ã¯ãäºæ¿ãã ãã)