Skip to content

Commit e54c0d1

Browse files
authored
Merge branch 'main' into aistats2025
2 parents d81b93d + 47945ca commit e54c0d1

File tree

3 files changed

+24
-20
lines changed

3 files changed

+24
-20
lines changed

cebra/data/assets.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def download_file_with_progress_bar(url: str,
9393
)
9494

9595
# Create the directory and any necessary parent directories
96-
location_path.mkdir(exist_ok=True)
96+
location_path.mkdir(parents=True, exist_ok=True)
9797

9898
filename = filename_match.group(1)
9999
file_path = location_path / filename

cebra/integrations/matplotlib.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ def _to_heatmap_format(
684684
else:
685685
heatmap_values[i, j] = score_dict[label_i, label_j]
686686

687-
return np.minimum(heatmap_values * 100, 99)
687+
return heatmap_values * 100
688688

689689
def _create_text(self):
690690
"""Create the text to add in the confusion matrix grid and the title."""

docs/source/usage.rst

+22-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Using CEBRA
22
===========
33

4-
This page covers a standard CEBRA usage. We recommend checking out the :py:doc:`demos` for in-depth CEBRA usage examples as well. Here we present a quick overview on how to use CEBRA on various datasets. Note that we provide two ways to interact with the code:
4+
This page covers a standard CEBRA usage. We recommend checking out the :py:doc:`demos` for CEBRA usage examples as well. Here we present a quick overview on how to use CEBRA on various datasets. Note that we provide two ways to interact with the code:
55

66
* For regular usage, we recommend leveraging the **high-level interface**, adhering to ``scikit-learn`` formatting.
77
* Upon specific needs, advanced users might consider diving into the **low-level interface** that adheres to ``PyTorch`` formatting.
@@ -12,7 +12,7 @@ Firstly, why use CEBRA?
1212

1313
CEBRA is primarily designed for producing robust, consistent extractions of latent factors from time-series data. It supports three modes, and is a self-supervised representation learning algorithm that uses our modified contrastive learning approach designed for multi-modal time-series data. In short, it is a type of non-linear dimensionality reduction, like `tSNE <https://www.jmlr.org/papers/v9/vandermaaten08a.html>`_ and `UMAP <https://arxiv.org/abs/1802.03426>`_. We show in our original paper that it outperforms tSNE and UMAP at producing closer-to-ground-truth latents and is more consistent.
1414

15-
That being said, CEBRA can be used on non-time-series data and it does not strictly require multi-modal data. In general, we recommend considering using CEBRA for measuring changes in consistency across conditions (brain areas, cells, animals), for hypothesis-guided decoding, and for topological exploration of the resulting embedding spaces. It can also be used for visualization and considering dynamics within the embedding space. For examples of how CEBRA can be used to map space, decode natural movies, and make hypotheses for neural coding of sensorimotor systems, see our paper (Schneider, Lee, Mathis, 2023).
15+
That being said, CEBRA can be used on non-time-series data and it does not strictly require multi-modal data. In general, we recommend considering using CEBRA for measuring changes in consistency across conditions (brain areas, cells, animals), for hypothesis-guided decoding, and for topological exploration of the resulting embedding spaces. It can also be used for visualization and considering dynamics within the embedding space. For examples of how CEBRA can be used to map space, decode natural movies, and make hypotheses for neural coding of sensorimotor systems, see `Schneider, Lee, Mathis. Nature 2023 <https://www.nature.com/articles/s41586-023-06031-6>`_.
1616

1717
The CEBRA workflow
1818
------------------
@@ -22,7 +22,7 @@ We recommend to start with running CEBRA-Time (unsupervised) and look both at th
2222

2323
(1) Use CEBRA-Time for unsupervised data exploration.
2424
(2) Consider running a hyperparameter sweep on the inputs to the model, such as :py:attr:`cebra.CEBRA.model_architecture`, :py:attr:`cebra.CEBRA.time_offsets`, :py:attr:`cebra.CEBRA.output_dimension`, and set :py:attr:`cebra.CEBRA.batch_size` to be as high as your GPU allows. You want to see clear structure in the 3D plot (the first 3 latents are shown by default).
25-
(3) Use CEBRA-Behavior with many different labels and combinations, then look at the InfoNCE loss - the lower the loss value, the better the fit (see :py:doc:`cebra-figures/figures/ExtendedDataFigure5`), and visualize the embeddings. The goal is to understand which labels are contributing to the structure you see in CEBRA-Time, and improve this structure. Again, you should consider a hyperparameter sweep.
25+
(3) Use CEBRA-Behavior with many different labels and combinations, then look at the InfoNCE loss - the lower the loss value, the better the fit (see :py:doc:`cebra-figures/figures/ExtendedDataFigure5`), and visualize the embeddings. The goal is to understand which labels are contributing to the structure you see in CEBRA-Time, and improve this structure. Again, you should consider a hyperparameter sweep (and avoid overfitting by performing the proper train/validation split (see Step 3 in our quick start guide below).
2626
(4) Interpretability: now you can use these latents in downstream tasks, such as measuring consistency, decoding, and determining the dimensionality of your data with topological data analysis.
2727

2828
All the steps to do this are described below. Enjoy using CEBRA! 🔥🦓
@@ -179,7 +179,7 @@ We provide a set of pre-defined models. You can access (and search) a list of av
179179

180180
Then, you can choose the one that fits best with your needs and provide it to the CEBRA model as the :py:attr:`~.CEBRA.model_architecture` parameter.
181181

182-
As an indication the table below presents the model architecture we used to train CEBRA on the datasets presented in our paper (Schneider, Lee, Mathis, 2022).
182+
As an indication the table below presents the model architecture we used to train CEBRA on the datasets presented in our paper (Schneider, Lee, Mathis. Nature 2023).
183183

184184
.. list-table::
185185
:widths: 25 25 20 30
@@ -265,9 +265,8 @@ For standard usage we recommend the default values (i.e., ``InfoNCE`` and ``cosi
265265

266266
.. rubric:: Temperature :py:attr:`~.CEBRA.temperature`
267267

268-
:py:attr:`~.CEBRA.temperature` has the largest effect on visualization of the embedding (see :py:doc:`cebra-figures/figures/ExtendedDataFigure2`). Hence, it is important that it is fitted to your specific data.
268+
:py:attr:`~.CEBRA.temperature` has the largest effect on *visualization* of the embedding (see :py:doc:`cebra-figures/figures/ExtendedDataFigure2`). Hence, it is important that it is fitted to your specific data. Lower temperatures (e.g. around 0.1) will result in a more dispersed embedding, higher temperatures (larger than 1) will concentrate the embedding.
269269

270-
The simplest way to handle it is to use a *learnable temperature*. For that, set :py:attr:`~.CEBRA.temperature_mode` to ``auto``. :py:attr:`~.CEBRA.temperature` will be trained alongside the model.
271270

272271
🚀 For advance usage, you might need to find the optimal :py:attr:`~.CEBRA.temperature`. For that we recommend to perform a grid-search.
273272

@@ -307,7 +306,6 @@ Here is an example of a CEBRA model initialization:
307306
cebra_model = CEBRA(
308307
model_architecture = "offset10-model",
309308
batch_size = 1024,
310-
temperature_mode="auto",
311309
learning_rate = 0.001,
312310
max_iterations = 10,
313311
time_offsets = 10,
@@ -321,8 +319,7 @@ Here is an example of a CEBRA model initialization:
321319
.. testoutput::
322320

323321
CEBRA(batch_size=1024, learning_rate=0.001, max_iterations=10,
324-
model_architecture='offset10-model', temperature_mode='auto',
325-
time_offsets=10)
322+
model_architecture='offset10-model', time_offsets=10)
326323

327324
.. admonition:: See API docs
328325
:class: dropdown
@@ -568,7 +565,8 @@ We provide a simple hyperparameters sweep to compare CEBRA models with different
568565
learning_rate = [0.001],
569566
time_offsets = 5,
570567
max_iterations = 5,
571-
temperature_mode = "auto",
568+
temperature_mode='constant',
569+
temperature = 0.1,
572570
verbose = False)
573571

574572
# 2. Define the datasets to iterate over
@@ -820,7 +818,7 @@ It takes a CEBRA model and returns a 2D plot of the loss against the number of i
820818
Displaying the temperature
821819
""""""""""""""""""""""""""
822820

823-
:py:attr:`~.CEBRA.temperature` has the largest effect on the visualization of the embedding. Hence it might be interesting to check its evolution when ``temperature_mode=auto``.
821+
:py:attr:`~.CEBRA.temperature` has the largest effect on the visualization of the embedding. Hence it might be interesting to check its evolution when ``temperature_mode=auto``. We recommend only using `auto` if you have first explored the `constant` setting. If you use the ``auto`` mode, please always check the time evolution of the temperature over time alongside the loss curve.
824822

825823
To that extend, you can use the function :py:func:`~.plot_temperature`.
826824

@@ -1186,9 +1184,10 @@ Improve model performance
11861184
🧐 Below is a (non-exhaustive) list of actions you can try if your embedding looks different from what you were expecting.
11871185

11881186
#. Assess that your model `converged <https://machine-learning.paperspace.com/wiki/convergence>`_. For that, observe if the training loss stabilizes itself around the end of the training or still seems to be decreasing. Refer to `Visualize the training loss`_ for more details on how to display the training loss.
1189-
#. Increase the number of iterations. It should be at least 10,000.
1187+
#. Increase the number of iterations. It typically should be at least 10,000. On small datasets, it can make sense to stop training earlier to avoid overfitting effects.
11901188
#. Make sure the batch size is big enough. It should be at least 512.
11911189
#. Fine-tune the model's hyperparameters, namely ``learning_rate``, ``output_dimension``, ``num_hidden_units`` and eventually ``temperature`` (by setting ``temperature_mode`` back to ``constant``). Refer to `Grid search`_ for more details on performing hyperparameters tuning.
1190+
#. To note, you should still be mindful of performing train/validation splits and shuffle controls to avoid `overfitting <https://developers.google.com/machine-learning/crash-course/overfitting/overfitting>`_.
11921191

11931192

11941193

@@ -1202,14 +1201,19 @@ Putting all previous snippet examples together, we obtain the following pipeline
12021201
import cebra
12031202
from numpy.random import uniform, randint
12041203
from sklearn.model_selection import train_test_split
1204+
import os
1205+
import tempfile
1206+
from pathlib import Path
12051207

12061208
# 1. Define a CEBRA model
12071209
cebra_model = cebra.CEBRA(
12081210
model_architecture = "offset10-model",
12091211
batch_size = 512,
12101212
learning_rate = 1e-4,
1211-
max_iterations = 10, # TODO(user): to change to at least 10'000
1212-
max_adapt_iterations = 10, # TODO(user): to change to ~100-500
1213+
temperature_mode='constant',
1214+
temperature = 0.1,
1215+
max_iterations = 10, # TODO(user): to change to ~500-10000 depending on dataset size
1216+
#max_adapt_iterations = 10, # TODO(user): use and to change to ~100-500 if adapting
12131217
time_offsets = 10,
12141218
output_dimension = 8,
12151219
verbose = False
@@ -1243,7 +1247,7 @@ Putting all previous snippet examples together, we obtain the following pipeline
12431247
# time contrastive learning
12441248
cebra_model.fit(train_data)
12451249
# discrete behavior contrastive learning
1246-
cebra_model.fit(train_data, train_discrete_label,)
1250+
cebra_model.fit(train_data, train_discrete_label)
12471251
# continuous behavior contrastive learning
12481252
cebra_model.fit(train_data, train_continuous_label)
12491253
# mixed behavior contrastive learning
@@ -1257,10 +1261,10 @@ Putting all previous snippet examples together, we obtain the following pipeline
12571261
cebra_model = cebra.CEBRA.load(tmp_file)
12581262
train_embedding = cebra_model.transform(train_data)
12591263
valid_embedding = cebra_model.transform(valid_data)
1260-
assert train_embedding.shape == (70, 8)
1261-
assert valid_embedding.shape == (30, 8)
1264+
assert train_embedding.shape == (70, 8) # TODO(user): change to split ratio & output dim
1265+
assert valid_embedding.shape == (30, 8) # TODO(user): change to split ratio & output dim
12621266

1263-
# 7. Evaluate the model performances
1267+
# 7. Evaluate the model performance (you can also check the train_data)
12641268
goodness_of_fit = cebra.sklearn.metrics.infonce_loss(cebra_model,
12651269
valid_data,
12661270
valid_discrete_label,

0 commit comments

Comments
 (0)