{ "cells": [ { "cell_type": "markdown", "id": "2780fd26", "metadata": {}, "source": [ "# Using custom labelling schemes" ] }, { "cell_type": "markdown", "id": "874e3ada", "metadata": {}, "source": [ "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lucasmiranda42/deepof/blob/master/docs/source/tutorial_notebooks/deepof_custom_labels_tutorial.ipynb)" ] }, { "cell_type": "markdown", "id": "b059b912", "metadata": {}, "source": [ "##### What we'll cover:\n", " \n", "* Labelling schemes supported by DeepOF.\n", "* How to create a new labelling scheme and integrate it with the unsupervised pipeline." ] }, { "cell_type": "code", "execution_count": 1, "id": "998be631", "metadata": {}, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "code", "execution_count": 2, "id": "25ccbea4", "metadata": {}, "outputs": [], "source": [ "# # If using Google colab, uncomment and run this cell and the one below to set up the environment\n", "# # Note: because of how colab handles the installation of local packages, this cell will kill your runtime.\n", "# # This is not an error! Just continue with the cells below.\n", "# import os\n", "# !git clone -q https://github.com/mlfpm/deepof.git\n", "# !pip install -q -e deepof --progress-bar off\n", "# os.chdir(\"deepof\")\n", "# !curl --output tutorial_files.zip https://datashare.mpcdf.mpg.de/s/Hu1XjZkY9zml0mm/download\n", "# !unzip tutorial_files.zip" ] }, { "cell_type": "code", "execution_count": 3, "id": "80e4b2fc", "metadata": {}, "outputs": [], "source": [ "# import os\n", "# os.chdir(\"deepof\")\n", "# import os, warnings\n", "# warnings.filterwarnings('ignore')" ] }, { "cell_type": "markdown", "id": "7632cba8", "metadata": {}, "source": [ "Let's start by importing some packages. We'll use python's os library to handle paths, pickle to load saved objects, pandas to load data frames, and the data entry API within DeepOF, located in deepof.data" ] }, { "cell_type": "code", "execution_count": 4, "id": "4d85f5bf", "metadata": { "scrolled": false }, "outputs": [], "source": [ "import os\n", "import pandas as pd\n", "import pickle\n", "import deepof.data" ] }, { "cell_type": "markdown", "id": "ffdcefa1", "metadata": {}, "source": [ "We'll also need some plotting gear:" ] }, { "cell_type": "code", "execution_count": 5, "id": "e438d39f", "metadata": {}, "outputs": [], "source": [ "from IPython import display\n", "from networkx import Graph, draw\n", "import deepof.visuals\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns" ] }, { "cell_type": "markdown", "id": "983af8b4", "metadata": {}, "source": [ "### Recap: labelling schemes supported by DeepOF" ] }, { "cell_type": "markdown", "id": "9c41de92", "metadata": {}, "source": [ "DeepOF supports three labelling schemes out of the box: the `deepof_14` scheme, selected by default, the `deepof_11` scheme, which is deepof_14 without tail, and `deepof_8`, a reduced set of tracking labels that is common among, for example, [SimBA](https://goldenneurolab.com/simba) users. These schemes expect specific bodyparts to be present and named with specific names. This is necessary, as the supervised analysis and other parts of DeepOF build upon these assumtions. After all, it is hard to measure a nose-to-nose distance, if no noses where labeled." ] }, { "cell_type": "markdown", "id": "2e2d3ae5", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "0a3c0b08", "metadata": {}, "source": [ "While, as mentioned above, `deepof_14` is selected by default, the provided alternative can be selected when defining a new `deepof.Project` instance:" ] }, { "cell_type": "code", "execution_count": 6, "id": "7abae556", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[33mInfo! Set arena dimension to 380.0 mm!\u001b[0m\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\u001b[38;5;208mThe sampling rate of some of your videos differ. The maximum difference is 20191204_Day2_SI_JB08_Test_54: 24.99 fps and 20191204_Day2_SI_JB08_Test_63: 24.994 fps! Proceed with cauthion\u001b[0m\n" ] } ], "source": [ "my_deepof_project = deepof.data.Project(\n", " project_path=os.path.join(\"tutorial_files\"),\n", " video_path=os.path.join(\"tutorial_files/Videos/\"),\n", " table_path=os.path.join(\"tutorial_files/Tables/\"),\n", " project_name=\"deepof_tutorial_project\",\n", " arena=\"circular-autodetect\",\n", " animal_ids=[\"B\", \"W\"],\n", " video_format=\".mp4\",\n", " bodypart_graph=\"deepof_8\", # Can also be set to 'deepof_14' (default), 'deepof_11' or take a custom graph\n", " video_scale=\"380 mm\",\n", " iterative_imputation=\"partial\",\n", " smooth_alpha=1,\n", " exp_conditions=None,\n", ")" ] }, { "cell_type": "markdown", "id": "e8ca5323", "metadata": {}, "source": [ "The sampling rate warning here is only a minimal deviation for our 10 minute videos and can be ignored. Sometimes it may have happened that you accidentally named bodyparts differently from what DeepOF expects or that you switched labels. This can be corrected during project definition with the rename_bodyparts input. Here you can simply enter the bodypart names as they are given in your table and then see how DeepOF would reassign them. With the order of the inputs in the list you can determine which label get's assigned to what. For this example her let's assume that we accidentally swapped the front hips and used some less conventional names for other bodyparts:" ] }, { "cell_type": "code", "execution_count": 7, "id": "aec666d2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[33mInfo! Set arena dimension to 380.0 mm!\u001b[0m\n", "Your custom bodypart names will be assigned to deepOF bodyparts as follows:\n", "Nose : Nose_tip,\n", "Center : main_body_middle,\n", "Tail_base : tail_base ,\n", "Left_ear : Left_Ear,\n", "Right_ear : RigHt_ear ,\n", "Left_fhip : Right_fhip,\n", "Right_fhip : Left_fhip,\n", "Tail_tip : Tail_end,\n", "If this assignment is incorrect, please update your \"bodypart_names\" list with the correct order and rerun the project creation\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\u001b[38;5;208mThe sampling rate of some of your videos differ. The maximum difference is 20191204_Day2_SI_JB08_Test_54: 24.99 fps and 20191204_Day2_SI_JB08_Test_63: 24.994 fps! Proceed with cauthion\u001b[0m\n" ] } ], "source": [ "my_deepof_project = deepof.data.Project(\n", " project_path=os.path.join(\"tutorial_files\"),\n", " video_path=os.path.join(\"tutorial_files/Videos/\"),\n", " table_path=os.path.join(\"tutorial_files/Tables/\"),\n", " project_name=\"deepof_tutorial_project\",\n", " arena=\"circular-autodetect\",\n", " animal_ids=[\"B\", \"W\"],\n", " video_format=\".mp4\",\n", " bodypart_graph=\"deepof_8\", # Can also be set to 'deepof_14' (default), 'deepof_11' or take a custom graph\n", " video_scale=\"380 mm\",\n", " iterative_imputation=\"partial\",\n", " smooth_alpha=1,\n", " rename_bodyparts=['Nose_tip','main_body_middle','tail_base ','Left_Ear','RigHt_ear ','Right_fhip', 'Left_fhip', 'Tail_end'],\n", " exp_conditions=None,\n", ")" ] }, { "cell_type": "markdown", "id": "497cc5bb", "metadata": {}, "source": [ "The resulting print statement then shows us how bodyparts would get assigned. Since we did not really accidentally mix up anything, let's not rename anything (and define the video scale in cm for an illustration how to sue different measurment units). " ] }, { "cell_type": "code", "execution_count": 8, "id": "c4958eb6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[33mInfo! Set arena dimension to 380.0 mm!\u001b[0m\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\u001b[38;5;208mThe sampling rate of some of your videos differ. The maximum difference is 20191204_Day2_SI_JB08_Test_54: 24.99 fps and 20191204_Day2_SI_JB08_Test_63: 24.994 fps! Proceed with cauthion\u001b[0m\n" ] } ], "source": [ "my_deepof_project = deepof.data.Project(\n", " project_path=os.path.join(\"tutorial_files\"),\n", " video_path=os.path.join(\"tutorial_files/Videos/\"),\n", " table_path=os.path.join(\"tutorial_files/Tables/\"),\n", " project_name=\"deepof_tutorial_project\",\n", " arena=\"circular-autodetect\",\n", " animal_ids=[\"B\", \"W\"],\n", " video_format=\".mp4\",\n", " bodypart_graph=\"deepof_8\", # Can also be set to 'deepof_14' (default), 'deepof_11' or take a custom graph\n", " video_scale=\"38 cm\",\n", " iterative_imputation=\"partial\",\n", " smooth_alpha=1,\n", " exp_conditions=None,\n", ")" ] }, { "cell_type": "code", "execution_count": 9, "id": "94d8c03b", "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Setting up project directories...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Preprocessing tables : 100%|██████████| 6/6 [00:02<00:00, 2.24it/s, file=20191204_D..., step=Saving data] \n", "Detecting arenas : 100%|██████████| 6/6 [01:37<00:00, 16.33s/arena]\n", "Rescaling tables : 100%|██████████| 6/6 [00:00<00:00, 557.12table/s]\n", "Computing distances : 100%|██████████| 6/6 [00:00<00:00, 9.69table/s]\n", "Computing angles : 100%|██████████| 6/6 [00:00<00:00, 33.92table/s]\n", "Computing areas : 100%|██████████| 6/6 [00:01<00:00, 5.02table/s]\n", "\u001b[38;5;208mIt seems you're using deepof_8 or a custom labelling scheme which is missing key body parts.\n", "You can proceed, but not all areas will be computed.\n", "\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Done!\n" ] } ], "source": [ "my_deepof_project = my_deepof_project.create(force=True)" ] }, { "cell_type": "markdown", "id": "65393407", "metadata": {}, "source": [ "We can take a look at the constructed graph in this case (you can see how the default looks like in the previous tutorial, or change the labelling scheme to `deepof_14` in the cell above if you're following in colab):" ] }, { "cell_type": "code", "execution_count": 10, "id": "630bd119", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Loading tables : 100%|██████████| 5/5 [00:02<00:00, 1.84step/s, step=Get graph info] \n", "Sampling : 100%|██████████| 6/6 [00:00<00:00, 35.07table/s]\n", "Scaling : 100%|██████████| 6/6 [00:00<00:00, 12.85table/s]\n", "Get training windows : 100%|██████████| 5/5 [00:00<00:00, 995.52table/s]\n", "Get testing windows : 100%|██████████| 1/1 [00:00<00:00, 1000.31table/s]\n", "Reshaping : 100%|██████████| 2/2 [00:00<00:00, 20.03table/s]\n" ] } ], "source": [ "graph_preprocessed_coords, shapes, adj_matrix, to_preprocess, global_scaler = my_deepof_project.get_graph_dataset(\n", " animal_id=\"B\", # Comment out for multi-animal embeddings\n", " center=\"Center\",\n", " align=\"Center\",\n", " window_size=25,\n", " window_step=1,\n", " test_videos=1,\n", " preprocess=True,\n", " scale=\"standard\",\n", ")" ] }, { "cell_type": "code", "execution_count": 11, "id": "eeada2e4", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(3, 3))\n", "draw(Graph(adj_matrix))\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "caa71e54", "metadata": {}, "source": [ "We indeed see a graph with 8 labels! The diamond shape corresponds to nose, ears and center. The outer branches to both sides and the tail." ] }, { "cell_type": "markdown", "id": "6c99ef3c", "metadata": {}, "source": [ "This will adapt the whole downstream pipeline to work with the 8-label scheme. A more flexible alternative, if neither scheme fits your data, is to create a custom graph. Next, let's see how this can be achieved!" ] }, { "cell_type": "markdown", "id": "7079cbfb", "metadata": {}, "source": [ "### Creating a new labelling scheme" ] }, { "cell_type": "markdown", "id": "73f40230", "metadata": {}, "source": [ "Now, on for a slightly more involved task. What happens if we want another labelling scheme, not supported by DeepOF? We need to build the graph by hand using an adjacency list, and pass it to the `deepof.Project` constructor. Let's see! We'll adapt the `deepof_8` labelling scheme to include the full tail, which should look like this:" ] }, { "cell_type": "markdown", "id": "4e3b370f", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "557e1f2c", "metadata": {}, "source": [ "To start, we should create a Python dictionary specifying all connections we want. To be clear, keys in the dictionary will be connected to every element in the lists passed as values. There is no unique way of implementing this, so feel free to be creative! But an example that works is the following:" ] }, { "cell_type": "code", "execution_count": 12, "id": "0c4826a9", "metadata": {}, "outputs": [], "source": [ "deepof_custom = {\n", " \"Nose\": [\"Left_ear\", \"Right_ear\"],\n", " \"Center\": [\"Left_ear\", \"Right_ear\", \"Left_fhip\", \"Right_fhip\", \"Tail_base\"],\n", " \"Tail_base\": [\"Tail_1\"],\n", " \"Tail_1\": [\"Tail_2\"],\n", " \"Tail_2\": [\"Tail_tip\"],\n", "}" ] }, { "cell_type": "markdown", "id": "73a6284e", "metadata": {}, "source": [ "Here, `Nose` is connected to `Left_ear` and `Right_ear`, and so on. Next, we'll pass this structure to the `bodypart_graph` parameter in the `deepof.Project` constructor." ] }, { "cell_type": "code", "execution_count": 13, "id": "f9be8dbb", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[33mInfo! Set arena dimension to 380.0 mm!\u001b[0m\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\u001b[38;5;208mThe sampling rate of some of your videos differ. The maximum difference is 20191204_Day2_SI_JB08_Test_54: 24.99 fps and 20191204_Day2_SI_JB08_Test_63: 24.994 fps! Proceed with cauthion\u001b[0m\n" ] } ], "source": [ "my_deepof_project = deepof.data.Project(\n", " project_path=os.path.join(\"tutorial_files\"),\n", " video_path=os.path.join(\"tutorial_files/Videos/\"),\n", " table_path=os.path.join(\"tutorial_files/Tables/\"),\n", " project_name=\"deepof_tutorial_project\",\n", " arena=\"circular-autodetect\",\n", " animal_ids=[\"B\", \"W\"],\n", " video_format=\".mp4\",\n", " bodypart_graph=deepof_custom, # Can also be set to 'deepof_14' (default), 'deepof_11' or 'deepof_8'\n", " video_scale=\"380 mm\",\n", " iterative_imputation=\"partial\",\n", " smooth_alpha=1,\n", " exp_conditions=None,\n", ")" ] }, { "cell_type": "code", "execution_count": 14, "id": "314be955", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Setting up project directories...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Preprocessing tables : 100%|██████████| 6/6 [00:02<00:00, 2.13it/s, file=20191204_D..., step=Saving data] \n", "Detecting arenas : 100%|██████████| 6/6 [01:16<00:00, 12.67s/arena]\n", "Rescaling tables : 100%|██████████| 6/6 [00:00<00:00, 554.39table/s]\n", "Computing distances : 100%|██████████| 6/6 [00:00<00:00, 9.31table/s]\n", "Computing angles : 100%|██████████| 6/6 [00:00<00:00, 54.47table/s]\n", "Computing areas : 100%|██████████| 6/6 [00:00<00:00, 42.32table/s]\n", "\u001b[38;5;208mIt seems you're using deepof_8 or a custom labelling scheme which is missing key body parts.\n", "You can proceed, but not all areas will be computed.\n", "\u001b[0m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Done!\n" ] } ], "source": [ "my_deepof_project = my_deepof_project.create(force=True)" ] }, { "cell_type": "markdown", "id": "5333813e", "metadata": {}, "source": [ "### Getting a custom graph dataset for the unsupervised pipeline" ] }, { "cell_type": "markdown", "id": "0b987573", "metadata": {}, "source": [ "Now everything works the same way as before! Let's then obtain a new graph dataset using this custom labelling scheme, and make sure the obtained graph matches our expectations:" ] }, { "cell_type": "code", "execution_count": 15, "id": "a1573968", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Loading tables : 100%|██████████| 5/5 [00:00<00:00, 5.44step/s, step=Get graph info] \n", "Sampling : 100%|██████████| 6/6 [00:00<00:00, 31.68table/s]\n", "Scaling : 100%|██████████| 6/6 [00:00<00:00, 11.37table/s]\n", "Get training windows : 100%|██████████| 5/5 [00:00<00:00, 720.67table/s]\n", "Get testing windows : 100%|██████████| 1/1 [00:00<00:00, 990.62table/s]\n", "Reshaping : 100%|██████████| 2/2 [00:00<00:00, 12.39table/s]\n" ] } ], "source": [ "graph_preprocessed_coords, shapes, adj_matrix, to_preprocess, global_scaler = my_deepof_project.get_graph_dataset(\n", " animal_id=\"B\", # Comment out for multi-animal embeddings\n", " center=\"Center\",\n", " align=\"Tail_base\",\n", " window_size=25,\n", " window_step=1,\n", " test_videos=1,\n", " preprocess=True,\n", " scale=\"standard\",\n", ")" ] }, { "cell_type": "code", "execution_count": 23, "id": "ff935bfb", "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(3, 3))\n", "draw(Graph(adj_matrix))\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "8dea4b2a", "metadata": {}, "source": [ "**NOTE**: the supervised annotations and other parts of DeepOF require the presence or absence of specific bodyparts, so keep in mind that many supervised behaviors cannot be computed, if the respective bodyparts are not included in your custom labelling scheme " ] }, { "cell_type": "markdown", "id": "eb8ced0d", "metadata": {}, "source": [ "And that's it! Now you should be able to adapt the unsupervised pipeline within DeepOF to any labelling scheme of choice. Note that this should still work with bottom-up or side view videos." ] }, { "cell_type": "markdown", "id": "8ded862f", "metadata": {}, "source": [ "### Wrapping up" ] }, { "cell_type": "markdown", "id": "d4f08308", "metadata": {}, "source": [ "Thank you for making it until the end. This was a slightly more involved tutorial for those users that do not rely on top-down labels like those provided out of the box. Stay tuned for more content, and make sure to raise an [issue](https://github.com/mlfpm/deepof/issues) in our GitHub repository if you have any questions!" ] } ], "metadata": { "kernelspec": { "display_name": "dof", "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.10.11" } }, "nbformat": 4, "nbformat_minor": 5 }