def locregress_weights_old ( x, span = 0.2, order = 1, use_pbar = False ): '''DO NOT USE''' # Shortcuts N = len( x ) n_thresh = ceil( span * N ) # Pre-allocate ret = np.zeros( (N, N) ) method = 2 if use_pbar: iterator = pbar( range( N ) ) else: iterator = range( N ) for i in iterator: x0 = x[i] dx = x - x0 # Choose adaptive kernel width # TODO Do without sorting h_thresh = sort( abs( dx ) )[n_thresh] if method == 1: # Old method w = _kernel_tricube( dx, h_thresh ) S1 = sum( w * dx ) S2 = sum( w * (dx ** 2) ) den = sum( w * S2 - w * dx * S1 ) for j in range( N ): ret[i,j] = (1 / den) * ( w[j] * S2 - w[j] * dx[j] * S1 ) if method == 2: # New method w = _kernel_tricube( dx, h_thresh ) w_slice = w != 0 e1 = np.zeros( (order + 1, 1) ) e1[0] = 1.0 bigW = np.diag( w[w_slice] ) bigX = np.ones( (N, order + 1) ) bigX[:, 1] = dx if order > 1: bigX[:, 2] = dx ** 2 bigX = bigX[w_slice, :] A2 = np.dot( bigX.T, bigW ) A1 = np.dot( A2, bigX ) ret[i, w_slice] = np.dot( np.dot( e1.T, np.linalg.inv( A1 ) ), A2 ) return ret
def tvdbn2(X, step=1, predict_lag=1, reg_weight=1.0, kernel_width=4.0, kernel_thresh=0.001, show_pbar=False): ''' ... ''' # Shortcuts T = X.shape[0] N = X.shape[1] ts = np.arange(T) # Pre-allocate output t_out = np.arange(predict_lag, T, step) ret = np.zeros((N, N, t_out.shape[0])) # TODO Correct mapping between lambda and alpha?? model = lm.Ridge(alpha=reg_weight) t_iterator = pbar(range(t_out.shape[0])) if show_pbar else range( t_out.shape[0]) for i_t in t_iterator: t = t_out[i_t] # Compute weighting kernel cur_kernel = _tvdbn_kernel(ts, t, kernel_width) # Create slicing vectors for present and past, using threshold to cut fat kernel_slice = np.nonzero(cur_kernel[predict_lag:] > kernel_thresh)[0] kernel_slice_prev = kernel_slice - predict_lag for ch in range(N): # "All other channels" ch_slice = np.arange(N) != ch # Perform regression Xt = X[kernel_slice_prev, :][:, ch_slice] for ch_x in range(N - 1): Xt[:, ch_x] = np.multiply(cur_kernel[kernel_slice], Xt[:, ch_x]) Yt = X[kernel_slice, :][:, ch] Yt = np.multiply(cur_kernel[kernel_slice], Yt) result = np.dot( np.dot( np.linalg.pinv((np.dot(Xt.T, Xt)) + reg_weight * np.eye(N - 1)), Xt.T), Yt.T) # Add regression output to return value ret[ch, ch_slice, i_t] = result return ret
def tvdbn2 ( X, step = 1, predict_lag = 1, reg_weight = 1.0, kernel_width = 4.0, kernel_thresh = 0.001, show_pbar = False): ''' ... ''' # Shortcuts T = X.shape[0] N = X.shape[1] ts = np.arange( T ) # Pre-allocate output t_out = np.arange( predict_lag, T, step ) ret = np.zeros( (N, N, t_out.shape[0]) ) # TODO Correct mapping between lambda and alpha?? model = lm.Ridge( alpha = reg_weight ) t_iterator = pbar( range( t_out.shape[0] ) ) if show_pbar else range( t_out.shape[0] ) for i_t in t_iterator: t = t_out[i_t] # Compute weighting kernel cur_kernel = _tvdbn_kernel( ts, t, kernel_width ) # Create slicing vectors for present and past, using threshold to cut fat kernel_slice = np.nonzero( cur_kernel[predict_lag:] > kernel_thresh )[0] kernel_slice_prev = kernel_slice - predict_lag for ch in range( N ): # "All other channels" ch_slice = np.arange( N ) != ch # Perform regression Xt = X[kernel_slice_prev,:][:,ch_slice] for ch_x in range( N - 1 ): Xt[:, ch_x] = np.multiply( cur_kernel[kernel_slice], Xt[:, ch_x] ) Yt = X[kernel_slice,:][:,ch] Yt = np.multiply( cur_kernel[kernel_slice], Yt ) result = np.dot( np.dot( np.linalg.pinv( ( np.dot( Xt.T, Xt ) ) + reg_weight * np.eye( N - 1 ) ), Xt.T ), Yt.T ) # Add regression output to return value ret[ch, ch_slice, i_t] = result return ret
def tvdbn ( X, step = 1, predict_lag = 1, reg_weight = 1.0, kernel_width = 4.0, kernel_thresh = 0.001, show_pbar = False ): ''' ... ''' # Shortcuts T = X.shape[0] N = X.shape[1] ts = np.arange( T ) # Pre-allocate output t_out = np.arange( predict_lag, T, step ) ret = np.zeros( (N, N, t_out.shape[0]) ) # TODO Correct mapping between lambda and alpha?? model = lm.Ridge( alpha = reg_weight ) t_iterator = pbar( range( t_out.shape[0] ) ) if show_pbar else range( t_out.shape[0] ) for i_t in t_iterator: t = t_out[i_t] # Compute weighting kernel cur_kernel = _tvdbn_kernel( ts, t, kernel_width ) # Create slicing vectors for present and past, using threshold to cut fat kernel_slice = np.nonzero( cur_kernel[predict_lag:] > kernel_thresh )[0] kernel_slice_prev = kernel_slice - predict_lag for ch in range( N ): # "All other channels" ch_slice = np.arange( N ) != ch # Perform regression # TODO Don't know why I have to double-index like this model.fit( X[kernel_slice_prev,:][:,ch_slice], X[kernel_slice,:][:,ch], sample_weight = cur_kernel[kernel_slice] ) # Add regression output to return value params = model.coef_ ret[ch, ch_slice, i_t] = params return ret
def extract(self): '''Pulls out the data from all events into a LabeledArray. Each event is placed into its own entry along the 'trial' axis of the returned array. Output is a LabeledArray of signature ('time', 'channel', 'trial') ''' # TODO Get this to work without copying ... # Preallocate return value ret_axes = self._axes() ret_array = np.zeros(tuple(map(len, ret_axes.values()))) i = 0 event_names = [] for event in pbar(self.events): ret_array[:, :, i] = self.eeg[self._t_slice(event['start_idx']), :] event_names.append(event['name']) i += 1 ret_axes['trial'] = recfunctions.append_fields(ret_axes['trial'], 'event_name', np.array(event_names)) return LabeledArray(ret_array, ret_axes)
def extract ( self ): '''Pulls out the data from all events into a LabeledArray. Each event is placed into its own entry along the 'trial' axis of the returned array. Output is a LabeledArray of signature ('time', 'channel', 'trial') ''' # TODO Get this to work without copying ... # Preallocate return value ret_axes = self._axes() ret_array = np.zeros( tuple( map( len, ret_axes.values() ) ) ) i = 0 event_names = [] for event in pbar( self.events ): ret_array[:, :, i] = self.eeg[self._t_slice( event['start_idx'] ), :] event_names.append( event[ 'name' ] ) i += 1 ret_axes[ 'trial' ] = recfunctions.append_fields( ret_axes[ 'trial' ], 'event_name', np.array( event_names ) ) return LabeledArray( ret_array, ret_axes )
def fm(eeg, lock_events, aux_ch=[], bad_ch=[], taps_filt=200, f_filt=[70.0, 110.0], decimation=1, t_buffer=0.5, t_pre=1.0, t_safe=0.1, t_post=3.0, stat_method='bins', alpha=0.05, nu_max=100, plt_width=8, plt_height_per=0.15, plt_cmax=12): '''fm - ...''' # Basics fs_raw = eeg.get_rate() fs = fs_raw / decimation all_ch = eeg.get_labels() exclude_ch = aux_ch + bad_ch car_ch = [s for s in all_ch if s not in exclude_ch] n_t_raw = fs_raw * (t_pre + t_post + 2 * t_buffer) n_ch = len(car_ch) n_trials = len(lock_events) ## Preprocessing # CAR eeg.auto_CAR(exclude_ch) # Filtering & trial separation #print( 'Filtering:' ) # Construct FIR BP filter parameters a_filt = np.array([1.0]) b_filt = sig.firwin(taps_filt, f_filt, nyq=fs / 2.0, pass_zero=False) # Test decimation to get bounds if decimation > 1: event_start = fs * (t_pre + t_buffer) + 1 t_slice = range(int(round(event_start - fs_raw * (t_pre + t_buffer))), int(round(event_start + fs_raw * (t_post + t_buffer)))) #tv_raw = np.linspace( -(t_pre + t_buffer), (t_post + t_buffer), len( t_slice ) ) cur_data_raw = eeg[t_slice, [car_ch[0]]] cur_data = sig.decimate(cur_data_raw, decimation, axis=0) n_t = len(cur_data) else: n_t = n_t_raw # Preallocate total data big_data = np.zeros((n_t, n_ch, n_trials)) i_trial = 0 n_eta = 10 # TODO Magic for event_code, event_start, event_duration in pbar(lock_events, task='Filtering'): #print( '.', end = '' ) t_slice = range(int(round(event_start - fs_raw * (t_pre + t_buffer))), int(round(event_start + fs_raw * (t_post + t_buffer)))) timer_start = time.clock() cur_data_raw = eeg[t_slice, car_ch] if decimation > 1: cur_data = sig.decimate(cur_data_raw, decimation, axis=0) else: cur_data = cur_data_raw #print( cur_data_raw.shape ) #print( cur_data.shape ) cur_data_filt = sig.filtfilt(b_filt, a_filt, cur_data, axis=0) cur_data_env = np.abs(sig.hilbert(cur_data_filt, axis=0)) big_data[:, :, i_trial] = cur_data_env timer_end = time.clock() i_trial = i_trial + 1 # Show ETA if False and not (i_trial % n_eta): dt = timer_end - timer_start # s dmin, dsec = dt // 60, dt % 60 eta = dt * (n_trials - i_trial) emin, esec = eta // 60, eta % 60 print(' ETA: {:01.0f}m {:04.1f}s'.format(emin, esec)) #print( 'Done.' ) ## Aggregate baseline baseline_mean = np.zeros((n_ch)) baseline_std = np.zeros((n_ch)) t_slice_baseline = range(int(round(fs * t_buffer)), int(round(fs * (t_buffer + t_pre - t_safe)))) n_baseline = len(t_slice_baseline) * n_trials for i in range(n_ch): baseline_mean[i] = np.mean( np.log(np.ravel(big_data[t_slice_baseline, i, :]))) baseline_std[i] = np.std( np.log(np.ravel(big_data[t_slice_baseline, i, :]))) ## Log-transform and baseline normalize data if False: big_data_norm = np.zeros(big_data.shape) for i_ch in range(n_ch): for i_trial in range(n_trials): big_data_norm[:, i_ch, i_trial] = ( (np.log(big_data[:, i_ch, i_trial]) - baseline_mean[i_ch]) / (baseline_std[i] / np.sqrt(n_trials))) ## Statistics #print( 'Statistics:' ) if stat_method == 'bins': big_data_mean = np.mean(np.log(big_data), axis=2) big_data_std = np.std(np.log(big_data), axis=2) big_data_mean_norm = np.zeros(big_data_mean.shape) for i in range(n_ch): big_data_mean_norm[:, i] = (big_data_mean[:, i] - baseline_mean[i] ) / (baseline_std[i] / np.sqrt(n_trials)) n_tests = fs * t_post alpha_pointwise = alpha / 2.0 alpha_global = alpha_pointwise / n_tests t_crit_cache = [ dist.t.ppf(1 - alpha_global, nu) for nu in range(0, nu_max) ] z_crit = dist.norm.ppf(1 - alpha_global) t_crit = lambda nu: t_crit_cache[nu] if nu < nu_max else z_crit t_stat = lambda t, ch: ( (big_data_mean[t, ch] - baseline_mean[ch]) / np.sqrt( (big_data_std[t, ch]**2 / n_trials) + (baseline_std[ch]**2 / n_baseline))) nu_stat = lambda t, ch: (((big_data_std[t, ch]**2 / n_trials) + (baseline_std[ch]**2 / n_baseline))**2 / ((big_data_std[t, ch]**4 / (n_trials**2 * (n_trials - 1))) + (baseline_std[ch]**4 / (n_baseline**2 * (n_baseline - 1))))) big_data_t = np.zeros(big_data_mean.shape) big_data_nu = np.zeros(big_data_mean.shape) big_data_t_crit = np.zeros(big_data_mean.shape) for i_ch in pbar(range(n_ch), task='Statisticsing'): for t in range(int(n_t)): big_data_t[t, i_ch] = t_stat(t, i_ch) big_data_nu[t, i_ch] = nu_stat(t, i_ch) big_data_t_crit[t, i_ch] = t_crit( int(np.floor(big_data_nu[t, i_ch]))) big_data_thresh = np.abs(big_data_t) > big_data_t_crit #print( 'Done.' ) ## Construct FM object ## Display plt_height = plt_height_per * n_ch fig, ax = plt.subplots(figsize=(plt_width, plt_height)) im = ax.imshow(big_data_thresh.T * big_data_mean_norm.T, aspect='auto', interpolation='none', cmap=cm.Spectral_r, extent=(-(t_pre + t_buffer), t_post + t_buffer, -0.5, n_ch - 0.5), clim=(-plt_cmax, plt_cmax)) ax.set_xlim(-t_pre, t_post) ax.set_yticks(range(n_ch)) ax.set_yticklabels(car_ch) ax.grid(True) fig.colorbar(im) plt.show() return big_data_mean_norm.T
def sr(eeg, lock_events, ch, aux_ch=[], bad_ch=[], decimation=1, t_buffer=0.5, t_pre=1.0, t_safe=0.1, t_post=3.0, spec_dict={}, plt_width=8, plt_height=6, plt_cmax=12): '''sr - ...''' # Basics fs_raw = eeg.get_rate() fs = fs_raw / decimation all_ch = eeg.get_labels() exclude_ch = aux_ch + bad_ch car_ch = [s for s in all_ch if s not in exclude_ch] n_t_raw = fs_raw * (t_pre + t_post + 2 * t_buffer) n_trials = len(lock_events) ## Preprocessing # CAR eeg.auto_CAR(exclude_ch) ## Trial separation make_t_slice = lambda x: range( int(round(x - fs_raw * (t_pre + t_buffer))), int(round(x + fs_raw * (t_post + t_buffer)))) # Test decimation to get bounds event_start = fs * (t_pre + t_buffer) + 1 t_slice_raw = make_t_slice(event_start) #tv_raw = np.linspace( -(t_pre + t_buffer), (t_post + t_buffer), len( t_slice ) ) cur_data_raw = np.squeeze(eeg[t_slice_raw, [ch]]) if decimation > 1: cur_data = sig.decimate(cur_data_raw, decimation) else: cur_data = cur_data_raw n_t = len(cur_data) # Test spectrogram to get bounds f_spec, t_spec, spec_test = sig.spectrogram(np.squeeze(cur_data), axis=0, fs=fs, **spec_dict) t_spec = t_spec - (t_pre + t_buffer) n_t_spec = len(t_spec) n_f_spec = len(f_spec) # Preallocate total data big_data = np.zeros((n_t_spec, n_f_spec, n_trials)) i_trial = 0 n_eta = 10 # TODO Magic for event_code, event_start, event_duration in pbar(lock_events, task='Filtering'): #print( '.', end = '' ) t_slice_raw = make_t_slice(event_start) cur_data_raw = np.squeeze(eeg[t_slice_raw, [ch]]) if decimation > 1: cur_data = sig.decimate(cur_data_raw, decimation, axis=0) else: cur_data = cur_data_raw tmp1, tmp2, cur_data_spec = sig.spectrogram(np.squeeze(cur_data), axis=0, fs=fs, **spec_dict) big_data[:, :, i_trial] = cur_data_spec.T i_trial = i_trial + 1 ## Aggregate baseline baseline_mean = np.zeros((n_f_spec)) baseline_std = np.zeros((n_f_spec)) t_slice_baseline = np.where( np.logical_and(t_spec > -t_pre, t_spec < -t_safe)) n_baseline = len(t_slice_baseline) * n_trials for i in range(n_f_spec): baseline_mean[i] = np.mean( np.log(np.ravel(big_data[t_slice_baseline, i, :]))) baseline_std[i] = np.std( np.log(np.ravel(big_data[t_slice_baseline, i, :]))) ## Normalization big_data_mean = np.mean(np.log(big_data), axis=2) big_data_std = np.std(np.log(big_data), axis=2) big_data_mean_norm = np.zeros(big_data_mean.shape) for i in range(n_f_spec): big_data_mean_norm[:, i] = (big_data_mean[:, i] - baseline_mean[i]) / ( baseline_std[i] / np.sqrt(n_trials)) ## Display fig, ax = plt.subplots(figsize=(plt_width, plt_height)) big_data_thresh = np.abs(big_data_mean_norm) > 3.0 im = ax.imshow(big_data_thresh.T * big_data_mean_norm.T, aspect='auto', origin='lower', interpolation='none', cmap=cm.Spectral_r, extent=(t_spec[0], t_spec[-1], f_spec[0], f_spec[-1]), clim=(-plt_cmax, plt_cmax)) ax.set_xlim(-t_pre, t_post) ax.set_ylim(0, 2000) #ax.set_yticks( range( n_ch ) ) #ax.set_yticklabels( car_ch ) ax.grid(True) ax.set_title(ch) fig.colorbar(im) plt.show() return big_data_mean_norm.T
def train(model, train_loader, valid_loader, loss_function, optimizer, num_epochs): start = time.time() for epoch in range(1, num_epochs + 1): print('Epoch ' + str(epoch)) # Port model to the gpu model = model.to('cuda' if torch.cuda.is_available() else 'cpu') # Put model on train mode model.train() # Instantiate the train loss and total train samples train_loss = 0.0 train_total = 0 for i, (inputs, targets) in enumerate(train_loader): # Port data to gpu inputs = inputs.to('cuda' if torch.cuda.is_available() else 'cpu') targets = targets.to( 'cuda' if torch.cuda.is_available() else 'cpu') # Clear the weight gradients each batch of data optimizer.zero_grad() # Forward pass and loss outputs = model(inputs) loss = loss_function(outputs, targets) # Perform backward pass (calculating gradients of the weights) and use the optimizer to update weights loss.backward() optimizer.step() # Add loss and total samples train_loss += loss.item() train_total += targets.size(0) # Get number of batches in decimal form num_batches = len(train_loader.dataset) / train_loader.batch_size # If there is no excess samples, make the number of batches equal to the division, if not, add one to account for the excess if num_batches == int(num_batches): num_batches = int(num_batches) else: num_batches = int(num_batches) + 1 # Check if number of items in the dataset is less than the batch size, if it is, change the batch size # Else, make the batch size the default if num_batches == 1: batch_size = len(train_loader.dataset) else: batch_size = train_loader.batch_size # Print the pbar and stats pbar((i + 1) * batch_size, num_batches * batch_size, ['Loss'], [round(loss.item(), 3)]) # Print average loss of training print('\nTraining - Average Loss: {}'.format( round(train_loss / (train_total / train_loader.batch_size), 3))) # Put model in evaluation mode model.eval() # Instantiate validation loss and total number of validation samples valid_loss = 0.0 valid_total = 0 # Use no grad because of no weight updates with torch.no_grad(): for i, (inputs, targets) in enumerate(valid_loader): # Port data to gpu inputs = inputs.to( 'cuda' if torch.cuda.is_available() else 'cpu') targets = targets.to( 'cuda' if torch.cuda.is_available() else 'cpu') # Forward pass and loss calculation outputs = model(inputs) loss = loss_function(outputs, targets) # No backward pass and weight update # Add losses and total samples valid_loss += loss.item() valid_total += targets.size(0) # Get number of batches in decimal form num_batches = len( valid_loader.dataset) / valid_loader.batch_size # If there is no excess samples, make the number of batches equal to the division, if not, add one to account for the excess if num_batches == int(num_batches): num_batches = int(num_batches) else: num_batches = int(num_batches) + 1 # Check if number of items in the dataset is less than the batch size, if it is, change the batch size # Else, make the batch size the default if num_batches == 1: batch_size = len(valid_loader.dataset) else: batch_size = valid_loader.batch_size # Print the pbar and stats pbar((i + 1) * batch_size, num_batches * batch_size, ['Loss'], [round(loss.item(), 3)]) # Print average loss of validation print('\nValidation - Average Loss: {}'.format( round(valid_loss / (valid_total / valid_loader.batch_size), 3))) print() # Print total time for training total_time = time.time() - start print('Training complete in {:.0f}m {:.0f}s'.format( total_time // 60, total_time % 60)) return model
def locregress_weights ( x, span = 0.2, order = 1, fast_interior = True, return_stats = False ): '''DO NOT USE''' # Cache some constants n = x.shape[0] # Number of input points d = x.shape[1] # Dimensionality of fit span_samples = np.ceil( span * n ) # Number of samples in the span # Preallocate sparse return value ret = sparse.lil_matrix( (n, n) ) # Preallocate return statistics stat_dict = {} # Apply intuition that, for regularly spaced grids, weights on the interior # are just shifted versions of the same kernel if fast_interior: # Find "center" point x_center = 0.5 * ( np.max( x, axis = 0 ) + np.min( x, axis = 0 ) ) dx_center = x - np.tile( x_center, (n, 1) ) dx_norm = linalg.norm( dx_center, axis = 1 ) idx_center = np.argmin( dx_norm ) # Find critical kernel width x_star = x[idx_center, :] dx = x - np.tile( x_star, (n, 1) ) dx_norm = linalg.norm( dx, axis = 1 ) dx_norm = np.sort( dx_norm, axis = 0 ) h_interior = dx_norm[span_samples + 1] stat_dict['h_interior'] = h_interior # Find bounding box for where we can use interior kernel x_interior_min = np.min( x, axis = 0 ) + h_interior x_interior_max = np.max( x, axis = 0 ) - h_interior # Lambda for interior kernel kh_interior = lambda x_v : _kernel_tricube( linalg.norm( x_v, axis = 1 ), h_interior ) # Compute weight matrix for the interior w_vec = kh_interior( dx ) w_interior_slice = np.where( w_vec > 0 ) w_vec = w_vec[w_interior_slice] w = np.diag( w_vec ) # Include quadratic terms if order > 1: for j in range( d ): for k in range( j, d ): dx = np.c_[dx, dx[:, j] * dx[:, k]] # Include affine terms dx = np.c_[np.ones( (n, 1) ), dx] # Slice out only relevant items dx = dx[w_interior_slice] e1 = np.zeros( (dx.shape[1], 1) ) e1[0] = 1 a2 = np.dot( dx.T, w ) a1 = np.dot( a2, dx ) ret_interior = np.dot( e1.T, linalg.solve( a1, a2 ) ) # Cache the index offsets for quick copying offset_interior = w_interior_slice - idx_center # Compute weight vectors at each point for i in pbar( range( n ), task = 'locregress_weights' ): x0 = x[i, :] # Apply interior heuristic if fast_interior: # Check if we're in the interior is_interior = np.logical_and( np.logical_not( np.any( x0 <= x_interior_min ) ), np.logical_not( np.any( x0 >= x_interior_max ) ) ) if is_interior: # Copy known interior weights ret[i, i + offset_interior] = ret_interior continue # Not in interior; have to manually compute # For debugging purposes, screw that lol #continue # Determine input-space deltas dx = x - np.tile( x0, (n, 1) ) # Determine correct kernel width dx_norm = linalg.norm( dx, axis = 1 ) dx_norm = np.sort( dx_norm, axis = 0 ) h = dx_norm[span_samples + 1] # Lambda for interior kernel kh = lambda x_v : _kernel_tricube( linalg.norm( x_v, axis = 1 ), h ) # Calculate weight matrix w_vec = kh( dx ) w_slice = np.where( w_vec > 0 ) w_vec = w_vec[w_slice] w = np.diag( w_vec ) # Include quadratic terms if order > 1: for j in range( d ): for k in range( j, d ): dx = np.c_[dx, dx[:, j] * dx[:, k]] # Include affine terms dx = np.c_[np.ones( (n, 1) ), dx] # Slice out only relevant items dx = dx[w_slice] e1 = np.zeros( (dx.shape[1], 1) ) e1[0] = 1 a2 = np.dot( dx.T, w ) a1 = np.dot( a2, dx ) ret[i, w_slice] = np.dot( e1.T, linalg.solve( a1, a2 ) ) if return_stats: return ret.tocsr(), stat_dict return ret.tocsr()