diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/TF-PathPred.iml b/.idea/TF-PathPred.iml new file mode 100644 index 0000000..8b8c395 --- /dev/null +++ b/.idea/TF-PathPred.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d1e22ec --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2c43902 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/assets/brand/bootstrap-outline.svg b/assets/brand/bootstrap-outline.svg deleted file mode 100644 index ed1825e..0000000 --- a/assets/brand/bootstrap-outline.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - diff --git a/assets/brand/bootstrap-solid.svg b/assets/brand/bootstrap-solid.svg deleted file mode 100644 index 2f536b6..0000000 --- a/assets/brand/bootstrap-solid.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - diff --git a/beta_experiment.py b/beta_experiment.py new file mode 100644 index 0000000..f59add6 --- /dev/null +++ b/beta_experiment.py @@ -0,0 +1,77 @@ +from train_TF import train_model +from test_TF import test_model +import numpy as np +import argparse +import math +import os + +if __name__ == '__main__': + + # Parser arguments + parser = argparse.ArgumentParser(description= 'Experimment for the ') + parser.add_argument('--root-path', '--root', + default='./', + help='path to folder that contain dataset') + parser.add_argument('--dataset', '--ds', + default='', + help='path to folder that contain dataset') + parser.add_argument('--beta', '--bt', + default='0', + help='path to folder that contain dataset') + args = parser.parse_args() + + if not os.path.isfile('./generated_data/beta_experiment/results.npy'): + table = np.zeros((5,10)) + table[:] = np.NaN + np.save('./generated_data/beta_experiment/results.npy', table) + + + #------------- Training and updating results in the table of experiment ------------- + + table = np.load('./generated_data/beta_experiment/results.npy') + + datasets = ['ETH-univ','ETH-hotel', 'UCY-zara1', 'UCY-zara2', 'UCY-univ3'] + betas = np.array([0,0.3,0.5,1,-1]) + + try: + + test_index = int(args.dataset) + beta_index = int(args.beta) + + training_names = datasets.copy() + test_name = [datasets[test_index]] + del training_names[i] + beta = betas[beta_index] + + print(f"starting training for {test_name}") + train_model(training_names,test_name,args.root_path,beta = beta, epochs = 50) + ade,fde = test_model(test_name,args.root_path) + ade_average = np.mean(ade) + fde_average = np.mean(fde) + table[test_index,beta_index*2] = ade_average + table[test_index,beta_index*2+1] = fde_average + np.save('./generated_data/beta_experiment/results.npy', table) + + except: + + print("training did not start either because not demanded or because of poor parameter handling") + + #--------------------- Printing results in the table of experiment -------------------- + + # This generates latex code for the table to be copied directly + print("Printing current values") + for i in range(5): + s = datasets[i] + for j in range(5): + s += " & " + if math.isnan(table[i,2*j]): + s += "NC" + else: + s += str(table[i,2*j]) + s += "/" + if math.isnan(table[i,2*j+1]): + s += "NC" + else: + s += str(table[i,2*j+1]) + s += " \\\\" + print(s) \ No newline at end of file diff --git a/experiment_beta_cvae.ipynb b/experiment_beta_cvae.ipynb new file mode 100644 index 0000000..b61dedd --- /dev/null +++ b/experiment_beta_cvae.ipynb @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ImportError", + "evalue": "cannot import name 'print_sol' from 'train_TF' (C:\\TesisLicenciatura\\Cloned_repos\\TF-PathPred\\train_TF.py)", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mImportError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtensorflow\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mtf\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mtrain_TF\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtrain_model\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprint_sol\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpyplot\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mImportError\u001b[0m: cannot import name 'print_sol' from 'train_TF' (C:\\TesisLicenciatura\\Cloned_repos\\TF-PathPred\\train_TF.py)" + ] + } + ], + "source": [ + "import tensorflow as tf\n", + "from train_TF import train_model, print_sol\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Train model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "training_names = ['ETH-hotel', 'UCY-zara1', 'UCY-zara2', 'UCY-univ3']\n", + "test_name = ['ETH-univ']\n", + "\n", + "beta = 0\n", + "\n", + "epochs = 50" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "transformer = train_model(training_names, test_name, args.root_path, 3)" + ] + } + ], + "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.8.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/generated_data/beta_experiment/results.npy b/generated_data/beta_experiment/results.npy new file mode 100644 index 0000000..22c133e Binary files /dev/null and b/generated_data/beta_experiment/results.npy differ diff --git a/generated_data/checkpoints/train/ETH-univ/checkpoint b/generated_data/checkpoints/train/ETH-univ/checkpoint index 0c8bfeb..1bdcd5b 100644 --- a/generated_data/checkpoints/train/ETH-univ/checkpoint +++ b/generated_data/checkpoints/train/ETH-univ/checkpoint @@ -1,4 +1,6 @@ -model_checkpoint_path: "ckpt-2" -all_model_checkpoint_paths: "ckpt-2" -all_model_checkpoint_timestamps: 1619570785.2033064 -last_preserved_timestamp: 1619570530.1224155 +model_checkpoint_path: "ckpt-110" +all_model_checkpoint_paths: "ckpt-109" +all_model_checkpoint_paths: "ckpt-110" +all_model_checkpoint_timestamps: 1649347496.2443576 +all_model_checkpoint_timestamps: 1649347569.6077547 +last_preserved_timestamp: 1647457889.9092817 diff --git a/generated_data/checkpoints/train/ETH-univ/ckpt-109.data-00000-of-00001 b/generated_data/checkpoints/train/ETH-univ/ckpt-109.data-00000-of-00001 new file mode 100644 index 0000000..05a5d29 Binary files /dev/null and b/generated_data/checkpoints/train/ETH-univ/ckpt-109.data-00000-of-00001 differ diff --git a/generated_data/checkpoints/train/ETH-univ/ckpt-109.index b/generated_data/checkpoints/train/ETH-univ/ckpt-109.index new file mode 100644 index 0000000..f83c852 Binary files /dev/null and b/generated_data/checkpoints/train/ETH-univ/ckpt-109.index differ diff --git a/generated_data/checkpoints/train/ETH-univ/ckpt-110.data-00000-of-00001 b/generated_data/checkpoints/train/ETH-univ/ckpt-110.data-00000-of-00001 new file mode 100644 index 0000000..42ec088 Binary files /dev/null and b/generated_data/checkpoints/train/ETH-univ/ckpt-110.data-00000-of-00001 differ diff --git a/generated_data/checkpoints/train/ETH-univ/ckpt-110.index b/generated_data/checkpoints/train/ETH-univ/ckpt-110.index new file mode 100644 index 0000000..052dd6d Binary files /dev/null and b/generated_data/checkpoints/train/ETH-univ/ckpt-110.index differ diff --git a/generated_data/checkpoints/train/ETH-univ/ckpt-2.data-00000-of-00001 b/generated_data/checkpoints/train/ETH-univ/ckpt-2.data-00000-of-00001 deleted file mode 100644 index d6775b6..0000000 Binary files a/generated_data/checkpoints/train/ETH-univ/ckpt-2.data-00000-of-00001 and /dev/null differ diff --git a/generated_data/checkpoints/train/ETH-univ/ckpt-2.index b/generated_data/checkpoints/train/ETH-univ/ckpt-2.index deleted file mode 100644 index 3a8006f..0000000 Binary files a/generated_data/checkpoints/train/ETH-univ/ckpt-2.index and /dev/null differ diff --git a/generated_data/checkpoints/train/UCY-univ3/checkpoint b/generated_data/checkpoints/train/UCY-univ3/checkpoint deleted file mode 100644 index 0c8bfeb..0000000 --- a/generated_data/checkpoints/train/UCY-univ3/checkpoint +++ /dev/null @@ -1,4 +0,0 @@ -model_checkpoint_path: "ckpt-2" -all_model_checkpoint_paths: "ckpt-2" -all_model_checkpoint_timestamps: 1619570785.2033064 -last_preserved_timestamp: 1619570530.1224155 diff --git a/generated_data/checkpoints/train/UCY-univ3/ckpt-2.data-00000-of-00001 b/generated_data/checkpoints/train/UCY-univ3/ckpt-2.data-00000-of-00001 deleted file mode 100644 index d6775b6..0000000 Binary files a/generated_data/checkpoints/train/UCY-univ3/ckpt-2.data-00000-of-00001 and /dev/null differ diff --git a/generated_data/checkpoints/train/UCY-univ3/ckpt-2.index b/generated_data/checkpoints/train/UCY-univ3/ckpt-2.index deleted file mode 100644 index 3a8006f..0000000 Binary files a/generated_data/checkpoints/train/UCY-univ3/ckpt-2.index and /dev/null differ diff --git a/generated_data/checkpoints/train/UCY-zara1/checkpoint b/generated_data/checkpoints/train/UCY-zara1/checkpoint deleted file mode 100644 index 8ef2db2..0000000 --- a/generated_data/checkpoints/train/UCY-zara1/checkpoint +++ /dev/null @@ -1,4 +0,0 @@ -model_checkpoint_path: "ckpt-3" -all_model_checkpoint_paths: "ckpt-3" -all_model_checkpoint_timestamps: 1619566030.2539678 -last_preserved_timestamp: 1619565694.3859553 diff --git a/generated_data/checkpoints/train/UCY-zara1/ckpt-3.data-00000-of-00001 b/generated_data/checkpoints/train/UCY-zara1/ckpt-3.data-00000-of-00001 deleted file mode 100644 index e4865b4..0000000 Binary files a/generated_data/checkpoints/train/UCY-zara1/ckpt-3.data-00000-of-00001 and /dev/null differ diff --git a/generated_data/checkpoints/train/UCY-zara1/ckpt-3.index b/generated_data/checkpoints/train/UCY-zara1/ckpt-3.index deleted file mode 100644 index a134e76..0000000 Binary files a/generated_data/checkpoints/train/UCY-zara1/ckpt-3.index and /dev/null differ diff --git a/generated_data/testing_data/ETH-hotel/ade.npy b/generated_data/testing_data/ETH-hotel/ade.npy deleted file mode 100644 index 84d1ab9..0000000 Binary files a/generated_data/testing_data/ETH-hotel/ade.npy and /dev/null differ diff --git a/generated_data/testing_data/ETH-hotel/fde.npy b/generated_data/testing_data/ETH-hotel/fde.npy deleted file mode 100644 index 52f0726..0000000 Binary files a/generated_data/testing_data/ETH-hotel/fde.npy and /dev/null differ diff --git a/generated_data/testing_data/ETH-hotel/inp.npy b/generated_data/testing_data/ETH-hotel/inp.npy deleted file mode 100644 index 26defa6..0000000 Binary files a/generated_data/testing_data/ETH-hotel/inp.npy and /dev/null differ diff --git a/generated_data/testing_data/ETH-hotel/pred.npy b/generated_data/testing_data/ETH-hotel/pred.npy deleted file mode 100644 index 530e20c..0000000 Binary files a/generated_data/testing_data/ETH-hotel/pred.npy and /dev/null differ diff --git a/generated_data/testing_data/ETH-hotel/tar.npy b/generated_data/testing_data/ETH-hotel/tar.npy deleted file mode 100644 index 53a0c15..0000000 Binary files a/generated_data/testing_data/ETH-hotel/tar.npy and /dev/null differ diff --git a/generated_data/testing_data/ETH-univ/ade.npy b/generated_data/testing_data/ETH-univ/ade.npy index 61a2b02..af74a8d 100644 Binary files a/generated_data/testing_data/ETH-univ/ade.npy and b/generated_data/testing_data/ETH-univ/ade.npy differ diff --git a/generated_data/testing_data/ETH-univ/fde.npy b/generated_data/testing_data/ETH-univ/fde.npy index 9e61f45..b05ff5d 100644 Binary files a/generated_data/testing_data/ETH-univ/fde.npy and b/generated_data/testing_data/ETH-univ/fde.npy differ diff --git a/generated_data/testing_data/ETH-univ/inp.npy b/generated_data/testing_data/ETH-univ/inp.npy index d4c4ff4..e7baab3 100644 Binary files a/generated_data/testing_data/ETH-univ/inp.npy and b/generated_data/testing_data/ETH-univ/inp.npy differ diff --git a/generated_data/testing_data/ETH-univ/pred.npy b/generated_data/testing_data/ETH-univ/pred.npy index bf64162..9dc4aec 100644 Binary files a/generated_data/testing_data/ETH-univ/pred.npy and b/generated_data/testing_data/ETH-univ/pred.npy differ diff --git a/generated_data/testing_data/ETH-univ/tar.npy b/generated_data/testing_data/ETH-univ/tar.npy index 94fabe5..fa4b2ff 100644 Binary files a/generated_data/testing_data/ETH-univ/tar.npy and b/generated_data/testing_data/ETH-univ/tar.npy differ diff --git a/generated_data/testing_data/UCY-univ3/ade.npy b/generated_data/testing_data/UCY-univ3/ade.npy deleted file mode 100644 index a8223d2..0000000 Binary files a/generated_data/testing_data/UCY-univ3/ade.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-univ3/fde.npy b/generated_data/testing_data/UCY-univ3/fde.npy deleted file mode 100644 index d97c365..0000000 Binary files a/generated_data/testing_data/UCY-univ3/fde.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-univ3/inp.npy b/generated_data/testing_data/UCY-univ3/inp.npy deleted file mode 100644 index 534d3b7..0000000 Binary files a/generated_data/testing_data/UCY-univ3/inp.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-univ3/pred.npy b/generated_data/testing_data/UCY-univ3/pred.npy deleted file mode 100644 index 71922ce..0000000 Binary files a/generated_data/testing_data/UCY-univ3/pred.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-univ3/tar.npy b/generated_data/testing_data/UCY-univ3/tar.npy deleted file mode 100644 index c8d22af..0000000 Binary files a/generated_data/testing_data/UCY-univ3/tar.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara1/ade.npy b/generated_data/testing_data/UCY-zara1/ade.npy deleted file mode 100644 index f7b7a2d..0000000 Binary files a/generated_data/testing_data/UCY-zara1/ade.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara1/fde.npy b/generated_data/testing_data/UCY-zara1/fde.npy deleted file mode 100644 index 254bca6..0000000 Binary files a/generated_data/testing_data/UCY-zara1/fde.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara1/inp.npy b/generated_data/testing_data/UCY-zara1/inp.npy deleted file mode 100644 index e375995..0000000 Binary files a/generated_data/testing_data/UCY-zara1/inp.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara1/pred.npy b/generated_data/testing_data/UCY-zara1/pred.npy deleted file mode 100644 index 30e21ba..0000000 Binary files a/generated_data/testing_data/UCY-zara1/pred.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara1/tar.npy b/generated_data/testing_data/UCY-zara1/tar.npy deleted file mode 100644 index 0cc3a80..0000000 Binary files a/generated_data/testing_data/UCY-zara1/tar.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara2/ade.npy b/generated_data/testing_data/UCY-zara2/ade.npy deleted file mode 100644 index ba460da..0000000 Binary files a/generated_data/testing_data/UCY-zara2/ade.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara2/fde.npy b/generated_data/testing_data/UCY-zara2/fde.npy deleted file mode 100644 index 3e49a03..0000000 Binary files a/generated_data/testing_data/UCY-zara2/fde.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara2/inp.npy b/generated_data/testing_data/UCY-zara2/inp.npy deleted file mode 100644 index 2f6cd69..0000000 Binary files a/generated_data/testing_data/UCY-zara2/inp.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara2/pred.npy b/generated_data/testing_data/UCY-zara2/pred.npy deleted file mode 100644 index 58048d3..0000000 Binary files a/generated_data/testing_data/UCY-zara2/pred.npy and /dev/null differ diff --git a/generated_data/testing_data/UCY-zara2/tar.npy b/generated_data/testing_data/UCY-zara2/tar.npy deleted file mode 100644 index 66b5ce2..0000000 Binary files a/generated_data/testing_data/UCY-zara2/tar.npy and /dev/null differ diff --git a/generated_data/trajdatasets/ETH-hotel.h5 b/generated_data/trajdatasets/ETH-hotel.h5 index b9ecb74..3714d5a 100644 Binary files a/generated_data/trajdatasets/ETH-hotel.h5 and b/generated_data/trajdatasets/ETH-hotel.h5 differ diff --git a/generated_data/trajdatasets/ETH-univ.h5 b/generated_data/trajdatasets/ETH-univ.h5 index 8af9e31..a7c7f81 100644 Binary files a/generated_data/trajdatasets/ETH-univ.h5 and b/generated_data/trajdatasets/ETH-univ.h5 differ diff --git a/generated_data/trajdatasets/UCY-univ3.h5 b/generated_data/trajdatasets/UCY-univ3.h5 index 8adf5f0..81bf3e0 100644 Binary files a/generated_data/trajdatasets/UCY-univ3.h5 and b/generated_data/trajdatasets/UCY-univ3.h5 differ diff --git a/generated_data/trajdatasets/UCY-zara1.h5 b/generated_data/trajdatasets/UCY-zara1.h5 index faad266..ca4580b 100644 Binary files a/generated_data/trajdatasets/UCY-zara1.h5 and b/generated_data/trajdatasets/UCY-zara1.h5 differ diff --git a/generated_data/trajdatasets/UCY-zara2.h5 b/generated_data/trajdatasets/UCY-zara2.h5 index e25efab..fe8301a 100644 Binary files a/generated_data/trajdatasets/UCY-zara2.h5 and b/generated_data/trajdatasets/UCY-zara2.h5 differ diff --git a/generated_data/trajdatasets_old/ETH-hotel.h5 b/generated_data/trajdatasets_old/ETH-hotel.h5 new file mode 100644 index 0000000..fb83a33 Binary files /dev/null and b/generated_data/trajdatasets_old/ETH-hotel.h5 differ diff --git a/generated_data/trajdatasets_old/ETH-univ.h5 b/generated_data/trajdatasets_old/ETH-univ.h5 new file mode 100644 index 0000000..8af9e31 Binary files /dev/null and b/generated_data/trajdatasets_old/ETH-univ.h5 differ diff --git a/generated_data/trajdatasets_old/UCY-univ3.h5 b/generated_data/trajdatasets_old/UCY-univ3.h5 new file mode 100644 index 0000000..46bafbc Binary files /dev/null and b/generated_data/trajdatasets_old/UCY-univ3.h5 differ diff --git a/generated_data/trajdatasets_old/UCY-zara1.h5 b/generated_data/trajdatasets_old/UCY-zara1.h5 new file mode 100644 index 0000000..8fd1561 Binary files /dev/null and b/generated_data/trajdatasets_old/UCY-zara1.h5 differ diff --git a/generated_data/trajdatasets_old/UCY-zara2.h5 b/generated_data/trajdatasets_old/UCY-zara2.h5 new file mode 100644 index 0000000..05c223f Binary files /dev/null and b/generated_data/trajdatasets_old/UCY-zara2.h5 differ diff --git a/generated_data/trajlets/ETH-hotel-trl.npy b/generated_data/trajlets/ETH-hotel-trl.npy index 251542a..e558349 100644 Binary files a/generated_data/trajlets/ETH-hotel-trl.npy and b/generated_data/trajlets/ETH-hotel-trl.npy differ diff --git a/generated_data/trajlets/ETH-univ-trl.npy b/generated_data/trajlets/ETH-univ-trl.npy index 7d93fcc..d36de11 100644 Binary files a/generated_data/trajlets/ETH-univ-trl.npy and b/generated_data/trajlets/ETH-univ-trl.npy differ diff --git a/generated_data/trajlets/UCY-univ3-trl.npy b/generated_data/trajlets/UCY-univ3-trl.npy index 6cf6974..c0d89ed 100644 Binary files a/generated_data/trajlets/UCY-univ3-trl.npy and b/generated_data/trajlets/UCY-univ3-trl.npy differ diff --git a/generated_data/trajlets/UCY-zara1-trl.npy b/generated_data/trajlets/UCY-zara1-trl.npy index 8067f1f..9121eb4 100644 Binary files a/generated_data/trajlets/UCY-zara1-trl.npy and b/generated_data/trajlets/UCY-zara1-trl.npy differ diff --git a/generated_data/trajlets/UCY-zara2-trl.npy b/generated_data/trajlets/UCY-zara2-trl.npy index 6b8782c..0fabbdc 100644 Binary files a/generated_data/trajlets/UCY-zara2-trl.npy and b/generated_data/trajlets/UCY-zara2-trl.npy differ diff --git a/generated_data/trajlets_old/ETH-hotel-trl.npy b/generated_data/trajlets_old/ETH-hotel-trl.npy new file mode 100644 index 0000000..251542a Binary files /dev/null and b/generated_data/trajlets_old/ETH-hotel-trl.npy differ diff --git a/generated_data/trajlets_old/ETH-univ-trl.npy b/generated_data/trajlets_old/ETH-univ-trl.npy new file mode 100644 index 0000000..7d93fcc Binary files /dev/null and b/generated_data/trajlets_old/ETH-univ-trl.npy differ diff --git a/generated_data/trajlets_old/UCY-univ3-trl.npy b/generated_data/trajlets_old/UCY-univ3-trl.npy new file mode 100644 index 0000000..6cf6974 Binary files /dev/null and b/generated_data/trajlets_old/UCY-univ3-trl.npy differ diff --git a/generated_data/trajlets_old/UCY-zara1-trl.npy b/generated_data/trajlets_old/UCY-zara1-trl.npy new file mode 100644 index 0000000..8067f1f Binary files /dev/null and b/generated_data/trajlets_old/UCY-zara1-trl.npy differ diff --git a/generated_data/trajlets_old/UCY-zara2-trl.npy b/generated_data/trajlets_old/UCY-zara2-trl.npy new file mode 100644 index 0000000..6b8782c Binary files /dev/null and b/generated_data/trajlets_old/UCY-zara2-trl.npy differ diff --git a/loop_beta.cmd b/loop_beta.cmd new file mode 100644 index 0000000..4fa0eb9 --- /dev/null +++ b/loop_beta.cmd @@ -0,0 +1,12 @@ +$i = 0; + +while ($i -lt 4) +{ + $j = 0; + while ($j -lt 4) + { + python beta_experiment.py --dataset %i --beta %j + $j++ + } + $i++ +} \ No newline at end of file diff --git a/static/assets/brand/bootstrap-outline.svg b/static/assets/brand/bootstrap-outline.svg deleted file mode 100644 index ed1825e..0000000 --- a/static/assets/brand/bootstrap-outline.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - diff --git a/static/assets/brand/bootstrap-solid.svg b/static/assets/brand/bootstrap-solid.svg deleted file mode 100644 index 2f536b6..0000000 --- a/static/assets/brand/bootstrap-solid.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Bootstrap - - - diff --git a/static/css/dashboard.css b/static/css/dashboard.css deleted file mode 100644 index b71942a..0000000 --- a/static/css/dashboard.css +++ /dev/null @@ -1,103 +0,0 @@ -body { - font-size: .875rem; -} - -.feather { - width: 16px; - height: 16px; - vertical-align: text-bottom; -} - -/* - * Sidebar - */ - -.sidebar { - position: fixed; - top: 0; - bottom: 0; - left: 0; - z-index: 100; /* Behind the navbar */ - padding: 48px 0 0; /* Height of navbar */ - box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); -} - -@media (max-width: 767.98px) { - .sidebar { - top: 5rem; - } -} - -.sidebar-sticky { - position: relative; - top: 0; - height: calc(100vh - 48px); - padding-top: .5rem; - overflow-x: hidden; - overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */ -} - -@supports ((position: -webkit-sticky) or (position: sticky)) { - .sidebar-sticky { - position: -webkit-sticky; - position: sticky; - } -} - -.sidebar .nav-link { - font-weight: 500; - color: #333; -} - -.sidebar .nav-link .feather { - margin-right: 4px; - color: #999; -} - -.sidebar .nav-link.active { - color: #007bff; -} - -.sidebar .nav-link:hover .feather, -.sidebar .nav-link.active .feather { - color: inherit; -} - -.sidebar-heading { - font-size: .75rem; - text-transform: uppercase; -} - -/* - * Navbar - */ - -.navbar-brand { - padding-top: .75rem; - padding-bottom: .75rem; - font-size: 1rem; - background-color: rgba(0, 0, 0, .25); - box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25); -} - -.navbar .navbar-toggler { - top: .25rem; - right: 1rem; -} - -.navbar .form-control { - padding: .75rem 1rem; - border-width: 0; - border-radius: 0; -} - -.form-control-dark { - color: #fff; - background-color: rgba(255, 255, 255, .1); - border-color: rgba(255, 255, 255, .1); -} - -.form-control-dark:focus { - border-color: transparent; - box-shadow: 0 0 0 3px rgba(255, 255, 255, .25); -} diff --git a/static/js/dashboard.js b/static/js/dashboard.js deleted file mode 100644 index 846aa25..0000000 --- a/static/js/dashboard.js +++ /dev/null @@ -1,46 +0,0 @@ -/* globals Chart:false, feather:false */ - -(function () { - tests = [10,2,3,4,5,6,7] - 'use strict' - - feather.replace() - - // Graphs - var ctx = document.getElementById('myChart') - // eslint-disable-next-line no-unused-vars - var myChart = new Chart(ctx, { - type: 'line', - data: { - labels: [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday' - ], - datasets: [{ - data: tests, - lineTension: 0, - backgroundColor: 'transparent', - borderColor: '#007bff', - borderWidth: 4, - pointBackgroundColor: '#007bff' - }] - }, - options: { - scales: { - yAxes: [{ - ticks: { - beginAtZero: false - } - }] - }, - legend: { - display: false - } - } - }) -})() diff --git a/static/temp/progress.json b/static/temp/progress.json deleted file mode 100644 index 42cface..0000000 --- a/static/temp/progress.json +++ /dev/null @@ -1 +0,0 @@ -{"prog" : 50} \ No newline at end of file diff --git a/templates/base - Copy.html b/templates/base - Copy.html deleted file mode 100644 index ac90722..0000000 --- a/templates/base - Copy.html +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - Dashboard Template · Bootstrap - - - - - - - - - - - - - -
-
- - -
-
-

