Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
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))
Exemplo n.º 3
0
 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.')
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
                               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
Exemplo n.º 11
0
    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.')
Exemplo n.º 12
0
        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
Exemplo n.º 13
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)  
Exemplo n.º 14
0
    # 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
Exemplo n.º 15
0
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')
Exemplo n.º 16
0
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()
    '''
Exemplo n.º 17
0
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)
Exemplo n.º 18
0
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)
Exemplo n.º 19
0
    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()
Exemplo n.º 20
0
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()