Skip to content
This repository has been archived by the owner on Apr 10, 2024. It is now read-only.

Commit

Permalink
Merge pull request #36 from baraline/dev
Browse files Browse the repository at this point in the history
Tentative fix for numba cache  + interpreter class colors
  • Loading branch information
baraline authored Dec 29, 2022
2 parents d842dd3 + 64b178d commit f57716e
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 55 deletions.
12 changes: 8 additions & 4 deletions convst/classifiers/rdst_ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ def __init__(
prime_dilations=False,
n_samples=None,
n_jobs=1,
backend="processes",
prefer=None,
require='sharedmem',
random_state=None,
shp_alpha=0.5,
a_w=4,
Expand All @@ -87,7 +88,8 @@ def __init__(
self.shapelet_lengths_bounds = shapelet_lengths_bounds
self.lengths_bounds_reduction = check_is_numeric(lengths_bounds_reduction)
self.prime_dilations = check_is_boolean(prime_dilations)
self.backend = backend
self.prefer = prefer
self.require = require
self.random_state = random_state
if shapelet_lengths_bounds is not None:
self.n_samples = check_is_numeric(n_samples)
Expand Down Expand Up @@ -132,7 +134,8 @@ def fit(self, X, y):
set_num_threads(self.n_jobs_rdst)
models = Parallel(
n_jobs=self.n_jobs,
prefer=self.backend,
prefer=self.prefer,
require=self.require
)(
delayed(_parallel_fit)(
X, y,
Expand Down Expand Up @@ -164,7 +167,8 @@ def fit(self, X, y):
def predict(self, X):
preds_proba = Parallel(
n_jobs=self.n_jobs,
prefer=self.backend,
prefer=self.prefer,
require=self.require
)(
delayed(_parallel_predict)(
X,
Expand Down
8 changes: 6 additions & 2 deletions convst/interpreters/rdst_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,16 @@ def visualize_best_shapelets_one_class(
ax[1,0].set_title('Best match')
ax[1,2].set_title('Distance vectors')


self.rdst_interp.plot(i_shp, ax=ax[1,1])
self.rdst_interp.plot_on_X(i_shp, X[i_example,0], ax=ax[1,0], label='Class {}'.format(class_id))

self.rdst_interp.plot_on_X(i_shp, X[i_example2,0], ax=ax[1,0], label='Other class')
self.rdst_interp.plot_distance_vector(i_shp, X[i_example,0], ax=ax[1,2], label='Class {}'.format(class_id))
self.rdst_interp.plot_on_X(i_shp, X[i_example,0], ax=ax[1,0], label='Class {}'.format(class_id))

self.rdst_interp.plot_distance_vector(i_shp, X[i_example2,0], ax=ax[1,2], label='Other class')
self.rdst_interp.plot_distance_vector(i_shp, X[i_example,0], ax=ax[1,2], label='Class {}'.format(class_id))

ax[1,0].legend()


class RDST_Ensemble_interpreter:
Expand Down
99 changes: 69 additions & 30 deletions convst/transformers/_commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
###############################################################################

@njit(
fastmath=True, cache=True
fastmath=True, cache=True, nogil=True
)
def euclidean(x, y):
s = 0
Expand All @@ -19,7 +19,7 @@ def euclidean(x, y):
return sqrt(s)

@njit(
fastmath=True, cache=True
fastmath=True, cache=True, nogil=True
)
def squared_euclidean(x, y):
s = 0
Expand All @@ -28,7 +28,7 @@ def squared_euclidean(x, y):
return s

@njit(
fastmath=True, cache=True
fastmath=True, cache=True, nogil=True
)
def manhattan(x, y):
s = 0
Expand All @@ -43,7 +43,7 @@ def manhattan(x, y):
###############################################################################

@njit(
cache=True
cache=True, nogil=True
)
def generate_strides_1D(X, window_size, dilation, use_phase):
if use_phase:
Expand All @@ -52,7 +52,7 @@ def generate_strides_1D(X, window_size, dilation, use_phase):
return _generate_strides_1D(X, window_size, dilation)

@njit(
cache=True
cache=True, nogil=True
)

def generate_strides_2D(X, window_size, dilation, use_phase):
Expand All @@ -63,7 +63,7 @@ def generate_strides_2D(X, window_size, dilation, use_phase):


@njit(
cache=True
cache=True, nogil=True
)
def _generate_strides_1D(X, window_size, dilation):
"""
Expand Down Expand Up @@ -93,7 +93,7 @@ def _generate_strides_1D(X, window_size, dilation):
return X_new

@njit(
cache=True
cache=True, nogil=True
)

def _generate_strides_2D(X, window_size, dilation):
Expand Down Expand Up @@ -127,7 +127,7 @@ def _generate_strides_2D(X, window_size, dilation):


@njit(
cache=True
cache=True, nogil=True
)
def _generate_strides_1D_phase(X, window_size, dilation):
"""
Expand Down Expand Up @@ -156,7 +156,9 @@ def _generate_strides_1D_phase(X, window_size, dilation):
return X_new


@njit(cache=True)
@njit(
cache=True, nogil=True
)
def _generate_strides_2D_phase(X, window_size, dilation):
"""
Generate strides from an ensemble of univariate time series with specified
Expand Down Expand Up @@ -186,7 +188,9 @@ def _generate_strides_2D_phase(X, window_size, dilation):
return X_new


@njit(cache=True)
@njit(
cache=True, nogil=True
)
def get_subsequence(X, index, length, d, normalize, use_phase):
if use_phase:
return _get_subsequence_phase(
Expand All @@ -198,7 +202,9 @@ def get_subsequence(X, index, length, d, normalize, use_phase):
)


@njit(cache=True, fastmath=True)
@njit(
cache=True, fastmath=True, nogil=True
)
def _get_subsequence(X, i_start, length, d, normalize):
"""
Given a set of length and dilation, fetch a subsequence from an input
Expand Down Expand Up @@ -234,7 +240,10 @@ def _get_subsequence(X, i_start, length, d, normalize):
v = (v - v.mean())/(v.std()+1e-8)
return v

@njit(cache=True, fastmath=True)

@njit(
cache=True, fastmath=True, nogil=True
)
def _get_subsequence_phase(X, i_start, length, d, normalize):
"""
Given a set of length and dilation, fetch a subsequence from an input
Expand Down Expand Up @@ -278,7 +287,10 @@ def _get_subsequence_phase(X, i_start, length, d, normalize):
# #
###############################################################################

@njit(cache=True)

@njit(
cache=True, nogil=True
)
def compute_shapelet_dist_vector(
x, values, length, dilation, dist_func, normalize, use_phase
):
Expand All @@ -301,7 +313,10 @@ def compute_shapelet_dist_vector(
else:
raise ValueError('Wrong parameter for normalize or phase')

@njit(fastmath=True, cache=True)

@njit(
cache=True, fastmath=True, nogil=True
)
def _compute_shapelet_dist_vector(x, values, length, dilation, dist_func):
"""
Compute a shapelet distance vector from an univariate time series
Expand Down Expand Up @@ -334,7 +349,10 @@ def _compute_shapelet_dist_vector(x, values, length, dilation, dist_func):
x_conv[i] = dist_func(c[i], values)
return x_conv

@njit(fastmath=True, cache=True)

@njit(
cache=True, fastmath=True, nogil=True
)
def _compute_shapelet_dist_vector_norm(x, values, length, dilation, dist_func):
"""
Compute a shapelet distance vector from an univariate time series
Expand Down Expand Up @@ -368,7 +386,10 @@ def _compute_shapelet_dist_vector_norm(x, values, length, dilation, dist_func):
x_conv[i] = dist_func(x0, values)
return x_conv

@njit(fastmath=True, cache=True)

@njit(
cache=True, fastmath=True, nogil=True
)
def _compute_shapelet_dist_vector_phase(x, values, length, dilation, dist_func):
"""
Compute a shapelet distance vector from an univariate time series
Expand Down Expand Up @@ -401,7 +422,10 @@ def _compute_shapelet_dist_vector_phase(x, values, length, dilation, dist_func):
x_conv[i] = dist_func(c[i], values)
return x_conv

@njit(fastmath=True, cache=True)

@njit(
cache=True, fastmath=True, nogil=True
)
def _compute_shapelet_dist_vector_norm_phase(x, values, length, dilation, dist_func):
"""
Compute a shapelet distance vector from an univariate time series
Expand Down Expand Up @@ -436,7 +460,10 @@ def _compute_shapelet_dist_vector_norm_phase(x, values, length, dilation, dist_f
return x_conv


@njit(fastmath=True, cache=True)

@njit(
cache=True, fastmath=True, nogil=True
)
def apply_one_shapelet_one_sample_univariate(x, values, threshold, dist_func):
"""
Extract the three features from the distance between a shapelet and the
Expand Down Expand Up @@ -469,14 +496,14 @@ def apply_one_shapelet_one_sample_univariate(x, values, threshold, dist_func):
n_candidates, length = x.shape

_n_match = 0
_min = 1e+100
_min = -1.
_argmin = 0

#For each step of the moving window in the shapelet distance
for i in range(n_candidates):
for i in prange(n_candidates):
_dist = dist_func(x[i], values)

if _dist < _min:
if _dist < _min or _min==-1.:
_min = _dist
_argmin = i

Expand All @@ -485,7 +512,10 @@ def apply_one_shapelet_one_sample_univariate(x, values, threshold, dist_func):

return _min, float_(_argmin), float_(_n_match)

@njit(fastmath=True, cache=True)

@njit(
cache=True, fastmath=True, nogil=True
)
def apply_one_shapelet_one_sample_multivariate(x, values, threshold, dist_func):
"""
Extract the three features from the distance between a shapelet and the
Expand Down Expand Up @@ -518,16 +548,16 @@ def apply_one_shapelet_one_sample_multivariate(x, values, threshold, dist_func):
n_ft, n_candidates, length = x.shape

_n_match = 0
_min = 1e+10
_min = -1.
_argmin = 0

#For each step of the moving window in the shapelet distance
for i in range(n_candidates):
for i in prange(n_candidates):
_dist = 0
for ft in prange(n_ft):
_dist += dist_func(x[ft, i], values[ft])

if _dist < _min:
if _dist < _min or _min == -1.:
_min = _dist
_argmin = i

Expand All @@ -537,7 +567,10 @@ def apply_one_shapelet_one_sample_multivariate(x, values, threshold, dist_func):
return _min, float_(_argmin), float_(_n_match)


@njit(cache=True)

@njit(
cache=True, nogil=True
)
def _combinations_1d(x,y):
"""
Return the unique combination (in the 2nd dimension) of the 2D array made by
Expand Down Expand Up @@ -574,14 +607,19 @@ def _combinations_1d(x,y):
i_comb += 1
return combinations

@njit(cache=True)
@njit(
cache=True, nogil=True
)
def prime_up_to(n):
is_p = zeros(n+1, dtype=bool_)
for i in range(n+1):
is_p[i] = is_prime(i)
return where(is_p)[0]

@njit(cache=True)

@njit(
cache=True, nogil=True
)
def is_prime(n):
if (n % 2 == 0 and n > 2) or n == 0:
return False
Expand All @@ -590,7 +628,9 @@ def is_prime(n):
return False
return True

@njit(cache=True, fastmath=True)
@njit(
cache=True, fastmath=True, nogil=True
)
def choice_log(n_choice, n_sample):
if n_choice > 1:
P = array([1/2**log(i) for i in range(1,n_choice+1)])
Expand All @@ -601,4 +641,3 @@ def choice_log(n_choice, n_sample):
return loc
else:
return zeros(n_sample, dtype=int64)

6 changes: 3 additions & 3 deletions convst/transformers/_multivariate_same_length.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from numba import njit, prange

@njit(cache=True)
@njit(cache=True, nogil=True)
def M_SL_init_random_shapelet_params(
n_shapelets, shapelet_sizes, n_timestamps, p_norm, max_channels, prime_scheme
):
Expand Down Expand Up @@ -93,7 +93,7 @@ def M_SL_init_random_shapelet_params(

return values, lengths, dilations, threshold, normalize, n_channels, channel_ids

@njit(cache=True, parallel=True)
@njit(cache=True, parallel=True, nogil=True)
def M_SL_generate_shapelet(
X, y, n_shapelets, shapelet_sizes, r_seed, p_norm, p_min, p_max, alpha,
dist_func, use_phase, max_channels, prime_scheme
Expand Down Expand Up @@ -267,7 +267,7 @@ def M_SL_generate_shapelet(
channel_ids[:a2]
)

@njit(cache=True, parallel=True, fastmath=True)
@njit(cache=True, parallel=True, fastmath=True, nogil=True)
def M_SL_apply_all_shapelets(
X, shapelets, dist_func, use_phase
):
Expand Down
Loading

0 comments on commit f57716e

Please sign in to comment.