Dashboard

-
-
- - -
- -
-
- - - -

Section title

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#HeaderHeaderHeaderHeader
1,001Loremipsumdolorsit
1,002ametconsecteturadipiscingelit
1,003IntegernecodioPraesent
1,003liberoSedcursusante
1,004dapibusdiamSednisi
1,005Nullaquissemat
1,006nibhelementumimperdietDuis
1,007sagittisipsumPraesentmauris
1,008Fuscenectellussed
1,009auguesemperportaMauris
1,010massaVestibulumlaciniaarcu
1,011egetnullaClassaptent
1,012tacitisociosquadlitora
1,013torquentperconubianostra
1,014perinceptoshimenaeosCurabitur
1,015sodalesligulainlibero
-
-
-
-
- - - - - - diff --git a/templates/base.html b/templates/base.html deleted file mode 100644 index b1b49ba..0000000 --- a/templates/base.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - Dashboard Template · Bootstrap - - - - - - - - - - - - - -
-
- - -
-
-

Train

-
-
- -
-
-
- -
-
-
-
-


-
- ETH-univ - ETH-hotel - UCY-zara1 - UCY-zara2 - UCY-univ3 -
-
-
-
- - - - - - diff --git a/templates/change_parameters.html b/templates/change_parameters.html deleted file mode 100644 index 652aaac..0000000 --- a/templates/change_parameters.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - Dashboard Template · Bootstrap - - - - - - - - - - - - - -
-
- - -
-
-

