diff --git a/Manifest.toml b/Manifest.toml index aed827e057d313b7f8fa5c0cbd1c2b2221de3dc1..a4a7ee073294daca4cadfb488cb28ffcc390b800 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.8.2" manifest_format = "2.0" -project_hash = "4e8a5dcb55ba02909578a76b57750f4d6fb0a766" +project_hash = "d37bc0692e4cb75dce4365cae9dc31c02a907c73" [[deps.AbstractFFTs]] deps = ["ChainRulesCore", "LinearAlgebra"] @@ -147,12 +147,6 @@ deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" version = "0.5.2+0" -[[deps.Conda]] -deps = ["Downloads", "JSON", "VersionParsing"] -git-tree-sha1 = "6e47d11ea2776bc5627421d59cdcc1296c058071" -uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" -version = "1.7.0" - [[deps.Contour]] git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" @@ -676,12 +670,6 @@ git-tree-sha1 = "2ce8695e1e699b68702c03402672a69f54b8aca9" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" version = "2022.2.0+0" -[[deps.MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "42324d08725e200c23d4dfb549e0d5d89dede2d2" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.10" - [[deps.Makie]] deps = ["Animations", "Base64", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Distributions", "DocStringExtensions", "FFMPEG", "FileIO", "FixedPointNumbers", "Formatting", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MakieCore", "Markdown", "Match", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "Printf", "Random", "RelocatableFolders", "Serialization", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "UnicodeFun"] git-tree-sha1 = "b0323393a7190c9bf5b03af442fc115756df8e59" @@ -726,12 +714,6 @@ deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.0+0" -[[deps.Memoization]] -deps = ["MacroTools"] -git-tree-sha1 = "55dc27dc3d663900d1d768822528960acadc012a" -uuid = "6fafb56a-5788-4b4e-91ca-c0cea6611c73" -version = "0.1.14" - [[deps.Meshes]] deps = ["Bessels", "CircularArrays", "Distances", "IterTools", "IteratorInterfaceExtensions", "LinearAlgebra", "NearestNeighbors", "Random", "ReferenceFrameRotations", "SparseArrays", "StaticArrays", "StatsBase", "TableTraits", "Tables", "TransformsBase"] git-tree-sha1 = "589bc39cdaa212b352918b4c11cc4d2eaf899822" @@ -942,12 +924,6 @@ git-tree-sha1 = "d7a7aef8f8f2d537104f170139553b14dfe39fe9" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.7.2" -[[deps.PyCall]] -deps = ["Conda", "Dates", "Libdl", "LinearAlgebra", "MacroTools", "Serialization", "VersionParsing"] -git-tree-sha1 = "53b8b07b721b77144a0fbbbc2675222ebf40a02d" -uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" -version = "1.94.1" - [[deps.QOI]] deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce" @@ -1157,14 +1133,6 @@ git-tree-sha1 = "c79322d36826aa2f4fd8ecfa96ddb47b174ac78d" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" version = "1.10.0" -[[deps.TaggingBackends]] -deps = ["Dates", "HDF5", "LazyArtifacts", "MAT", "Memoization", "OrderedCollections", "PlanarLarvae", "PyCall", "Random", "StaticArrays", "Statistics"] -git-tree-sha1 = "610f42dc290ff67b54b4fbc84edebaec94eba2d8" -repo-rev = "main" -repo-url = "https://gitlab.pasteur.fr/nyx/TaggingBackends" -uuid = "e551f703-3b82-4335-b341-d497b48d519b" -version = "0.5.0" - [[deps.Tar]] deps = ["ArgTools", "SHA"] uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" @@ -1224,11 +1192,6 @@ git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" version = "0.4.1" -[[deps.VersionParsing]] -git-tree-sha1 = "58d6e80b4ee071f5efd07fda82cb9fbe17200868" -uuid = "81def892-9a0e-5fdd-b105-ffc91e053289" -version = "1.3.0" - [[deps.WGLMakie]] deps = ["Colors", "FileIO", "FreeTypeAbstraction", "GeometryBasics", "Hyperscript", "ImageMagick", "JSServe", "LinearAlgebra", "Makie", "Observables", "RelocatableFolders", "ShaderAbstractions", "StaticArrays"] git-tree-sha1 = "0c7a980515d2072b1bc094668b5ca94671d020de" diff --git a/Project.toml b/Project.toml index c480193e01a5a3f39f4bb7408449e31231b92f33..492c4be584ceb11bfbbf6c8adbd5a1275249f6fc 100644 --- a/Project.toml +++ b/Project.toml @@ -20,7 +20,6 @@ PlanarLarvae = "c2615984-ef14-4d40-b148-916c85b43307" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -TaggingBackends = "e551f703-3b82-4335-b341-d497b48d519b" TidyObservables = "c8131bbd-73a8-4254-a42d-d5d4c5febb31" WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008" diff --git a/README.md b/README.md index f298f5270650de964b0732c555475ce007c02a5a..17a2fff508a673f3e6cbf2e213e7e6ff65cec9fd 100644 --- a/README.md +++ b/README.md @@ -75,16 +75,16 @@ julia> using LarvaTagger; display(larvaeditor("path/to/data/file"; backend_direc Similarly, to let *larvatagger.jl* know about MaggotUBA: ``` -scripts/larvatagger.jl open "path/to/data/file" --backends="path/to/MaggotUBA's/parent/directory" --browser +scripts/larvatagger.jl open <path/to/data/file> --backends=<path/to/MaggotUBA's/parent/directory> --browser ``` The larvatagger.jl script can be used to proceed with training a new tagger: ``` -scripts/larvatagger.jl train "path/to/backend" "path/to/data/repository" "tagger-name" +scripts/larvatagger.jl train <path/to/backend> <path/to/data/repository> <tagger-name> ``` and applying a tagger to a tracking data file: ``` -scripts/larvatagger.jl predict "path/to/backend" "tagger-name" "path/to/data/file" +scripts/larvatagger.jl predict <path/to/backend> <tagger-name> <path/to/data/file> --skip-make-dataset ``` The `train` and `predict` commands admit more arguments. Check them out with: diff --git a/recipes/.dockerignore b/recipes/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..0eebccb20a89fd5939ab37e9f18bfd889b21cfc0 --- /dev/null +++ b/recipes/.dockerignore @@ -0,0 +1,37 @@ +#* + +**/.git +**/data/raw +**/data/interim +**/data/processed +**/notebooks +**/*.ipynb +**/__pycache__ +**/jl.*.cov +**/*.hdf5 +**/*.mat +**/*.spine +**/*.outline +**/*.csv +**/*.label +**/*.labels +**/*.pt +**/*.json +**/*.pkl +**/*.png +**/*.svg +**/*.avi +**/*.webm +**/*.gz +**/*.tgz +**/*.bz2 + +!**/*.toml +!**/*.jl +!**/*.py +!**/*.sh +!**/*.md +!**/LICENSE +!**/scripts/tagging-backend +!**/pretrained_models/default +!**/models/20221005 diff --git a/recipes/Dockerfile b/recipes/Dockerfile index 61a03ec76f965107d87bda1c48fe5124a1a703ac..ac5264d3ce6b6dcef3e1b0bb40f1911c9d15b690 100644 --- a/recipes/Dockerfile +++ b/recipes/Dockerfile @@ -2,32 +2,30 @@ FROM julia:1.8.2-bullseye ENV JULIA_PROJECT=/app ENV JULIA_DEPOT_PATH=/usr/local/share/julia +ENV POETRY_VIRTUALENVS_PATH=/usr/local/share/poetry ARG BRANCH=main ARG TIMEZONE=UTC RUN apt-get update \ && apt-get install -y git \ && rm -rf /var/lib/apt/lists/* \ - && git clone --depth 1 --single-branch -b $BRANCH https://gitlab.pasteur.fr/nyx/larvatagger.jl $JULIA_PROJECT \ - && mkdir -p $JULIA_DEPOT_PATH \ - && echo "JULIA_DEPOT_PATH=$JULIA_DEPOT_PATH" >> /etc/environment \ - && julia -e 'using Pkg; Pkg.instantiate()' \ + && git clone --depth 1 --single-branch -b $BRANCH https://gitlab.pasteur.fr/nyx/larvatagger.jl "$JULIA_PROJECT" \ + && julia -e 'using Pkg; try Pkg.rm("TaggingBackends"); catch end; Pkg.instantiate()' \ && ln -s $JULIA_PROJECT/scripts/larvatagger.jl /bin \ && ln -snf /usr/share/zoneinfo/$TIMEZONE /etc/localtime \ && echo $TIMEZONE > /etc/timezone ARG BACKEND -RUN cd $JULIA_PROJECT; \ +RUN cd "$JULIA_PROJECT"; \ if [ "$BACKEND" = "MaggotUBA/20221005" ]; then \ - apt-get update \ + julia --project=. -e "using Pkg; Pkg.add(url=\"https://gitlab.pasteur.fr/nyx/TaggingBackends\", rev=\"$BRANCH\")" \ + && apt-get update \ && apt-get install -y python3-pip \ && python3 -m pip install poetry \ + && mkdir -p "$POETRY_VIRTUALENVS_PATH" \ && git clone --depth 1 --single-branch -b 20221005 https://gitlab.pasteur.fr/nyx/MaggotUBA-adapter MaggotUBA \ && cd MaggotUBA \ - && python3 -m poetry install \ - && python3 -m poetry run python -c 'import julia; julia.install()' \ - #&& python3 -m poetry run python -c "from julia.api import Julia; Julia(compiled_modules=False); from julia import Pkg; Pkg.add(url=\"https://gitlab.pasteur.fr/nyx/planarlarvae.jl\", rev=\"$BRANCH\"); Pkg.add(url=\"https://gitlab.pasteur.fr/nyx/TaggingBackends\", rev=\"$BRANCH\")" \ - && cd .. \ + && poetry install \ && apt-get clean \ && rm -rf /var/lib/apt/lists/*; \ fi diff --git a/recipes/Dockerfile.local b/recipes/Dockerfile.local index 548889d30092a55c13593c53fe514e4be7f6f0be..a3926b81340a76110d3bb0f21e9f6c7cf1ec7721 100644 --- a/recipes/Dockerfile.local +++ b/recipes/Dockerfile.local @@ -1,14 +1,48 @@ FROM julia:1.8.2-bullseye -COPY src /app/src/ -COPY scripts /app/scripts/ -COPY Project.toml Manifest.toml /app/ +ENV JULIA_PROJECT=/app/TaggingBackends +ENV JULIA_DEPOT_PATH=/usr/local/share/julia +ENV POETRY_VIRTUALENVS_PATH=/usr/local/share/poetry + +ARG PLANARLARVAE=./PlanarLarvae +ARG LARVATAGGER=./LarvaTagger +ARG TAGGINGBACKENDS=./TaggingBackends +ARG MAGGOTUBA_CORE=./MaggotUBA-core +ARG MAGGOTUBA_ADAPTER=./maggot + +COPY $PLANARLARVAE/src /app/PlanarLarvae/src +COPY $PLANARLARVAE/Project.toml $PLANARLARVAE/Manifest.toml /app/PlanarLarvae/ +COPY $LARVATAGGER/src /app/src +COPY $LARVATAGGER/scripts /app/scripts +COPY $LARVATAGGER/Project.toml $LARVATAGGER/Manifest.toml /app/ RUN apt-get update \ - && apt-get install -y git \ - && rm -rf /var/lib/apt/lists/* \ + && apt-get install -y git python3-pip \ && cd /app \ - && julia --project=. -e 'using Pkg; Pkg.instantiate()' \ - && ln -s /app/scripts/larvatagger.jl /bin + && julia --project=. -e 'using Pkg; try Pkg.rm("TaggingBackends"); catch end; try Pkg.develop(path="PlanarLarvae"); catch end; try Pkg.add(url="https://gitlab.com/dbc-nyx/tidyobservables.jl"); catch end; try Pkg.add(url="https://gitlab.com/dbc-nyx/ObservationPolicies.jl"); catch end; Pkg.instantiate()' \ + && ln -s /app/scripts/larvatagger.jl /bin \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && ls /app + +COPY $TAGGINGBACKENDS/src /app/TaggingBackends/src +COPY $TAGGINGBACKENDS/scripts /app/TaggingBackends/scripts +COPY $TAGGINGBACKENDS/Project.toml $TAGGINGBACKENDS/Manifest.toml $TAGGINGBACKENDS/pyproject.toml /app/TaggingBackends/ +COPY $MAGGOTUBA_CORE/src /app/MaggotUBA-core/src +COPY $MAGGOTUBA_CORE/pyproject.toml /app/MaggotUBA-core/ +COPY $MAGGOTUBA_ADAPTER/src /app/MaggotUBA/src +COPY $MAGGOTUBA_ADAPTER/pyproject.toml /app/MaggotUBA/ +COPY $MAGGOTUBA_ADAPTER/models/20221005 /app/MaggotUBA/models/20221005 +COPY $MAGGOTUBA_ADAPTER/pretrained_models/default /app/MaggotUBA/pretrained_models/default + +RUN python3 -m pip install poetry \ + && mkdir -p "$POETRY_VIRTUALENVS_PATH" \ + && cd /app/TaggingBackends \ + && julia --project=. -e 'using Pkg; Pkg.develop(path="../PlanarLarvae"); Pkg.instantiate()' \ + && poetry install \ + && cd /app/MaggotUBA \ + && poetry add ../MaggotUBA-core \ + && poetry add ../TaggingBackends \ + && poetry install ENTRYPOINT ["larvatagger.jl"] diff --git a/recipes/README.md b/recipes/README.md index fd9c54cb77892d91022fc8a598370f1870dd616f..d2847bdc3548158d148dbc5f683b3ca2c60d439d 100644 --- a/recipes/README.md +++ b/recipes/README.md @@ -31,18 +31,20 @@ This is required, since no files outside the container can be accessed. The port *LarvaTagger.jl* listens to must also be exported with `-p 9284:9284` so that it can be accessed from outside the container. -Just like the `scripts/larvatagger.jl` script, the docker image admits more commands, including `import`, `train` and `predict`, or options such as `--help`. +Just like the `larvatagger.jl` script, the docker image admits more commands, including `import`, `train` and `predict`, or options such as `--help`. For these other commands, neither `-i` nor `-p 9284:9284` are necessary. -See also standalone script [`scripts/larvatagger.sh`](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/blob/main/scripts/larvatagger.sh) that wraps `docker` and exposes a simpler interface. For example: +For Unix-like systems, see also standalone script [`larvatagger.sh`](https://gitlab.pasteur.fr/nyx/larvatagger.jl/-/blob/main/scripts/larvatagger.sh) that can be downloaded separately and wraps the `docker` command and exposes a simpler interface. For example: ``` -scripts/larvatagger.sh open path/to/your/file +./larvatagger.sh open path/to/your/file ``` +Note you may need to set larvatagger.sh permissions so that it can be executed. + ## Building an image -The `scripts/larvatagger.sh` script features a `build` command: +The `larvatagger.sh` script features a `build` command: ``` scripts/larvatagger.sh build @@ -54,3 +56,18 @@ Optionally, you can also get the default *20221005* backend with: scripts/larvatagger.sh build --get-backend ``` +The `build` command requires a local copy of the LarvaTagger.jl project. In addition, the larvatagger.sh script must be executed from the project root directory, hence the path `scripts/larvatagger.sh`. + +## `train` and `predict` + +The larvatagger.sh script is recommended for the `train` and `predict` commands. + +Type `scripts/larvatagger.sh` alone to check out about command usage. + +For the trained models to be persistant, the `train` command must store them outside the container. +Per default, `larvatagger.sh train` creates a *models* directory in the current directory and stores the model instances in there. + +Note that the `larvatagger.sh` script is required here. Alternatively, the external *models* directory can be manually mounted as */app/MaggotUBA/models*. Ownership of the generated files will have to be fixed (*root* per default on Unix-like systems). + +The `predict` command can use external model instances passing paths instead of instance names. +To distinguish between paths and names, `larvatagger.sh` checks whether the corresponding directory exists. If a directory exists at the path pointed to by `--model-instance` (on the host), then it is mounted into the container as an external trained model. diff --git a/scripts/larvatagger.sh b/scripts/larvatagger.sh index 7ff894ced39e07918b88f6c577afb2b66b55a47b..8739258c75d3b4368eb9c28399aabfd7c5b36251 100755 --- a/scripts/larvatagger.sh +++ b/scripts/larvatagger.sh @@ -10,10 +10,10 @@ LARVATAGGER_IMAGE=flaur/larvatagger fi fi -IO_UID=$(id -u $USER) -IO_GID=$(id -g $USER) -RUN_ARGS="-u $IO_UID:$IO_GID -v $(pwd):/data" -RUN_ARGS="-e IO_UID=$IO_UID -e IO_GID=$IO_GID -v $(pwd):/data" +HOST_UID=$(id -u $USER) +HOST_GID=$(id -g $USER) +RUN_ARGS="-u $HOST_UID:$HOST_GID -v $(pwd):/data" +RUN_ARGS="-e HOST_UID=$HOST_UID -e HOST_GID=$HOST_GID -v $(pwd):/data" case "$cmd" in @@ -36,7 +36,9 @@ done DOCKER_ARGS="--build-arg TIMEZONE=$(cat /etc/timezone) $DOCKER_ARGS" if [ "$BUILD" == "--dev" ]; then if ! [[ "$LARVATAGGER_IMAGE" == *:* ]]; then LARVATAGGER_IMAGE="${LARVATAGGER_IMAGE}:dev"; fi -docker build -t "$LARVATAGGER_IMAGE" -f recipes/Dockerfile.local ${DOCKER_ARGS}. +PROJECT_ROOT=$(basename $(pwd)) +cd .. +DOCKER_BUILDKIT=1 docker build -t "$LARVATAGGER_IMAGE" -f "$PROJECT_ROOT/recipes/Dockerfile.local" ${DOCKER_ARGS}. elif [ "$BUILD" == "--stable" ]; then if ! [[ "$LARVATAGGER_IMAGE" == *:* ]]; then LARVATAGGER_IMAGE="${LARVATAGGER_IMAGE}:stable"; fi docker build -t "$LARVATAGGER_IMAGE" -f recipes/Dockerfile ${DOCKER_ARGS}. @@ -68,28 +70,73 @@ docker run $RUN_ARGS "$LARVATAGGER_IMAGE" import "/data/$file" $@ train) -backend_path=$1; shift data_repository=$1; shift tagger=$1; shift -docker run $RUN_ARGS "$LARVATAGGER_IMAGE" train "/data/$backend_path" "/data/$data_repository" "$tagger" $@ + +external_models_dir=models +path=$(dirname $tagger) +if [ "$path" != "." ]; then +external_models_dir=$path +tagger=$(basename $tagger) +fi + +backend=MaggotUBA +while [ -n "$1" ]; do +if [ "$1" = "--backend" ]; then +backend=$2; shift 2 +else +break +fi +done + +if [ -n "$external_models_dir" ]; then +mkdir -p "$external_models_dir" +RUN_ARGS="$RUN_ARGS --mount type=bind,src=$(realpath $external_models_dir),dst=/app/$backend/models" +fi + +echo "docker run $RUN_ARGS \"$LARVATAGGER_IMAGE\" train \"/app/$backend\" \"/data/$data_repository\" \"$tagger\" $@" + +docker run $RUN_ARGS "$LARVATAGGER_IMAGE" train "/app/$backend" "/data/$data_repository" "$tagger" $@ ;; predict) -backend_path=$1; shift -tagger=$1; shift data_file=$1; shift -docker run $RUN_ARGS "$LARVATAGGER_IMAGE" predict "/data/$backend_path" "$tagger" "/data/$data_file" $@ + +backend=MaggotUBA +tagger=20221005 +while [ -n "$1" ]; do +if [ "$1" = "--model-instance" ]; then +tagger=$2; shift 2 +if [ -d "$tagger" ]; then +tagger_path=$tagger +tagger=$(basename $tagger_path) +fi +elif [ "$1" = "--backend" ]; then +backend=$2; shift 2 +else +break +fi +done + +if [ -n "$tagger_path" ]; then +RUN_ARGS="$RUN_ARGS --mount type=bind,src=$(realpath $tagger_path),dst=/app/$backend/models/$tagger" +fi + +echo "docker run $RUN_ARGS \"$LARVATAGGER_IMAGE\" predict \"/app/$backend\" \"$tagger\" \"/data/$data_file\" $@" + +docker run $RUN_ARGS "$LARVATAGGER_IMAGE" predict "/app/$backend" "$tagger" "/data/$data_file" $@ ;; *) -echo "usage: $0 build [--get-backend]" +echo "usage: $0 build [--stable] [--get-backend]" echo " $0 open <filepath>" echo " $0 import <filepath> [<outputfilename>] [--id=<runid>] [--framerate=<fps>]" -echo " $0 train <backendpath> <datarepository> <taggername>" -echo " $0 predict <backendpath> <taggername> <datafile>" +echo " $0 train <datarepository> <taggername> [--backend <name>]" +echo " $0 predict <datafile> [--backend <name>] [--model-instance <taggername>]" echo 'see also `larvatagger.jl --help` for more arguments' +echo '`larvatagger.jl` arguments must come after the above mentioned arguments' ;; esac diff --git a/src/Taggers.jl b/src/Taggers.jl index 22de6b00be453a7d8e6437d76435e918a791af61..cb1b637d9cc0ab69aca742b8cff18d6b9dc1ab16 100644 --- a/src/Taggers.jl +++ b/src/Taggers.jl @@ -110,12 +110,12 @@ end Attempt to fix file ownership. This is useful in a Docker container that runs as root. -Environment variables IO_UID and IO_GID are set in the container by the larvatagger.sh script +Environment variables HOST_UID and HOST_GID are set in the container by the larvatagger.sh script so that the actual user is known. """ function check_permissions(file) try - uid, gid = ENV["IO_UID"], ENV["IO_GID"] + uid, gid = ENV["HOST_UID"], ENV["HOST_GID"] @info "Changing file ownership" uid gid file chown(file, parse(Int, uid), parse(Int, gid)) catch diff --git a/src/cli.jl b/src/cli.jl index 914f26707efaecca78cbce845eb29e96c778a2fc..26c02376afe005b049503b399b6034333e04bb34 100644 --- a/src/cli.jl +++ b/src/cli.jl @@ -8,7 +8,7 @@ usage = """Larva Tagger. Usage: larvatagger.jl import <input-path> [<output-file>] [--id=<id>] [--framerate=<fps>] larvatagger.jl open <file-path> [--backends=<path>] [--port=<number>] [--quiet] [--viewer] [--browser] - larvatagger.jl train <backend-path> <data-path> <model-instance> [--pretrained-model=<instance>] [--labels=<comma-separated-list>] [--sample-size=<N>] + larvatagger.jl train <backend-path> <data-path> <model-instance> [--pretrained-model=<instance>] [--labels=<comma-separated-list>] [--sample-size=<N>] [--layers=<L>] larvatagger.jl predict <backend-path> <model-instance> <data-path> [--skip-make-dataset] larvatagger.jl -h | --help @@ -23,6 +23,7 @@ Options: --browser Automatically open a browser tab at the served location. --skip-make-dataset Skip the make_dataset stage; makes `predict` faster. --sample-size=<N> Sample only N track segments from the data repository. + --layers=<L> (MaggotUBA) Number of layers of the classifier. --labels=<comma-separated-list> Comma-separated list of behavior tags/labels. --pretrained-model=<instance> Name of the pretrained encoder (from `pretrained_models` registry). @@ -88,10 +89,14 @@ function main(args=ARGS) tagger = Tagger(parsed_args["<backend-path>"], parsed_args["<model-instance>"]) Taggers.reset(tagger) Taggers.push(tagger, parsed_args["<data-path>"]) + kwargs = Dict{Symbol, Any}() + layers = parsed_args["--layers"] + isnothing(layers) || (kwargs[:layers] = layers) train(tagger; pretrained_instance=parsed_args["--pretrained-model"], labels=parsed_args["--labels"], sample_size=parsed_args["--sample-size"], + kwargs... ) elseif parsed_args["predict"] tagger = Tagger(parsed_args["<backend-path>"], parsed_args["<model-instance>"])