diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000000000000000000000000000000000000..2e9e6fd0400115d57e3da7ffec294313e63f6fcb --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,483 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.7.0" +manifest_format = "2.0" + +[[deps.Adapt]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "af92965fb30777147966f58acb05da51c5616b5f" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "3.3.3" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BufferedStreams]] +git-tree-sha1 = "bb065b14d7f941b8617bc323063dbe79f55d16ea" +uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" +version = "1.1.0" + +[[deps.CategoricalArrays]] +deps = ["DataAPI", "Future", "Missings", "Printf", "Requires", "Statistics", "Unicode"] +git-tree-sha1 = "5f5a975d996026a8dd877c35fe26a7b8179c02ba" +uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597" +version = "0.10.6" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "2dd813e5f2f7eec2d1268c57cf2373d3ee91fcea" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.15.1" + +[[deps.ChangesOfVariables]] +deps = ["ChainRulesCore", "LinearAlgebra", "Test"] +git-tree-sha1 = "1e315e3f4b0b7ce40feded39c73049692126cf53" +uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" +version = "0.1.3" + +[[deps.CircularArrays]] +deps = ["OffsetArrays"] +git-tree-sha1 = "3587fdbecba8c44f7e7285a1957182711b95f580" +uuid = "7a955b69-7140-5f4e-a0ed-f168c5e2e749" +version = "1.3.1" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.0" + +[[deps.Compat]] +deps = ["Dates", "LinearAlgebra", "UUIDs"] +git-tree-sha1 = "924cdca592bc16f14d2f7006754a621735280b74" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.1.0" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" + +[[deps.Conda]] +deps = ["Downloads", "JSON", "VersionParsing"] +git-tree-sha1 = "6e47d11ea2776bc5627421d59cdcc1296c058071" +uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" +version = "1.7.0" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.DataAPI]] +git-tree-sha1 = "fb5f5316dd3fd4c5e7c30a24d50643b73e37cd40" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.10.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "d1fff3a548102f48987a52a2e0d114fa97d730f0" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.13" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[deps.Distances]] +deps = ["LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "3258d0659f812acde79e8a74b11f17ac06d0ca04" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.7" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.8.6" + +[[deps.Downloads]] +deps = ["ArgTools", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.HDF5]] +deps = ["Compat", "HDF5_jll", "Libdl", "Mmap", "Random", "Requires"] +git-tree-sha1 = "9ffc57b9bb643bf3fce34f3daf9ff506ed2d8b7a" +uuid = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" +version = "0.16.10" + +[[deps.HDF5_jll]] +deps = ["Artifacts", "JLLWrappers", "LibCURL_jll", "Libdl", "OpenSSL_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "bab67c0d1c4662d2c4be8c6007751b0b6111de5c" +uuid = "0234f1f7-429e-5d53-9886-15a909be8d59" +version = "1.12.1+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "b3364212fb5d870f724876ffcd34dd8ec6d98918" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.7" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.1.1" + +[[deps.IterTools]] +git-tree-sha1 = "fa6287a4469f5e048d763df38279ee729fbd44e5" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.4.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLLWrappers]] +deps = ["Preferences"] +git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.4.1" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "3c837543ddb02250ef42f4738347454f95079d4e" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.3" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "StructTypes", "UUIDs"] +git-tree-sha1 = "fd6f0cae36f42525567108a42c1c674af2ac620d" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.9.5" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" + +[[deps.LibGit2]] +deps = ["Base64", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LogExpFunctions]] +deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "09e4b894ce6a976c354a69041a04748180d43637" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.15" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.MAT]] +deps = ["BufferedStreams", "CodecZlib", "HDF5", "SparseArrays"] +git-tree-sha1 = "971be550166fe3f604d28715302b58a3f7293160" +uuid = "23992714-dd62-5051-b70f-ba57cb901cac" +version = "0.10.3" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "3d3e902b31198a27340d0bf00d6ac452866021cf" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.9" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" + +[[deps.Memoization]] +deps = ["MacroTools"] +git-tree-sha1 = "55dc27dc3d663900d1d768822528960acadc012a" +uuid = "6fafb56a-5788-4b4e-91ca-c0cea6611c73" +version = "0.1.14" + +[[deps.Meshes]] +deps = ["CategoricalArrays", "CircularArrays", "Distances", "IterTools", "IteratorInterfaceExtensions", "LinearAlgebra", "NearestNeighbors", "Random", "RecipesBase", "ReferenceFrameRotations", "SimpleTraits", "SparseArrays", "SpecialFunctions", "StaticArrays", "StatsBase", "TableTraits", "Tables"] +git-tree-sha1 = "037fc9fcce2a83d0c933284e0bc01450e4aa5389" +uuid = "eacbb407-ea5a-433e-ab97-5258b1ca43fa" +version = "0.22.10" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.0.2" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" + +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "0e353ed734b1747fc20cd4cba0edd9ac027eff6a" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.11" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" + +[[deps.OffsetArrays]] +deps = ["Adapt"] +git-tree-sha1 = "1ea784113a6aa054c5ebd95945fa5e52c2f378e7" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.12.7" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e60321e3f2616584ff98f0a4f18d98ae6f89bbb3" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "1.1.17+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.4.1" + +[[deps.Parsers]] +deps = ["Dates"] +git-tree-sha1 = "0044b23da09b5608b4ecacb4e5e6c6332f833a7e" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.3.2" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[deps.PlanarLarvae]] +deps = ["DelimitedFiles", "HDF5", "JSON3", "MAT", "Meshes", "OrderedCollections", "SHA", "StaticArrays", "Statistics", "StructTypes"] +git-tree-sha1 = "6d3fa1c8ab879bf27dcfc22fbfbbc2dad46846df" +repo-rev = "dev" +repo-url = "https://gitlab.pasteur.fr/nyx/planarlarvae.jl" +uuid = "c2615984-ef14-4d40-b148-916c85b43307" +version = "0.5.0" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "47e5f437cc0e7ef2ce8406ce1e7e24d44915f88d" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.3.0" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.PyCall]] +deps = ["Conda", "Dates", "Libdl", "LinearAlgebra", "MacroTools", "Serialization", "VersionParsing"] +git-tree-sha1 = "1fc929f47d7c151c839c5fc1375929766fb8edcc" +uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" +version = "1.93.1" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA", "Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.RecipesBase]] +git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.2.1" + +[[deps.ReferenceFrameRotations]] +deps = ["Crayons", "LinearAlgebra", "Printf", "Random", "StaticArrays"] +git-tree-sha1 = "ec9bde2e30bc221e05e20fcec9a36a9c315e04a6" +uuid = "74f56ac7-18b3-5285-802d-d4bd4f104033" +version = "3.0.0" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.0.1" + +[[deps.SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.SpecialFunctions]] +deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "d75bda01f8c31ebb72df80a46c88b25d1c79c56d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.1.7" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "Random", "StaticArraysCore", "Statistics"] +git-tree-sha1 = "e972716025466461a3dc1588d9168334b71aafff" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.5.1" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "66fe9eb253f910fe8cf161953880cfdaef01cdf0" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.0.1" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "2c11d7290036fe7aac9038ff312d3b3a2a5bf89e" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.4.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "48598584bacbebf7d30e20880438ed1d24b7c7d6" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.33.18" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "d24a825a95a6d98c385001212dc9020d609f2d4f" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.8.1" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"] +git-tree-sha1 = "5ce79ce186cc678bbb5c5681ca3379d1ddae11a1" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.7.0" + +[[deps.TaggingBackends]] +deps = ["Dates", "HDF5", "LazyArtifacts", "MAT", "Memoization", "PlanarLarvae", "PyCall", "Random", "StaticArrays", "Statistics"] +git-tree-sha1 = "576ffec2899eb3cbfa123446de21bef19ac225af" +repo-rev = "dev" +repo-url = "https://gitlab.pasteur.fr/nyx/TaggingBackends" +uuid = "e551f703-3b82-4335-b341-d497b48d519b" +version = "0.4.0" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.TranscodingStreams]] +deps = ["Random", "Test"] +git-tree-sha1 = "216b95ea110b5972db65aa90f88d8d89dcb8851c" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.9.6" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.VersionParsing]] +git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" +uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" +version = "1.3.0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl", "OpenBLAS_jll"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000000000000000000000000000000000000..ff9c690c1f8af32b117aefdeb8520aebc5e8edd3 --- /dev/null +++ b/Project.toml @@ -0,0 +1,2 @@ +[deps] +TaggingBackends = "e551f703-3b82-4335-b341-d497b48d519b" diff --git a/models/autoencoder_config.json b/models/autoencoder_config.json new file mode 100644 index 0000000000000000000000000000000000000000..47f16364b72518690f5f7709e31e47cca78a3ba9 --- /dev/null +++ b/models/autoencoder_config.json @@ -0,0 +1,105 @@ +{ + "project_dir": "models", + "seed": 100, + "exp_name": "20220517", + "data_dir": "structured-temporal-convolution/20220425/larva_dataset_2022_04_25_20_20_100000.hdf5", + "raw_data_dir": "structured-temporal-convolution/larva_dataset/t5_t15_point_dynamics", + "log_dir": "models", + "exp_folder": "models", + "config": "models/autoencoder_config.json", + "num_workers": 4, + "n_features": 10, + "len_traj": 20, + "len_pred": 20, + "dim_latent": 10, + "activation": "relu", + "enc_filters": [ + 128, + 64, + 32, + 32, + 32, + 16 + ], + "dec_filters": [ + 128, + 64, + 32, + 32, + 32, + 16 + ], + "enc_kernel": [ + [ + 5, + 1 + ], + [ + 1, + 20 + ], + [ + 5, + 1 + ], + [ + 1, + 20 + ], + [ + 5, + 1 + ], + [ + 1, + 20 + ] + ], + "dec_kernel": [ + [ + 1, + 20 + ], + [ + 5, + 1 + ], + [ + 1, + 20 + ], + [ + 5, + 1 + ], + [ + 1, + 20 + ], + [ + 5, + 1 + ] + ], + "bias": false, + "enc_depth": 4, + "dec_depth": 4, + "init": "kaiming", + "n_clusters": 2, + "dim_reduc": "UMAP", + "optim_iter": 1000, + "pseudo_epoch": 100, + "batch_size": 128, + "lr": 0.005, + "loss": "MSE", + "cluster_penalty": null, + "cluster_penalty_coef": 0.0, + "length_penalty_coef": 0.0, + "grad_clip": 100.0, + "optimizer": "adam", + "target": [ + "past", + "present", + "future" + ] +} diff --git a/models/best_validated_encoder.pt b/models/best_validated_encoder.pt new file mode 100644 index 0000000000000000000000000000000000000000..ebc06f6e9b1c60ad2f858aabf903157a7b79a354 Binary files /dev/null and b/models/best_validated_encoder.pt differ diff --git a/pyproject.toml b/pyproject.toml index 356de2b5f9b604a07ddcd5fd2fdc9fedd87c2967..dc095dae7e2220542cc46dc7febdee0d26de3639 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,12 +10,11 @@ packages = [ [tool.poetry.dependencies] python = "^3.8,<3.11" -taggingbackends = {git = "https://gitlab.pasteur.fr/nyx/TaggingBackends", rev = "main"} structured-temporal-convolution = {git = "git@gitlab.pasteur.fr:les-larves/structured-temporal-convolution.git", branch="light-stable-for-tagging"} torch = "^1.11.0" numpy = "^1.19.3" - -[tool.poetry.dev-dependencies] +protobuf = "3.9.2" +taggingbackends = {git = "https://gitlab.pasteur.fr/nyx/TaggingBackends", rev = "dev"} [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/src/maggotuba/models/denselayer.py b/src/maggotuba/models/denselayer.py index 7196bcd3cbe76fc077ddbf176b6822ee8fd3a9c2..815e0e6fb7d06ef7ebba5d8441d46878bebd10e0 100644 --- a/src/maggotuba/models/denselayer.py +++ b/src/maggotuba/models/denselayer.py @@ -4,12 +4,9 @@ import pathlib import numpy as np import torch import torch.nn as nn -from behavior_model.models.neural_nets import Encoder -from behavior_model.models.model import Trainer +from behavior_model.models.neural_nets import Encoder, device import behavior_model.data.utils as data_utils -from behavior_model.data.enums import Label -device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") class SupervisedMaggot(nn.Module): def __init__(self, n_latent_features, n_behaviors, enc_config, enc_path, @@ -27,6 +24,7 @@ class SupervisedMaggot(nn.Module): nn.init.zeros_(self.clf.bias) def forward(self, x): + #x = torch.flip(x, (2,)) return self.clf(self.encoder(x)) """ @@ -36,6 +34,10 @@ for the decoder, and (re-)trains the entire model. Attribute `config` refers to MaggotUBA autoencoder. Attribute `clf_config` refers to the supervised model, both the retrained encoder and the trained classifier. + +Several data preprocessing steps are included for use in prediction mode. +Training the model instead relies on the readily-preprocessed data of a +*larva_dataset hdf5* file. """ class DenseLayer: def __init__(self, @@ -54,6 +56,11 @@ class DenseLayer: self.average_body_length = average_body_length self.device = device + """ + dict: JSON-deserialized parameters for the pretrained autoencoder. + Warning: not all keys are properly adjusted after the original file + is repurposed for `SupervisedMaggot`. + """ @property def config(self): if self._config is None: @@ -128,8 +135,11 @@ class DenseLayer: if data.shape[0] == 1: return data else: - ind = np.r_[np.zeros(winlen // 2, dtype=int), np.arange(data.shape[0]), (data.shape[1]-1) * - np.ones(winlen // 2 - 1, dtype=int)] + ind = np.r_[ + np.zeros(winlen // 2, dtype=int), + np.arange(data.shape[0]), + (data.shape[1]-1) * np.ones(winlen // 2 - 1, dtype=int), + ] return data[ind] def body_length(self, data): @@ -137,77 +147,115 @@ class DenseLayer: dy = np.diff(data[:,1::2], axis=1) return np.sum(np.sqrt(dx*dx + dy*dy), axis=1) - def preprocess(self, data): + def maggotuba_preprocess(self, data): # normalize length if self.average_body_length: data = data / self.average_body_length # revert the spines data = data[:,[8,9,6,7,4,5,2,3,0,1]] ws = [] - for coords in self.window(data): + for w in self.window(data): # rotate - matrix = data_utils.compute_rotation_matrix(coords) - coords = np.stack([coords[:,::2], coords[:,1::2]], axis=-1) - coords = np.einsum('ji,tpi->tpj', matrix, coords) - coords = coords.reshape(coords.shape[0],-1) - w = coords + matrix = data_utils.compute_rotation_matrix(w) + w = np.stack([w[:,::2], w[:,1::2]], axis=-1) + w = np.einsum('ji,tpi->tpj', matrix, w) + w = w.reshape(w.shape[0],-1) # center coordinates wc = np.mean(w[:,4:6], axis=0, keepdims=True) - w -= np.tile(wc, 5).reshape(1, -1) - # select coordinates columns - # (nothing to do) + w = w - np.tile(wc, (1, 5)) # reshape w = data_utils.reshape(w) ws.append(w) if ws: return self.pad(np.stack(ws)) + def preprocess(self, data): + ws = [] + for w in self.window(data): + # center coordinates + wc = np.mean(w[:,4:6], axis=0, keepdims=True) + w = w - np.tile(wc, (1, 5)) + # rotate + v = np.mean(w[:,8:10] - w[:,0:2], axis=0) + v = v / np.sqrt(np.dot(v, v)) + c, s = v / self.average_body_length # scale using the rotation matrix + rot = np.array([[ c, s], + [-s, c]]) # clockwise rotation + w = np.einsum("ij,jkl", rot, np.reshape(w.T, (2, 5, -1), order='F')) + ws.append(w) + if ws: + return self.pad(np.stack(ws))[:,:,::-1,:] # swap head and tail + def forward(self, x, train=False): - if not isinstance(x, torch.Tensor): - x = torch.from_numpy(x.astype(np.float32)) - y = self.model(x.to(self.device)) if train: - return y + return self.model(x) else: + if not isinstance(x, torch.Tensor): + x = torch.from_numpy(x.astype(np.float32)) + y = self.model(x.to(self.device)) return y.cpu().numpy() - def train(self, all_spines=None, tags=None): - if all_spines is None or tags is None: - trainer = Trainer(**self.config) - else: - data = self.preprocess(all_spines) - if data is None: - return - expected = tags # TODO + def train(self, dataset): + try: + dataset.batch_size + except AttributeError: + dataset.batch_size = self.config["batch_size"] + past_future_len = self.config["len_pred"] + present_len = self.config["len_traj"] + assert past_future_len == 20 and present_len == 20 + dataset._mask = slice(past_future_len, past_future_len + present_len) # enc_path = "best_validated_encoder.pt" if self.prepend_log_dir: - enc_path = os.path.join(config["log_dir"], enc_path) + enc_path = os.path.join(self.config["log_dir"], enc_path) + if isinstance(dataset.labels[0], str): + self.labels = dataset.labels + else: + self.labels = [s.decode() for s in dataset.labels] self.model = model = SupervisedMaggot( n_latent_features=self.config["dim_latent"], n_behaviors=self.n_behaviors, enc_config=self.config, enc_path=enc_path, ) + model.train() # this only sets the model in training mode (enables gradients) + model.to(self.device) criterion = nn.CrossEntropyLoss() + # pre-train the classifier with static encoder weights + optimizer = torch.optim.Adam(model.clf.parameters()) + print("pre-training the classifier...") + for step in range(self.config["optim_iter"] // 2): + optimizer.zero_grad() + data, expected = self.draw(dataset) + predicted = self.forward(data, train=True) + loss = criterion(predicted, expected) + #print("pre-train", torch.mean(loss).detach().numpy()) + loss.backward() + optimizer.step() + # fine-tune both the encoder and the classifier optimizer = torch.optim.Adam(model.parameters()) - model.train() - model.to(self.device) - for step in range(trainer.optim_iter): + print("fine-tuning the encoder and classifier...") + for step in range(self.config["optim_iter"] // 2): optimizer.zero_grad() - if all_spines is None: - batch = trainer.data.sample("train") - data = batch.present - expected = batch.label["present_label"].numpy() - expected = torch.tensor(expected, dtype=torch.long) - expected = expected.to(self.device) + data, expected = self.draw(dataset) predicted = self.forward(data, train=True) loss = criterion(predicted, expected) + #print("fine-tune", torch.mean(loss).detach().numpy()) loss.backward() optimizer.step() # return self + def draw(self, dataset): + data, expected = dataset.getsample() + if isinstance(data, list): + data = torch.stack(data) + data = data.to(torch.float32).to(self.device) + if isinstance(expected, list): + expected = torch.stack(expected) + expected = expected.to(torch.long).to(self.device) + return data, expected + @torch.no_grad() def predict(self, all_spines): data = self.preprocess(all_spines) @@ -224,8 +272,11 @@ class DenseLayer: model.to(self.device) output = self.forward(data) label_ids = np.argmax(output, axis=1) - labelset = {float(symbol.value): symbol.name.lower() for symbol in Label} - labels = [labelset[label] for label in label_ids] + try: + self.labels + except AttributeError: + self.labels = self.clf_config["behavior_labels"] + labels = [self.labels[label] for label in label_ids] return labels def save(self, config_path="clf_config.json", config_only=False): @@ -240,6 +291,7 @@ class DenseLayer: enc_path=self.enc_path, clf_path=self.clf_path, n_behaviors=self.n_behaviors, + behavior_labels=self.labels, # additional information (not reused): clf_depth=0, bias=True, diff --git a/src/maggotuba/models/predict_model.py b/src/maggotuba/models/predict_model.py index 4299dd2f381df7a3d2ccd758d6608f406bcf9027..afcae80017c4cfcdb3ab11ade54d4ef34b114920 100644 --- a/src/maggotuba/models/predict_model.py +++ b/src/maggotuba/models/predict_model.py @@ -3,8 +3,7 @@ from taggingbackends.data.chore import load_spine import taggingbackends.data.fimtrack as fimtrack from taggingbackends.data.labels import Labels from taggingbackends.features.skeleton import get_5point_spines -#from randomforest import RandomForest as Clf -from denselayer import DenseLayer as Clf +from denselayer import DenseLayer import numpy as np import json @@ -66,10 +65,10 @@ def predict_model(backend): config_file = [file for file in model_files if file.name.endswith("config.json")] if 1 < len(config_file): config_file = [file for file in config_file if file.name.endswith("clf_config.json")] - model = Clf(config_file[-1]) + model = DenseLayer(config_file[-1]) # assign labels if isinstance(data, dict): - ref_length = np.mean(np.concatenate([ + ref_length = np.median(np.concatenate([ model.body_length(spines) for spines in data.values() ])) model.average_body_length = ref_length @@ -81,7 +80,7 @@ def predict_model(backend): else: labels[run, larva] = dict(zip(t[larva], predictions)) else: - ref_length = model.body_length(data).mean() + ref_length = np.median(model.body_length(data)) model.average_body_length = ref_length print(f"average body length: {ref_length}") for larva in np.unique(larvae): @@ -92,11 +91,12 @@ def predict_model(backend): else: labels[run, larva] = dict(zip(t[mask], predictions)) # save the predicted labels to file - labels.labelspec = { - "names": ["run", "bend", "stop", "hunch", "back", "roll"], - "colors": ["#000000", "#ff0000", "#00ff00", "#0000ff", - "#00ffff", "#ffff00"] - } + # labels.labelspec = { + # "names": ["run", "bend", "stop", "hunch", "back", "roll"], + # "colors": ["#000000", "#ff0000", "#00ff00", "#0000ff", + # "#00ffff", "#ffff00"] + # } + labels.labelspec = model.clf_config["behavior_labels"] labels.dump(backend.processed_data_dir() / "predicted.labels") diff --git a/src/maggotuba/models/train_model.py b/src/maggotuba/models/train_model.py new file mode 100644 index 0000000000000000000000000000000000000000..7a5d3a578a78d2912ec365b5a5758856c7cf4d8d --- /dev/null +++ b/src/maggotuba/models/train_model.py @@ -0,0 +1,50 @@ +from taggingbackends.data.labels import Labels +from taggingbackends.data.dataset import LarvaDataset +from denselayer import DenseLayer, device +import numpy as np +import json +import torch +import os + +def train_model(backend): + # make_dataset generated or moved the larva_dataset file into data/interim/{instance}/ + larva_dataset_file = backend.list_interim_files() + assert len(larva_dataset_file) == 1 + dataset = LarvaDataset(larva_dataset_file[0], torch.Generator(device).manual_seed(42)) + nlabels = len(dataset.labels) + assert 0 < nlabels + # copy the pretrained model into the model instance directory + pretrained_autoencoder_dir = backend.model_dir() / ".." + config_file = None + for file in pretrained_autoencoder_dir.iterdir(): + if not file.is_file(): + continue + dst = backend.model_dir() / file.name + if file.name.endswith("config.json"): + with open(str(file)) as f: + config = json.load(f) + dir = backend.model_dir().relative_to(backend.project_dir) + config["log_dir"] = str(dir) + # optional updates? + config["project_dir"] = config["exp_folder"] = str(dir) + config["exp_name"] = backend.model_instance + config["config"] = str(dir / os.path.basename(config["config"])) + with open(str(dst), "w") as f: + json.dump(config, f, indent=2) + assert config_file is None + config_file = dst + else: + with open(str(file), "rb") as i: + with open(str(dst), "wb") as o: + o.write(i.read()) + # load the pretrained model + model = DenseLayer(autoencoder_config=config_file, n_behaviors=nlabels) + # fine-tune and save the model + model.train(dataset) + model.save() + + +from taggingbackends.main import main + +if __name__ == "__main__": + main(train_model)