• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 穩態視覺誘發電位(SSVEP)識別| Extended Canonical Correlation Analysis, eCCA

    標簽: 腦-機接口  算法【ML etc.】

    Note: 在我有空的時候盡量把SSVEP流行的方法都開源出來,一是方便自己復習和鞏固,二是希望廣大網友能夠指出我思路中存在的一些問題。本人接觸這個領域時間較短,有什么紕漏請多指教。

    前言

    如果要說目前SSVEP識別中最流行的幾個方法,那么Extended Canonical Correlation Analysis(eCCA)1絕對是其中之一。目前來看,如果研究SSVEP算法,那么對比算法基本是TRCA或者eCCA2 3。此外,很多在線BCI系統也是采用該方法進行頻率識別。與TRCA這種具有自己數學模型的方法不同,eCCA僅是對CCA的一種計算結構調整。我們知道受試者的template中包含著一些潛在可利用的分類信息(相位等),eCCA在CCA基礎上考慮到了受試者template項。

    算法

    我們知道典型相關分析(CCA)是一種降維和評估兩組多維數據相關性的方法,它通過一對典型變量將兩組數據變為一維,使得兩者之間的相關系數最大。可以參考博客12
    CCA應用在SSVEP識別上得到了很好的效果,當已有受試者訓練數據的時候,我們能夠獲得三種多通道信號:測試數據X(t)RNc×Ns×NtX(t)\in R^{N_c\times N_s\times N_t},受試者訓練數據的平均X^kNc×Ns\hat X_k^{N_c\times N_s}以及構造的正余弦參考信號YfkY_{f_k},其中NcN_cNsN_sNtN_t分別表示通道數、采樣點數和測試集trial數。任意兩種信號可以根據CCA計算出空間濾波器。
    按照排列組合方式來看,如果我們要根據其中兩個信號求空間濾波器,那么會有六種空間濾波器形式。六種空間濾波器會產生10個典型變量,然后每兩個典型變量之間又可以計算相關系數,那么就有45個相關系數。這個在Mohammad Hadi MehdizavarehI等人2020年發表在PLOS ONE上的文章4有詳述。但實際應用過程中,我們通常只取了三種空間濾波器形式(這里以Chen X等人PANS上的文章為例,第三項做了修正)分別為

    • WX(XX^k)W_X(X\hat X_k)WX^k(XX^k)W_{\hat X_k}(X\hat X_k):測試數據和template之間;
    • WX(XYfk)W_X(XY_{f_k}):測試數據和參考信號之間;
    • WX^k(X^kYfk)W_{\hat X_k}(\hat X_kY_{f_k}):template和參考信號之間。

    由上述空間濾波器,我們可以得到5個相關系數組合(這里的數量在不同的論文中不一致,最初提出eCCA的時候并沒有對為什么采用下述相關系數組合做解釋。),如下
    在這里插入圖片描述
    注:上述公式來自Chen X等人的論文,其中rk(4)r_k(4)所對應的空間濾波器形式有誤,應該為WX^k(X^kYfk)W_{\hat X_k}(\hat X_kY_{f_k})如果僅考慮第一項,那么算法變為標準的CCA;如果對相關系數進行融合,便可以得到k-th刺激下的相關系數。最后通過確認最大相關系數對應的刺激便可以實現分類
    在這里插入圖片描述
    整個算法的計算結構為
    在這里插入圖片描述

    Matlab代碼

    CCA

    function [output1, output2] = CCA(signal1, signal2)
    % Canonical Correlation Analysis, CCA
    % Input:
    %   signal: #channels, #points
    % Output:
    % output1: spatial filter of signal1
    % output2: spatial filter of signal2
    %
    X=signal1;
    Y=signal2;
    T=size(signal2, 2);
    %compute covariance matrix 
    meanx=mean(X,2);
    meany=mean(Y,2);
    s11=0;s22=0;s12=0;s21=0;
    for i1=1:T
      s11=s11+(X(:,i1)-meanx)*(X(:,i1)-meanx)';
      s22=s22+(Y(:,i1)-meany)*(Y(:,i1)-meany)';
      s12=s12+(X(:,i1)-meanx)*(Y(:,i1)-meany)';
      s21=s21+(Y(:,i1)-meany)*(X(:,i1)-meanx)';
    end
    s11=s11/(T-1);         
    s22=s22/(T-1); 
    s12=s12/(T-1); 
    s21=s21/(T-1);
    %compute eigvalue and eigvector
    [eigvectora,eigvaluea]=eig(inv(s11)*s12*inv(s22)*s21);
    [eigvectorb,eigvalueb]=eig(inv(s22)*s21*inv(s11)*s12);
    
    evaluea= diag(eigvaluea);
    evalueb = diag(eigvalueb);
    % correlation coefficient & canonical variates of signal1
    [corrcoef1, index]= max(sqrt(evaluea));
    output1 = eigvectora(:, index);
    % correlation coefficient & canonical variates of signal2
    [corrcoef2, index]= max(sqrt(evalueb));
    output2 = eigvectorb(:, index);    
    end
    

    對上述程序做簡要解釋

    • 上述CCA求解采用的是特征值分解的方法,另外還可以參考SVD分解的做法
    • 通過CCA的推導過程可以看到,corrcoef1和corrcoef2相等,表示兩個輸入多通道信號的相關系數。在SSVEP中,標準CCA可采用該值直接輸出;
    • 這個函數文件輸出的是兩個多通道信號的典型變量,即空間濾波器。

    eCCA

    % -------------------------------------------------------------------------
    % Main for Extended Canonical Correlation Analysis[1]
    %
    % Dataset (Sx.mat):
    %   A 40-target SSVEP dataset recorded from a single subject. The stimuli
    %   were generated by the j oint frequency-phase modulation (JFPM)
    %     - Stimulus frequencies    : 8.0 - 15.8 Hz with an interval of 0.2 Hz
    %     - Stimulus phases         : 0pi, 0.5pi, 1.0pi, and 1.5pi
    %     - # of channels           : Oz
    %     - # of recording blocks   : 6
    %     - Data length of epochs   : 1.5 [seconds]
    %     - Sampling rate           : 250 [Hz]
    %     - Data format             : # channels, # points, # targets, # blocks
    % 
    % See also:
    %   CCA.m
    %
    % Reference:
    %   [1] Chen X, Wang Y, Nakanishi M, Gao X, Jung TP, Gao S (2015)
    %       High-speed spelling with a noninvasive brain-computer interface. 
    %       PNAS 112:E6058-6067.
    % -------------------------------------------------------------------------
    
    clear all
    close all
    
    load ('Freq_Phase.mat')
    load('subject1.mat')
    eeg = subject1;
    [N_channel, N_point, N_target, N_block] = size(eeg);
    % sample rate
    fs = 250;
    t=1/fs:1/fs:N_point/fs;   
    %% ------------classification-------------
    tic
    % LOO cross-validation
    for loocv_i = 1:N_block
         Testdata = eeg(:, :, :, loocv_i);
         Traindata = eeg;
         Traindata(:, :, :, loocv_i) = [];
         % number of harmonics
         N_harmonic = 2;
        for targ_i = 1:N_target
            % Template
            Template(:, :, targ_i) = mean(squeeze(Traindata(:,:,targ_i,:)),3);
            % Reference
            Y=[];
            for har_i=1:N_harmonic
                 Y=cat(1,Y,cat(1, sin(2*pi*freqs(targ_i)*har_i*t), ...
                     cos(2*pi*freqs(targ_i)*har_i*t)));        
            end
            Reference(:, :, targ_i) = Y;
        end
        
        % labels assignment according to testdata
        truelabels=freqs;
        
        N_testTrial=size(Testdata, 3);
        for trial_i=1:N_testTrial
            Allcoefficience = [];
            for targ_j=1:length(freqs)             
                % ρ1 (Filter: Test data & Reference)
                [wn1, wn2]= CCA(Testdata(:,:,trial_i), Reference(:, :, targ_j));
                weighted_train = wn2'*Reference(:,:,targ_j);
                weighted_test = wn1'*Testdata(:,:,trial_i);
                coefficienceMatrix = corrcoef(weighted_test,weighted_train);
                coefficience(1) = abs(coefficienceMatrix(1,2));
                % ρ2 (Filter: Test data & Template)
                [wn, ~] = CCA(Testdata(:,:,trial_i), Template(:, :, targ_j));
                weighted_train = wn'*Template(:,:,targ_j);
                weighted_test = wn'*Testdata(:,:,trial_i);
                coefficienceMatrix = corrcoef(weighted_test,weighted_train);
                coefficience(2) = coefficienceMatrix(1,2);
                 % ρ3 (Filter: Test data & Reference)
                [wn, ~] = CCA(Testdata(:,:,trial_i), Reference(:, :, targ_j));
                weighted_train = wn'*Template(:,:,targ_j);
                weighted_test = wn'*Testdata(:,:,trial_i);
                coefficienceMatrix = corrcoef(weighted_test,weighted_train);
                coefficience(3) = coefficienceMatrix(1,2);
                % ρ4 (Filter: Template & Reference)
                [wn, ~] = CCA(Template(:, :, targ_j), Reference(:, :, targ_j));
                weighted_train = wn'*Template(:,:,targ_j);
                weighted_test = wn'*Testdata(:,:,trial_i);
                coefficienceMatrix = corrcoef(weighted_test,weighted_train);
                coefficience(4) = coefficienceMatrix(1,2);
    %              % ρ5 (Filter: Test data & Template)
    %             [wn1, wn2] = CCA(Testdata(:,:,trial_i), Template(:, :, targ_j));
    %             weighted_train = wn2'*Template(:,:,targ_j);
    %             weighted_test = wn1'*Template(:,:,targ_j);
    %             coefficienceMatrix = corrcoef(weighted_test,weighted_train);
    %             coefficience(5) = coefficienceMatrix(1,2);
                % compute correlation values
                Allcoefficience(targ_j) = sum(sign(coefficience).*coefficience.^2);
            end % end targ_i
                % target detection
                [~, index] = max(Allcoefficience);
                outputlabels(trial_i) = freqs(index);
                
        end % end trial_i
        trueNum = sum((outputlabels-truelabels)==0);
        acc(loocv_i) = trueNum/length(truelabels);
        fprintf('The %d-th CV accuracy is: %.4f, samples: %d/%d\n',loocv_i,...
            acc(loocv_i),trueNum, N_testTrial)
    end % end looCv_i
    t=toc;
    % data visualization
    fprintf('\n-----------------------------------------\n')
    disp(['total time: ',num2str(t),' s']);
    fprintf('6-fold CV average accuracy is: %.4f\n',mean(acc))
    

    對上述程序做簡要解釋

    • 采用的數據為清華benchmark dataset 受試者1,數據已經經過濾波等預處理,數據長度為1.5s;
    • 實驗中發現第五項的加入使得正確率降低,故只采用了四項的融合,和萬峰老師論文保持一致2
    • 完整代碼見我的倉庫

    前四項相關系數融合運行結果為

    The 1-th CV accuracy is: 0.9250, samples: 37/40
    The 2-th CV accuracy is: 0.9750, samples: 39/40
    The 3-th CV accuracy is: 0.9750, samples: 39/40
    The 4-th CV accuracy is: 0.9750, samples: 39/40
    The 5-th CV accuracy is: 0.9750, samples: 39/40
    The 6-th CV accuracy is: 0.9750, samples: 39/40
    
    -----------------------------------------
    total time: 175.7503 s
    6-fold CV average accuracy is: 0.9667
    

    五項相關系數融合運行結果為

    The 1-th CV accuracy is: 0.5750, samples: 23/40
    The 2-th CV accuracy is: 0.5750, samples: 23/40
    The 3-th CV accuracy is: 0.7750, samples: 31/40
    The 4-th CV accuracy is: 0.4750, samples: 19/40
    The 5-th CV accuracy is: 0.6000, samples: 24/40
    The 6-th CV accuracy is: 0.6500, samples: 26/40
    
    -----------------------------------------
    total time: 216.9206 s
    6-fold CV average accuracy is: 0.6083
    

    關于取哪些相關系數進行融合的問題,本文參考了四篇較新的文獻,其中采用5個相關系數融合是常用的選擇(都是清華的文章…)。但是在本文實驗后發現,第五項加入使正確率下降了…所以采用了萬峰老師的做法,只取了前四項,如果有問題希望各位能及時提出來。

    References

    1. Chen X, Wang Y, Nakanishi M, Gao X, Jung TP, Gao S (2015) High-speed spelling with a noninvasive brain-computer interface. PNAS 112:E6058-6067.
    2. Wong CM, Wan F, Wang B, Wang Z, Nan W, Lao KF, Mak PU, Vai MI, Rosa A (2020) Learning across multi-stimulus enhances target recognition methods in SSVEP-based BCIs. Journal of neural engineering 17:016026.
    3. Xu M, Han J, Wang Y, Jung TP, Ming D (2020) Implementing over 100 command codes for a high-speed hybrid brain-computer interface using concurrent P300 and SSVEP features. IEEE Transactions on Biomedical Engineering.
    4. Mehdizavareh MH, Hemati S, Soltanian-Zadeh H (2020) Enhancing performance of subject-specific models via subject-independent information for SSVEP-based BCIs. PloS one 15:e0226048.
    版權聲明:本文為weixin_42765703原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_42765703/article/details/105674990

    智能推薦

    相關矩陣 Correlation matrix

      根據提供的文件分析各個特征之間的相關性 Id MSSubClass MSZoning LotFrontage LotArea LandContour OverallCond YearBuilt YearRemodAdd RoofStyle MasVnrArea ExterQual ExterCond Heating HeatingQC CentralAir Electrical 1s...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    猜你喜歡

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    styled-components —— React 中的 CSS 最佳實踐

    https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...

    精品国产乱码久久久久久蜜桃不卡