def dtw_warp(x, labels, slope_constraint="symmetric", use_window=True, dtw_type="normal"): import utils.dtw as dtw if use_window: window = np.ceil(x.shape[1] / 10.).astype(int) else: window = None orig_steps = np.arange(x.shape[1]) l = np.argmax(labels, axis=1) if labels.ndim > 1 else labels ret = np.zeros_like(x) for i, pat in enumerate(tqdm(x)): # guarentees that same one isnt selected choices = np.delete(np.arange(x.shape[0]), i) # remove ones of different classes choices = np.where(l[choices] == l[i])[0] if choices.size > 0: # pick random intra-class pattern random_prototype = x[np.random.choice(choices)] if dtw_type == "shape": path = dtw.shape_dtw(random_prototype, pat, dtw.RETURN_PATH, slope_constraint=slope_constraint, window=window) else: path = dtw.dtw(random_prototype, pat, dtw.RETURN_PATH, slope_constraint=slope_constraint, window=window) # Time warp warped = pat[path[1]] for dim in range(x.shape[2]): ret[i,:,dim] = np.interp(orig_steps, np.linspace(0, x.shape[1]-1., num=warped.shape[0]), warped[:,dim]).T else: print("There is only one pattern of class %d, skipping timewarping"%l[i]) ret[i,:] = pat return ret
def discriminative_guided_warp(x, labels, batch_size=6, slope_constraint="symmetric", use_window=True, dtw_type="normal", use_variable_slice=True): import utils.dtw as dtw if use_window: window = np.ceil(x.shape[1] / 10.).astype(int) else: window = None orig_steps = np.arange(x.shape[1]) l = np.argmax(labels, axis=1) if labels.ndim > 1 else labels positive_batch = np.ceil(batch_size / 2).astype(int) negative_batch = np.floor(batch_size / 2).astype(int) ret = np.zeros_like(x) warp_amount = np.zeros(x.shape[0]) for i, pat in enumerate(tqdm(x)): # guarentees that same one isnt selected choices = np.delete(np.arange(x.shape[0]), i) # remove ones of different classes positive = np.where(l[choices] == l[i])[0] negative = np.where(l[choices] != l[i])[0] if positive.size > 0 and negative.size > 0: pos_k = min(positive.size, positive_batch) neg_k = min(negative.size, negative_batch) positive_prototypes = x[np.random.choice(positive, pos_k, replace=False)] negative_prototypes = x[np.random.choice(negative, neg_k, replace=False)] # vector embedding and nearest prototype in one pos_aves = np.zeros((pos_k)) neg_aves = np.zeros((pos_k)) if dtw_type == "shape": for p, pos_prot in enumerate(positive_prototypes): for ps, pos_samp in enumerate(positive_prototypes): if p != ps: pos_aves[p] += (1. / (pos_k - 1.)) * dtw.shape_dtw( pos_prot, pos_samp, dtw.RETURN_VALUE, slope_constraint=slope_constraint, window=window) for ns, neg_samp in enumerate(negative_prototypes): neg_aves[p] += (1. / neg_k) * dtw.shape_dtw( pos_prot, neg_samp, dtw.RETURN_VALUE, slope_constraint=slope_constraint, window=window) selected_id = np.argmax(neg_aves - pos_aves) path = dtw.shape_dtw(positive_prototypes[selected_id], pat, dtw.RETURN_PATH, slope_constraint=slope_constraint, window=window) else: for p, pos_prot in enumerate(positive_prototypes): for ps, pos_samp in enumerate(positive_prototypes): if p != ps: pos_aves[p] += (1. / (pos_k - 1.)) * dtw.dtw( pos_prot, pos_samp, dtw.RETURN_VALUE, slope_constraint=slope_constraint, window=window) for ns, neg_samp in enumerate(negative_prototypes): neg_aves[p] += (1. / neg_k) * dtw.dtw( pos_prot, neg_samp, dtw.RETURN_VALUE, slope_constraint=slope_constraint, window=window) selected_id = np.argmax(neg_aves - pos_aves) path = dtw.dtw(positive_prototypes[selected_id], pat, dtw.RETURN_PATH, slope_constraint=slope_constraint, window=window) # Time warp warped = pat[path[1]] warp_path_interp = np.interp( orig_steps, np.linspace(0, x.shape[1] - 1., num=warped.shape[0]), path[1]) warp_amount[i] = np.sum(np.abs(orig_steps - warp_path_interp)) for dim in range(x.shape[2]): ret[i, :, dim] = np.interp( orig_steps, np.linspace(0, x.shape[1] - 1., num=warped.shape[0]), warped[:, dim]).T else: print("There is only one pattern of class %d" % l[i]) ret[i, :] = pat warp_amount[i] = 0. if use_variable_slice: max_warp = np.max(warp_amount) if max_warp == 0: # unchanged ret = window_slice(ret, reduce_ratio=0.95) else: for i, pat in enumerate(ret): # Variable Sllicing ret[i] = window_slice(pat[np.newaxis, :, :], reduce_ratio=0.95 + 0.05 * warp_amount[i] / max_warp)[0] return ret