{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.12.12"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":91498,"databundleVersionId":11655853},{"sourceType":"datasetVersion","sourceId":15703333,"datasetId":10059358,"databundleVersionId":16642726},{"sourceType":"datasetVersion","sourceId":15707134,"datasetId":10062294,"databundleVersionId":16646817},{"sourceType":"datasetVersion","sourceId":15707646,"datasetId":10062689,"databundleVersionId":16647375},{"sourceType":"datasetVersion","sourceId":15714664,"datasetId":10067986,"databundleVersionId":16654894},{"sourceType":"datasetVersion","sourceId":15734816,"datasetId":10082186,"databundleVersionId":16676713},{"sourceType":"datasetVersion","sourceId":15735115,"datasetId":10082382,"databundleVersionId":16677040},{"sourceType":"datasetVersion","sourceId":15735310,"datasetId":10082527,"databundleVersionId":16677255},{"sourceType":"datasetVersion","sourceId":15703246,"datasetId":10059287,"databundleVersionId":16642634},{"sourceType":"kernelVersion","sourceId":231062342}],"dockerImageVersionId":31328,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":1225.225513,"end_time":"2026-04-16T03:22:15.332387+00:00","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2026-04-16T03:01:50.106874+00:00","version":"2.7.0"},"widgets":{"application/vnd.jupyter.widget-state+json":{"state":{"002493b898f747bba2fea2615aae40cf":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"07e6aadd11c04d1e833502a52794450d":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1068c4b182744696bd3150700f86884b":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"10716f3dc9ce41708a3ac09b6f7e493e":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"13620545e86e46ddb26595e913bcbbe6":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_50d33d4b28154d659f1e060fc55d7d6d","max":2,"min":0,"orientation":"horizontal","style":"IPY_MODEL_dcc63bae42e14899a0ac1dc3213f4da7","tabbable":null,"tooltip":null,"value":2}},"13b0c6722a2f4c31b8bb5ca7efc4a89c":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"14d8f05e224444f786b73635a95ee753":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_9f71faa8331348c0a6ff4991de4737a4","placeholder":"​","style":"IPY_MODEL_a883af6edd854d2984a81554c76e4d40","tabbable":null,"tooltip":null,"value":"Geometric: 100%"}},"18855ebb29e94d48b4007636b292df19":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1b5fc6dbf8c24a1eae6cd67b3b7228bf":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_62c9514753c44a06ab248711d338f5d1","max":7,"min":0,"orientation":"horizontal","style":"IPY_MODEL_249b425fa4464bc187fe7aa13c33cfb5","tabbable":null,"tooltip":null,"value":7}},"1d3b8759cf9e4166aabfdd7071b459f7":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1e067bb83bdc45a1939e3a1204f679c3":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"1fe60737ef7e401aa0846d3c83117d5d":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"248a2b99296c4fd9abbff06e03d1e8b5":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_c35a1e5ce22e46199ce00ca73976271c","placeholder":"​","style":"IPY_MODEL_bf576311ac494369b4d88e548f794e3f","tabbable":null,"tooltip":null,"value":" 3/3 [00:05&lt;00:00,  1.64s/it]"}},"249b425fa4464bc187fe7aa13c33cfb5":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"297d16ada5564fddb82d9d2d1d6d2a5f":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_58a0e6fb7d534803924dd67f924b782c","IPY_MODEL_835b5fc5b9c3479a83347b2d791a70a7","IPY_MODEL_6ca313f37a4c47a9b171cb7f5cc5df59"],"layout":"IPY_MODEL_1d3b8759cf9e4166aabfdd7071b459f7","tabbable":null,"tooltip":null}},"2e14190a43b14d58823959f231ff77fa":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3759fe8b6a30404e8095284f7e6f7b3d":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_92b9006d7b0f462db51f1377f5ba8753","max":231,"min":0,"orientation":"horizontal","style":"IPY_MODEL_6f4651df25a84c73ac6f1a3523d61594","tabbable":null,"tooltip":null,"value":231}},"3e5a3d792e8b423cbb6c260fcf9a8bde":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"3fe51420fcfc4998a08631f00af3bacf":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_bf15a0dabf144a18a8861cddcedcb01c","placeholder":"​","style":"IPY_MODEL_fd8cedbcffd14f77b8a35b31f0bc0201","tabbable":null,"tooltip":null,"value":"MASt3R SPoC: 100%"}},"41e7347f1bef496ca1c6de8d192276fb":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_f714d6b75588480dbd420a9d1fb91f9e","IPY_MODEL_f930f3cb70874fd683ec6ee08dec29fa","IPY_MODEL_5cafa6dd42c74af2886ce9cdb2c6aeb5"],"layout":"IPY_MODEL_002493b898f747bba2fea2615aae40cf","tabbable":null,"tooltip":null}},"444aa173c5bb4152b22ce725caf25c5e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"46bfeec19a0c407d9d09be1f8c4a9aa4":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_3fe51420fcfc4998a08631f00af3bacf","IPY_MODEL_1b5fc6dbf8c24a1eae6cd67b3b7228bf","IPY_MODEL_900c6aeb06e24176a4f178c38070f9e9"],"layout":"IPY_MODEL_aab5281875e845c9ad888b15e376991c","tabbable":null,"tooltip":null}},"46e96ca691ed4d19aa4d0af149461b88":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"50d33d4b28154d659f1e060fc55d7d6d":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5551043599dd4d19a666d9be45aea752":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"586d366cfa4c4defab5505f1228631b7":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"58a0e6fb7d534803924dd67f924b782c":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_07e6aadd11c04d1e833502a52794450d","placeholder":"​","style":"IPY_MODEL_b852b678264f4335bdfe7959bb47004d","tabbable":null,"tooltip":null,"value":"DINOv3: 100%"}},"5cafa6dd42c74af2886ce9cdb2c6aeb5":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_f51fcbc2c4824f3baeef34fde1e04f85","placeholder":"​","style":"IPY_MODEL_f8a1a83936ad4ec28365f0e5a4a8d22e","tabbable":null,"tooltip":null,"value":" 1275/1275 [10:16&lt;00:00,  2.02it/s]"}},"5cdd1a74df07459185312f14ed815e93":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"5f29218b657140debfd4b78bf25ece26":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_79d4ec58e514468dbebfb6a5c62bfb30","placeholder":"​","style":"IPY_MODEL_9bdaa90c179c4b918e148fcc6aac1a50","tabbable":null,"tooltip":null,"value":" 4/4 [00:05&lt;00:00,  1.21s/it]"}},"60fdfef62c3f4ff69acfed408460df81":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"61f04df468924679be51715fc23db8ac":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_60fdfef62c3f4ff69acfed408460df81","placeholder":"​","style":"IPY_MODEL_46e96ca691ed4d19aa4d0af149461b88","tabbable":null,"tooltip":null,"value":" 231/231 [01:33&lt;00:00,  2.78it/s]"}},"62c9514753c44a06ab248711d338f5d1":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"65d2f2d1ce2d47219074a41e04d3281a":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"6961d2f93a244298acebd79015d4eefd":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"6ca313f37a4c47a9b171cb7f5cc5df59":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_65d2f2d1ce2d47219074a41e04d3281a","placeholder":"​","style":"IPY_MODEL_bd7ff620feae4fadbbf2e9c8d8fb57c3","tabbable":null,"tooltip":null,"value":" 2/2 [00:02&lt;00:00,  1.28s/it]"}},"6d08142bc5a34891a24a4f19ea292e31":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_18855ebb29e94d48b4007636b292df19","max":3,"min":0,"orientation":"horizontal","style":"IPY_MODEL_1e067bb83bdc45a1939e3a1204f679c3","tabbable":null,"tooltip":null,"value":3}},"6f3b0738f674488095e033869f3d48c0":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_2e14190a43b14d58823959f231ff77fa","placeholder":"​","style":"IPY_MODEL_f556651f03d841c59d5ede541d841860","tabbable":null,"tooltip":null,"value":" 211/211 [00:00&lt;00:00, 255.12it/s, Materializing param=norm.weight]"}},"6f4651df25a84c73ac6f1a3523d61594":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"73e761efbe064615899bd12fc82dda05":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"7742bc7fb832404dbbda8d9b2b359b4d":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_14d8f05e224444f786b73635a95ee753","IPY_MODEL_3759fe8b6a30404e8095284f7e6f7b3d","IPY_MODEL_61f04df468924679be51715fc23db8ac"],"layout":"IPY_MODEL_1fe60737ef7e401aa0846d3c83117d5d","tabbable":null,"tooltip":null}},"7780e35e028c4fe380e5eaa5542423bf":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_e023925d2d59414dbc2680de2e042aa3","max":4,"min":0,"orientation":"horizontal","style":"IPY_MODEL_586d366cfa4c4defab5505f1228631b7","tabbable":null,"tooltip":null,"value":4}},"79d4ec58e514468dbebfb6a5c62bfb30":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7a8a00b39b5d422181b60ce8f0a67dd3":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"7dd6b705d9404bb88c3b2c2bafd5eab8":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_92518bea84354ade9618151442e61e69","IPY_MODEL_6d08142bc5a34891a24a4f19ea292e31","IPY_MODEL_248a2b99296c4fd9abbff06e03d1e8b5"],"layout":"IPY_MODEL_ea4e95b0664f4d60a0fa6e512734d59b","tabbable":null,"tooltip":null}},"835b5fc5b9c3479a83347b2d791a70a7":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_6961d2f93a244298acebd79015d4eefd","max":2,"min":0,"orientation":"horizontal","style":"IPY_MODEL_13b0c6722a2f4c31b8bb5ca7efc4a89c","tabbable":null,"tooltip":null,"value":2}},"86cb133838f440dbb4eecba55832ec23":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_b7b8f92361c64ace8df7bf8626a94f6e","placeholder":"​","style":"IPY_MODEL_df43d5062bde4eb18de75d2617829d27","tabbable":null,"tooltip":null,"value":" 2/2 [06:25&lt;00:00, 203.85s/it]"}},"900c6aeb06e24176a4f178c38070f9e9":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_10716f3dc9ce41708a3ac09b6f7e493e","placeholder":"​","style":"IPY_MODEL_9bf4104394414473bf038ee0627da122","tabbable":null,"tooltip":null,"value":" 7/7 [00:15&lt;00:00,  1.96s/it]"}},"921065eb6862432db988259c9fa0336c":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"92371377dcce4b7abe88df88c5a73445":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"92518bea84354ade9618151442e61e69":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_bfbfceaefe894542b31e9529d84eef12","placeholder":"​","style":"IPY_MODEL_3e5a3d792e8b423cbb6c260fcf9a8bde","tabbable":null,"tooltip":null,"value":"MASt3R SPoC: 100%"}},"92b9006d7b0f462db51f1377f5ba8753":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"99a796d632984b45aa12a38991cae7a3":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_cc68025ce7734f6c8807c8ad76c74db4","IPY_MODEL_13620545e86e46ddb26595e913bcbbe6","IPY_MODEL_86cb133838f440dbb4eecba55832ec23"],"layout":"IPY_MODEL_f49b8d01296849febff5835a22a9541d","tabbable":null,"tooltip":null}},"9bdaa90c179c4b918e148fcc6aac1a50":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"9bf4104394414473bf038ee0627da122":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"9f71faa8331348c0a6ff4991de4737a4":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"a883af6edd854d2984a81554c76e4d40":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"aab5281875e845c9ad888b15e376991c":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b0ba01649d104812adec481a4a00cd03":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b506d7073282432dbd2cf8cf19734be7":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_dcdc988b29f6446ebd596c96f9a0ec61","placeholder":"​","style":"IPY_MODEL_921065eb6862432db988259c9fa0336c","tabbable":null,"tooltip":null,"value":"DINOv3: 100%"}},"b7b11772d4df4021aac6358039f08dcb":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b7b8f92361c64ace8df7bf8626a94f6e":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b852b678264f4335bdfe7959bb47004d":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"bd7ff620feae4fadbbf2e9c8d8fb57c3":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"bf15a0dabf144a18a8861cddcedcb01c":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"bf576311ac494369b4d88e548f794e3f":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"bfbfceaefe894542b31e9529d84eef12":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c35a1e5ce22e46199ce00ca73976271c":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"c74e7c5f22624209810c96d52d066d3d":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"cc68025ce7734f6c8807c8ad76c74db4":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_1068c4b182744696bd3150700f86884b","placeholder":"​","style":"IPY_MODEL_c74e7c5f22624209810c96d52d066d3d","tabbable":null,"tooltip":null,"value":"Reconstructing: 100%"}},"cf6383cdfcac4e23850f72ea8d36c023":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_b506d7073282432dbd2cf8cf19734be7","IPY_MODEL_7780e35e028c4fe380e5eaa5542423bf","IPY_MODEL_5f29218b657140debfd4b78bf25ece26"],"layout":"IPY_MODEL_92371377dcce4b7abe88df88c5a73445","tabbable":null,"tooltip":null}},"d0935f18705c4824a438007e8ec59c23":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d1a8aff5ec404fea86f0e3ad14de5b17":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_b0ba01649d104812adec481a4a00cd03","placeholder":"​","style":"IPY_MODEL_5551043599dd4d19a666d9be45aea752","tabbable":null,"tooltip":null,"value":"Loading weights: 100%"}},"dcc63bae42e14899a0ac1dc3213f4da7":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"dcdc988b29f6446ebd596c96f9a0ec61":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"df43d5062bde4eb18de75d2617829d27":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"e023925d2d59414dbc2680de2e042aa3":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"e22744f7c33349529e7f359a4cb9b11a":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"e804073eb58543d7a060fc7da8041f88":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_d1a8aff5ec404fea86f0e3ad14de5b17","IPY_MODEL_f050a36a54234cc6ba7d6cb3e7a8b36a","IPY_MODEL_6f3b0738f674488095e033869f3d48c0"],"layout":"IPY_MODEL_5cdd1a74df07459185312f14ed815e93","tabbable":null,"tooltip":null}},"ea4e95b0664f4d60a0fa6e512734d59b":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f050a36a54234cc6ba7d6cb3e7a8b36a":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_d0935f18705c4824a438007e8ec59c23","max":211,"min":0,"orientation":"horizontal","style":"IPY_MODEL_7a8a00b39b5d422181b60ce8f0a67dd3","tabbable":null,"tooltip":null,"value":211}},"f49b8d01296849febff5835a22a9541d":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f51fcbc2c4824f3baeef34fde1e04f85":{"model_module":"@jupyter-widgets/base","model_module_version":"2.0.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"2.0.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border_bottom":null,"border_left":null,"border_right":null,"border_top":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f556651f03d841c59d5ede541d841860":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"f714d6b75588480dbd420a9d1fb91f9e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"HTMLView","description":"","description_allow_html":false,"layout":"IPY_MODEL_b7b11772d4df4021aac6358039f08dcb","placeholder":"​","style":"IPY_MODEL_444aa173c5bb4152b22ce725caf25c5e","tabbable":null,"tooltip":null,"value":"Geometric: 100%"}},"f8a1a83936ad4ec28365f0e5a4a8d22e":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}},"f930f3cb70874fd683ec6ee08dec29fa":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"2.0.0","_view_name":"ProgressView","bar_style":"success","description":"","description_allow_html":false,"layout":"IPY_MODEL_e22744f7c33349529e7f359a4cb9b11a","max":1275,"min":0,"orientation":"horizontal","style":"IPY_MODEL_73e761efbe064615899bd12fc82dda05","tabbable":null,"tooltip":null,"value":1275}},"fd8cedbcffd14f77b8a35b31f0bc0201":{"model_module":"@jupyter-widgets/controls","model_module_version":"2.0.0","model_name":"HTMLStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"2.0.0","_model_name":"HTMLStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"2.0.0","_view_name":"StyleView","background":null,"description_width":"","font_size":null,"text_color":null}}},"version_major":2,"version_minor":0}}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":6.822164,"end_time":"2026-04-16T03:02:00.397661+00:00","exception":false,"start_time":"2026-04-16T03:01:53.575497+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:52:52.609580Z","iopub.execute_input":"2026-04-16T16:52:52.610190Z","iopub.status.idle":"2026-04-16T16:52:57.858521Z","shell.execute_reply.started":"2026-04-16T16:52:52.610156Z","shell.execute_reply":"2026-04-16T16:52:57.857871Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 1 — Pre-flight (run this first, before anything else)\n# ============================================================\nimport os, sys, shutil, gc, pickle, warnings\nfrom pathlib import Path\nimport glob as _glob\n\nwarnings.filterwarnings(\"ignore\", category=FutureWarning)\nwarnings.filterwarnings(\"ignore\", message=\".*trimesh.*\")\nwarnings.filterwarnings(\"ignore\", message=\".*RoPE2D.*\")\n\n# ── Install roma offline ──────────────────────────────────────────────────────\n_roma_wheels = _glob.glob(\"/kaggle/input/datasets/solomontneo/model7/roma*.whl\")\nif _roma_wheels:\n    os.system(f\"pip install {_roma_wheels[0]} --no-index --no-deps --force-reinstall -q\")\n    print(\"✅ roma installed\")\nelse:\n    os.system(\"pip install roma -q\")\n    print(\"✅ roma installed (from PyPI)\")\n\n# ── Copy weights to PyTorch hub cache (writable) ─────────────────────────────\nHUB_CACHE = Path(\"/root/.cache/torch/hub/checkpoints\")\nHUB_CACHE.mkdir(parents=True, exist_ok=True)\n\n# SuperPoint weights\n_SP_SRC = Path(\"/kaggle/input/datasets/solomontneo/model8/superpoint_v1.pth\")\n_SP_DST = HUB_CACHE / \"superpoint_v1.pth\"\nif not _SP_DST.exists():\n    if _SP_SRC.exists():\n        shutil.copy2(_SP_SRC, _SP_DST)\n        print(f\"✅ SuperPoint weights copied to hub cache\")\n    else:\n        _candidates = list(Path(\"/kaggle/input\").rglob(\"superpoint_v1.pth\"))\n        if _candidates:\n            shutil.copy2(_candidates[0], _SP_DST)\n            print(f\"✅ SuperPoint weights cached from {_candidates[0]}\")\n        else:\n            raise FileNotFoundError(\"superpoint_v1.pth not found in any dataset\")\nelse:\n    print(f\"✅ SuperPoint weights already cached\")\n\n# LightGlue weights — CRITICAL: Exact filename LightGlue's source code expects\n_LG_SRC = Path(\"/kaggle/input/datasets/solomontneo/model9/superpoint_lightglue.pth\")\n_LG_DST = HUB_CACHE / \"superpoint_lightglue_v0-1_arxiv.pth\"  # ← EXACT filename from LightGlue source\n\n# Remove any wrong versions first\nfor f in HUB_CACHE.glob(\"superpoint_lightglue*.pth\"):\n    if f.name != \"superpoint_lightglue_v0-1_arxiv.pth\":\n        f.unlink()\n        print(f\"🗑️  Removed conflicting file: {f.name}\")\n\nif not _LG_DST.exists():\n    if _LG_SRC.exists():\n        shutil.copy2(_LG_SRC, _LG_DST)\n        print(f\"✅ LightGlue weights copied → { _LG_DST.name}\")\n    else:\n        _candidates = list(Path(\"/kaggle/input\").rglob(\"superpoint_lightglue*.pth\"))\n        if _candidates:\n            shutil.copy2(_candidates[0], _LG_DST)\n            print(f\"✅ LightGlue weights cached from {_candidates[0]}\")\n        else:\n            raise FileNotFoundError(\"superpoint_lightglue.pth not found in any dataset\")\nelse:\n    print(f\"✅ LightGlue weights ready: {_LG_DST.name}\")\n\n# Verify both files exist with correct names\nprint(f\"\\nHub cache contents:\")\nfor f in sorted(HUB_CACHE.glob(\"*.pth\")):\n    print(f\"  📁 {f.name} ({f.stat().st_size/1e6:.1f}MB)\")\n\nprint(\"\\n✅ Pre-flight complete — safe to import LightGlue now\")","metadata":{"papermill":{"duration":4.804831,"end_time":"2026-04-16T03:02:05.211391+00:00","exception":false,"start_time":"2026-04-16T03:02:00.406560+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:52:57.859851Z","iopub.execute_input":"2026-04-16T16:52:57.860212Z","iopub.status.idle":"2026-04-16T16:53:02.090229Z","shell.execute_reply.started":"2026-04-16T16:52:57.860188Z","shell.execute_reply":"2026-04-16T16:53:02.089496Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# Image Matching Challenge 2025 – COMPLETE SOLUTION\n# Strategy: DINOv3 + MASt3R + DUSt3R Global Alignment\n# NO PyColMap required.\n# ============================================================\n\n# ============================================================\n# SECTION 0: IMPORTS & CONFIG\n# ============================================================\n# ============================================================\n# CELL 2 — Imports\n# ============================================================\nimport cv2\nimport torch\nimport numpy as np\nimport pandas as pd\n\nfrom PIL import Image\nfrom tqdm.auto import tqdm\nfrom scipy.spatial.distance import cdist\nfrom sklearn.metrics.pairwise import cosine_similarity\nfrom sklearn.cluster import DBSCAN\n\nimport networkx as nx\nfrom community import community_louvain\nfrom transformers import AutoImageProcessor, AutoModel\n\nLIGHTGLUE_ROOT = Path(\"/kaggle/input/datasets/solomontneo/models/LightGlue-offline/LightGlue-main\")\nMAST3R_ROOT    = Path(\"/kaggle/input/datasets/solomontneo/model5/mast3r-offline\")\n\nfor _p in [MAST3R_ROOT, MAST3R_ROOT / \"dust3r\", LIGHTGLUE_ROOT]:\n    if str(_p) not in sys.path:\n        sys.path.insert(0, str(_p))\n\nimport mast3r.utils.path_to_dust3r\nimport dust3r.utils.path_to_croco\nfrom mast3r.model import AsymmetricMASt3R\nfrom dust3r.utils.image import load_images\nfrom dust3r.inference import inference\nfrom dust3r.cloud_opt import global_aligner, GlobalAlignerMode\n\n# LightGlue — weights already in hub cache, no download will occur\nfrom lightglue import LightGlue, SuperPoint\nfrom lightglue.utils import load_image, rbd\n\nprint(\"✅ All imports OK\")\n","metadata":{"papermill":{"duration":41.305053,"end_time":"2026-04-16T03:02:46.526026+00:00","exception":false,"start_time":"2026-04-16T03:02:05.220973+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:02.091305Z","iopub.execute_input":"2026-04-16T16:53:02.091688Z","iopub.status.idle":"2026-04-16T16:53:37.421768Z","shell.execute_reply.started":"2026-04-16T16:53:02.091640Z","shell.execute_reply":"2026-04-16T16:53:37.420996Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# SECTION 1: PATHS  –– adjust to your Kaggle dataset paths\n# ============================================================\n# ============================================================\n# CELL 3 — Paths & Config (Kaggle-optimised)\n# ============================================================\nimport torch\nimport torch.backends.cudnn as cudnn\n\nif Path(\"/kaggle/input/competitions/image-matching-challenge-2025\").exists():\n    DATA_ROOT = Path(\"/kaggle/input/competitions/image-matching-challenge-2025\")\nelse:\n    DATA_ROOT = Path(\"/kaggle/input/image-matching-challenge-2025\")\n\nTEST_DIR = DATA_ROOT / \"train\" \nWORK_DIR = Path(\"/kaggle/working\")\nWORK_DIR.mkdir(parents=True, exist_ok=True)\n\nDINO_MODEL_DIR = Path(\"/kaggle/input/datasets/solomontneo/models/dinov3-offline/kaggle/working/dinov3-model\")\n\nCACHE_DIR        = WORK_DIR / \"cache\"\nSTEP1_DINO_DIR   = CACHE_DIR / \"step1_dino\"\nSTEP1_MAST3R_DIR = CACHE_DIR / \"step1_mast3r\"\nSTEP2_DIR        = CACHE_DIR / \"step2\"\nSTEP3_DIR        = CACHE_DIR / \"step3\"\nSTEP4_DIR        = CACHE_DIR / \"step4_poses\"\nSUBMISSION_PATH  = WORK_DIR / \"submission.csv\"\n\nfor _d in [CACHE_DIR, STEP1_DINO_DIR, STEP1_MAST3R_DIR, STEP2_DIR, STEP3_DIR, STEP4_DIR]:\n    _d.mkdir(parents=True, exist_ok=True)\n\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nN_GPU  = torch.cuda.device_count() if torch.cuda.is_available() else 0\n\n# GPU speed settings\nif torch.cuda.is_available():\n    cudnn.benchmark = True\n    cudnn.deterministic = False\n    torch.backends.cuda.matmul.allow_tf32 = True\n    torch.backends.cudnn.allow_tf32 = True\n\n# Conservative defaults first\nDINO_DTYPE = torch.float16 if DEVICE == \"cuda\" else torch.float32\nBATCH_SIZE_DINO   = 8\nBATCH_SIZE_MAST3R = 4\n\n# Accelerator-aware tuning\nif DEVICE == \"cuda\":\n    gpu_names = [torch.cuda.get_device_name(i) for i in range(N_GPU)]\n    print(f\"GPUs detected ({N_GPU}): {gpu_names}\")\n\n    if N_GPU >= 2:\n        # T4 x2 or similar: bigger throughput, but still keep MASt3R moderate\n        BATCH_SIZE_DINO   = 16\n        BATCH_SIZE_MAST3R = 8\n        DINO_WORKERS      = 2\n        USE_DP_FOR_DINO   = True\n        USE_DP_FOR_MAST3R = False   # safer: DUSt3R / MASt3R internals are not always DP-friendly\n    else:\n        gpu0 = gpu_names[0]\n        if \"P100\" in gpu0:\n            BATCH_SIZE_DINO   = 12\n            BATCH_SIZE_MAST3R = 6\n        elif \"T4\" in gpu0:\n            BATCH_SIZE_DINO   = 12\n            BATCH_SIZE_MAST3R = 6\n        else:\n            BATCH_SIZE_DINO   = 10\n            BATCH_SIZE_MAST3R = 4\n        DINO_WORKERS      = 1\n        USE_DP_FOR_DINO   = False\n        USE_DP_FOR_MAST3R = False\nelse:\n    DINO_WORKERS      = 0\n    USE_DP_FOR_DINO   = False\n    USE_DP_FOR_MAST3R = False\n\nK_EASY   = 20\nK_MEDIUM = 30\nK_HARD   = 50\n\nDBSCAN_EPS         = 0.30\nDBSCAN_MIN_SAMPLES = 2\nMIN_INLIERS        = 12\n\n# Keep this moderate — large scenes explode pair count\nMAX_IMAGES_PER_SCENE = 40\nNITER_GLOBAL         = 200\nLR_GLOBAL            = 0.07\n\n# For large clusters, avoid full graph\nFULLY_CONNECTED_LIMIT = 12\nPAIR_SKIP_LIST = [1, 2]\n\nNAN_R = \"0.997491479;-0.001187749;-0.070777766;-0.000589166;0.999685347;-0.025079396;0.070785277;0.025058180;0.997176886\"\nNAN_T = \"0.119209088;0.007134018;0.021655859\"\n\nprint(f\"✅ Config done — device={DEVICE}, n_gpu={N_GPU}\")\nprint(f\"✅ BATCH_SIZE_DINO={BATCH_SIZE_DINO}, BATCH_SIZE_MAST3R={BATCH_SIZE_MAST3R}\")\nprint(f\"✅ MAX_IMAGES_PER_SCENE={MAX_IMAGES_PER_SCENE}, NITER_GLOBAL={NITER_GLOBAL}\")","metadata":{"papermill":{"duration":0.068071,"end_time":"2026-04-16T03:02:46.602563+00:00","exception":false,"start_time":"2026-04-16T03:02:46.534492+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.422728Z","iopub.execute_input":"2026-04-16T16:53:37.423356Z","iopub.status.idle":"2026-04-16T16:53:37.483501Z","shell.execute_reply.started":"2026-04-16T16:53:37.423324Z","shell.execute_reply":"2026-04-16T16:53:37.482806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 4 — Utilities\n# ============================================================\ndef safe_empty_cache():\n    gc.collect()\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n\ndef format_R(R):\n    return \";\".join(f\"{x:.9f}\" for x in np.asarray(R, dtype=float).reshape(-1))\n\ndef format_t(t):\n    return \";\".join(f\"{x:.9f}\" for x in np.asarray(t, dtype=float).reshape(3))\n\ndef list_test_datasets(test_dir):\n    out = {}\n    for d in sorted(Path(test_dir).iterdir()):\n        if d.is_dir():\n            out[d.name] = sorted(d.glob(\"*.png\"))\n    return out\n\ndef normalize_labels(labels):\n    uniq  = sorted(x for x in set(labels.tolist()) if x != -1)\n    remap = {old: new for new, old in enumerate(uniq)}\n    return np.array([remap[x] if x != -1 else -1 for x in labels], dtype=int)\n\ndef load_feature_pickles(base_dir: Path):\n    feats = {}\n    for pkl in sorted(Path(base_dir).rglob(\"*.pkl\")):\n        try:\n            data = torch.load(pkl, weights_only=False, map_location=\"cpu\")\n            feats[pkl.stem] = data\n            print(f\"  ✅ {pkl.stem}: {len(data['image_names'])} images\")\n        except Exception as e:\n            print(f\"  ❌ {pkl}: {e}\")\n    return feats\n","metadata":{"papermill":{"duration":0.019819,"end_time":"2026-04-16T03:02:46.630605+00:00","exception":false,"start_time":"2026-04-16T03:02:46.610786+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.485299Z","iopub.execute_input":"2026-04-16T16:53:37.485594Z","iopub.status.idle":"2026-04-16T16:53:37.493464Z","shell.execute_reply.started":"2026-04-16T16:53:37.485536Z","shell.execute_reply":"2026-04-16T16:53:37.492756Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 5 — DINOv3 Feature Extraction\n# ============================================================\nclass DINOv3FeatureExtractor:\n    def __init__(self, model_dir=DINO_MODEL_DIR, device=None):\n        self.device = device or DEVICE\n        self.processor = AutoImageProcessor.from_pretrained(model_dir, local_files_only=True)\n        self.model = AutoModel.from_pretrained(\n            model_dir, torch_dtype=DINO_DTYPE, local_files_only=True\n        ).to(self.device).eval()\n        self.embed_dim = self.model.config.hidden_size\n        print(f\"DINOv3 loaded on {self.device}. dim={self.embed_dim}\")\n\n    def extract_batch(self, image_paths, batch_size=BATCH_SIZE_DINO):\n        image_names, all_features = [], []\n        for i in tqdm(range(0, len(image_paths), batch_size), desc=\"DINOv3\"):\n            batch = image_paths[i:i+batch_size]\n            imgs, valid = [], []\n            for p in batch:\n                try:\n                    imgs.append(Image.open(p).convert(\"RGB\")); valid.append(p)\n                except Exception as e:\n                    print(f\"Skip {p}: {e}\")\n            if not imgs:\n                continue\n            inputs = {k: v.to(self.device) for k, v in\n                      self.processor(images=imgs, return_tensors=\"pt\").items()}\n            with torch.inference_mode():\n                out = self.model(**inputs)\n            cls = out.pooler_output if out.pooler_output is not None else out.last_hidden_state[:, 0]\n            cls = torch.nn.functional.normalize(cls, dim=-1)\n            all_features.append(cls.detach().cpu().numpy())\n            image_names.extend([Path(p).name for p in valid])\n            del imgs, inputs, out, cls; safe_empty_cache()\n        if not all_features:\n            return [], np.array([], dtype=np.float32)\n        return image_names, np.concatenate(all_features, axis=0)\n\n    def extract_dataset(self, dataset_dir):\n        paths = sorted(Path(dataset_dir).glob(\"*.png\"))\n        return self.extract_batch(paths) if paths else ([], np.array([]))\n\n    def release(self):\n        del self.model, self.processor; safe_empty_cache()\n\ndef extract_all_dino_datasets(data_dir, save_dir):\n    save_path = Path(save_dir); extractor = None\n    for d in sorted(Path(data_dir).iterdir()):\n        if not d.is_dir(): continue\n        pkl = save_path / f\"{d.name}.pkl\"\n        if pkl.exists(): continue\n        if extractor is None: extractor = DINOv3FeatureExtractor()\n        names, feats = extractor.extract_dataset(d)\n        torch.save({\"image_names\": names, \"features\": feats}, pkl)\n        safe_empty_cache()\n    if extractor: extractor.release()\n","metadata":{"papermill":{"duration":0.021029,"end_time":"2026-04-16T03:02:46.659582+00:00","exception":false,"start_time":"2026-04-16T03:02:46.638553+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.494662Z","iopub.execute_input":"2026-04-16T16:53:37.495348Z","iopub.status.idle":"2026-04-16T16:53:37.732035Z","shell.execute_reply.started":"2026-04-16T16:53:37.495316Z","shell.execute_reply":"2026-04-16T16:53:37.731278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 6 — MASt3R SPoC Extraction\n# ============================================================\nclass MASt3RSPoCExtractor:\n    def __init__(self, image_size=512, device=None):\n        self.device = device or DEVICE\n        self.image_size = image_size\n        weights_dir = MAST3R_ROOT / \"mast3r\" / \"weights\"\n        self.model = AsymmetricMASt3R.from_pretrained(weights_dir).to(self.device).eval()\n        print(\"MASt3R SPoC extractor loaded.\")\n\n    def _spoc(self, img_dict):\n        t = img_dict[\"img\"].to(self.device)\n        if t.dim() == 3: t = t.unsqueeze(0)\n        with torch.inference_mode():\n            enc, _, _ = self.model._encode_image(t, img_dict[\"true_shape\"])\n            spoc = torch.nn.functional.normalize(enc.mean(dim=1), dim=-1)\n        return spoc.squeeze(0).detach().cpu().numpy()\n\n    def extract_batch(self, image_paths, batch_size=BATCH_SIZE_MAST3R):\n        names, feats = [], []\n        for i in tqdm(range(0, len(image_paths), batch_size), desc=\"MASt3R SPoC\"):\n            batch = image_paths[i:i+batch_size]\n            try:\n                imgs = load_images([str(p) for p in batch], size=self.image_size, verbose=False)\n            except:\n                continue\n            for img_dict, path in zip(imgs, batch):\n                try:\n                    feats.append(self._spoc(img_dict)); names.append(Path(path).name)\n                except: pass\n            safe_empty_cache()\n        if not feats: return [], np.array([])\n        return names, np.stack(feats, axis=0)\n\n    def extract_dataset(self, dataset_dir):\n        paths = sorted(Path(dataset_dir).glob(\"*.png\"))\n        return self.extract_batch(paths) if paths else ([], np.array([]))\n\n    def release(self):\n        del self.model; safe_empty_cache()\n\ndef extract_all_mast3r_datasets(data_dir, save_dir):\n    save_path = Path(save_dir); extractor = None\n    for d in sorted(Path(data_dir).iterdir()):\n        if not d.is_dir(): continue\n        pkl = save_path / f\"{d.name}.pkl\"\n        if pkl.exists(): continue\n        if extractor is None: extractor = MASt3RSPoCExtractor()\n        names, feats = extractor.extract_dataset(d)\n        torch.save({\"image_names\": names, \"features\": feats}, pkl)\n        safe_empty_cache()\n    if extractor: extractor.release()\n","metadata":{"papermill":{"duration":0.02067,"end_time":"2026-04-16T03:02:46.688358+00:00","exception":false,"start_time":"2026-04-16T03:02:46.667688+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.733032Z","iopub.execute_input":"2026-04-16T16:53:37.733351Z","iopub.status.idle":"2026-04-16T16:53:37.750836Z","shell.execute_reply.started":"2026-04-16T16:53:37.733322Z","shell.execute_reply":"2026-04-16T16:53:37.750101Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 7 — Retrieval\n# ============================================================\ndef choose_strategy(sim_matrix):\n    upper = sim_matrix[np.triu_indices_from(sim_matrix, k=1)]\n    std   = np.std(upper) if len(upper) > 0 else 0.0\n    if   std < 0.06:  s = \"dinov3_only\"\n    elif std > 0.18:  s = \"full_geometric\"\n    else:             s = \"dinov3+geometric\"\n    print(f\"  std={std:.3f} → strategy={s}\")\n    return s\n\ndef get_top_k_pairs(image_names, features, k=20):\n    n   = len(image_names)\n    sim = cosine_similarity(features)\n    np.fill_diagonal(sim, -1)\n    pairs_set = set()\n    for i in range(n):\n        for j in np.argsort(sim[i])[-k:]:\n            if sim[i, j] > 0:\n                pairs_set.add((min(i, j), max(i, j)))\n    pairs = [(i, j, sim[i, j]) for i, j in pairs_set]\n    pairs.sort(key=lambda x: x[2], reverse=True)\n    np.fill_diagonal(sim, 1.0)\n    return pairs, sim\n\ndef merge_pairs(pair_lists):\n    pair_map = {}\n    for pairs in pair_lists:\n        for i, j, s in pairs:\n            key = (min(i, j), max(i, j))\n            if key not in pair_map or s > pair_map[key]:\n                pair_map[key] = s\n    merged = [(i, j, s) for (i, j), s in pair_map.items()]\n    merged.sort(key=lambda x: x[2], reverse=True)\n    return merged\n\ndef retrieve_all_datasets(dino_features, mast3r_features=None):\n    results = {}\n    for dname, data in dino_features.items():\n        names = data[\"image_names\"]\n        feats = data[\"features\"]\n        n     = len(names)\n        print(f\"\\nRetrieval: {dname} ({n} images)\")\n        sim_mat  = cosine_similarity(feats)\n        strategy = choose_strategy(sim_mat)\n        k = K_EASY if strategy == \"dinov3_only\" else (K_MEDIUM if strategy == \"dinov3+geometric\" else K_HARD)\n        k = min(k, max(1, n - 1))\n        dino_pairs, sim_mat = get_top_k_pairs(names, feats, k=k)\n\n        if mast3r_features and dname in mast3r_features:\n            mdata   = mast3r_features[dname]\n            mfeats  = mdata[\"features\"]\n            mnames  = mdata[\"image_names\"]\n            idx_map = {nm: i for i, nm in enumerate(mnames)}\n            aligned = np.zeros((n, mfeats.shape[1]), dtype=np.float32)\n            valid   = []\n            for i, nm in enumerate(names):\n                if nm in idx_map:\n                    aligned[i] = mfeats[idx_map[nm]]; valid.append(i)\n            if len(valid) >= n * 0.8:\n                mast3r_pairs, _ = get_top_k_pairs(names, aligned, k=min(10, max(1, n - 1)))\n                pairs = merge_pairs([dino_pairs, mast3r_pairs])\n            else:\n                pairs = dino_pairs\n        else:\n            pairs = dino_pairs\n\n        results[dname] = {\n            \"pairs\": pairs, \"sim_matrix\": sim_mat,\n            \"strategy\": strategy, \"image_names\": names, \"features\": feats,\n        }\n    return results\n\n","metadata":{"papermill":{"duration":0.022554,"end_time":"2026-04-16T03:02:46.719163+00:00","exception":false,"start_time":"2026-04-16T03:02:46.696609+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.751916Z","iopub.execute_input":"2026-04-16T16:53:37.752205Z","iopub.status.idle":"2026-04-16T16:53:37.770069Z","shell.execute_reply.started":"2026-04-16T16:53:37.752174Z","shell.execute_reply":"2026-04-16T16:53:37.769399Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 8 — Clustering\n# ============================================================\ndef dbscan_cluster(features, sim_matrix):\n    dist = np.clip(1.0 - sim_matrix, 0, 2)\n    return DBSCAN(eps=DBSCAN_EPS, min_samples=DBSCAN_MIN_SAMPLES,\n                  metric=\"precomputed\").fit(dist).labels_\n\nclass GeometricMatcher:\n    def __init__(self, device=None, max_keypoints=2048):\n        self.device = device or DEVICE\n        self.extractor = SuperPoint(max_num_keypoints=max_keypoints).eval().to(self.device)\n        self.matcher   = LightGlue(features=\"superpoint\").eval().to(self.device)\n        print(\"✅ SuperPoint + LightGlue loaded (offline).\")\n\n    def match_pair(self, path_i, path_j):\n        try:\n            img_i = load_image(str(path_i)).to(self.device)\n            img_j = load_image(str(path_j)).to(self.device)\n            with torch.inference_mode():\n                fi = self.extractor.extract(img_i)\n                fj = self.extractor.extract(img_j)\n                m  = self.matcher({\"image0\": fi, \"image1\": fj})\n                fi, fj, m = rbd(fi), rbd(fj), rbd(m)\n            matches = m[\"matches\"]\n            if matches is None or len(matches) < 8: return 0, 0\n            kpi = fi[\"keypoints\"][matches[:, 0]].cpu().numpy()\n            kpj = fj[\"keypoints\"][matches[:, 1]].cpu().numpy()\n            _, mask = cv2.findFundamentalMat(\n                kpi, kpj, cv2.USAC_MAGSAC,\n                ransacReprojThreshold=1.0, confidence=0.999, maxIters=10000)\n            return (int(mask.sum()) if mask is not None else 0), len(matches)\n        except Exception as e:\n            print(f\"  match_pair failed: {e}\"); return 0, 0\n        finally:\n            safe_empty_cache()\n\n    def match_pairs(self, image_dir, image_names, pairs, max_pairs=None):\n        if max_pairs: pairs = pairs[:max_pairs]\n        results = []\n        for idx, (i, j, sim) in enumerate(tqdm(pairs, desc=\"Geometric\")):\n            ni, nm = self.match_pair(\n                Path(image_dir) / image_names[i],\n                Path(image_dir) / image_names[j])\n            results.append((i, j, ni, nm))\n            if idx % 25 == 0: safe_empty_cache()\n        return results\n\n    def release(self):\n        del self.extractor, self.matcher; safe_empty_cache()\n\ndef build_match_graph(image_names, match_results):\n    G = nx.Graph()\n    for i, nm in enumerate(image_names): G.add_node(i, image=nm)\n    for i, j, ni, nm in match_results:\n        if ni >= MIN_INLIERS: G.add_edge(i, j, weight=ni)\n    return G\n\ndef detect_communities(G, image_names):\n    n      = len(image_names)\n    labels = np.full(n, -1, dtype=int)\n    connected = [v for v in G.nodes() if G.degree(v) > 0]\n    if not connected: return labels\n    G2       = G.subgraph(connected).copy()\n    scene_id = 0\n    for comp in nx.connected_components(G2):\n        nodes = list(comp)\n        if len(nodes) < 3: continue\n        sub = G2.subgraph(nodes).copy()\n        if len(nodes) > 10:\n            partition = community_louvain.best_partition(sub, weight=\"weight\", resolution=1.0)\n            comms = {}\n            for v, c in partition.items(): comms.setdefault(c, []).append(v)\n            for cnodes in comms.values():\n                if len(cnodes) >= 3:\n                    for v in cnodes: labels[v] = scene_id\n                    scene_id += 1\n        else:\n            for v in nodes: labels[v] = scene_id\n            scene_id += 1\n    return labels\n\ndef cluster_dataset(dataset_name, retrieval_result, data_dir):\n    image_names = retrieval_result[\"image_names\"]\n    features = retrieval_result[\"features\"]\n    sim_matrix = retrieval_result[\"sim_matrix\"]\n    pairs = retrieval_result[\"pairs\"]\n    strategy = retrieval_result[\"strategy\"]\n\n    print(f\"\\nClustering: {dataset_name} strategy={strategy}\")\n\n    if strategy == \"dinov3_only\":\n        labels = dbscan_cluster(features, sim_matrix)\n    else:\n        max_pairs = 1000 if strategy == \"dinov3+geometric\" else 3000\n        matcher = GeometricMatcher()\n        match_results = matcher.match_pairs(data_dir, image_names, pairs, max_pairs=max_pairs)\n        graph = build_match_graph(image_names, match_results)\n        labels = detect_communities(graph, image_names)\n        matcher.release()\n\n    return normalize_labels(labels)\n","metadata":{"papermill":{"duration":0.025239,"end_time":"2026-04-16T03:02:46.752365+00:00","exception":false,"start_time":"2026-04-16T03:02:46.727126+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.771066Z","iopub.execute_input":"2026-04-16T16:53:37.771308Z","iopub.status.idle":"2026-04-16T16:53:37.791431Z","shell.execute_reply.started":"2026-04-16T16:53:37.771280Z","shell.execute_reply":"2026-04-16T16:53:37.790736Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 9 — Pose Estimation via DUSt3R (faster + Kaggle-safe)\n# ============================================================\ndef load_mast3r_model_once():\n    if not hasattr(load_mast3r_model_once, \"_model\"):\n        weights_dir = MAST3R_ROOT / \"mast3r\" / \"weights\"\n        model = AsymmetricMASt3R.from_pretrained(weights_dir)\n\n        # Keep MASt3R on single GPU for stability\n        model = model.to(DEVICE).eval()\n\n        load_mast3r_model_once._model = model\n        print(\"✅ MASt3R inference model loaded.\")\n    return load_mast3r_model_once._model\n\n\ndef build_scene_pairs(n):\n    if n <= FULLY_CONNECTED_LIMIT:\n        return [(i, j) for i in range(n) for j in range(i + 1, n)]\n\n    raw = []\n    for i in range(n):\n        for skip in PAIR_SKIP_LIST:\n            j = i + skip\n            if j < n:\n                raw.append((i, j))\n\n    # add a few long-range links for connectivity\n    step = max(3, n // 5)\n    for i in range(0, n, step):\n        j = min(n - 1, i + step)\n        if i < j:\n            raw.append((i, j))\n\n    pairs = sorted(list({(min(a, b), max(a, b)) for a, b in raw}))\n    return pairs\n\n\ndef reconstruct_scene_with_dust3r(image_paths: list) -> dict:\n    n = len(image_paths)\n    if n < 2:\n        return {}\n\n    if n > MAX_IMAGES_PER_SCENE:\n        print(f\"  Capping scene from {n} to {MAX_IMAGES_PER_SCENE} images.\")\n        image_paths = image_paths[:MAX_IMAGES_PER_SCENE]\n        n = MAX_IMAGES_PER_SCENE\n\n    model = load_mast3r_model_once()\n    imgs = load_images([str(p) for p in image_paths], size=512, verbose=False)\n\n    pairs = build_scene_pairs(n)\n    pair_dicts = [(imgs[i], imgs[j]) for i, j in pairs]\n\n    print(f\"  MASt3R inference: {len(pair_dicts)} pairs, {n} images ...\")\n\n    # IMPORTANT:\n    # use no_grad, not inference_mode, because global_aligner needs autograd later\n    with torch.no_grad():\n        output = inference(\n            pair_dicts,\n            model,\n            DEVICE,\n            batch_size=BATCH_SIZE_MAST3R,\n            verbose=False\n        )\n\n    print(f\"  Global alignment ({NITER_GLOBAL} iters) ...\")\n    scene = global_aligner(\n        output,\n        device=DEVICE,\n        mode=GlobalAlignerMode.PointCloudOptimizer\n    )\n\n    loss = scene.compute_global_alignment(\n        init=\"mst\",\n        niter=NITER_GLOBAL,\n        schedule=\"cosine\",\n        lr=LR_GLOBAL\n    )\n    print(f\"  Alignment loss: {float(loss):.4f}\")\n\n    poses_c2w = scene.get_im_poses()\n    pose_dict = {}\n\n    for img_path, c2w in zip(image_paths, poses_c2w):\n        try:\n            c2w_np = c2w.detach().cpu().numpy() if hasattr(c2w, \"detach\") else np.array(c2w)\n            R_c2w = c2w_np[:3, :3]\n            t_c2w = c2w_np[:3, 3]\n\n            # competition wants world-to-camera\n            R_w2c = R_c2w.T\n            t_w2c = -R_w2c @ t_c2w\n\n            pose_dict[Path(img_path).name] = {\n                \"R\": R_w2c,\n                \"t\": t_w2c\n            }\n        except Exception as e:\n            print(f\"  Pose extraction failed for {img_path}: {e}\")\n\n    del output, scene, poses_c2w, imgs, pair_dicts\n    safe_empty_cache()\n    return pose_dict\n\n\ndef run_all_reconstruction(clustering_results, test_dir: Path):\n    all_poses = {}\n\n    for dname, result in tqdm(clustering_results.items(), desc=\"Reconstructing\"):\n        all_poses[dname] = {}\n        scene_labels = result[\"scene_labels\"]\n        image_names  = result[\"image_names\"]\n        dataset_dir  = test_dir / dname\n        unique_scenes = sorted(set(scene_labels) - {-1})\n\n        print(f\"\\n=== {dname} | {len(unique_scenes)} clusters ===\")\n\n        for sid in unique_scenes:\n            sname = f\"scene_{sid}\"\n            img_paths = [\n                dataset_dir / image_names[i]\n                for i, l in enumerate(scene_labels)\n                if l == sid\n            ]\n            img_paths = [p for p in img_paths if p.exists()]\n\n            print(f\"  {sname}: {len(img_paths)} images\")\n\n            if len(img_paths) < 2:\n                all_poses[dname][sname] = {}\n                continue\n\n            try:\n                poses = reconstruct_scene_with_dust3r(img_paths)\n                all_poses[dname][sname] = poses\n                print(f\"  ✅ {len(poses)}/{len(img_paths)} posed\")\n            except Exception as e:\n                print(f\"  ❌ {sname} failed: {e}\")\n                all_poses[dname][sname] = {}\n\n            safe_empty_cache()\n\n    return all_poses","metadata":{"papermill":{"duration":0.025839,"end_time":"2026-04-16T03:02:46.786825+00:00","exception":false,"start_time":"2026-04-16T03:02:46.760986+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.792568Z","iopub.execute_input":"2026-04-16T16:53:37.792873Z","iopub.status.idle":"2026-04-16T16:53:37.813185Z","shell.execute_reply.started":"2026-04-16T16:53:37.792842Z","shell.execute_reply":"2026-04-16T16:53:37.812563Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ============================================================\n# CELL 10 — Submission helpers\n# ============================================================\ndef build_base_from_test_root(test_dir):\n    rows = []\n    datasets = list_test_datasets(test_dir)\n    for dataset_name, image_paths in datasets.items():\n        for path in image_paths:\n            rows.append({\n                \"dataset\": dataset_name,\n                \"image\": path.name,\n            })\n\n    base = pd.DataFrame(rows)\n    base[\"image_id\"] = base[\"dataset\"] + base[\"image\"]\n    return base\n\n\ndef build_prediction_tables(clustering_results, all_poses):\n    predictions_by_dataset = {}\n\n    for dataset_name, cluster_result in clustering_results.items():\n        scene_labels = np.asarray(cluster_result[\"scene_labels\"])\n        image_names = list(cluster_result[\"image_names\"])\n\n        unique_labels = sorted(x for x in set(scene_labels.tolist()) if x != -1)\n        label_remap = {old: new for new, old in enumerate(unique_labels)}\n\n        scene_by_image = {}\n        for image_name, label in zip(image_names, scene_labels):\n            if int(label) == -1:\n                scene_by_image[image_name] = \"outliers\"\n            else:\n                scene_by_image[image_name] = f\"cluster{label_remap[int(label)]}\"\n\n        pose_by_image = {}\n        if dataset_name in all_poses:\n            for scene_name, scene_payload in all_poses[dataset_name].items():\n                if not isinstance(scene_payload, dict):\n                    continue\n                for image_name, pose in scene_payload.items():\n                    if not isinstance(pose, dict):\n                        continue\n                    R = pose.get(\"R\")\n                    t = pose.get(\"t\")\n                    if R is None or t is None:\n                        continue\n                    pose_by_image[image_name] = {\n                        \"rotation_matrix\": format_R(R),\n                        \"translation_vector\": format_t(t),\n                    }\n\n        rows = []\n        for image_name in image_names:\n            pose = pose_by_image.get(\n                image_name,\n                {\"rotation_matrix\": NAN_R, \"translation_vector\": NAN_T}\n            )\n            rows.append({\n                \"image\": image_name,\n                \"scene\": scene_by_image[image_name],\n                \"rotation_matrix\": pose[\"rotation_matrix\"],\n                \"translation_vector\": pose[\"translation_vector\"],\n            })\n\n        predictions_by_dataset[dataset_name] = pd.DataFrame(rows)\n\n    return predictions_by_dataset\n\n\ndef build_submission_from_predictions(test_dir, predictions_by_dataset, submission_path):\n    base = build_base_from_test_root(test_dir)\n    parts = []\n\n    for dataset_name in sorted(base[\"dataset\"].unique()):\n        base_ds = base[base[\"dataset\"] == dataset_name].copy()\n\n        if dataset_name in predictions_by_dataset:\n            pred_ds = predictions_by_dataset[dataset_name].copy()\n            merged = base_ds.merge(pred_ds, on=\"image\", how=\"left\")\n        else:\n            merged = base_ds.copy()\n            merged[\"scene\"] = \"outliers\"\n            merged[\"rotation_matrix\"] = NAN_R\n            merged[\"translation_vector\"] = NAN_T\n\n        merged[\"scene\"] = merged[\"scene\"].fillna(\"outliers\")\n        merged[\"rotation_matrix\"] = merged[\"rotation_matrix\"].fillna(NAN_R)\n        merged[\"translation_vector\"] = merged[\"translation_vector\"].fillna(NAN_T)\n\n        parts.append(merged)\n\n    submission_df = pd.concat(parts, axis=0, ignore_index=True)\n    submission_df = submission_df[\n        [\"image_id\", \"dataset\", \"scene\", \"image\", \"rotation_matrix\", \"translation_vector\"]\n    ]\n    submission_df.to_csv(submission_path, index=False)\n    return submission_df","metadata":{"papermill":{"duration":0.022174,"end_time":"2026-04-16T03:02:46.817826+00:00","exception":false,"start_time":"2026-04-16T03:02:46.795652+00:00","status":"completed"},"tags":[],"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.813876Z","iopub.execute_input":"2026-04-16T16:53:37.814147Z","iopub.status.idle":"2026-04-16T16:53:37.832677Z","shell.execute_reply.started":"2026-04-16T16:53:37.814101Z","shell.execute_reply":"2026-04-16T16:53:37.832039Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# CELL 11 Run Everything\n\ndatasets = list_test_datasets(TEST_DIR)\nprint(f\"Test datasets found: {len(list_test_datasets(TEST_DIR))}\")\n\nprint(\"STEP 1 Feature extraction\")\nextract_all_dino_datasets(TEST_DIR, STEP1_DINO_DIR)\nextract_all_mast3r_datasets(TEST_DIR, STEP1_MAST3R_DIR)\n\ndino_features = load_feature_pickles(STEP1_DINO_DIR)\nmast3r_features = load_feature_pickles(STEP1_MAST3R_DIR)\n\nprint(\"STEP 2 Retrieval results\")\nretrieval_results = retrieve_all_datasets(dino_features, mast3r_features)\nwith open(STEP2_DIR / \"step2.pkl\", \"wb\") as f:\n    pickle.dump(retrieval_results, f)\n\nprint(\"STEP 3 Clustering results\")\nclustering_results = {}\nfor dataset_name, retrieval_result in retrieval_results.items():\n    labels = cluster_dataset(dataset_name, retrieval_result, TEST_DIR / dataset_name)\n    clustering_results[dataset_name] = {\n        \"scene_labels\": labels,\n        \"strategy\": retrieval_result[\"strategy\"],\n        \"image_names\": retrieval_result[\"image_names\"],\n    }\n    safe_empty_cache()\n\nwith open(STEP3_DIR / \"step3.pkl\", \"wb\") as f:\n    pickle.dump(clustering_results, f)\n\nprint(\"STEP 4 Pose estimation\")\nall_poses = run_all_reconstruction(clustering_results, TEST_DIR)\nwith open(STEP4_DIR / \"poses.pkl\", \"wb\") as f:\n    pickle.dump(all_poses, f)\n\nprint(\"STEP 5 Build submission\")\npredictions_by_dataset = build_prediction_tables(clustering_results, all_poses)\nsubmission_df = build_submission_from_predictions(TEST_DIR, predictions_by_dataset, SUBMISSION_PATH)\n\nprint(f\"Saved: {SUBMISSION_PATH}\")\nprint(submission_df.head(10).to_string())\nprint(f\"rows={len(submission_df)}, datasets={submission_df['dataset'].nunique()}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-16T16:53:37.833423Z","iopub.execute_input":"2026-04-16T16:53:37.833691Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}