Commit b0cb5c69 authored by lucas_miranda's avatar lucas_miranda
Browse files

Added nose2body to rule_based_annotation()

parent 9da3260c
......@@ -485,6 +485,7 @@ class coordinates:
align: bool = False,
align_inplace: bool = False,
propagate_labels: bool = False,
propagate_annotations: Dict = False,
) -> Table_dict:
"""
Returns a table_dict object with the coordinates of each animal as values.
......@@ -503,6 +504,9 @@ class coordinates:
- align_inplace (bool): Only valid if align is set. Aligns the vector that goes from the origin to
the selected body part with the y axis, for all time points.
- propagate_labels (bool): If True, adds an extra feature for each video containing its phenotypic label
- propagate_annotations (Dict): if a dictionary is provided, rule based annotations
are propagated through the training dataset. This can be used for initialising the weights of the
clusters in the latent space, in a way that each cluster is related to a different annotation.
Returns:
tab_dict (Table_dict): table_dict object containing all the computed information
......@@ -603,6 +607,13 @@ class coordinates:
for key, tab in tabs.items():
tab.loc[:, "pheno"] = self._exp_conditions[key]
if propagate_annotations:
annotations = list(propagate_annotations.values())[0].columns
for key, tab in tabs.items():
for ann in annotations:
tab.loc[:, ann] = propagate_annotations[key].loc[:, ann]
return table_dict(
tabs,
"coords",
......@@ -611,10 +622,15 @@ class coordinates:
center=center,
polar=polar,
propagate_labels=propagate_labels,
propagate_annotations=bool(propagate_annotations),
)
def get_distances(
self, speed: int = 0, length: str = None, propagate_labels: bool = False
self,
speed: int = 0,
length: str = None,
propagate_labels: bool = False,
propagate_annotations: Dict = False,
) -> Table_dict:
"""
Returns a table_dict object with the distances between body parts animal as values.
......@@ -625,6 +641,9 @@ class coordinates:
- length (str): length of the video in a datetime compatible format (hh::mm:ss). If stated, the index
of the stored dataframes will reflect the actual timing in the video.
- propagate_labels (bool): If True, adds an extra feature for each video containing its phenotypic label
- propagate_annotations (Dict): if a dictionary is provided, rule based annotations
are propagated through the training dataset. This can be used for initialising the weights of the
clusters in the latent space, in a way that each cluster is related to a different annotation.
Returns:
tab_dict (Table_dict): table_dict object containing all the computed information
......@@ -649,7 +668,19 @@ class coordinates:
for key, tab in tabs.items():
tab.loc[:, "pheno"] = self._exp_conditions[key]
return table_dict(tabs, propagate_labels=propagate_labels, typ="dists")
if propagate_annotations:
annotations = list(propagate_annotations.values())[0].columns
for key, tab in tabs.items():
for ann in annotations:
tab.loc[:, ann] = propagate_annotations[key].loc[:, ann]
return table_dict(
tabs,
propagate_labels=propagate_labels,
propagate_annotations=bool(propagate_annotations),
typ="dists",
)
raise ValueError(
"Distances not computed. Read the documentation for more details"
......@@ -661,6 +692,7 @@ class coordinates:
speed: int = 0,
length: str = None,
propagate_labels: bool = False,
propagate_annotations: Dict = False,
) -> Table_dict:
"""
Returns a table_dict object with the angles between body parts animal as values.
......@@ -672,6 +704,9 @@ class coordinates:
- length (str): length of the video in a datetime compatible format (hh::mm:ss). If stated, the index
of the stored dataframes will reflect the actual timing in the video.
- propagate_labels (bool): If True, adds an extra feature for each video containing its phenotypic label
- propagate_annotations (Dict): if a dictionary is provided, rule based annotations
are propagated through the training dataset. This can be used for initialising the weights of the
clusters in the latent space, in a way that each cluster is related to a different annotation.
Returns:
tab_dict (Table_dict): table_dict object containing all the computed information
......@@ -698,7 +733,19 @@ class coordinates:
for key, tab in tabs.items():
tab["pheno"] = self._exp_conditions[key]
return table_dict(tabs, propagate_labels=propagate_labels, typ="angles")
if propagate_annotations:
annotations = list(propagate_annotations.values())[0].columns
for key, tab in tabs.items():
for ann in annotations:
tab.loc[:, ann] = propagate_annotations[key].loc[:, ann]
return table_dict(
tabs,
propagate_labels=propagate_labels,
propagate_annotations=bool(propagate_annotations),
typ="angles",
)
raise ValueError(
"Angles not computed. Read the documentation for more details"
......@@ -906,6 +953,7 @@ class table_dict(dict):
center: str = None,
polar: bool = None,
propagate_labels: bool = False,
propagate_annotations: bool = False,
):
super().__init__(tabs)
self._type = typ
......@@ -914,6 +962,7 @@ class table_dict(dict):
self._arena = arena
self._arena_dims = arena_dims
self._propagate_labels = propagate_labels
self._propagate_annotations = propagate_annotations
def filter_videos(self, keys: list) -> Table_dict:
"""Returns a subset of the original table_dict object, containing only the specified keys. Useful, for example,
......@@ -1239,5 +1288,5 @@ def merge_tables(*args):
# - with the current implementation, preprocess can't fully work on merged table_dict instances.
# While some operations (mainly alignment) should be carried out before merging, others require
# the whole dataset to function properly.
# - Understand how keras handles NA values. Decide whether to do nothing, to mask them or to impute them using
# a clear outlier (e.g. -9999)
# - For now, propagate_annotations is optional and requires the user to actively pass a data frame with traits.
# - If this gives good results, we'll make it default or give a boolean option that requires less effort
......@@ -69,44 +69,6 @@ def plot_lr_vs_loss(rates, losses): # pragma: no cover
plt.ylabel("Loss")
@tf.function
def far_away_uniform_initialiser(
shape: tuple, minval: int = 0, maxval: int = 15, iters: int = 100000
) -> tf.Tensor:
"""
Returns a uniformly initialised matrix in which the columns are as far as possible
Parameters:
- shape (tuple): shape of the object to generate.
- minval (int): Minimum value of the uniform distribution from which to sample
- maxval (int): Maximum value of the uniform distribution from which to sample
- iters (int): the algorithm generates values at random and keeps those runs that
are the farthest apart. Increasing this parameter will lead to more accurate,
results while making the function run slowlier.
Returns:
- init (tf.Tensor): tensor of the specified shape in which the column vectors
are as far as possible
"""
init = tf.random.uniform(shape, minval, maxval)
init_dist = tf.abs(tf.norm(tf.math.subtract(init[1:], init[:1])))
i = 0
while tf.less(i, iters):
temp = tf.random.uniform(shape, minval, maxval)
dist = tf.abs(tf.norm(tf.math.subtract(temp[1:], temp[:1])))
if dist > init_dist:
init_dist = dist
init = temp
i += 1
return init
def compute_kernel(x: tf.Tensor, y: tf.Tensor) -> tf.Tensor:
"""
......
......@@ -306,12 +306,6 @@ class SEQ_2_SEQ_GMVAE:
"""Sets the Variational Autoencoder prior distribution"""
if self.prior == "standard_normal":
# init_means = deepof.model_utils.far_away_uniform_initialiser(
# shape=(self.number_of_components, self.ENCODING),
# minval=0,
# maxval=5,
# iters=self.initialiser_iters,
# )
self.prior = tfd.MixtureSameFamily(
mixture_distribution=tfd.categorical.Categorical(
......@@ -584,7 +578,7 @@ class SEQ_2_SEQ_GMVAE:
)
// 2,
activation=None,
initializer=Orthogonal(), # An alternative is a constant initializer with a matrix of values computed from the labels
initializer=Orthogonal(), # An alternative is a constant initializer with a matrix of values computed from the labels
)(encoder)
z_gauss_var = Dense(
......
......@@ -27,21 +27,6 @@ tfpl = tfp.layers
tfd = tfp.distributions
@settings(deadline=None)
@given(
shape=st.tuples(
st.integers(min_value=5, max_value=10), st.integers(min_value=5, max_value=10)
)
)
def test_far_away_uniform_initialiser(shape):
far = deepof.model_utils.far_away_uniform_initialiser(shape, 0, 15, 1000)
random = tf.random.uniform(shape, 0, 15)
assert far.shape == shape
assert tf.abs(tf.norm(tf.math.subtract(far[1:], far[:1]))) > tf.abs(
tf.norm(tf.math.subtract(random[1:], random[:1]))
)
@settings(deadline=None, suppress_health_check=[HealthCheck.too_slow])
@given(
tensor=arrays(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment