def __init__(self, window_size=1.0, buffer_size=0, amp_serial=None, eeg_only=False, amp_name=None): """ Params: window_size (in seconds): keep the latest window_size seconds of the buffer. buffer_size (in seconds): keep everything if buffer_size=0. amp_name: connect to a server named 'amp_name'. None: no constraint. amp_serial: connect to a server with serial number 'amp_serial'. None: no constraint. eeg_only: ignore non-EEG servers """ self.winsec = window_size self.bufsec = buffer_size self.amp_serial = amp_serial self.eeg_only = eeg_only self.amp_name = amp_name self.tr_channel = None # trigger indx used by StreamReceiver class self.eeg_channels = [] # signal indx used by StreamReceiver class self.lsl_tr_channel = None # raw trigger indx in pylsl.pull_chunk() (DO NOT USE) self.lsl_eeg_channels = [ ] # raw signal indx in pylsl.pull_chunk() (DO NOT USE) self.ready = False # False until the buffer is filled for the first time self.bufsize = 0 # to be calculated using sampling rate self.connected = False self.buffers = [] self.timestamps = [] self.watchdog = qc.Timer() self.multiplier = 1 # 10**6 for Volts unit (automatically updated for openvibe servers) self.connect()
def cross_validation(X_data, Y_data, cfg): Y_data = Y_data.flatten() cv = StratifiedShuffleSplit(cfg.CV_FOLDS, test_size=cfg.CV_TEST_RATIO, random_state=0) scores = [] cnum = 1 timer = qc.Timer() for train_index, test_index in cv.split(X_data, Y_data): timer.reset() # print("TRAIN:", train_index, "TEST:", test_index) X_train, X_test = X_data[train_index], X_data[test_index] y_train, y_test = Y_data[train_index], Y_data[test_index] X_train = X_train.reshape(X_train.shape[0], X_train.shape[1] * X_train.shape[2]) X_test = X_test.reshape(X_test.shape[0], X_test.shape[1] * X_test.shape[2]) classifier.fit(X_train, y_train) Y_pred = classifier.predict(X_test) score = skmetrics.accuracy_score(y_test, Y_pred) scores.append(score) print('Cross-validation %d / %d (%.2f) - %.1f sec' % (cnum, cfg.CV_FOLDS, score, timer.sec())) cnum += 1 print('Average accuracy: %.2f' % np.mean(scores))
def __init__(self, mock=False): self.BUFFER_SIZE = 1024 self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.last_dir = 'L' self.timer = qc.Timer(autoreset=True) self.mock = mock if self.mock: self.print('Using a fake, mock Glass control object.')
def mergeMulti(self, argList): """ argList= [gn, ntlist.pop(), new_gid, P_LOCK] """ #print('###### <%s> self.mergeMulti() STARTED -- %.3f'% (current_process().name, time.time()-self.runtime) ) gn, nt, new_gid, P_LOCK = argList[0], argList[1], argList[2], argList[ 3] timer = qc.Timer() worse = gn.worse # merge grammar g_new, dlt_new = self.merge(nt[0], nt[1], self.getNextNT(gn.g), deepcopy(gn.g), deepcopy(gn.dlt), gn.gid) if g_new != None: new_pri = self.getPrior(g_new) new_lik = self.getLikelihood(g_new, dlt_new) g_new, dlt_new, pruned = self.pruneGrammar(g_new, dlt_new) if pruned: new_pri = self.getPrior(g_new) new_lik = self.getLikelihood(g_new, dlt_new) new_mdl = new_pri + new_lik ''' if new_mdl >= gn.bestmdl: worse += 1 else: worse= 0 ''' # debug info if VERBOSE > 1: msg = '[#%d] After MERGE(%s,%s) on #%d\n' % (new_gid, nt[0], nt[1], gn.gid) else: msg = '[#%d from #%d] ' % (new_gid, gn.gid) msg+= 'Worse=%d, Pri=%.3f, Lik=%.3f, OldMDL=%.3f, NewMDL=%.3f, bestBranchMDL=%.3f <%s: %.2f sec>'% \ (worse, new_pri, new_lik, gn.mdl, new_mdl, gn.bestmdl, current_process().name, timer.sec()) P_LOCK.acquire() if VERBOSE > 1: for p in pruned: self.printMsg( 2, '>> Rule %s -> %s [%0.6f] got pruned.' % (p[0], p[1], p[2])) self.printGrammar(2, g_new, dlt_new, msg) else: self.printMsg(1, msg) P_LOCK.release() #print('###### <%s> self.mergeMulti() FINISHED -- %.3f'% (current_process().name, time.time()-self.runtime) ) if new_mdl < gn.bestmdl: bestmdl = new_mdl else: bestmdl = gn.bestmdl return GNode(g_new, dlt_new, new_pri, new_lik, new_mdl, bestmdl, new_gid, worse)
def init_timer(self): self.tm = qc.Timer() # leeq QtCore.QCoreApplication.processEvents() QtCore.QCoreApplication.flush() self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update_loop) self.timer.start(20)
def fit_predict(cls1, cls2, X1_train, X2_train, Y_train, X1_test, X2_test, Y_test, cnum, label_set): """ Train and test a single fold """ tm = qc.Timer() cls1.fit(X1_train, Y_train) cls2.fit(X2_train, Y_train) Y_pred = get_final_label(cls1, cls2, X1_test, X2_test) score = skmetrics.accuracy_score(Y_test, Y_pred) cm = skmetrics.confusion_matrix(Y_test, Y_pred, label_set) print('Cross-validation %d (%.3f) - %.1f sec' % (cnum, score, tm.sec())) return score, cm
def azureml_main(dataframe1=None, dataframe2=None): # If a zip file is connected to the third input port is connected, # it is unzipped under ".\Script Bundle". This directory is added # to sys.path. Therefore, if your zip file contains a Python file # mymodule.py you can import it using: # import mymodule # print('Input pandas.DataFrame #1:\r\n\r\n{0}'.format(dataframe1)) # Import dependent modules. Run the tester module (tester.py) from your local machine to train and cross-validate your models. import sys import sklearn import numpy import pandas import q_common as qc import tester # System envrionment check print(sys.version) print('\nPlatform: %s' % tester.PLATFORM) print('sklearn: %s' % sklearn.__version__) print('pandas: %s' % pandas.__version__) print('numpy: %s' % numpy.__version__) print('MY_PATH: %s\n\n' % tester.MY_PATH) # Create a timer object to measure the runnning time tm = qc.Timer() # Load trained classifiers saved in a Python pickle format model_file = '%s/classifiers.pkl' % tester.MY_PATH model = qc.load_obj(model_file) assert model is not None # Load preprocessing and feature computation parameters cfg = model['cfg'] psd_params = model['psd_params'] epochs = model['epochs'] # Compute features from raw data features = tester.get_features(dataframe1, cfg, psd_params, epochs) # Test classifiers on computed features answers_pd = tester.predictor(features, model) # Print out predictions and running time print('Done. Took %.1f seconds.' % tm.sec()) print('\n*** Predicted labels start ***\n') print(answers_pd) print('\n*** Predicted labels end ***\n') # Return predictions return answers_pd
def get_prob(self): """ Read the latest window Returns ------- The likelihood P(X|C), where X=window, C=model """ tm = qc.Timer() if self.fake: probs = [random.uniform(0.3, 0.8)] # biased fake probs p_others = (1 - probs[0]) / (len(self.labels) - 1) for x in range(1, len(self.labels)): probs.append(p_others) time.sleep(0.0666) # simulated delay for PSD + RF on Rex laptop else: self.sr.acquire() w, ts = self.sr.get_window() # w = times x channels w = w.T # -> channels x times if self.spfilter == 'car': if self.spchannels is None: raise RuntimeError, 'FUNCTION NOT IMPLEMENTED YET.' else: w[self.spchannels] = w[self.spchannels] - np.mean( w[self.spchannels], axis=0) w = w[self.picks] # assuming trigger channel # psd = channels x freqs psd = self.psde.transform(w.reshape((1, w.shape[0], w.shape[1]))) # update psd buffer ( < 1 msec overhead ) self.psd_buffer = np.concatenate((self.psd_buffer, psd), axis=0) self.ts_buffer.append(ts[0]) if ts[0] - self.ts_buffer[0] > self.buffer_sec: # search speed comparison for ordered arrays: # http://stackoverflow.com/questions/16243955/numpy-first-occurence-of-value-greater-than-existing-value t_index = np.searchsorted(self.ts_buffer, ts[0] - 1.0) self.ts_buffer = self.ts_buffer[t_index:] self.psd_buffer = self.psd_buffer[ t_index:, :, :] # numpy delete is slower #assert ts[0] - self.ts_buffer[0] <= self.buffer_sec # make a feautre vector and classify feats = np.concatenate(psd[0]).reshape(1, -1) probs = self.cls.predict_proba(feats)[0] return probs
def update_ringbuffers(self): # leeq self.data_plot = np.roll(self.data_plot, -len(self.ts_list), 0) self.data_plot[-len(self.ts_list):, :] = self.eeg # We have to remove those indexes that reached time = 0 delete_indices_e = [] delete_indices_c = [] for x in xrange(0, len(self.events_detected), 2): xh = int(x / 2) self.events_detected[x] -= len(self.ts_list) # leeq if (self.events_detected[x] < 0) and (not self.stop_plot): delete_indices_e.append(x) delete_indices_e.append(x + 1) delete_indices_c.append(xh) self.events_curves[xh].clear() self.main_plot_handler.removeItem(self.events_text[xh]) self.events_detected = [ i for j, i in enumerate(self.events_detected) if j not in delete_indices_e ] self.events_curves = [ i for j, i in enumerate(self.events_curves) if j not in delete_indices_c ] self.events_text = [ i for j, i in enumerate(self.events_text) if j not in delete_indices_c ] # Find LPT events and add them if (self.show_LPT_events) and (not self.stop_plot): tm = qc.Timer() for x in range(len(self.tri)): if self.tri[x] != 0 and (self.tri[x] != self.last_tri): self.last_tri = int(self.tri[x]) self.addEventPlot("LPT", self.last_tri) self.print('Trigger %d received' % self.last_tri)
fake=False, amp_name=amp_name, amp_serial=amp_serial) # run on foreground (for debugging) #decoder= BCIDecoder(MODEL_FILE, buffer_size=1.0, amp_name=amp_name, amp_serial=amp_serial) # fake classifier #decoder= BCIDecoderDaemon(fake=True) # load trigger definitions for labeling tdef = TriggerDef() labels = [tdef.by_value[x] for x in decoder.get_labels()] probs = [0.5] * len(labels) # integrator tm = qc.Timer(autoreset=True) tm_cls = qc.Timer() while True: if isinstance(decoder, BCIDecoderDaemon): praw = decoder.get_prob_unread() else: praw = decoder.get_prob() if praw == None: if tm_cls.sec() > 5: print( '[%.1fs] WARNING: No classification being done. Are you receiving data streams?' % pylsl.local_clock()) tm_cls.reset() tm.sleep_atleast(0.001) # 1 ms
def go(self, symbolFile, seqDir): global ALGORITHM self.upper = sorted(ascii_uppercase, reverse=True) self.max_mdl = float("inf") self.algorithm = ALGORITHM self.term_p_other = None # computed once in the beginning based on the number of terminals self.t_dic_rev = { } # reverse look-up of self.t_dic defined once in the beginning self.t_stat = {} self.input_list = [] # history of inputs self.testfile = '%s/s%%02d.seq' % (seqDir) self.t_seq = open(symbolFile).readline().split() self.t_dic = {x: x.upper() for x in self.t_seq} #self.runtime= time.time() # for debugging assert len(self.t_dic) <= 25 assert len(self.t_seq) <= 25 for t in self.t_dic: self.t_dic_rev[self.t_dic[t]] = t if len(self.t_dic) == 1: self.term_p_other = 0 else: self.term_p_other = (1.0 - TERM_P) / (len(self.t_dic) - 1 ) # prob of other terminals rawdata = [] print('Reading input data') for f in qc.get_file_list(seqDir, fullpath=True): if f[-4:] != '.seq': continue print(f) syms = [] for l in open(f): probs = [float(x) for x in l.split()] max_sym = qc.get_index_max(probs) syms.extend([self.t_seq[max_sym], probs[max_sym]]) rawdata.append(syms) print('\n>> Algorithm %s started using following parameters:' % self.algorithm) '''"""""""""""""""""""""""""""""""""""""""""""""""""""""" Build initial grammar from input """"""""""""""""""""""""""""""""""""""""""""""""""""""''' print(">> Let's go !") G = {} dlt_init = OrderedDict() dlt_init['Z'] = {'terms': [], 'score': -1, 'count': 0, 'parent': None} for t in self.t_dic: G = self.addRule(G, self.t_dic[t], t) self.t_stat[t] = {'count': 0, 'prob': 0} for rawinput in rawdata: input = self.buildInput(rawinput) self.input_list.append(input) cin = ''.join(input['symbols']) G = self.addRule(G, 'Z', cin) self.updateTStat(input) dlt_init = self.inputDLT(input, dlt_init) dlt_init['Z']['terms'].append(self.conv2T(cin)) #dlt_init[cin]['parent']= 'Z' # keep counts only if self.algorithm == 'STOLCKE': for input in self.input_list: cin = ''.join(input['symbols']) self.t_stat[self.conv2T(cin)]['prob'] = 1.0 self.printTSTAT(1, 'Terminal Symbol Statistics') self.printGrammar(1, G, dlt_init, 'After adding new input') dlt_init = self.updateDLT(G, dlt_init) self.printDLT(1, dlt_init) timer = qc.Timer() '''"""""""""""""""""""""""""""""""""""""""""""""""""""""" Search for the best grammar """"""""""""""""""""""""""""""""""""""""""""""""""""""''' timer.reset() pri = self.getPrior(G) lik = self.getLikelihood(G, dlt_init) mdl = pri + lik gn = GNode(G, dlt_init, pri, lik, mdl, mdl, 0) gList = self.learnMulti(gn) # multi-process searching timeStamp = timer.sec() '''"""""""""""""""""""""""""""""""""""""""""""""""""""""" Post-process """"""""""""""""""""""""""""""""""""""""""""""""""""""''' # delete duplicates delList = [] for i in range(len(gList)): # sort RHS rules to compare equalities gList[i].g = self.sortRules(gList[i].g) rangePr = [self.max_mdl, 0] # min, max of DL(prior) rangeLi = [self.max_mdl, 0] # min, max of DL(likelihood) for i in range(len(gList)): pr = gList[i].pri li = gList[i].lik if (pr < rangePr[0]): rangePr[0] = pr if (pr > rangePr[1]): rangePr[1] = pr if li < self.max_mdl: if (li < rangeLi[0]): rangeLi[0] = li if (li > rangeLi[1]): rangeLi[1] = li for k in range(i + 1, len(gList)): if gList[i].g == gList[k].g: # THINK: SOMETIMES MDL IS DIFF FOR SAME GRAMMARS DUE TO DIFF DLT if gList[i].mdl != gList[k].mdl: pass delList.append(k) for d in sorted(list(set(delList)), reverse=True): del (gList[d]) gList = sorted(gList, key=lambda gnode: gnode.mdl) self.printGrammarList(0, gList, 'MDL values:') self.exportGrammarList(gList) print('\n>> Learning finished. Showing input symbols.') for input in self.input_list: print(' '.join(input['symbols'])) for x in input['values']: print('%0.2f ' % x, end='') print() print('\n>> Time consumed: %.1f secs' % timeStamp) print('Prune probability: %0.2f' % PRUNE_P) print('Terminal confidence (for exporting grammar): %0.2f' % TERM_P) print('Search beam size: %d' % BEAMSIZE) print('>> Finished.')
labels = [tdef.by_value[x] for x in decoder.get_labels()] probDown = labels.index(CLS_LEFT) probUp = labels.index(CLS_RIGHT) else: decoder = None # init event = 'start' trial = 1 num_samples = 0 sps_txt = '' segments = [] cval = None # timers timer = qc.Timer() timer_refresh = qc.Timer(autoreset=True) # visualization img = np.zeros((screen_height, screen_width, 3), np.uint8) bar = Bars(img, GLASS_USE) cv2.putText(img, 'Waiting to start', (120, 250), cv2.FONT_HERSHEY_SIMPLEX, 1, bar.color['W'], 2) cv2.namedWindow("mi") cv2.moveWindow("mi", 100, 20) cv2.imshow("mi", img) bar.fill('G') # loop tm_cls = qc.Timer() p_index = 0
def run_trainer(cfg, ftrain, interactive=False): # feature selection? datadir= cfg.DATADIR feat_picks= None txt= 'all' do_balance= False # preprocessing, epoching and PSD computation n_epochs= {} spfilter= cfg.SP_FILTER tpfilter= cfg.TP_FILTER # Load multiple files multiplier= 1 raw, events= pu.load_multi(ftrain, spfilter=spfilter, multiplier=multiplier) #print(raw._data.shape) #(17L, 2457888L) triggers= { cfg.tdef.by_value[c]:c for c in set(cfg.TRIGGER_DEF) } # Pick channels if cfg.CHANNEL_PICKS is None: picks= pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') #print (picks) # [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] else: picks= [] for c in cfg.CHANNEL_PICKS: if type(c)==int: picks.append(c) elif type(c)==str: picks.append( raw.ch_names.index(c) ) else: raise RuntimeError, 'CHANNEL_PICKS is unknown format.\nCHANNEL_PICKS=%s'% cfg.CHANNEL_PICKS if max(picks) > len(raw.info['ch_names']): print('ERROR: "picks" has a channel index %d while there are only %d channels.'%\ ( max(picks),len(raw.info['ch_names']) ) ) sys.exit(-1) # # Spatial filter if cfg.SP_CHANNELS is None: spchannels= pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') else: spchannels= [] for c in cfg.SP_CHANNELS: if type(c)==int: spchannels.append(c) elif type(c)==str: spchannels.append( raw.ch_names.index(c) ) else: raise RuntimeError, 'SP_CHANNELS is unknown format.\nSP_CHANNELS=%s'% cfg.SP_CHANNELS # # Spectral filter if tpfilter is not None: raw= raw.filter( tpfilter[0], tpfilter[1], picks=picks, n_jobs= mp.cpu_count() ) if cfg.NOTCH_FILTER is not None: raw= raw.notch_filter( cfg.NOTCH_FILTER, picks=picks, n_jobs= mp.cpu_count() ) # Read epochs try: epochs_train= Epochs(raw, events, triggers, tmin=cfg.EPOCH[0], tmax=cfg.EPOCH[1], proj=False,\ picks=picks, baseline=None, preload=True, add_eeg_ref=False, verbose=False, detrend=None) #print (epochs_train)# <Epochs | n_events : 422 (all good), tmin : 1.0 (s), tmax : 2.0 (s), baseline : None, ~26.5 MB, data loaded,'LEFT_GO': 212, 'RIGHT_GO': 210> except: print('\n*** (trainer.py) ERROR OCCURRED WHILE EPOCHING ***\n') traceback.print_exc() if interactive: print('Dropping into a shell.\n') pdb.set_trace() raise RuntimeError ''' epochs_data= epochs_train.get_data() print (epochs_data.shape) #(422L, 16L, 513L) trail*channel*caiyangdian #Visualize raw data for some channel in some trial ptrial=1 trail=np.zeros((len(spchannels),epochs_data.shape[2])) print(trail) for pch in range(len(spchannels)): print(pch) trail[pch,::] =epochs_data[ptrial,pch,::] color=["b","g","r",'c','m','y','k','w',"b","g","r",'c','m','y','k','w'] linstyle=['-','-','-','-','-','-','-','-','--','--','--','--','--','--','--','--',] for pch in range(len(spchannels)): print(color[pch]) print(linstyle[pch]) plt.plot(np.linspace(cfg.EPOCH[0], cfg.EPOCH[1], epochs_data.shape[2]), trail[pch,::],c=color[pch],ls=linstyle[pch], label='channel %d'%(pch+1),lw=0.5) plt.xlabel('time/s') plt.ylabel('voltage/uV') plt.title('Viewer') plt.legend(loc="lower right") plt.show() ''' label_set= np.unique(triggers.values()) sfreq= raw.info['sfreq'] # Compute features res= get_psd_feature(epochs_train, cfg.EPOCH, cfg.PSD, feat_picks) X_data= res['X_data'] Y_data= res['Y_data'] wlen= res['wlen'] w_frames= res['w_frames'] psde= res['psde'] psdfile= '%s/psd/psd-train.pcl'% datadir plot_pca_componet(X_data, Y_data) psdparams= cfg.PSD # print (events) for ev in triggers: print (ev) n_epochs[ev]= len( np.where(events[:,-1]==triggers[ev])[0] )#{'RIGHT_GO': 150, 'LEFT_GO': 150} total trails # Init a classifier if cfg.CLASSIFIER=='RF': # Make sure to set n_jobs=cpu_count() for training and n_jobs=1 for testing. cls= RandomForestClassifier(n_estimators=cfg.RF['trees'], max_features='auto',\ max_depth=cfg.RF['maxdepth'], n_jobs=mp.cpu_count(), class_weight='balanced' ) elif cfg.CLASSIFIER=='LDA': cls= LDA() # elif cfg.CLASSIFIER=='rLDA': # cls= rLDA(cfg.RLDA_REGULARIZE_COEFF) else: raise RuntimeError, '*** Unknown classifier %s'% cfg.CLASSIFIER # Cross-validation if cfg.CV_PERFORM is not None: ntrials, nsamples, fsize= X_data.shape if cfg.CV_PERFORM=='LeaveOneOut': print('\n>> %d-fold leave-one-out cross-validation'% ntrials) cv= LeaveOneOut(len(Y_data)) elif cfg.CV_PERFORM=='StratifiedShuffleSplit': print('\n>> %d-fold stratified cross-validation with test set ratio %.2f'% (cfg.CV_FOLDS, cfg.CV_TEST_RATIO)) cv= StratifiedShuffleSplit(Y_data[:,0], cfg.CV_FOLDS, test_size=cfg.CV_TEST_RATIO, random_state=0) else: print('>> ERROR: Unsupported CV method yet.') sys.exit(-1) print('%d trials, %d samples per trial, %d feature dimension'% (ntrials, nsamples, fsize) ) # Do it! scores= crossval_epochs(cv, X_data, Y_data, cls, cfg.tdef.by_value, do_balance) ''' #learning curve train_sizes,train_loss,test_loss=learning_curve(cls,X_data.reshape(X_data.shape[0]*X_data.shape[1],X_data.shape[2]),Y_data.reshape(Y_data.shape[0]*Y_data.shape[1]),train_sizes=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]) print(X_data.shape) print(Y_data.shape) train_loss_mean=np.mean(train_loss,axis=1) test_loss_mean=np.mean(test_loss,axis=1) plt.plot(train_sizes,train_loss_mean,label='training') plt.plot(train_sizes,test_loss_mean,label='Cross-validation') plt.xlabel('training examples') plt.ylabel('loss') plt.legend(loc='best') plt.show() ''' # Results print('\n>> Class information') for ev in np.unique(Y_data): print('%s: %d trials'% (cfg.tdef.by_value[ev], len(np.where(Y_data[:,0]==ev)[0])) ) if do_balance: print('The number of samples was balanced across classes. Method:', do_balance) print('\n>> Experiment conditions') print('Spatial filter: %s (channels: %s)'% (spfilter, spchannels) ) print('Spectral filter: %s'% tpfilter) print('Notch filter: %s'% cfg.NOTCH_FILTER) print('Channels: %s'% picks) print('PSD range: %.1f - %.1f Hz'% (psdparams['fmin'], psdparams['fmax']) ) print('Window step: %.1f msec'% (1000.0 * psdparams['wstep'] / sfreq) ) if type(wlen) is list: for i, w in enumerate(wlen): print('Window size: %.1f sec'% (w) ) print('Epoch range: %s sec'% (cfg.EPOCH[i])) else: print('Window size: %.1f sec'% (psdparams['wlen']) ) print('Epoch range: %s sec'% (cfg.EPOCH)) #chance= 1.0 / len(np.unique(Y_data)) cv_mean, cv_std= np.mean(scores), np.std(scores) print('\n>> Average CV accuracy over %d epochs'% ntrials) if cfg.CV_PERFORM in ['LeaveOneOut','StratifiedShuffleSplit']: print("mean %.3f, std: %.3f" % (cv_mean, cv_std) ) print('Classifier: %s'% cfg.CLASSIFIER) if cfg.CLASSIFIER=='RF': print(' %d trees, %d max depth'% (cfg.RF['trees'], cfg.RF['maxdepth']) ) if cfg.USE_LOG: logfile= '%s/result_%s_%s.txt'% (datadir, cfg.CLASSIFIER, txt) logout= open(logfile, 'a') logout.write('%s\t%.3f\t%.3f\n'% (ftrain[0], np.mean(scores), np.var(scores)) ) logout.close() # Train classifier archtype= platform.architecture()[0] # (’64bit’, ‘Windows7’) clsfile= '%s/classifier/classifier-%s.pcl'% (datadir,archtype) print('\n>> Training classifier') X_data_merged= np.concatenate( X_data ) Y_data_merged= np.concatenate( Y_data ) timer= qc.Timer() cls.fit( X_data_merged, Y_data_merged) print('Trained %d samples x %d dimension in %.1f sec'% \ (X_data_merged.shape[0], X_data_merged.shape[1], timer.sec())) # set n_jobs = 1 for testing cls.n_jobs= 1 classes= { c:cfg.tdef.by_value[c] for c in np.unique(Y_data) } #save FEATURES'PSD': data= dict( cls=cls, psde=psde, sfreq=sfreq, picks=picks, classes=classes, epochs=cfg.EPOCH, w_frames=w_frames, w_seconds=psdparams['wlen'], wstep=psdparams['wstep'], spfilter=spfilter, spchannels=spchannels, refchannel=None, tpfilter=tpfilter, notch=cfg.NOTCH_FILTER, triggers=cfg.tdef ) qc.make_dirs('%s/classifier'% datadir) qc.save_obj(clsfile, data) # Show top distinctive features if cfg.CLASSIFIER=='RF': print('\n>> Good features ordered by importance') keys, _= qc.sort_by_value( list(cls.feature_importances_), rev=True ) if cfg.EXPORT_GOOD_FEATURES: gfout= open('%s/good_features.txt'% datadir, 'w') # reverse-lookup frequency from fft if type(wlen) is not list: fq= 0 fq_res= 1.0 / psdparams['wlen'] fqlist= [] while fq <= psdparams['fmax']: if fq >= psdparams['fmin']: fqlist.append(fq) fq += fq_res for k in keys[:cfg.FEAT_TOPN]: ch,hz= qc.feature2chz(k, fqlist, picks, ch_names=raw.ch_names) print('%s, %.1f Hz (feature %d)'% (ch,hz,k) ) if cfg.EXPORT_GOOD_FEATURES: gfout.write( '%s\t%.1f\n'% (ch, hz) ) if cfg.EXPORT_GOOD_FEATURES: if cfg.CV_PERFORM is not None: gfout.write('\nCross-validation performance: mean %.2f, std %.2f\n'%(cv_mean, cv_std) ) gfout.close() print() else: print('Ignoring good features because of multiple epochs.') # Test file if len(cfg.ftest) > 0: raw_test, events_test= pu.load_raw('%s'%(cfg.ftest), spfilter) ''' TODO: implement multi-segment epochs ''' if type(cfg.EPOCH[0]) is list: print('MULTI-SEGMENT EPOCH IS NOT SUPPORTED YET.') sys.exit(-1) epochs_test= Epochs(raw_test, events_test, triggers, tmin=cfg.EPOCH[0], tmax=cfg.EPOCH[1],\ proj=False, picks=picks, baseline=None, preload=True, add_eeg_ref=False) psdfile= 'psd-test.pcl' if not os.path.exists(psdfile): print('\n>> Computing PSD for test set') X_test, y_test= pu.get_psd(epochs_test, psde, w_frames, int(sfreq/8)) qc.save_obj(psdfile, {'X':X_test, 'y':y_test}) else: print('\n>> Loading %s'% psdfile) data= qc.load_obj(psdfile) X_test, y_test= data['X'], data['y'] score_test= cls.score( np.concatenate(X_test), np.concatenate(y_test) ) print('Testing score', score_test) # running performance print('\nRunning performance over time') scores_windows= [] timer= qc.Timer() for ep in range( y_test.shape[0] ): scores= [] frames= X_test[ep].shape[0] timer.reset() for t in range(frames): X= X_test[ep][t,:] y= [y_test[ep][t]] scores.append( cls.score(X, y) ) #print('%d /%d %.1f msec'% (t,X_test[ep].shape[0],1000*timer.sec()) ) print('Tested epoch %d, %.3f msec per window'%(ep, timer.sec()*1000.0/frames) ) scores_windows.append(scores) scores_windows= np.array(scores_windows)
# settings CH_INDEX = [0] # zero-baesd TIME_INDEX = -1 import q_common as qc import mne amp_name, amp_serial = pu.search_lsl() sr = StreamReceiver(window_size=1, buffer_size=1, amp_serial=amp_serial, eeg_only=False, amp_name=amp_name) sfreq = sr.get_sample_rate() watchdog = qc.Timer() tm = qc.Timer(autoreset=True) trg_ch = sr.get_trigger_channel() qc.print_c('Trigger channel: %d' % trg_ch, 'G') psde= mne.decoding.PSDEstimator(sfreq=sfreq, fmin=1, fmax=50, bandwidth=None,\ adaptive=False, low_bias=True, n_jobs=1, normalization='length', verbose=None) last_ts = 0 while True: lsl_time = pylsl.local_clock() sr.acquire() window, tslist = sr.get_window() window = window.T
def record(state, amp_name, amp_serial, eeg_only=False): # set data file name filename = time.strftime(OUT_DIR + "/%Y%m%d-%H%M%S-raw.pcl", time.localtime()) qc.print_c('\n>> Output file: %s' % (filename), 'W') # test writability try: qc.make_dirs(OUT_DIR) open( filename, 'w').write('The data will written when the recording is finished.') except: qc.print_c( '\n*** ERROR: There was a problem writing file %s\n' % filename, 'W') sys.exit(-1) # start a server for sending out data filename for software trigger outlet = cnbi_lsl.start_server('StreamRecorderInfo', channel_format='string', source_id=filename, stype='Markers') # connect to EEG stream server sr = receiver.StreamReceiver(amp_name=amp_name, amp_serial=amp_serial, eeg_only=eeg_only) # record start qc.print_c('\n>> Recording started (PID %d).' % os.getpid(), 'W') qc.print_c('\n>> Press Enter to stop recording', 'G') tm = qc.Timer(autoreset=True) next_sec = 1 while state.value == 1: sr.acquire() if sr.get_buflen() > next_sec: duration = str(datetime.timedelta(seconds=int(sr.get_buflen()))) print('RECORDING %s' % duration) next_sec += 1 ###################################################### #data, ts= sr.get_window() #tc= pylsl.local_clock() #tson= np.argmax( ts >= int(tc) ) #print( ts[tson], tson, data[tson,0] ) ###################################################### tm.sleep_atleast(0.01) # record stop qc.print_c('>> Stop requested. Copying buffer', 'G') buffers, times = sr.get_buffer() # DO NOT INFER TRIGGER CHANNEL AUTOMATICALLY ''' signal_idx= [] for x in range(buffers.shape[1]): if x != sr.get_trigger_channel(): signal_idx.append(x) signals= buffers[:, signal_idx] events= buffers[ :, sr.get_trigger_channel() ] ''' signals = buffers events = None # channels = total channels from amp, including trigger channel data = { 'signals': signals, 'timestamps': times, 'events': events, 'sample_rate': sr.get_sample_rate(), 'channels': sr.get_num_channels(), 'ch_names': sr.get_channel_names() } qc.print_c('Saving data ...', 'W') qc.save_obj(filename, data) print('Saved to %s' % filename) import convert2fif as cf cf.pcl2fif(filename) qc.print_c('File saved and converted to fif format.', 'W')
def run_trainer(cfg, ftrain, interactive=False): # feature selection? datadir = cfg.DATADIR feat_picks = None txt = 'all' if cfg.USE_CVA: fcva = ftrain[0] + '.cva' if os.path.exists(fcva): feat_picks = open(fcva).readline().strip().split(',') feat_picks = [int(x) for x in feat_picks] print('\n>> Using only selected features') print(feat_picks) txt = 'cva' if hasattr(cfg, 'BALANCE_SAMPLES'): do_balance = cfg.BALANCE_SAMPLES else: do_balance = False # preprocessing, epoching and PSD computation n_epochs = {} if cfg.LOAD_PSD: raise RunetimeError, 'SORRY, CODE NOT FINISHED.' labels = np.array([]) X_data = None Y_data = None sfreq = None ts = None te = None for fpsd in qc.get_file_list(datadir, fullpath=True): if fpsd[-4:] != '.psd': continue data = qc.load_obj(fpsd) labels = np.hstack((labels, data['Y'][:, 0])) if X_data is None: sfreq = data['sfreq'] tmin = data['tmin'] tmax = data['tmax'] ''' TODO: implement multi-segment epochs ''' if type(cfg.EPOCH[0]) is list: print('MULTI-SEGMENT EPOCH IS NOT SUPPORTED YET.') sys.exit(-1) if cfg.EPOCH[0] < tmin or cfg.EPOCH[1] > tmax: raise RuntimeError, '\n*** Epoch time range is out of data range.' ts = int((cfg.EPOCH[0] - tmin) * sfreq / data['wstep']) te = int((cfg.EPOCH[1] - tmin) * sfreq / data['wstep']) # X: trials x channels x features X_data = data['X'][:, ts:te, :] Y_data = data['Y'][:, ts:te] else: X_data = np.vstack((X_data, data['X'][:, ts:te, :])) Y_data = np.vstack((Y_data, data['Y'][:, ts:te])) assert (len(labels) > 0) psde = data['psde'] psd_tmin = data['tmin'] psd_tmax = data['tmax'] picks = data['picks'] w_frames = int(sfreq * data['wlen']) # window length psdparams = dict(fmin=data['fmin'], fmax=data['fmax'], wlen=data['wlen'], wstep=data['wstep']) if 'classes' in data: triggers = data['classes'] else: triggers = {c: cfg.tdef.by_value[c] for c in set(labels)} spfilter = data['spfilter'] spchannels = data['spchannels'] tpfilter = data['tpfilter'] for ev in data['classes']: n_epochs[ev] = len( np.where(Y_data[:, 0] == data['classes'][ev])[0]) else: spfilter = cfg.SP_FILTER tpfilter = cfg.TP_FILTER # Load multiple files if hasattr(cfg, 'MULTIPLIER'): multiplier = cfg.MULTIPLIER else: multiplier = 1 raw, events = pu.load_multi(ftrain, spfilter=spfilter, multiplier=multiplier) if cfg.LOAD_EVENTS_FILE is not None: events = mne.read_events(cfg.LOAD_EVENTS_FILE) triggers = {cfg.tdef.by_value[c]: c for c in set(cfg.TRIGGER_DEF)} # Pick channels if cfg.CHANNEL_PICKS is None: picks = pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') else: picks = [] for c in cfg.CHANNEL_PICKS: if type(c) == int: picks.append(c) elif type(c) == str: picks.append(raw.ch_names.index(c)) else: raise RuntimeError, 'CHANNEL_PICKS is unknown format.\nCHANNEL_PICKS=%s' % cfg.CHANNEL_PICKS if max(picks) > len(raw.info['ch_names']): print('ERROR: "picks" has a channel index %d while there are only %d channels.'%\ ( max(picks),len(raw.info['ch_names']) ) ) sys.exit(-1) # Spatial filter if cfg.SP_CHANNELS is None: spchannels = pick_types(raw.info, meg=False, eeg=True, stim=False, eog=False, exclude='bads') else: spchannels = [] for c in cfg.SP_CHANNELS: if type(c) == int: spchannels.append(c) elif type(c) == str: spchannels.append(raw.ch_names.index(c)) else: raise RuntimeError, 'SP_CHANNELS is unknown format.\nSP_CHANNELS=%s' % cfg.SP_CHANNELS # Spectral filter if tpfilter is not None: raw = raw.filter(tpfilter[0], tpfilter[1], picks=picks, n_jobs=mp.cpu_count()) if cfg.NOTCH_FILTER is not None: raw = raw.notch_filter(cfg.NOTCH_FILTER, picks=picks, n_jobs=mp.cpu_count()) # Read epochs try: if type(cfg.EPOCH[0]) is list: epochs_train = [] for ep in cfg.EPOCH: epochs_train.append( Epochs(raw, events, triggers, tmin=ep[0], tmax=ep[1], proj=False,\ picks=picks, baseline=None, preload=True, add_eeg_ref=False, verbose=False, detrend=None) ) else: epochs_train= Epochs(raw, events, triggers, tmin=cfg.EPOCH[0], tmax=cfg.EPOCH[1], proj=False,\ picks=picks, baseline=None, preload=True, add_eeg_ref=False, verbose=False, detrend=None) except: print('\n*** (trainer.py) ERROR OCCURRED WHILE EPOCHING ***\n') traceback.print_exc() if interactive: print('Dropping into a shell.\n') pdb.set_trace() raise RuntimeError label_set = np.unique(triggers.values()) sfreq = raw.info['sfreq'] # Compute features if cfg.FEATURES == 'PSD': res = get_psd_feature(epochs_train, cfg.EPOCH, cfg.PSD, feat_picks) X_data = res['X_data'] Y_data = res['Y_data'] wlen = res['wlen'] w_frames = res['w_frames'] psde = res['psde'] psdfile = '%s/psd/psd-train.pcl' % datadir elif cfg.FEATURES == 'TIMELAG': ''' TODO: Implement multiple epochs for timelag feature ''' if type(epcohs_train) is list: print( 'MULTIPLE EPOCHS NOT IMPLEMENTED YET FOR TIMELAG FEATURE.') sys.exit(-1) X_data, Y_data = get_timelags(epochs_train, cfg.TIMELAG['w_frames'], cfg.TIMELAG['wstep'], cfg.TIMELAG['downsample']) elif cfg.FEATURES == 'WAVELET': ''' TODO: Implement multiple epochs for wavelet feature ''' if type(epcohs_train) is list: print( 'MULTIPLE EPOCHS NOT IMPLEMENTED YET FOR WAVELET FEATURE.') sys.exit(-1) ############################### DO WE NEED SLIDING WINDOW ????????? X_data, Y_data = None, None for ev in epochs_train.event_id: e = 0 for ep in epochs_train[ev]: e += 1 freqs = np.arange(4, 30, 2) n_cycles = freqs / 2 tfr = mne.time_frequency.cwt_morlet(ep, sfreq, freqs=freqs, n_cycles=n_cycles) tlen = 0.8 tfr = np.log(np.abs(tfr[:, :, round(-sfreq * tlen):])) ''' qc.make_dirs('%s/mat'% cfg.DATADIR) scipy.io.savemat('%s/mat/tfr-%s-%d.mat'% (cfg.DATADIR,ev,e), {'tfr':tfr[2]}) ''' feat = tfr.reshape(1, -1) if X_data is None: X_data = feat else: X_data = np.concatenate((X_data, feat), axis=0) # Y_data dimension is different here ! y = np.empty((epochs_train[ev]._data.shape[0])) # windows x 1 y.fill(epochs_train.event_id[ev]) if Y_data is None: Y_data = y else: Y_data = np.concatenate((Y_data, y)) cls= RandomForestClassifier(n_estimators=cfg.RF['trees'], max_features='auto',\ max_depth=cfg.RF['maxdepth'], n_jobs=mp.cpu_count() )#, class_weight={cfg.tdef.LOS:20, cfg.tdef.LO:1}) scores = [] cnum = 1 timer = qc.Timer() num_labels = len(label_set) cm = np.zeros((num_labels, num_labels)) # select train and test trial ID's from sklearn import cross_validation cv = cross_validation.ShuffleSplit(X_data.shape[0], n_iter=20, test_size=0.1) for train, test in cv: timer.reset() X_train = X_data[train] X_test = X_data[test] Y_train = Y_data[train] Y_test = Y_data[test] if do_balance != False: X_train, Y_train = balance_samples(X_train, Y_train, do_balance, False) X_test, Y_test = balance_samples(X_test, Y_test, do_balance, False) cls.n_jobs = mp.cpu_count() cls.fit(X_train, Y_train) cls.n_jobs = 1 #score= cls.score( X_test, Y_test ) Y_pred = cls.predict(X_test) score = skmetrics.accuracy_score(Y_test, Y_pred) cm += skmetrics.confusion_matrix(Y_test, Y_pred, label_set) scores.append(score) print('Cross-validation %d / %d (%.2f) - %.1f sec' % (cnum, len(cv), score, timer.sec())) cnum += 1 # show confusion matrix cm_sum = np.sum(cm, axis=1) cm_rate = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis] print('\nY: ground-truth, X: predicted') for l in label_set: print('%-5s' % cfg.tdef.by_value[l][:5], end='\t') print() for r in cm_rate: for c in r: print('%-5.2f' % c, end='\t') print() print('Average accuracy: %.2f' % np.mean(scores)) #X_data= X_data.reshape(1, X_data.shape[0], X_data.shape[1]) sys.exit() else: print('>> ERROR: %s not supported yet.' % cfg.FEATURES) sys.exit() psdparams = cfg.PSD for ev in triggers: n_epochs[ev] = len(np.where(events[:, -1] == triggers[ev])[0]) # Init a classifier if cfg.CLASSIFIER == 'RF': # Make sure to set n_jobs=cpu_count() for training and n_jobs=1 for testing. cls= RandomForestClassifier(n_estimators=cfg.RF['trees'], max_features='auto',\ max_depth=cfg.RF['maxdepth'], n_jobs=mp.cpu_count(), class_weight='balanced' ) elif cfg.CLASSIFIER == 'LDA': cls = LDA() elif cfg.CLASSIFIER == 'rLDA': cls = rLDA(cfg.RLDA_REGULARIZE_COEFF) else: raise RuntimeError, '*** Unknown classifier %s' % cfg.CLASSIFIER # Cross-validation if cfg.CV_PERFORM is not None: ntrials, nsamples, fsize = X_data.shape if cfg.CV_PERFORM == 'LeaveOneOut': print('\n>> %d-fold leave-one-out cross-validation' % ntrials) cv = LeaveOneOut(len(Y_data)) elif cfg.CV_PERFORM == 'StratifiedShuffleSplit': print( '\n>> %d-fold stratified cross-validation with test set ratio %.2f' % (cfg.CV_FOLDS, cfg.CV_TEST_RATIO)) cv = StratifiedShuffleSplit(Y_data[:, 0], cfg.CV_FOLDS, test_size=cfg.CV_TEST_RATIO, random_state=0) else: print('>> ERROR: Unsupported CV method yet.') sys.exit(-1) print('%d trials, %d samples per trial, %d feature dimension' % (ntrials, nsamples, fsize)) # Do it! scores = crossval_epochs(cv, X_data, Y_data, cls, cfg.tdef.by_value, do_balance) # Results print('\n>> Class information') for ev in np.unique(Y_data): print( '%s: %d trials' % (cfg.tdef.by_value[ev], len(np.where(Y_data[:, 0] == ev)[0]))) if do_balance: print('The number of samples was balanced across classes. Method:', do_balance) print('\n>> Experiment conditions') print('Spatial filter: %s (channels: %s)' % (spfilter, spchannels)) print('Spectral filter: %s' % tpfilter) print('Notch filter: %s' % cfg.NOTCH_FILTER) print('Channels: %s' % picks) print('PSD range: %.1f - %.1f Hz' % (psdparams['fmin'], psdparams['fmax'])) print('Window step: %.1f msec' % (1000.0 * psdparams['wstep'] / sfreq)) if type(wlen) is list: for i, w in enumerate(wlen): print('Window size: %.1f sec' % (w)) print('Epoch range: %s sec' % (cfg.EPOCH[i])) else: print('Window size: %.1f sec' % (psdparams['wlen'])) print('Epoch range: %s sec' % (cfg.EPOCH)) #chance= 1.0 / len(np.unique(Y_data)) cv_mean, cv_std = np.mean(scores), np.std(scores) print('\n>> Average CV accuracy over %d epochs' % ntrials) if cfg.CV_PERFORM in ['LeaveOneOut', 'StratifiedShuffleSplit']: print("mean %.3f, std: %.3f" % (cv_mean, cv_std)) print('Classifier: %s' % cfg.CLASSIFIER) if cfg.CLASSIFIER == 'RF': print(' %d trees, %d max depth' % (cfg.RF['trees'], cfg.RF['maxdepth'])) if cfg.USE_LOG: logfile = '%s/result_%s_%s.txt' % (datadir, cfg.CLASSIFIER, txt) logout = open(logfile, 'a') logout.write('%s\t%.3f\t%.3f\n' % (ftrain[0], np.mean(scores), np.var(scores))) logout.close() # Train classifier archtype = platform.architecture()[0] clsfile = '%s/classifier/classifier-%s.pcl' % (datadir, archtype) print('\n>> Training classifier') X_data_merged = np.concatenate(X_data) Y_data_merged = np.concatenate(Y_data) if do_balance: X_data_merged, Y_data_merged = balance_samples(X_data_merged, Y_data_merged, do_balance, verbose=True) timer = qc.Timer() cls.fit(X_data_merged, Y_data_merged) print('Trained %d samples x %d dimension in %.1f sec'% \ (X_data_merged.shape[0], X_data_merged.shape[1], timer.sec())) # set n_jobs = 1 for testing cls.n_jobs = 1 if cfg.EXPORT_CLS == True: classes = {c: cfg.tdef.by_value[c] for c in np.unique(Y_data)} if cfg.FEATURES == 'PSD': data = dict(cls=cls, psde=psde, sfreq=sfreq, picks=picks, classes=classes, epochs=cfg.EPOCH, w_frames=w_frames, w_seconds=psdparams['wlen'], wstep=psdparams['wstep'], spfilter=spfilter, spchannels=spchannels, refchannel=None, tpfilter=tpfilter, notch=cfg.NOTCH_FILTER, triggers=cfg.tdef) elif cfg.FEATURES == 'TIMELAG': data = dict(cls=cls, parameters=cfg.TIMELAG) qc.make_dirs('%s/classifier' % datadir) qc.save_obj(clsfile, data) # Show top distinctive features if cfg.CLASSIFIER == 'RF' and cfg.FEATURES == 'PSD': print('\n>> Good features ordered by importance') keys, _ = qc.sort_by_value(list(cls.feature_importances_), rev=True) if cfg.EXPORT_GOOD_FEATURES: gfout = open('%s/good_features.txt' % datadir, 'w') # reverse-lookup frequency from fft if type(wlen) is not list: fq = 0 fq_res = 1.0 / psdparams['wlen'] fqlist = [] while fq <= psdparams['fmax']: if fq >= psdparams['fmin']: fqlist.append(fq) fq += fq_res for k in keys[:cfg.FEAT_TOPN]: ch, hz = feature2chz(k, fqlist, picks, ch_names=raw.ch_names) print('%s, %.1f Hz (feature %d)' % (ch, hz, k)) if cfg.EXPORT_GOOD_FEATURES: gfout.write('%s\t%.1f\n' % (ch, hz)) if cfg.EXPORT_GOOD_FEATURES: if cfg.CV_PERFORM is not None: gfout.write( '\nCross-validation performance: mean %.2f, std %.2f\n' % (cv_mean, cv_std)) gfout.close() print() else: print('Ignoring good features because of multiple epochs.') # Test file if len(cfg.ftest) > 0: raw_test, events_test = pu.load_raw('%s' % (cfg.ftest), spfilter) ''' TODO: implement multi-segment epochs ''' if type(cfg.EPOCH[0]) is list: print('MULTI-SEGMENT EPOCH IS NOT SUPPORTED YET.') sys.exit(-1) epochs_test= Epochs(raw_test, events_test, triggers, tmin=cfg.EPOCH[0], tmax=cfg.EPOCH[1],\ proj=False, picks=picks, baseline=None, preload=True, add_eeg_ref=False) if cfg.FEATURES == 'PSD': psdfile = 'psd-test.pcl' if not os.path.exists(psdfile): print('\n>> Computing PSD for test set') X_test, y_test = pu.get_psd(epochs_test, psde, w_frames, int(sfreq / 8)) qc.save_obj(psdfile, {'X': X_test, 'y': y_test}) else: print('\n>> Loading %s' % psdfile) data = qc.load_obj(psdfile) X_test, y_test = data['X'], data['y'] else: print('>> Feature not supported yet for testing set.') sys.exit(-1) score_test = cls.score(np.concatenate(X_test), np.concatenate(y_test)) print('Testing score', score_test) # running performance print('\nRunning performance over time') scores_windows = [] timer = qc.Timer() for ep in range(y_test.shape[0]): scores = [] frames = X_test[ep].shape[0] timer.reset() for t in range(frames): X = X_test[ep][t, :] y = [y_test[ep][t]] scores.append(cls.score(X, y)) #print('%d /%d %.1f msec'% (t,X_test[ep].shape[0],1000*timer.sec()) ) print('Tested epoch %d, %.3f msec per window' % (ep, timer.sec() * 1000.0 / frames)) scores_windows.append(scores) scores_windows = np.array(scores_windows) ############################################################################### # Plot performance over time ############################################################################### #w_times= (w_start + w_frames / 2.) / sfreq + epochs.tmin step = float(epochs_test.tmax - epochs_test.tmin) / scores_windows.shape[1] w_times = np.arange(epochs_test.tmin, epochs_test.tmax, step) plt.plot(w_times, np.mean(scores_windows, 0), label='Score') plt.axvline(0, linestyle='--', color='k', label='Onset') plt.axhline(0.5, linestyle='-', color='k', label='Chance') plt.xlabel('time (s)') plt.ylabel('Classification accuracy') plt.title('Classification score over time') plt.legend(loc='lower right') plt.show() '''
def crossval_epochs(cv, epochs_data, labels, cls, label_names=None, do_balance=False): """ Epoch (trial) based cross-validation cv: scikit-learn cross-validation object epochs_data: np.array of [epochs x samples x features] cls: classifier labels: vector of integer labels label_names: associated label names {0:'Left', 1:'Right', ...} do_balance: oversample or undersample to match the number of samples among classes """ scores = [] cnum = 1 timer = qc.Timer() label_set = np.unique(labels) num_labels = len(label_set) cm = np.zeros((num_labels, num_labels)) if label_names == None: label_names = {l: '%s' % l for l in label_set} # select train and test trial ID's for train, test in cv: timer.reset() X_train = np.concatenate(epochs_data[train]) X_test = np.concatenate(epochs_data[test]) Y_train = np.concatenate(labels[train]) Y_test = np.concatenate(labels[test]) if do_balance != False: X_train, Y_train = balance_samples(X_train, Y_train, do_balance) X_test, Y_test = balance_samples(X_test, Y_test, do_balance) cls.n_jobs = mp.cpu_count() cls.fit(X_train, Y_train) cls.n_jobs = 1 #score= cls.score( X_test, Y_test ) Y_pred = cls.predict(X_test) score = skmetrics.accuracy_score(Y_test, Y_pred) cm += skmetrics.confusion_matrix(Y_test, Y_pred, label_set) scores.append(score) print('Cross-validation %d / %d (%.2f) - %.1f sec' % (cnum, len(cv), score, timer.sec())) cnum += 1 # show confusion matrix cm_rate = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis] print('\nY: ground-truth, X: predicted') for l in label_set: print('%-5s' % label_names[l][:5], end='\t') print() for r in cm_rate: for c in r: print('%-5.2f' % c, end='\t') print() print('Average accuracy: %.2f' % np.mean(scores)) ''' # plot confusion matrix plt.matshow(cm_rate) plt.title('Confusion matrix') plt.colorbar() plt.ylabel('True label') plt.xlabel('Predicted label') plt.show() ''' return np.array(scores)
def crossval_epochs(cv, epochs_data, labels, cls, label_names=None, do_balance=False): """ Epoch (trial) based cross-validation cv: scikit-learn cross-validation object epochs_data: np.array of [epochs x samples x features] cls: classifier labels: vector of integer labels label_names: associated label names {0:'Left', 1:'Right', ...} do_balance: oversample or undersample to match the number of samples among classes """ scores= [] cnum= 1 timer= qc.Timer() label_set= np.unique(labels) num_labels= len(label_set) cm= np.zeros( (num_labels, num_labels) ) if label_names==None: label_names= {l:'%s'%l for l in label_set} # select train and test trial ID's for i, (train, test) in enumerate(cv): timer.reset() X_train= np.concatenate( epochs_data[train] ) X_test= np.concatenate( epochs_data[test] ) Y_train= np.concatenate( labels[train] ) Y_test= np.concatenate( labels[test] ) cls.n_jobs= mp.cpu_count() cls.fit( X_train, Y_train ) cls.n_jobs= 1 #score= cls.score( X_test, Y_test ) Y_pred= cls.predict( X_test ) score= skmetrics.accuracy_score(Y_test, Y_pred) cm += skmetrics.confusion_matrix(Y_test, Y_pred, label_set) scores.append( score ) print('Cross-validation %d / %d (%.2f) - %.1f sec'% (cnum, len(cv), score,timer.sec()) ) cnum += 1 ''' #ROC AUC if(num_labels==2): mean_tpr = 0.0 mean_fpr = np.linspace(0, 1, 100) all_tpr = [] probas_ = cls.fit(X_train, Y_train ).predict_proba(X_test) Y_test[np.where(Y_test==label_set[0])]=0 Y_test[np.where(Y_test==label_set[1])]=1 fpr, tpr, thresholds = roc_curve(Y_test, probas_[:, 1]) mean_tpr += interp(mean_fpr, fpr, tpr) print (mean_tpr) mean_tpr[0] = 0.0 roc_auc = auc(fpr, tpr) plt.plot(fpr, tpr, lw=1, label='ROC fold %d (area = %0.2f)' % (i, roc_auc)) plt.plot([0, 1], [0, 1], '--', color=(0.6, 0.6, 0.6), label='Luck') #mean_tpr[-1] = 1.0 #坐标最后一个点为(1,1) print (mean_tpr) mean_auc = auc(mean_fpr, mean_tpr) #计算平均AUC值 #画平均ROC曲线 #print mean_fpr,len(mean_fpr) #print mean_tpr plt.plot(mean_fpr, mean_tpr, 'k--', label='Mean ROC (area = %0.2f)' % mean_auc, lw=2) plt.xlim([-0.05, 1.05]) plt.ylim([-0.05, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver operating characteristic example') plt.legend(loc="lower right") plt.show() ''' # show confusion matrix cm_rate= cm.astype('float') / cm.sum(axis=1)[:, np.newaxis] print('\nY: ground-truth, X: predicted') for l in label_set: print('%-5s'% label_names[l][:5], end='\t') print() for r in cm_rate: for c in r: print('%-5.2f'% c, end='\t') print() print('Average accuracy: %.2f'% np.mean(scores) ) ''' # plot confusion matrix plt.matshow(cm_rate) plt.title('Confusion matrix') plt.colorbar() plt.ylabel('True label') plt.xlabel('Predicted label') plt.show() ''' return np.array(scores)
cv2.rectangle(img, (0, 0), (500, 500), (0, 0, 0), -1) def draw_cue(img, box=color['R'], cross=color['W']): cv2.rectangle(img, (100, 200), (400, 300), color['w'], -1) cv2.rectangle(img, (200, 100), (300, 400), color['w'], -1) cv2.rectangle(img, (200, 200), (300, 300), box, -1) #cv2.circle( img, (250,250), 10, color['Y'], -1 ) cv2.rectangle(img, (240, 248), (260, 252), cross, -1) cv2.rectangle(img, (248, 240), (252, 260), cross, -1) cv2.namedWindow("mi") cv2.moveWindow("mi", 430, 130) #Moves window to the specified position timer_refresh = qc.Timer() #class Timer: timer_trigger = qc.Timer() timer_dir = qc.Timer() # start while trial <= cfg.num_trials: timer_refresh.sleep_atleast(0.2) #print(timer_refresh.sec()) timer_refresh.reset() # segment= { 'cue':(s,e), 'dir':(s,e), 'label':0-4 } (zero-based) if event == 'start' and timer_trigger.sec() > cfg.t_init: event = 'gap_s' screen_erase(img) timer_trigger.reset()
event = 'start' trial = 1 # Hardware trigger #trigger= pyLptControl.Trigger(TRIGGER_DEVICE) trigger = pyLptControl.Trigger('USB2LPT', 0x378) if trigger.init(50) == False: print( '\n# Error connecting to USB2LPT device. Use a mock trigger instead?') raw_input('Press Ctrl+C to stop or Enter to continue.') trigger = pyLptControl.MockTrigger() trigger.init(50) cv2.namedWindow("mi") cv2.moveWindow("mi", 430, 130) timer_trigger = qc.Timer() timer_dir = qc.Timer() timer_refresh = qc.Timer() tdef = TriggerDef() # start while trial <= num_trials: timer_refresh.sleep_atleast(0.2) #print(timer_refresh.sec()) timer_refresh.reset() # segment= { 'cue':(s,e), 'dir':(s,e), 'label':0-4 } (zero-based) if event == 'start' and timer_trigger.sec() > t_init: event = 'gap_s' screen_erase(img) timer_trigger.reset()