Parameters

-
-
- -
-
-
- -
-
-
-
-

-
-
-
-

-
-
-
-

-
-
-
-

-
- - - - - - - diff --git a/templates/parameters.html b/templates/parameters.html deleted file mode 100644 index 43f6a37..0000000 --- a/templates/parameters.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - Dashboard Template · Bootstrap - - - - - - - - - - - - - -
-
- - -
-
-

Parameters

-
-
- Edit -
-
-
- -
  • Tobs = {{ Tobs }}
  • -
  • Tpred = {{ Tpred }}
  • -
  • dmodel = {{ d_model }}
  • -
  • Number of heads = {{ num_head }}
  • -
  • Number of layers = {{ num_layers }}
  • -
  • dff = {{ dff }}
  • -
  • Dropout rate = {{ dropout_rate }}
  • - - - - - - diff --git a/templates/train_progress.html b/templates/train_progress.html deleted file mode 100644 index a771475..0000000 --- a/templates/train_progress.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - Dashboard Template · Bootstrap - - - - - - - - - - - - - - -
    -
    - - -
    -
    -

    Training Progress

    -
    -
    -
    -
    -
    -
    -
    - - - - - - - - diff --git a/test_TF.py b/test_TF.py index c7db7ef..8ef5b1a 100644 --- a/test_TF.py +++ b/test_TF.py @@ -9,29 +9,42 @@ from tools.opentraj_benchmark.all_datasets import get_trajlets -from tools.trajectories import obs_pred_trajectories, convert_to_traj, obs_pred_rotated_velocities, convert_to_traj_with_rotations +from tools.trajectories import obs_pred_trajectories,obs_pred_rotated_trajectories, convert_to_traj_with_rotations from tools.parameters import * -from tools.transformer.transformer import Transformer -from tools.transformer.training import ADE_FDE +from tools.transformer.transformer import Transformer_CVAE, Transformer +from tools.transformer.training import min_ADE_FDE def test_model(test_name,path, n_trajs = None): trajectories = get_trajlets(path,test_name)[test_name[0]][:,:,:2] - Starts_train , Xm_test, Xp_test, dists, mtcs = obs_pred_rotated_velocities(trajectories,Tobs,Tpred+Tobs) - + Starts_train , Xm_test, Xp_test, dists, mtcs = obs_pred_rotated_trajectories(trajectories,Tobs,Tpred+Tobs) Xm_test = tf.constant(Xm_test) - Xp_test = tf.constant(Xp_test) + print(Xm_test.shape) + print(Xp_test.shape) #-------------------- Visualize solution ---------------------- - transformer = Transformer(d_model, num_layers, num_heads, dff, Tobs, Tpred, num_modes, dropout_rate) + transformer = Transformer_CVAE(d_model, num_layers, num_heads, dff, num_modes, dropout_rate) + # transformer = Transformer_CVAE(d_model, num_layers, num_heads, dff, num_modes, dropout_rate) + test_dataset = {"observations":[],"predictions":[],"starts":[],"distances":[],"mtcs":[]} + # Form the training dataset + for i in range(len(Xp_test)): + test_dataset["observations"].append(Xm_test[i]) + test_dataset["predictions"].append(Xp_test[i]) + test_dataset["starts"].append(Starts_train[i]) + test_dataset["distances"].append(dists[i]) + test_dataset["mtcs"].append(mtcs[i]) + # Get the necessary data into a tf Dataset + test_data = tf.data.Dataset.from_tensor_slices(test_dataset) + # Form batches + batched_test_data = test_data.batch(len(Xp_test)) checkpoint_path = f"./generated_data/checkpoints/train/{test_name[0]}" - + print(checkpoint_path) ckpt = tf.train.Checkpoint(transformer=transformer, optimizer=optimizer) @@ -40,52 +53,45 @@ def test_model(test_name,path, n_trajs = None): # if a checkpoint exists, restore the latest checkpoint. if ckpt_manager.latest_checkpoint: ckpt.restore(ckpt_manager.latest_checkpoint) - print('Latest checkpoint restored!!') + print('Latest checkpoint restored!!',ckpt_manager.latest_checkpoint) else: print('No model trained for this particular dataset') return None - ade,fde,weights,inps,tars,preds = [],[],[],[],[],[] - print("calculating predictions") - if not type(n_trajs) == int: - A = range(len(Xm_test)) - else: - A = range(n_trajs) - for s in A: - print(s, end = ", ") - start = Starts_train[s] - distance = dists[s] - mtc = mtcs[s] - inp = Xm_test[s].numpy() - tar = Xp_test[s].numpy() - aux = Xm_test[0].numpy()[-1:] - pred, w = transformer(inp,inp[-1:],False,12) - pred = pred.numpy() - # print(inp[-1]) - # print(pred) - - inp_tar = np.concatenate([inp,tar],axis = 0) - inp_pred = np.zeros([pred.shape[0],(inp.shape[0]+pred.shape[1]),2]) - for i in range(pred.shape[0]): - inp_pred[i] = np.concatenate([inp,pred[i]],axis = 0) - - inp_tar = convert_to_traj_with_rotations(start,inp_tar,distance,mtc) - inp_pred = convert_to_traj_with_rotations(start,inp_pred,distance,mtc) - inp = inp_tar[:8] - tar = inp_tar[7:20] - pred = inp_pred[:,7:20,:] - - a,f = ADE_FDE(tar,pred) - ade.append(a) - fde.append(f) - inps.append(inp) - tars.append(tar) - preds.append(pred) - # print(Xm_test[s].numpy()-(inp[:-1]-inp[1:]),Xp_test[s].numpy()-tar[:-1]) - - trajs=[np.array(inps),np.array(tars),np.array(preds)] - print("ADE:", np.mean(ade),"FDE:", np.mean(fde)) + weights = [],[],[],[] + print("Calculating predictions") + for batch in batched_test_data: + start = batch["starts"].numpy() + distance = batch["distances"].numpy() + mtc = batch["mtcs"].numpy() + input = batch["observations"] + target = batch["predictions"] + pred, w, KL_value = transformer(input,input[:,-1:],training=False,evaluate=12) + + # Reconstruct full trajectory: n_batch x sequence_lenth x p + input = input.numpy() + target = target.numpy() + pred = pred.numpy() + + inp_tar = np.concatenate([input,target],axis = 1) + inp_pred= np.zeros([pred.shape[0],pred.shape[1],(input.shape[1]+pred.shape[2]),2]) + # Stack the modes + for i in range(pred.shape[1]): + inp_pred[:,i] = np.concatenate([input,pred[:,i]],axis = 1) + + for i in range(len(inp_tar)): + inp_tar[i] = distance[i] * inp_tar[i] @ mtc[i].T + start[i] + inp_pred[i] = distance[i] * inp_pred[i] @ mtc[i].T +start[i] + + # Observations + observations = inp_tar[:,:7] + ground_truth = inp_tar[:,6:] + predictions = inp_pred[:,:,6:] + + ade,fde = min_ADE_FDE(ground_truth,predictions) + trajs=[observations,ground_truth,predictions] + print("ADE:", np.mean(ade),"FDE:", np.mean(fde)) return ade,fde,None,trajs,transformer #------------------------------ plot solution ---------------------------- @@ -111,7 +117,6 @@ def print_sol(inp, tar, pred, img = None): if __name__ == '__main__': #------------------------ Parser --------------------------- - # Parser arguments parser = argparse.ArgumentParser(description='Train transformer') parser.add_argument('--root-path', '--root', @@ -120,12 +125,10 @@ def print_sol(inp, tar, pred, img = None): args = parser.parse_args() #-------------------- Info for testing ---------------------- - # test_name = ['ETH-univ'] + test_name = ['ETH-univ'] # test_name = ['ETH-hotel'] - test_name = ['UCY-zara1'] + # test_name = ['UCY-zara1'] # test_name = ['UCY-zara2'] # test_name = ['UCY-univ3'] test_model(test_name,args.root_path) - - \ No newline at end of file diff --git a/tester.ipynb b/tester.ipynb index dc25c03..3618d58 100644 --- a/tester.ipynb +++ b/tester.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -60,33 +60,28 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Loading trajlets from: ./generated_data/trajlets\\ETH-hotel-trl.npy\n", - "No model trained for this particular dataset\n" - ] - }, - { - "ename": "TypeError", - "evalue": "cannot unpack non-iterable NoneType object", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[1;32mexcept\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;32mpass\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 12\u001b[1;33m \u001b[0made\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mfde\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mweights\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mtrajs\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mtransformer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtest_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mtest_dataset\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 13\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 14\u001b[0m \u001b[0made\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mfde\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0made\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfde\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mTypeError\u001b[0m: cannot unpack non-iterable NoneType object" + "Loading trajlets from: ./generated_data/trajlets\\ETH-Univ-trl.npy\n", + "Small trajectories: 92\n", + "(2321, 8, 2)\n", + "(2321, 12, 2)\n", + "./generated_data/checkpoints/train/ETH-Univ\n", + "Latest checkpoint restored!! ./generated_data/checkpoints/train/ETH-Univ\\ckpt-110\n", + "Calculating predictions\n", + "ADE: 0.58671695 FDE: 1.3588676\n" ] } ], "source": [ "path = \"./\"\n", "#choose a dataset\n", - "test_dataset = \"ETH-hotel\"\n", + "test_dataset = \"ETH-Univ\"\n", "\n", "test_path = path + f\"generated_data/testing_data/{test_dataset}/\"\n", "\n", @@ -106,6 +101,39 @@ "np.save(test_path+\"pred.npy\", trajs[2])" ] }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0.37390298, -0.2288619 ],\n", + " [ 0. , 0. ],\n", + " [-0.0871935 , -0.03051508],\n", + " [-0.20659758, -0.38946742],\n", + " [-0.45374957, -0.24956225],\n", + " [-0.6715732 , -0.05334945],\n", + " [-0.9829161 , -0.161539 ],\n", + " [-1.3253201 , -0.18906768],\n", + " [-1.7472138 , -0.28921288],\n", + " [-2.2055075 , -0.44761813],\n", + " [-2.64101 , -0.69115925],\n", + " [-2.9735653 , -0.9468997 ],\n", + " [-3.3288553 , -1.3065428 ],\n", + " [-3.611939 , -1.7388265 ]], dtype=float32)" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "trajs[1][12]" + ] + }, { "cell_type": "code", "execution_count": 3, @@ -115,18 +143,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "Model: \"transformer\"\n", + "Model: \"transformer_cvae\"\n", "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", - "encoder (Encoder) multiple 299136 \n", + "encoder (Encoder) multiple 545664 \n", + "_________________________________________________________________\n", + "cvae_attention (CVAE_attenti multiple 52234 \n", "_________________________________________________________________\n", - "decoder (Decoder) multiple 597888 \n", + "decoder (Decoder) multiple 695040 \n", "_________________________________________________________________\n", - "multi_modal (multi_modal) multiple 5160 \n", + "dense_47 (Dense) multiple 258 \n", "=================================================================\n", - "Total params: 902,184\n", - "Trainable params: 902,184\n", + "Total params: 1,293,196\n", + "Trainable params: 1,293,196\n", "Non-trainable params: 0\n", "_________________________________________________________________\n" ] @@ -147,20 +177,45 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "General: ADE: 0.8959661707049471 FDE: 1.18791418954522\n" + "Loading trajlets from: ./generated_data/trajlets\\ETH-univ-trl.npy\n", + "Small trajectories: 92\n" + ] + } + ], + "source": [ + "Tobs = 8\n", + "Tpred = 12\n", + "\n", + "from tools.opentraj_benchmark.all_datasets import get_trajlets\n", + "from tools.trajectories import obs_pred_trajectories,obs_pred_rotated_trajectories, convert_to_traj_with_rotations\n", + "test_name = ['ETH-univ']\n", + "trajectories = get_trajlets(\"./\",test_name)[test_name[0]][:,:,:2]\n", + "Starts_train , Xm_test, Xp_test, dists, mtcs = obs_pred_rotated_trajectories(trajectories,Tobs,Tpred+Tobs)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "General: ADE: 0.58671695 FDE: 1.3588676\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "3bab6bff976c41688a11680d44f3dd5e", + "model_id": "aa9b480e94a64f6eb5e89d7eb6f7bbc9", "version_major": 2, "version_minor": 0 }, @@ -177,7 +232,7 @@ "#choose a dataset\n", "test_dataset = \"ETH-univ\"\n", "\n", - "test_path = path + f\"testing_data/{test_dataset}/\"\n", + "test_path = path + f\"generated_data/testing_data/{test_dataset}/\"\n", "reference_path = path + f\"datasets/ETH/seq_eth/reference.png\"\n", "H_path = path + f\"datasets/ETH/seq_eth/H.txt\"\n", "\n", @@ -205,7 +260,7 @@ " if x >= len(ade):\n", " print(\"There aren't that many trajectories\")\n", " return\n", - " #print_sol(inp[x],tar[x],pred[x],None)\n", + "# print_sol(inp[x],tar[x],pred[x],None)\n", " a = traj_to_real_coordinates(inp[x],H)\n", " b = traj_to_real_coordinates(tar[x],H)\n", " c = traj_to_real_coordinates(pred[x],H)\n", @@ -235,6 +290,98 @@ "\n", "interact(f, x=\"0\");" ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 1.0000000e+00, -1.6870156e-18],\n", + " [ 7.6804924e-01, -3.6168404e-02],\n", + " [ 6.8319803e-01, -5.2176796e-02],\n", + " [ 5.3687590e-01, -4.3020580e-02],\n", + " [ 3.5017157e-01, -5.6467921e-02],\n", + " [ 2.4483772e-01, 6.4771124e-03],\n", + " [ 1.2285026e-01, 8.2979165e-03]], dtype=float32)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "inp[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0.12285026, 0.00829792],\n", + " [ 0. , 0. ],\n", + " [-0.13646209, 0.01131812],\n", + " [-0.25367513, 0.02418254],\n", + " [-0.3715892 , 0.02686667],\n", + " [-0.49097073, 0.02958424],\n", + " [-0.60017306, 0.02257409],\n", + " [-0.7002231 , 0.02671189],\n", + " [-0.79009384, 0.0315993 ],\n", + " [-0.8933986 , 0.0570505 ],\n", + " [-0.98500806, 0.06212363],\n", + " [-1.042929 , 0.06932585],\n", + " [-1.1030437 , 0.10870075],\n", + " [-1.1775117 , 0.19050777]], dtype=float32)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tar[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[[ 0.12285026, 0.00829792],\n", + " [ 0. , 0. ],\n", + " [-0.12279233, 0.01117741],\n", + " [-0.26081228, 0.00693151],\n", + " [-0.41017687, 0.00797362],\n", + " [-0.53467 , 0.00796123],\n", + " [-0.64435357, 0.00701118],\n", + " [-0.74307019, 0.00649073],\n", + " [-0.86878723, 0.00361584],\n", + " [-0.97647029, 0.00133931],\n", + " [-1.08544576, -0.00273226],\n", + " [-1.19096804, -0.00820347],\n", + " [-1.27997339, -0.01881041],\n", + " [-1.33447945, -0.02417786]]])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pred[0]" + ] } ], "metadata": { diff --git a/tools/crowdscan/crowd/trajdataset.py b/tools/crowdscan/crowd/trajdataset.py index 980c613..e354a88 100644 --- a/tools/crowdscan/crowd/trajdataset.py +++ b/tools/crowdscan/crowd/trajdataset.py @@ -43,7 +43,7 @@ def postprocess(self, fps, sampling_rate=1, use_kalman=False): -: check fps value, should be set and bigger than 0 -: check critical columns should exist in the table -: update data types - -: fill 'groumates' if they are not set + -: fill 'groupmates' if they are not set -: checks if velocity do not exist, compute it for each agent -: compute bounding box of trajectories @@ -93,7 +93,7 @@ def postprocess(self, fps, sampling_rate=1, use_kalman=False): else:pass # remove the trajectories shorter than 2 frames - data_grouped = self.data.groupby(["scene_id", "agent_id"]) + data_grouped = self.data.groupby(["scene_id", "agent_id"]) single_length_inds = data_grouped.head(1).index[data_grouped.size() < 2] self.data = self.data.drop(single_length_inds) @@ -277,5 +277,3 @@ def merge_datasets(dataset_list, new_title=[]): merged.title = new_title return merged - - diff --git a/tools/opentraj_benchmark/all_datasets.py b/tools/opentraj_benchmark/all_datasets.py index e61c0c3..82a22b4 100644 --- a/tools/opentraj_benchmark/all_datasets.py +++ b/tools/opentraj_benchmark/all_datasets.py @@ -81,6 +81,7 @@ def get_trajlets(opentraj_root, dataset_names): for dataset_name in dataset_names: trajlet_npy_file = os.path.join(trajlet_dir, dataset_name + '-trl.npy') if os.path.exists(trajlet_npy_file): + #if False: trajlets[dataset_name] = np.load(trajlet_npy_file) print("Loading trajlets from: ", trajlet_npy_file) else: @@ -107,6 +108,7 @@ def get_datasets(opentraj_root, dataset_names): for dataset_name in dataset_names: dataset_h5_file = os.path.join(trajdataset_dir, dataset_name + '.h5') if os.path.exists(dataset_h5_file): + #if False: datasets[dataset_name] = TrajDataset() datasets[dataset_name].data = pd.read_pickle(dataset_h5_file) datasets[dataset_name].title = dataset_name @@ -124,6 +126,7 @@ def get_datasets(opentraj_root, dataset_names): elif 'eth-hotel' == dataset_name.lower(): eth_hotel_root = os.path.join(opentraj_root, 'datasets/ETH/seq_hotel/obsmat.txt') datasets[dataset_name] = loadETH(eth_hotel_root, title=dataset_name, scene_id='Hotel') + print(datasets[dataset_name]) # ****************************** # ========== UCY ============== diff --git a/tools/opentraj_benchmark/trajlet.py b/tools/opentraj_benchmark/trajlet.py index c4e03d0..5a3051e 100644 --- a/tools/opentraj_benchmark/trajlet.py +++ b/tools/opentraj_benchmark/trajlet.py @@ -8,8 +8,8 @@ def split_trajectories(traj_groups, length=8, overlap=2., static_filter_thresh=1., to_numpy=False): """ :param traj_groups: DataFrameGroupBy containing N group for N agents - :param length: min duration for trajlets - :param overlap: min overlap duration between consequent trajlets + :param length: min duration for trajlets (in seconds) + :param overlap: min overlap duration between consecutive trajlets :param static_filter_thresh: if a trajlet is shorter than this thrshold, then it is static :param to_numpy: (bool) if True the result will be np.ndarray :return: list of Pandas DataFrames (all columns) @@ -22,29 +22,23 @@ def split_trajectories(traj_groups, length=8, overlap=2., static_filter_thresh=1 # Delta time between the first two frames dt = ts.iloc[1] - ts.iloc[0] eps= 1E-2 - for tr in trajs: # Too short trajectories - if len(tr) < 2: continue + if len(tr) < 2: + continue # Number of frames per trajectory f_per_traj = int(np.ceil((length - eps) / dt)) - # Frames to skip to get the desired overlap - f_step = int(np.ceil((length - overlap - eps) / dt)) + f_step = 1 # Number of frames n_frames = len(tr) for start_f in range(0, n_frames - f_per_traj, f_step): - if static_filter_thresh < 1E-3 or \ - np.linalg.norm(tr[["pos_x", "pos_y"]].iloc[start_f + f_per_traj].to_numpy() - - tr[["pos_x", "pos_y"]].iloc[start_f].to_numpy()) > static_filter_thresh: - # Append the trajectory if it satisfies the non-staticness threshold above - trajlets.append(tr.iloc[start_f:start_f + f_per_traj]) + trajlets.append(tr.iloc[start_f:start_f + f_per_traj]) if to_numpy: trl_np_list = [] for trl in trajlets: trl_np = trl[["pos_x", "pos_y", "vel_x", "vel_y", "timestamp"]].to_numpy() trl_np_list.append(trl_np) trajlets = np.stack(trl_np_list) - return trajlets diff --git a/tools/parameters.py b/tools/parameters.py index f711d4f..75d2247 100644 --- a/tools/parameters.py +++ b/tools/parameters.py @@ -2,14 +2,15 @@ from tools.optimizer import CustomSchedule -Tobs = 8 +Tobs = 8 Tpred = 12 -d_model = 128 +d_model = 128 num_heads = 8 -num_layers = 6 -num_modes = 20 -dff = 512 +num_layers= 3 +num_modes = 1 +dff = 512 +beta = 0.25 dropout_rate = 0.1 learning_rate = CustomSchedule(d_model) @@ -19,4 +20,4 @@ temp_learning_rate_schedule = CustomSchedule(d_model) loss_object = tf.keras.losses.SparseCategoricalCrossentropy( -from_logits=True, reduction='none') \ No newline at end of file +from_logits=True, reduction='none') diff --git a/tools/training.py b/tools/training.py deleted file mode 100644 index 7256097..0000000 --- a/tools/training.py +++ /dev/null @@ -1,67 +0,0 @@ -import numpy as np -import tensorflow as tf -from transformer.masking import create_look_ahead_mask -from tools.trajectories import convert_to_traj, convert_tensor_to_traj - -def loss_function(real,pred): - # Error for ade/fde - diff = pred - real - diff = diff**2 - diff = tf.sqrt(tf.reduce_sum(diff,[1,2])) - return tf.math.reduce_min(diff) - -def ADE_train(real,pred): - # Error for ade/fde - diff = pred - real - res = 0. - for i in range(real.shape[0]+1): - for j in range(i): - aux = tf.reduce_sum(diff[:,:j,:],1) - aux = aux**2 - aux = tf.sqrt(tf.reduce_sum(aux,1)) - res = aux + res - return tf.reduce_sum(res)/diff.shape[0] - - -def ADE_FDE(real,pred): - real_traj = convert_to_traj(tf.constant(np.array([[0,0]],dtype = "float32")), real) - pred_traj = convert_to_traj(tf.constant(np.array([[0,0]],dtype = "float32")), pred) - - n = real_traj.shape[0] - diff = pred_traj - real_traj - diff = diff**2 - FDE = diff[:,-1,:] - FDE = tf.sqrt(tf.reduce_sum(FDE,axis = 1)) - FDE = tf.math.reduce_min(FDE) - - diff = tf.reduce_sum(diff,[1,2])/n - ADE = tf.math.reduce_min(diff) - - return ADE.numpy(),FDE.numpy() - - -def accuracy_function(real,pred): - # Error for ade/fde - diff = real - pred - diff = diff**2 - diff = -tf.sqrt(tf.reduce_sum(diff, axis=1)) - return tf.math.exp(diff) - -@tf.function -def train_step(inp, tar, transformer, optimizer, train_loss, train_accuracy): - tar_train = tar - tar_train = tar[:-1,:] - aux = tf.expand_dims(inp[-1,:],0) - tar_train = tf.concat([aux,tar_train], axis = 0) - - with tf.GradientTape() as tape: - predictions, _ = transformer(inp, tar_train, True) - # predictions = transformer(inp, inp, True,12) - # loss = loss_function(tar, predictions) - loss = ADE_train(tar, predictions) - - gradients = tape.gradient(loss, transformer.trainable_variables) - optimizer.apply_gradients(zip(gradients, transformer.trainable_variables)) - - train_loss(loss) - train_accuracy(accuracy_function(tar, predictions)) \ No newline at end of file diff --git a/tools/trajectories.py b/tools/trajectories.py index 2e556a5..833e11d 100644 --- a/tools/trajectories.py +++ b/tools/trajectories.py @@ -1,7 +1,8 @@ import numpy as np import tensorflow as tf from math import atan,cos,sin -def convert_to_changes(tr): +import matplotlib.pyplot as plt +def convert_to_displacements(tr): start = tr[0] changes = tr[1:]-tr[:-1] return start, changes @@ -21,31 +22,38 @@ def convert_to_traj(s,changes): res[i,0] = s for j in range(n): res[i,j+1] = res[i,j]+changes[i,j] - + return res def convert_to_traj_with_rotations(s, changes, d=1, mtc=np.array([[1.,0],[0,1]]) ): - - if len(changes.shape) == 2: - n = changes.shape[0] - res = np.zeros([n+1,2]) - for i in range(n): - res[i+1] = res[i]+changes[i] - res = res*d - res = res.dot(mtc.T) - res = res + s - + # For a single trajectory, n_batch x sequence_lenth x p + if len(changes.shape) == 3: + # Sequence length + sequence_length = changes.shape[1] + res = np.zeros([changes.shape[0],sequence_length+1,2]) + for i in range(sequence_length): + res[:,i+1] = res[:,i]+changes[:,i] + d = tf.expand_dims(tf.expand_dims(d,1),2) + # Scale the elements of res by factor d + res = tf.math.multiply(d, res) + # Apply inverse rotation + res = tf.matmul(res,mtc) + # Translates + res = res + tf.expand_dims(s,1) else: - l = changes.shape[0] - n = changes.shape[1] - res = np.zeros([l,n+1,2]) - for i in range(l): - for j in range(n): - res[i,j+1] = res[i,j]+changes[i,j] - res[i] = res[i]*d - res[i] = res[i].dot(mtc.T) - res[i] = res[i] + s - + # For multiple trajectories, n_batch x n_modes x sequence_lenth x p + n_batch = changes.shape[0] + n_modes = changes.shape[1] + sequence_length = changes.shape[2] + res = np.zeros([n_batch,n_modes,sequence_length+1,2]) + d = tf.expand_dims(tf.expand_dims(d,1),2) + for i in range(n_modes): + for j in range(sequence_length): + res[:,i,j+1] = res[:,i,j]+changes[:,i,j] + res[:,i] = tf.math.multiply(d, res[:,i]) + res[:,i] = tf.matmul(res[:,i],mtc) + res[:,i] = res[:,i] + tf.expand_dims(s,1) + return res def obs_pred_trajectories(trajectories, separator = 8, f_per_traj = 20): @@ -54,42 +62,127 @@ def obs_pred_trajectories(trajectories, separator = 8, f_per_traj = 20): Trajp = [] starts = [] for tr in trajectories: - s, tr = convert_to_changes(tr) + s, tr = displacements(tr) Trajm.append(np.array(tr[range(separator-1),:],dtype = 'float32')) Trajp.append(np.array(tr[range(separator-1,f_per_traj-1),:], dtype = 'float32')) starts.append(s) return np.array(starts),np.array(Trajm),np.array(Trajp) -def obs_pred_rotated_velocities(trajectories, separator = 8, f_per_traj = 20): - N_t = len(trajectories) - Trajm = [] - Trajp = [] +def obs_pred_rotated_trajectories(trajectories, separator = 8, f_per_traj = 20): + # Number of trajectories in the dataset + N_t = len(trajectories) + observations = [] + predictions = [] + starting_points = [] + rot_mtcs = [] + scales = [] + # Scan for all the trajctories + for tr in trajectories: + # First position + s = tr[separator-1] + tr = tr - s + # Goes to the first non-zero position + i = 0 + while i 0: i+=1 + + # In case we have not seen one single significant displacement + if i>=tr.shape[0]: + continue + + # Get the x,y coordinates + b,a = s + # Norm of the displacement + d = np.linalg.norm(s) + + # When the displacement is very small, we scale by a fixed quanttity + if d<0.2: + d = 0.2 + rot_matrix = np.eye(2) + else: + # One idea could be not to do anything in this case? + rot_matrix = np.array([[b/d,a/d],[-a/d,b/d]]) + # Scaling the trajectory with respect to the length of the first non-null displacement + tr = tr/d + # Rotate tr with the inverse: this will make all the trajectories having direction 1,0 + # at the point of first non-null displacement + tr = tr.dot(rot_matrix.T) + # Keep the rotation inverse + rot_matrix = rot_matrix.T + # Keep the observations + observations.append(np.array(tr[range(separator),:],dtype = 'f')) + # Keep the positions to predict + predictions.append(np.array(tr[range(separator,f_per_traj),:], dtype = 'f')) + # Keep absolute starting point + starting_points.append(s) + # Keep the inverse of the rotation matrix + rot_mtcs.append(rot_matrix.T) + # The normalizing distances + scales.append(d) + return np.array(starting_points), np.array(observations),np.array(predictions), np.array(scales), np.array(rot_mtcs) + +def obs_pred_rotated_velocities(trajectories, separator = 8, f_per_traj = 20, plot=False): + # Number of trajectories in the dataset + N_t = len(trajectories) + Trajm = [] + Trajp = [] starts = [] rot_mtcs = [] dists = [] - + # To plot the trajectory dataset + if plot: + fig,ax = plt.subplots(1) + plt.margins(0, 0) + plt.gca().set_axis_off() + plt.gca().xaxis.set_major_locator(plt.NullLocator()) + plt.gca().yaxis.set_major_locator(plt.NullLocator()) + + # Scan for all the trajctories (they come ) for tr in trajectories: - s = tr[0] + # First position + # TODO: in most other codes the reference is taken at the last observation + s = tr[0] tr = tr - s + # Goes to the first non-zero position + i = 0 + while i 0: i+=1 - i = 0 - while not np.linalg.norm(tr[i]) > 0: i+=1 + # In case we have not seen one single significant displacement + if i>=tr.shape[0]: + continue + # Get the x,y coordinates b,a = tr[i] d = np.linalg.norm(tr[i]) - rot_matrix = np.array([[b/d,a/d],[-a/d,b/d]]) + # When the displacemnt is very small, we scale by a fixed quanttity + if d<0.2: + d=0.2 + + rot_matrix = np.array([[b/d,a/d],[-a/d,b/d]]) + # Scaling the trajectory with respect to the length of the first non-null displacement tr = tr/d + # Rotate tr with the inverse tr = tr.dot(rot_matrix.T) - _ , tr = convert_to_changes(tr) + if plot: + ax.plot(tr[:,0],tr[:,1]) + + # Get displacements from differences in absolute positions + _ , tr = convert_to_displacements(tr) + # Keep the rotation inverse rot_matrix = rot_matrix.T + # Keep the observations Trajm.append(np.array(tr[range(separator-1),:],dtype = 'f')) + # Keep the positions to predict Trajp.append(np.array(tr[range(separator-1,f_per_traj-1),:], dtype = 'f')) + # Keep absolute starting point starts.append(s) - rot_mtcs.append(rot_matrix) + # Keep the inverse of the rotation matrix + rot_mtcs.append(rot_matrix.T) + # The normalizing distances dists.append(d) - + if plot: + plt.show() return np.array(starts), np.array(Trajm),np.array(Trajp), np.array(dists), np.array(rot_mtcs) def detect_separator(trajectories,secs): @@ -116,4 +209,4 @@ def traj_to_real_coordinates(traj,H): x = tCat[:, 1] / tCat[:, 2] y = tCat[:, 0] / tCat[:, 2] res.append(np.vstack([x,y]).T) - return np.array(res) \ No newline at end of file + return np.array(res) diff --git a/tools/transformer/CVAE.py b/tools/transformer/CVAE.py new file mode 100644 index 0000000..b2c2f9e --- /dev/null +++ b/tools/transformer/CVAE.py @@ -0,0 +1,159 @@ +import tensorflow as tf +import tensorflow_probability as tfp +multi_gaussian = tfp.distributions.MultivariateNormalDiag + +from .attention import Attention +from .ffnn import point_wise_feed_forward_network + +# class CVAE_attention_1(tf.keras.layers.Layer): +# def __init__(self, d_model, num_modes, rate=0.1): +# super(CVAE_attention, self).__init__() + +# #The number of modes to obtain from the CVAE +# self.num_modes = num_modes + +# #This are the prior distribution parameters +# self.d_model = d_model +# self.prior_loc = tf.zeros(d_model) +# self.prior_scale_diag = tf.ones(d_model) +# self.prior = multi_gaussian(loc = self.prior_loc, scale_diag = self.prior_scale_diag) + +# #Attention module and query vector to obtain loc and log_scale +# self.attention = Attention(d_model) +# self.average_query = tf.Variable(tf.ones(d_model), trainable = False) +# self.average_query = tf.expand_dims(tf.expand_dims(self.average_query, axis = 0), axis = 0) + +# #Dense layers to obtain loc and log_scale +# self.loc_dense = tf.keras.layers.Dense(d_model) +# self.log_scale_dense = tf.keras.layers.Dense(d_model) + +# def KL_Loss(self,mu,log_sigma): +# k = tf.shape(mu)[0] +# KL = tf.norm(mu)**2 +# KL += tf.math.reduce_sum(tf.math.exp(log_sigma)) +# KL -= tf.cast(k, tf.float32) +# KL -= tf.math.reduce_sum(log_sigma) +# KL = KL/2 +# return KL + +# def call(self, x, training): +# # Input size: num_batch x sequence_length x d_model +# batch_size = tf.shape(x)[0] +# # sequence_size = tf.shape(x)[1] +# x , _ = self.attention(x, x, self.average_query, None) + +# if training: +# #Obtain the location and the variance +# loc = self.loc_dense(x) +# log_sigma = self.log_scale_dense(x) + +# #Flatten to process simultaneously in a multi gaussian distribution +# loc_flat = tf.reshape(loc, [-1]) +# log_sigma_flat = tf.reshape(log_sigma, [-1]) + +# else: +# #Obtain the flat location and variance +# loc_flat = tf.zeros(batch_size *self.d_model) +# log_sigma_flat = tf.ones(batch_size *self.d_model) + +# #Obtain the posterior +# posterior = multi_gaussian(loc = loc_flat, scale_diag = log_sigma_flat) + +# #Obtain the samples +# samples = posterior.sample(self.num_modes) # num_modes x (batch_size x d_model) + +# #Reshape to obtain compatible tensor +# samples = tf.reshape(samples, [self.num_modes, batch_size, self.d_model]) +# x = tf.transpose(samples, perm = [1,0,2]) +# x = tf.reshape(x, [self.num_modes, batch_size, 1, self.d_model]) + +# #return output and value for the modified loss +# aux = self.KL_Loss(loc_flat, log_sigma_flat) +# return x, aux + + +#----- new try ---------------------------------------- + +class CVAE_attention(tf.keras.layers.Layer): + def __init__(self, d_model, num_modes, rate=0.1): + super(CVAE_attention, self).__init__() + + self.d_model = d_model + + #The number of modes to obtain from the CVAE + self.num_modes = num_modes + + #TODO: the value 10 should be a hyperparameter of the entire model + self.z_size = 10 + + #Attention module and query vector to obtain loc and log_scale + self.attention = Attention(d_model) + self.average_query = tf.Variable(tf.ones([1,1,self.z_size]), trainable = True) + + #Dense layers to obtain loc and log_scale + self.loc_dense = tf.keras.layers.Dense(self.z_size) + self.log_scale_dense = tf.keras.layers.Dense(self.z_size) + + #Dense layer to go back to dimension d_model after concatenation + self.dense3 = tf.keras.layers.Dense(d_model) + + def KL_Loss(self,mu,log_sigma): + # ------------------------ NOTE ------------------------------ + # Notice that the equation for the KL divergence of isotropic + # gaussian distributions is additive for batched information + # we then get the average value over the number of batchs + # ------------------------------------------------------------ + k = tf.math.reduce_prod(tf.shape(mu)) + KL = tf.norm(mu)**2 + KL += tf.math.reduce_sum(tf.math.exp(2*log_sigma)) + KL -= tf.cast(k, tf.float32) + KL -= 2*tf.math.reduce_sum(log_sigma) + KL = KL/(2*mu.shape[0]) + return KL + + def call(self, x, training): + # Input size: batch_size x sequence_length x d_model + batch_size = tf.shape(x)[0] + sequence_size = tf.shape(x)[1] + avg , _ = self.attention(x, x, self.average_query, None) # batch_size x 1 x d_model + + if training: + #Obtain the location and the variance + loc = self.loc_dense(avg) # batch_size x 1 x z_size + log_sigma = self.log_scale_dense(avg) # batch_size x 1 x z_size + sigma = tf.math.exp(log_sigma) # batch_size x 1 x z_size + + #Flatten to process simultaneously in a multi gaussian distribution + KL_value = self.KL_Loss(loc, log_sigma) + + else: + #Obtain the flat location and variance + loc = tf.zeros([batch_size,1,self.z_size]) + sigma = tf.ones([batch_size,1,self.z_size]) + KL_value = 0 + + #Obtain the posterior + posterior = multi_gaussian(loc = loc, scale_diag = sigma) + + #Obtain the samples + samples = posterior.sample(self.num_modes) # num_modes x batch_size x 1 x z_size + + #Reshape to obtain compatible tensor + samples = tf.transpose(samples, perm = [1,0,2,3]) + # samples = tf.reshape(samples, [self.num_modes, batch_size, 1, self.z_size]) + + #repeat to make the concatenation + samples = tf.repeat(samples,sequence_size, axis = 2) # num_modes x batch_size x sequence_size x z_size + + #do concatenation + x = tf.reshape(x,tf.concat([[1],x.shape],axis = 0)) # 1 x batch_size x sequence_size x d_model + x = tf.repeat(x,self.num_modes, axis = 0) # num_modes x batch_size x sequence_size x d_model + x = tf.transpose(x,[1,0,2,3]) # batch_size x num_modes x sequence_size x d_model + x = tf.concat([x,samples], axis = -1) # batch_size x num_modes x sequence_size x (d_model + z_size) + + #go back to size d_model + x = self.dense3(x) # batch_size x num_modes x sequence_size x d_model + + #TODO: check if dropout is necessary + + return x, KL_value \ No newline at end of file diff --git a/tools/transformer/attention.py b/tools/transformer/attention.py index c222f44..869d601 100644 --- a/tools/transformer/attention.py +++ b/tools/transformer/attention.py @@ -1,21 +1,19 @@ import tensorflow as tf def scaled_dot_product_attention(q, k, v, mask): - + # Size q,k,v: num_batch x num_heads x sequence_length x depth matmul_qk = tf.matmul(q, k, transpose_b=True) - - # scale matmul_qk + # Scale matmul_qk dk = tf.cast(tf.shape(k)[-1], tf.float32) scaled_attention_logits = matmul_qk / tf.math.sqrt(dk) - - # add the mask to the scaled tensor. + # Add the mask to the scaled tensor (used in decoder). if mask is not None: scaled_attention_logits += (mask * -1e9) - + # Attention weights + # Size attention_weights: num_batch x num_heads x sequence_length x sequence_length attention_weights = tf.nn.softmax(scaled_attention_logits, axis=-1) - + # Output: num_batch x num_heads x sequence_length x depth output = tf.matmul(attention_weights, v) - return output, attention_weights class Attention(tf.keras.layers.Layer): @@ -27,12 +25,9 @@ def __init__(self, d_model): self.wv = tf.keras.layers.Dense(d_model) def call(self, v, k, q, mask): - batch_size = tf.shape(q)[0] - q = self.wq(q) k = self.wk(k) v = self.wv(v) - scaled_attention, attention_weights = scaled_dot_product_attention(q, k, v, mask) output = scaled_attention @@ -42,39 +37,87 @@ def call(self, v, k, q, mask): class Multi_headed_attention(tf.keras.layers.Layer): def __init__(self, d_model, num_heads): super(Multi_headed_attention, self).__init__() - + # Number of heads self.num_heads = num_heads - self.d_model = d_model - + # Hidden dimension + self.d_model = d_model assert d_model % self.num_heads == 0 - + # Dimension (depth) per head self.depth = d_model // self.num_heads + # Query, Key, Value matrices for the multiple heads self.wq = tf.keras.layers.Dense(d_model) self.wk = tf.keras.layers.Dense(d_model) self.wv = tf.keras.layers.Dense(d_model) def split_heads(self, x): - x = tf.reshape(x,[-1,self.num_heads, self.depth]) - return tf.transpose(x, perm=[1,0,2]) + # Reshape the obtained tensor (queries,keys,values) + # as num_batch x sequence_length x num_heads x depth + x = tf.reshape(x,[x.shape[0],-1,self.num_heads, self.depth]) + # Reorganize as num_batch x num_heads x sequence_length x depth + return tf.transpose(x, perm=[0,2,1,3]) def call(self, v, k, q, mask): - batch_size = tf.shape(q)[0] - + batch_size = tf.shape(q)[0] + sequence_size = tf.shape(q)[1] + # All inputs size: num_batch x sequence_length x d_model + # Generate the query, key, value vectors q = self.wq(q) k = self.wk(k) v = self.wv(v) - + # Split heads before applying dot products q = self.split_heads(q) k = self.split_heads(k) v = self.split_heads(v) - + # Size q,k,v: num_batch x num_heads x sequence_length x depth scaled_attention, attention_weights = scaled_dot_product_attention(q, k, v, mask) + concat_attention = tf.reshape(scaled_attention,[scaled_attention.shape[0],-1,self.d_model]) + # Size output: num_batch x sequence_length x d_model + output = concat_attention + return output, attention_weights - concat_attention = tf.reshape(scaled_attention,[-1,self.d_model]) +class Multi_headed_attention_cvae(tf.keras.layers.Layer): + def __init__(self, d_model, num_heads, num_modes): + super(Multi_headed_attention_cvae, self).__init__() + #Number of modes + self.num_modes = num_modes + # Number of heads + self.num_heads = num_heads + # Hidden dimension + self.d_model = d_model + assert d_model % self.num_heads == 0 + # Dimension (depth) per head + self.depth = d_model // self.num_heads - output = concat_attention + # Query, Key, Value matrices for the multiple heads + self.wq = tf.keras.layers.Dense(d_model) + self.wk = tf.keras.layers.Dense(d_model) + self.wv = tf.keras.layers.Dense(d_model) - # output = self.dense(concat_attention) + def split_heads(self, x): + # Reshape the obtained tensor (queries,keys,values) + # as num_batch x num_modes x sequence_length x num_heads x depth + x = tf.reshape(x,[x.shape[0],self.num_modes,-1,self.num_heads, self.depth]) + # Reorganize as num_batch x num_modes x num_heads x sequence_length x depth + return tf.transpose(x, perm=[0,1,3,2,4]) + def call(self, v, k, q, mask): + batch_size = tf.shape(q)[0] + num_modes = tf.shape(q)[1] + sequence_size = tf.shape(q)[2] + # All inputs size: num_batch x num_modes x sequence_length x d_model + # Generate the query, key, value vectors + q = self.wq(q) + k = self.wk(k) + v = self.wv(v) + # Split heads before applying dot products + q = self.split_heads(q) + k = self.split_heads(k) + v = self.split_heads(v) + # Size q,k,v: num_batch x num_modes x num_heads x sequence_length x depth + scaled_attention, attention_weights = scaled_dot_product_attention(q, k, v, mask) + # concat_attention = tf.reshape(scaled_attention,[scaled_attention.shape[0],-1,self.d_model]) + concat_attention = tf.reshape(scaled_attention,[batch_size,num_modes,sequence_size,self.d_model]) + # Size output: num_batch x num_modes x sequence_length x d_model + output = concat_attention return output, attention_weights \ No newline at end of file diff --git a/tools/transformer/decoder.py b/tools/transformer/decoder.py index c7c0c77..64f70e6 100644 --- a/tools/transformer/decoder.py +++ b/tools/transformer/decoder.py @@ -1,84 +1,98 @@ import tensorflow as tf from .position_enc import positional_encoding -from .attention import Multi_headed_attention +from .attention import Multi_headed_attention, Multi_headed_attention_cvae from .ffnn import point_wise_feed_forward_network from .masking import create_look_ahead_mask class DecoderLayer(tf.keras.layers.Layer): - def __init__(self, d_model, num_heads, dff, rate=0.1): + def __init__(self, d_model, num_heads, dff, rate=0.1, num_modes = 0, cvae = False): super(DecoderLayer, self).__init__() - self.att1 = Multi_headed_attention(d_model, num_heads) - self.att2 = Multi_headed_attention(d_model, num_heads) + if not cvae: + self.att1 = Multi_headed_attention(d_model, num_heads) + self.att2 = Multi_headed_attention(d_model, num_heads) + else: + self.num_modes = num_modes + self.att1 = Multi_headed_attention_cvae(d_model, num_heads, num_modes) + self.att2 = Multi_headed_attention_cvae(d_model, num_heads, num_modes) - # self.ffn = point_wise_feed_forward_network(d_model,dff) + self.ffn = point_wise_feed_forward_network(d_model,dff) self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6) self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - # self.layernorm3 = tf.keras.layers.LayerNormalization(epsilon=1e-6) + self.layernorm3 = tf.keras.layers.LayerNormalization(epsilon=1e-6) - self.dropout1 = tf.keras.layers.Dropout(rate) - self.dropout2 = tf.keras.layers.Dropout(rate) - # self.dropout3 = tf.keras.layers.Dropout(rate) + self.dropout1 = tf.keras.layers.Dropout(rate) + self.dropout2 = tf.keras.layers.Dropout(rate) + self.dropout3 = tf.keras.layers.Dropout(rate) def call(self, x, enc_output, training, mask): attn1, attn_weights_block1 = self.att1(x, x, x, mask) attn1 = self.dropout1(attn1, training=training) - out1 = self.layernorm1(x + attn1) + out1 = self.layernorm1(x + attn1) attn2, attn_weights_block2 = self.att2(enc_output, enc_output, out1, None) attn2 = self.dropout2(attn2, training=training) - out2 = self.layernorm2(attn2 + out1) + out2 = self.layernorm2(attn2 + out1) - # ffn_output = self.ffn(out2) - # ffn_output = self.dropout3(ffn_output, training=training) - # out3 = self.layernorm3(ffn_output + out2) + ffn_output = self.ffn(out2) + ffn_output = self.dropout3(ffn_output, training=training) + out3 = self.layernorm3(ffn_output + out2) - return out2, attn_weights_block1, attn_weights_block2 + return out3, attn_weights_block1, attn_weights_block2 class Decoder(tf.keras.layers.Layer): - def __init__(self, d_model, num_layers, num_heads, dff, maximum_position_encoding, rate=0.1): + def __init__(self, d_model, num_layers, num_heads, dff, maximum_position_encoding, rate=0.1, num_modes = 0, cvae = False): super(Decoder, self).__init__() + self.cvae = cvae + self.num_modes = num_modes + self.d_model = d_model self.num_layers = num_layers self.embedding = tf.keras.layers.Dense(d_model) self.pos_encoding = positional_encoding(maximum_position_encoding, d_model) - self.dec_layers = [DecoderLayer(d_model, num_heads, dff, rate) + self.dec_layers = [DecoderLayer(d_model, num_heads, dff, rate, num_modes, cvae = cvae) for _ in range(num_layers)] self.dropout = tf.keras.layers.Dropout(rate) - + def call(self, x, enc_output, training, evaluate = None): - batch_size = x.shape[0] + batch_size = x.shape[0] + sequence_size = x.shape[1] attention_weights = [] - x = self.embedding(x) - x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32)) - x += self.pos_encoding[:batch_size,:] - + x*= tf.math.sqrt(tf.cast(self.d_model, tf.float32)) + x+= tf.repeat(self.pos_encoding[:sequence_size,:],repeats=1,axis=0) x = self.dropout(x, training=training) - + if self.cvae: + x = tf.tile(x, [self.num_modes,1,1]) + x = tf.reshape(x, [self.num_modes,batch_size,sequence_size,self.d_model]) + x = tf.transpose(x, perm = [1,0,2,3]) if evaluate == None: - mask = create_look_ahead_mask(x.shape[0]) + mask = create_look_ahead_mask(x.shape[-2]) for i in range(self.num_layers): x, _ , _ = self.dec_layers[i](x, enc_output, training, mask) return x, None else: + predictions = tf.identity(x) for j in range(evaluate): - predictions = x - mask = create_look_ahead_mask(predictions.shape[0]) + mask = create_look_ahead_mask(predictions.shape[-2]) for i in range(self.num_layers): predictions, block1, block2 = self.dec_layers[i](predictions, enc_output, training, mask) attention_weights.append(block1) attention_weights.append(block2) - prediction = tf.expand_dims(predictions[-1,:],0) - x = tf.concat([x,prediction], axis = 0) - x = x[-evaluate:] - - - return x, attention_weights \ No newline at end of file + if self.cvae: + prediction = tf.expand_dims(predictions[:,:,-1,:], axis = -2) + else: + prediction = tf.expand_dims(predictions[:,-1,:], axis = -2) + x = tf.concat([x,prediction], axis = -2) + if self.cvae: + x = x[:,:,-evaluate:,:] + else: + x = x[:,-evaluate:,:] + return x, attention_weights diff --git a/tools/transformer/encoder.py b/tools/transformer/encoder.py index 3f78684..647f3e6 100644 --- a/tools/transformer/encoder.py +++ b/tools/transformer/encoder.py @@ -3,61 +3,79 @@ from .position_enc import positional_encoding from .attention import Multi_headed_attention from .ffnn import point_wise_feed_forward_network +# from neighbor_attention import neighbor_attention +# Encoder layer class EncoderLayer(tf.keras.layers.Layer): def __init__(self, d_model, num_heads, dff, rate=0.1): super(EncoderLayer, self).__init__() - self.att = Multi_headed_attention(d_model,num_heads) - # self.ffn = point_wise_feed_forward_network(d_model, dff) + # Multi-headed attention layer + self.attention = Multi_headed_attention(d_model,num_heads) + # self.neighbor_attention = neighbor_attention(d_model) + self.ffn = point_wise_feed_forward_network(d_model, dff) self.layernorm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6) # self.layernorm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6) + self.layernorm3 = tf.keras.layers.LayerNormalization(epsilon=1e-6) self.dropout1 = tf.keras.layers.Dropout(rate) # self.dropout2 = tf.keras.layers.Dropout(rate) + self.dropout3 = tf.keras.layers.Dropout(rate) def call(self, x, training): - attn_output, _ = self.att(x, x, x, None) - attn_output = self.dropout1(attn_output, training=training) - out1 = self.layernorm1(x+attn_output) + # Self-attention layer + attn_output, _ = self.attention(x, x, x, None) + attn_output = self.dropout1(attn_output, training=training) + # Residual connection + out1 = self.layernorm1(x+attn_output) - # ffn_output = self.ffn(out1) - # ffn_output = self.dropout2(ffn_output, training=training) - # out2 = self.layernorm2(out1+ffn_output) + #neighbor attention + # neigh_output = self.neighbor_attention() + # neigh_output = self.dropout2() + # out2 = self.layernorm2(out1 + neigh_output) - return out1 + ffn_output = self.ffn(out1) + ffn_output = self.dropout3(ffn_output, training=training) + out3 = self.layernorm3(out1+ffn_output) + + return out3 class Encoder(tf.keras.layers.Layer): - def __init__(self, d_model, num_layers, num_heads, dff, input_size, maximum_position_encoding, rate=0.1): + def __init__(self, d_model, num_layers, num_heads, dff, maximum_position_encoding, dropout_rate=0.1): super(Encoder, self).__init__() #Dimensions used for interchanging between attention and the FFNN - self.d_model = d_model - self.dff = dff + self.d_model = d_model + self.dff = dff self.num_layers = num_layers - + # Embedding of the positions + # TODO: activation function here? self.embedding = tf.keras.layers.Dense(d_model) - + # Positional encoding self.pos_encoding = positional_encoding(maximum_position_encoding, d_model) - - self.enc_layers = [EncoderLayer(d_model, num_heads, dff, rate) + # Encoding layers + self.enc_layers = [EncoderLayer(d_model, num_heads, dff, dropout_rate) for _ in range(num_layers)] - - self.dropout = tf.keras.layers.Dropout(rate) + # Dropout layer + self.dropout = tf.keras.layers.Dropout(dropout_rate) def call(self, x, training): - batch_size = x.shape[0] - - #This only happens once - x = self.embedding(x) + batch_size = x.shape[0] + sequence_size = x.shape[1] + # Embedding of the displacements + # Size: n_batch x T_obs-1 x d_model + x = self.embedding(x) + # Scaling + # TODO: Is it useful here? x *= tf.math.sqrt(tf.cast(self.d_model, tf.float32)) - x += self.pos_encoding[:batch_size,:] - x = self.dropout(x, training=training) - - - #This sends the data through the encoder Layers + # Add the positional encoding + pos_encoding = self.pos_encoding[:sequence_size,:] + x += tf.repeat(pos_encoding,repeats=1,axis=0) + # Apply dropout to the embedding + x = self.dropout(x, training=training) + # This sends the data through the different encoder Layers for i in range(self.num_layers): x = self.enc_layers[i](x, training) - return x \ No newline at end of file + return x diff --git a/tools/transformer/neighbor_attention.py b/tools/transformer/neighbor_attention.py new file mode 100644 index 0000000..83feafa --- /dev/null +++ b/tools/transformer/neighbor_attention.py @@ -0,0 +1,25 @@ +import tensorflow as tf +import tensorflow_probability as tfpro +multi_gaussian = tfpro.python.distributions.MultivariateNormalDiag + +from .attention import Attention +from .ffnn import point_wise_feed_forward_network + +class neighbor_attention(tf.keras.layers.Layer): + def __init__(self, d_model, rate=0.1): + super(neighbor_attention, self).__init__() + + #The number of modes to obtain from the CVAE + self.att_average = Attention(d_model) + self.average_query = tf.Variable(tf.ones(d_model), trainable = True) + self.average_query = tf.expand_dims(tf.expand_dims(tf.expand_dims(self.average_query, axis = 0), axis = 0), axis = 0) + + self.neighbor_att = Attention(d_model) + + + def call(self, x, neighbors): + + neighbors, _ = self.att_average(neighbors,neighbors,self.average_query) + x = self.neighbor_att(neighbors,neighbors,x) + + return x \ No newline at end of file diff --git a/tools/transformer/position_enc.py b/tools/transformer/position_enc.py index ddf631a..0e725ea 100644 --- a/tools/transformer/position_enc.py +++ b/tools/transformer/position_enc.py @@ -5,6 +5,7 @@ def get_angles(pos, i, d_model): angle_rates = 1 / np.power(10000, (2 * (i//2)) / np.float32(d_model)) return pos * angle_rates +# Positional encoding as in the Attention is all you need paper def positional_encoding(position, d_model): angle_rads = get_angles(np.arange(position)[:, np.newaxis], np.arange(d_model)[np.newaxis, :], @@ -16,6 +17,4 @@ def positional_encoding(position, d_model): # apply cos to odd indices in the array; 2i+1 angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2]) - # pos_encoding = angle_rads[np.newaxis, ...] - return tf.cast(angle_rads, dtype=tf.float32) diff --git a/tools/transformer/training.py b/tools/transformer/training.py index b4e3a3f..03e9dc4 100644 --- a/tools/transformer/training.py +++ b/tools/transformer/training.py @@ -1,65 +1,107 @@ import numpy as np import tensorflow as tf -def loss_function(real,pred): + +def loss_function(real, pred): # Error for ade/fde diff = pred - real - diff = diff**2 - diff = tf.sqrt(tf.reduce_sum(diff,[1,2])) + diff = diff ** 2 + diff = tf.sqrt(tf.reduce_sum(diff, [1, 2])) return tf.math.reduce_min(diff) -def ADE_train(real,pred, max = False): - diff = pred - real - res = 0. - for i in range(real.shape[0]): - aux = tf.reduce_sum(diff[:,:i,:],1) - aux = aux**2 - aux = tf.sqrt(tf.reduce_sum(aux,1)) - res = aux + res - if max == False: - return tf.reduce_min(res)/real.shape[0] + +# real: n_batch x sequence_length x p +# prediction: n_batch x n_modes x sequence_length x p +def ADE_train(real, prediction, maxi=False): + sequence_length= real.shape[1] + n_batches = prediction.shape[0] + n_modes = prediction.shape[1] + real_expanded = tf.expand_dims(real, 1) + # diff: n_batch x n_modes x sequence_length x p + diff = (prediction - real_expanded)**2 + # diff = (tf.cumsum(prediction,axis=2) - tf.cumsum(real_expanded,axis=2))**2 + # Along time, Euclidean distance between predicted and real points + losses = tf.sqrt(tf.reduce_sum(diff, 3)) + losses = tf.reduce_mean(losses, 2) + # Over the samples: take the min or the max + if not maxi: + losses = tf.reduce_min(losses, axis=1) else: - return tf.reduce_max(res)/real.shape[0] - + losses = tf.reduce_max(losses, axis=1) + # Average over batch elements + return tf.reduce_sum(losses) / n_batches -def ADE_FDE(real,pred): - n = real.shape[0] - diff = pred - real - diff = diff**2 - FDE = diff[:,-1,:] - FDE = tf.sqrt(tf.reduce_sum(FDE,axis = 1)) - FDE = tf.math.reduce_min(FDE) +def KL_loss(real, prediction, mu, sigma, beta, maxi=False): + k = len(mu) + KL = np.dot(mu, mu) + np.sum(sigma) - k - np.sum(np.log(sigma)) + KL = KL / 2 + return ADE_train(real, prediction, maxi) + beta * KL + + +def ADE_train_CVAE(real, prediction, maximum=False): + sequence_length = real.shape[1] + n_batches = prediction.shape[0] + n_modes = prediction.shape[1] + real_expanded = tf.expand_dims(real, 1) + # diff: n_batch x n_modes x sequence_length x p + diff = prediction - real_expanded + # Sum over time to get absolute positions and take the squares + losses = tf.reduce_sum(diff, 2) ** 2 + losses = tf.sqrt(tf.reduce_sum(losses, 3)) + # Average over time + losses = tf.reduce_sum(losses, 2) / sequence_length + # Over the samples: take the min or the max + if not maximum: + losses = tf.reduce_min(losses, axis=1) + else: + losses = tf.reduce_max(losses, axis=1) + # Average over batch elements + return tf.reduce_sum(losses) / n_batches + - diff = tf.reduce_sum(diff,[1,2])/n - ADE = tf.math.reduce_min(diff) +def min_ADE_FDE(ground_truth, prediction): + # ground_truth : batch_size x sequence_length x 2 + # prediction : batch_size x num_modes x sequence_length x 2 - return ADE.numpy(),FDE.numpy() + sequence_length = ground_truth.shape[1] + diff = prediction - tf.expand_dims(ground_truth, 1) + diff = diff + # Evaluate FDE + FDE = diff[:, :, -1, :] # batch_size x num_modes x 2 + FDE = np.linalg.norm(FDE, axis=2) + FDE = np.amin(FDE, axis=1, keepdims=True) + # Evaluate ADE + ADE = np.linalg.norm(diff, axis=3) # batch_size x num_modes x sequence_length + ADE = np.amin(np.mean(ADE, axis=2), axis=1) + return ADE, FDE -def accuracy_function(real,pred): +def accuracy_function(real, pred): # Error for ade/fde diff = real - pred - diff = diff**2 + diff = diff ** 2 diff = -tf.sqrt(tf.reduce_sum(diff, axis=1)) return tf.math.exp(diff) -@tf.function -def train_step(inp, tar, transformer, optimizer, train_loss, train_accuracy, burnout = False): - tar_train = tar - tar_train = tar[:-1,:] - aux = tf.expand_dims(inp[-1,:],0) - tar_train = tf.concat([aux,tar_train], axis = 0) - with tf.GradientTape() as tape: - predictions, _ = transformer(inp, tar_train, True) - # predictions = transformer(inp, inp, True,12) - # loss = loss_function(tar, predictions) - loss = ADE_train(tar, predictions,burnout) - if loss < 10 or burnout == True: - gradients = tape.gradient(loss, transformer.trainable_variables) +#Beta is always positive +@tf.function +def train_step(input, target, transformer, optimizer, beta = 0, burnout=False): + # Target + target_train = target[:, :-1, :] + # This is to hold one position only + aux = input[:, -1:] + # target_train will hold the last input data + the T_pred-1 first positions of the future + # size: n_batch x sequence_size x p + target_train = tf.concat([aux, target_train], axis=1) + with tf.GradientTape() as tape: + # Apply the transformer network to the input + predictions, _, KL_value = transformer(input, aux, training = True, evaluate = 12) + loss = ADE_train(target, predictions, burnout) + beta*KL_value + if loss < 1000 or burnout == True: + gradients = tape.gradient(loss, transformer.trainable_variables) optimizer.apply_gradients(zip(gradients, transformer.trainable_variables)) - train_loss(loss) - train_accuracy(accuracy_function(tar, predictions)) \ No newline at end of file + return loss, KL_value diff --git a/tools/transformer/transformer.py b/tools/transformer/transformer.py index badf8f6..fef3ff5 100644 --- a/tools/transformer/transformer.py +++ b/tools/transformer/transformer.py @@ -6,40 +6,74 @@ from .encoder import Encoder from .decoder import Decoder +from .CVAE import CVAE_attention class multi_modal(tf.keras.layers.Layer): - def __init__(self, num_modes): - super(multi_modal, self).__init__() - - self.dense = [tf.keras.layers.Dense(2) for _ in range(num_modes)] - self.num_modes = num_modes - - def call(self, dec_output, training, evaluate = None): - modes = [] - for i in range(self.num_modes): - modes.append(self.dense[i](dec_output)) - modes = tf.stack(modes) - - return modes + def __init__(self, num_modes): + super(multi_modal, self).__init__() + self.dense = [tf.keras.layers.Dense(2) for _ in range(num_modes)] + self.num_modes = num_modes + def call(self, dec_output, training, evaluate=None): + modes = [] + for i in range(self.num_modes): + modes.append(self.dense[i](dec_output)) + # Stack in the 2nd dimension + return tf.stack(modes, axis=1) +# Our Transformer model class Transformer(tf.keras.Model): - def __init__(self, d_model, num_layers, num_heads, dff, input_size, target_size, num_modes, rate=0.1): - super(Transformer, self).__init__() - self.encoder = Encoder(d_model, num_layers, num_heads, dff, input_size, 100, rate) - - self.decoder = Decoder(d_model, num_layers, num_heads, dff, 100, rate) - - self.modes = multi_modal(num_modes) - - - def call(self, inp, x, training, evaluate = None): - enc_output = self.encoder(inp, training) - dec_output, attention_weights = self.decoder(x, enc_output, training, evaluate) - - partition_output = self.modes(dec_output) - - return partition_output, attention_weights \ No newline at end of file + def __init__(self, d_model, num_layers, num_heads, dff, num_modes, rate=0.1): + super(Transformer, self).__init__() + # Encoder + self.encoder = Encoder(d_model, num_layers, num_heads, dff, 100, rate) + # Decoder + self.decoder = Decoder(d_model, num_layers, num_heads, dff, 100, rate) + # + self.modes = multi_modal(num_modes) + + # Call to the transformer + def call(self, input, x, training, evaluate=None): + # Call the encoder on the inputs + enc_output = self.encoder(input, training) # [batch_size,sequence_size,d_model] + # Decoder: takes as input the input encoding and the partial prediction + dec_output, attention_weights = self.decoder(x, enc_output, training, + evaluate) # [batch_size,sequence_size,d_model] + # The output + partition_output = self.modes(dec_output) # [batch_size,num_modes,sequence_size,2] + return partition_output, attention_weights, 0 + + +# Our Transformer model with CVAE +class Transformer_CVAE(tf.keras.Model): + def __init__(self, d_model, num_layers, num_heads, dff, num_modes, rate=0.1): + super(Transformer_CVAE, self).__init__() + # Encoder + self.encoder = Encoder(d_model, num_layers, num_heads, dff, 100, rate) + # CVAE + self.cvae = CVAE_attention(d_model, num_modes, rate) + # Decoder + self.decoder = Decoder(d_model, num_layers, num_heads, dff, 100, rate, num_modes=num_modes, cvae=True) + + # Go back to coordinates + self.coor = tf.keras.layers.Dense(2) + + # Call to the transformer + def call(self, input, x, training, evaluate=None): + # Call the encoder on the inputs + enc_output = self.encoder(input, training) # [batch_size,sequence_size,d_model] + + # CVAE: Middle layer. Adds stochastic component + cvae_output,KL_value = self.cvae(enc_output, training) + + # Decoder: takes as input the input encoding and the partial prediction + dec_output, attention_weights = self.decoder(x, cvae_output, training, + evaluate) # [batch_size,num_modes,sequence_size,d_model] + + # Go back to coordinates + final_output = self.coor(dec_output) + + return final_output, attention_weights, KL_value diff --git a/train_TF.py b/train_TF.py index a0966fc..9afb9e8 100644 --- a/train_TF.py +++ b/train_TF.py @@ -3,132 +3,178 @@ import argparse import numpy as np import tensorflow as tf +import matplotlib.pyplot as plt from tools.opentraj_benchmark.all_datasets import get_trajlets - - -from tools.trajectories import obs_pred_trajectories, obs_pred_rotated_velocities, convert_to_traj_with_rotations, convert_to_traj +from tools.trajectories import obs_pred_trajectories, obs_pred_rotated_trajectories, convert_to_traj_with_rotations, \ + convert_to_traj from tools.parameters import * - - -from tools.transformer.transformer import Transformer +from tools.transformer.transformer import Transformer, Transformer_CVAE from tools.transformer.masking import create_look_ahead_mask from tools.transformer.training import loss_function, accuracy_function, train_step -def train_model(training_names, test_name, path, EPOCHS = 50): - # trajlets is a dictionary of trajectories, keys are the datasets names - trajlets = get_trajlets(path, training_names) - - Xm = np.zeros([1,Tobs-1,2], dtype = "float32") - Xp = np.zeros([1,Tpred,2], dtype = "float32") - starts = np.array([[0,0]]) - dists = np.array([]) - mtcs = np.array([[[0.,0],[0,0]]]) - - # Process all the trajectories on the dictionary - for key in trajlets: - - # Get just the position information - trajectories = trajlets[key][:,:,:2] - print("Reading: ",trajectories.shape[0]," trajectories from ",key) - # Obtain observed and predicted diferences in trajlets - _, minus, plus, _, _ = obs_pred_rotated_velocities(trajectories,Tobs,Tpred+Tobs) - # Append the new past parts (minus) and future parts (plus) - Xm = np.concatenate((Xm,minus), axis = 0) - Xp = np.concatenate((Xp,plus), axis = 0) - # Remove first element - Xm = Xm[1:] - Xp = Xp[1:] - - Xm = tf.constant(Xm) - Xp = tf.constant(Xp) - - #------------------------ Training ------------------------- - # Build the model - transformer = Transformer(d_model, num_layers, num_heads, dff, Tobs, Tpred, num_modes, dropout_rate) - - checkpoint_path = f"./generated_data/checkpoints/train/{test_name[0]}" - - ckpt = tf.train.Checkpoint(transformer=transformer, - optimizer=optimizer) - - ckpt_manager = tf.train.CheckpointManager(ckpt, checkpoint_path, max_to_keep=1) - - # if a checkpoint exists, restore the latest checkpoint. - if ckpt_manager.latest_checkpoint: - ckpt.restore(ckpt_manager.latest_checkpoint) - print ('Latest checkpoint restored!!') - - - train_dataset = [] - # Form the training dataset - for i in range(len(Xp)): - train_dataset.append((Xm[i],Xp[i])) - - train_loss = tf.keras.metrics.Mean(name='train_loss') - train_accuracy = tf.keras.metrics.Mean(name='train_accuracy') - - # Main training loop - for epoch in range(EPOCHS): - start = time.time() - - train_loss.reset_states() - train_accuracy.reset_states() - - # Iterate over batches - for (batch, (inp, tar)) in enumerate(train_dataset): - if epoch < 2: - train_step(inp, tar, transformer, optimizer, train_loss, train_accuracy, burnout = True) - else: - train_step(inp, tar, transformer, optimizer, train_loss, train_accuracy) - - if batch % 50 == 0: - print ('Epoch {} Batch {} Loss {:.4f} Accuracy {:.4f}'.format( - epoch + 1, batch, train_loss.result(), train_accuracy.result())) - - if (epoch + 1) % 6 == 0: - ckpt_save_path = ckpt_manager.save() - print ('Saving checkpoint for epoch {} at {}'.format(epoch+1, - ckpt_save_path)) - - print ('Epoch {} Loss {:.4f} Accuracy {:.4f}'.format(epoch + 1, - train_loss.result(), - train_accuracy.result())) - - print ('Time taken for 1 epoch: {} secs\n'.format(time.time() - start)) - - return transformer - - -if __name__=='__main__': - - #------------------------ Parser --------------------------- - - # Parser arguments - parser = argparse.ArgumentParser(description='Train transformer') - parser.add_argument('--root-path', '--root', - default='./', - help='path to folder that contain dataset') - args = parser.parse_args() - - #------------info for training -------------------------------- - - training_names = ['ETH-hotel', 'UCY-zara1', 'UCY-zara2', 'UCY-univ3'] - # training_names = ['ETH-univ','ETH-hotel'] - test_name = ['ETH-univ'] - - # training_names = ['ETH-univ', 'UCY-zara1', 'UCY-zara2', 'UCY-univ3'] - # test_name = ['ETH-hotel'] - - # training_names = ['ETH-univ','ETH-hotel', 'UCY-zara1', 'UCY-univ3'] - # test_name = ['UCY-zara2'] - - # training_names = ['ETH-univ','ETH-hotel','UCY-zara2', 'UCY-univ3'] - # test_name = ['UCY-zara1'] - - # training_names = ['ETH-univ','ETH-hotel', 'UCY-zara1', 'UCY-zara2'] - # test_name = ['UCY-univ3'] - - transformer = train_model(training_names,test_name,args.root_path,2) +#if beta is negative, it means cyclic annealing +def train_model(training_names, test_name, path, args, beta = 0): + # trajlets is a dictionary of trajectories, keys are the datasets names + trajlets = get_trajlets(path, training_names) + # observations and groundtruth will hold the observations and paths-to-predict, respectively + # Dimensions: N x Tobs-1 x 2 + observations = np.zeros([1, Tobs, 2], dtype="float32") + # Dimensions: N x Tpred x 2 + groundtruth = np.zeros([1, Tpred, 2], dtype="float32") + + # Process all the trajectories on the dictionary + for key in trajlets: + # Get just the position information + trajectories = trajlets[key][:, :, :2] + print("Reading: ", trajectories.shape[0], " trajectories from ", key) + # Obtain observed and predicted with normalized speeds and rotations in trajlets + _, minus, plus, _, _ = obs_pred_rotated_trajectories(trajectories, Tobs, Tpred + Tobs) + # Append the new past parts (minus) and future parts (plus) + observations = np.concatenate((observations, minus), axis=0) + groundtruth = np.concatenate((groundtruth, plus), axis=0) + # Remove first element + observations = observations[1:] + groundtruth = groundtruth[1:] + #observations = observations[:,1:]-observations[:,:-1] + #groundtruth[:,1:]= groundtruth[:,1:] -groundtruth[:,:-1] + observations = tf.constant(observations) + groundtruth = tf.constant(groundtruth) + + # ------------------------ Training ------------------------- + # Build the model + transformer = Transformer(d_model, num_layers, num_heads, dff, num_modes, dropout_rate) + # transformer = Transformer_CVAE(d_model, num_layers, num_heads, dff, num_modes, dropout_rate) + + checkpoint_path = f"./generated_data/checkpoints/train/{test_name[0]}" + + ckpt = tf.train.Checkpoint(transformer=transformer, + optimizer=optimizer) + + ckpt_manager = tf.train.CheckpointManager(ckpt, checkpoint_path, max_to_keep=2) + + # if a checkpoint exists, restore the latest checkpoint. + if ckpt_manager.latest_checkpoint: + ckpt.restore(ckpt_manager.latest_checkpoint) + print('Latest checkpoint restored!!') + + train_dataset = {"observations": [], "predictions": []} + # Form the training dataset + for i in range(len(groundtruth)): + train_dataset["observations"].append(observations[i]) + train_dataset["predictions"].append(groundtruth[i]) + # Get the necessary data into a tf Dataset + train_data = tf.data.Dataset.from_tensor_slices(train_dataset) + # Form batches + batched_train_data = train_data.batch(args.batch_size) + batched_train_data = batched_train_data.shuffle(10000, reshuffle_each_iteration=True) + + num_batches_per_epoch = batched_train_data.cardinality().numpy() + + train_accuracy = tf.keras.metrics.Mean(name='train_accuracy') + + train_loss_results = [] + + if beta < 0: + cyclic_begin = int(EPOCHS/2 - M/2) + cyclic_end = int(EPOCHS/2 + M/2) + # Main training loop + for epoch in range(args.epochs): + start = time.time() + train_accuracy.reset_states() + total_loss = 0 + # Iterate over batches + for (id_batch, batch) in enumerate(batched_train_data): + + if epoch < 0: #modify the value to determine how many epochs are for burnout + batch_loss = train_step(batch["observations"], batch["predictions"], transformer, optimizer, beta = 0, + burnout=True) + else: + #When beta is negative, its absolute value represents the amount of cycles + if beta < 0: + if epoch < cyclic_begin: beta_aux = 0 + elif epoch > cyclic_end: beta_aux = 0 + else: beta_aux = (epoch - cyclic_begin)/M + + #This is when there is no cyclic annealing + else: beta_aux = beta + + batch_loss, dummy = train_step(batch["observations"], batch["predictions"], transformer, optimizer, + beta = beta_aux) + # print(f"{id_batch} batch, KL_value:{dummy}") + total_loss += batch_loss + if id_batch % 10 == 0: + print('Epoch {} Batch {:03d} Loss {:.4f} Accuracy {:.4f}'.format(epoch + 1, id_batch, batch_loss, + train_accuracy.result())) + total_loss = total_loss / num_batches_per_epoch + train_loss_results.append(total_loss) + if (epoch + 1) % 3 == 0: + ckpt_save_path = ckpt_manager.save() + print('Saving checkpoint for epoch {} at {}'.format(epoch + 1, + ckpt_save_path)) + + print('Epoch {} Loss {:.4f} Accuracy {:.4f}'.format(epoch + 1, + total_loss, + train_accuracy.result())) + + print('Time taken for 1 epoch: {} secs\n'.format(time.time() - start)) + # PLot + if args.plot_loss: + fig, ax = plt.subplots(1) + plt.margins(0, 0) + plt.plot(train_loss_results) + plt.show() + return transformer, observations, groundtruth + + +if __name__ == '__main__': + # ------------------------ Parser --------------------------- + + # Arguments parser + parser = argparse.ArgumentParser(description='Train transformer') + parser.add_argument('--root-path', '--root', + default='./', + help='path to folder that contain dataset') + parser.add_argument('--test', + default='ETH-univ', + help='name of the dataset to test') + parser.add_argument('--batch-size', '--b', + type=int, default=256, metavar='N', + help='input batch size for training (default: 32)') + parser.add_argument('--epochs', '--e', + type=int, default=50, metavar='N', + help='number of epochs to train (default: 2)') + parser.add_argument('--plot-loss', '--pl', + action='store_true', + help='plot the evolution of the loss during training') + + args = parser.parse_args() + + # ------------info for training ------------------------------- + datasets_names = ['ETH-hotel', 'ETH-univ', 'UCY-zara1', 'UCY-zara2', 'UCY-univ3'] + datasets_test = [dataset for dataset in datasets_names if dataset==args.test] + datasets_train = [dataset for dataset in datasets_names if dataset!=args.test] + + # Train the model + transformer, train_observations, train_groundtruth = train_model(datasets_train, datasets_test, args.root_path, args, 1) + + # Perform a sanity check + idx = np.random.randint(train_observations.shape[0]) + obs = train_observations[idx:idx+1] + fig, ax = plt.subplots(1) + plt.margins(0, 0) + plt.plot(obs[0,:,0],obs[0,:,1],'g-') + # gt = np.cumsum(train_groundtruth[idx:idx+1],axis=1) + gt = train_groundtruth[idx:idx+1] + plt.plot([0,gt[0,0,0]],[0,gt[0,0,1]],'r-') + plt.plot(gt[0,:,0],gt[0,:,1],'r-') + + aux = obs[:,-1:] + # Apply the transformer network to the input + pred,__,__ = transformer(obs, aux, training = False, evaluate = 12) + # pred = np.cumsum(pred,axis=2) + plt.plot([0,pred[0,0,0,0]],[0,pred[0,0,0,1]],'b-') + plt.plot(pred[0,0,:,0],pred[0,0,:,1],'b-') + plt.show() diff --git a/visual_main.py b/visual_main.py deleted file mode 100644 index d67ce69..0000000 --- a/visual_main.py +++ /dev/null @@ -1,80 +0,0 @@ -from flask import Flask, request, render_template, redirect, url_for -from flask_bootstrap import Bootstrap -import numpy as np -import json - -app = Flask(__name__) -Bootstrap(app) - -@app.route('/') -def hello(): - """Return a friendly HTTP greeting.""" - return redirect(url_for('base')) - -@app.route("/base/", methods=["GET", "POST"]) -def base(): - return render_template('base.html') - -def get_pars(): - pars = np.load("./tools/parameters.npy") - aux = pars[-1] - pars = pars[:-1] - pars = np.array(pars, dtype = int) - pars = np.array(pars, dtype = str) - aux = np.array([aux], dtype = str) - pars = np.concatenate([pars,aux]) - - return pars - - -@app.route("/parameters/", methods=["GET", "POST"]) -def parameters(mode = "view"): - pars = get_pars() - - if mode == "view": - return render_template('parameters.html', - Tobs = pars[0], Tpred = pars[1], - d_model = pars[2], num_head = pars[3], - num_layers = pars[4], num_modes = pars[5], - dff = pars[6], dropout_rate = pars[7]) - if mode == "change": - return render_template('change_parameters.html', - Tobs = pars[0], Tpred = pars[1], - d_model = pars[2], num_head = pars[3], - num_layers = pars[4], num_modes = pars[5], - dff = pars[6], dropout_rate = pars[7]) - - -@app.route("/act_pars/", methods=["GET", "POST"]) -def act_pars(): - if request.method == 'POST': - user = request.form - ls = [] - for a in user: ls.append(user[a]) - ls = np.array(ls, dtype = "float32") - np.save("parameters.npy", ls) - return redirect(url_for('parameters', mode = "view")) - -@app.route("/train_h/", methods=["GET", "POST"]) -def train_h(): - if request.method == 'POST': - user = request.form - ls = list(user) - if len(ls)>2: - epochs = int(user[ls[0]]) - test_name = user[ls[0]] - training_names = list(user)[2:] - print(test_name) - print(training_names) - else: - print("no dataset for training selected") - - return redirect(url_for('train_progress')) - -@app.route("/train_progress/", methods=["GET", "POST"]) -def train_progress(): - - return render_template('train_progress.html') - -if __name__ == '__main__': - app.run(host='127.0.0.1', port=8080, debug=True) \ No newline at end of file