반응형

이번엔 이전 글에서 집중도를 구했던 방법으로 실제 게임을 하며 집중도를 구해볼 것이다!

 

참고로 이번엔 코드는 제공 안할 것이다.

그렇기에 해보고 싶다면 이전에 한 집중도 코드와 결합해서 해보면 될 것 같다.

 

시작

Brainflow에서는 Github를 돌아다니다 보면 예시로 실행할 수 있는 파일들을 찾을 수 있다.

그 중에서는 실시간 시각화 파일들도 있는데.. 바로 아래꺼다!

https://github.com/brainflow-dev/brainflow/blob/master/python_package/examples/plot_real_time/plot_real_time.py

 

brainflow/python_package/examples/plot_real_time/plot_real_time.py at master · brainflow-dev/brainflow

BrainFlow is a library intended to obtain, parse and analyze EEG, EMG, ECG and other kinds of data from biosensors - brainflow-dev/brainflow

github.com

 

https://github.com/brainflow-dev/brainflow/blob/master/python_package/examples/plot_real_time/plot_real_time_min.py

 

brainflow/python_package/examples/plot_real_time/plot_real_time_min.py at master · brainflow-dev/brainflow

BrainFlow is a library intended to obtain, parse and analyze EEG, EMG, ECG and other kinds of data from biosensors - brainflow-dev/brainflow

github.com

 

위에 링크에 들어가면 나오는 파일을 실행한 결과가 아래 사진이다.

뇌파가 많아보이는건 보드가 SYNTHETIC_BOARD 이걸로 설정되어서 인데.. 그냥 데모 보드라고 생각하면 될 것 같다.

그래서 저걸 실행하면 EEG 기기를 연결하지 않아도 예시로 저렇게 볼 수 있는데, 물론 연결하면 보드에 있는 정보들로 표시가 된다.

 

아무튼 이번에는 저 그래프에 추가적으로 집중도 그래프를 추가하고 게임을 하며 측정해볼 것이다!

 

코드 문제점

그런데 실행해보기 전 한가지 문제가 있긴 하다.

저 코드는 PyQT가 옛날 버전이라서 최신 버전에서는 실행이 안된다. 그래서 최신 버전으로 바꿔야 하는데..

그냥 

  • QtGui > QtWidgets
  • GraphicsWindow > GraphicsLayoutWidget
  • pg.GraphicsLayoutWidget(title='BrainFlow Plot', size=(800, 600), show=True)

현재 코드에다가 > 되어있는건 그렇게 바꾸면 되고 GraphicsLayoutWidget 함수 뒤에 show=True만 추가하면 제대로 작동한다.

현재는 내가 따로 코드를 수정해서 커밋 요청을 해놓았다. 문제가 없다면 아마 수정되어서 업데이트가 될 것이다.

https://github.com/brainflow-dev/brainflow/pull/756

 

Fix PyQT Error by cheongpark · Pull Request #756 · brainflow-dev/brainflow

Fixed PyQt and PyQtGraph compatibility issues: QtGui.QApplication -> QtWidgets.QApplication Error: AttributeError: module 'pyqtgraph.Qt.QtGui' has no attribute 'QApplication' F...

github.com

 

암튼 그렇다. (글을 쓰던 중 업데이트가 되었다. 그러니 직접 가서 다운받아서 수정해서 쓰면 될 것 같다.

 

본론

일단 실행하면 어떻게 뜨는지 본다면.. 이런식으로 뜬다!

https://github.com/brainflow-dev/brainflow/blob/master/python_package/examples/plot_real_time/plot_real_time.py

 

brainflow/python_package/examples/plot_real_time/plot_real_time.py at master · brainflow-dev/brainflow

BrainFlow is a library intended to obtain, parse and analyze EEG, EMG, ECG and other kinds of data from biosensors - brainflow-dev/brainflow

github.com

그냥 이거를 수정한 파일이다. 이 코드로 선정한건 그냥 정보가 많고 예뻐보여서..

수정한건 드라큘라 테마로 바꾼 것, 그래프 2개 추가한 것 정도가 끝이다.

 

그리고 참고로 이 코드에서는 Muse 2 기기를 연결하는 방법은 2가지 정도 있다.

연결할 때는 실행할 때 인수 값을 추가해서 연결할 수도 있고.. 나 같은 경우에는 코드에 이전 글에 있는 것 처럼 MUSE 2와 시리얼 코드를 넣어서 연결되도록 했다. 저 코드의 메인 함수로 가보면 알 수 있을 것이다.

 

그리고 저 아래에 Attention과 Mindfulness는 이전 글에서 설명한 대로의 코드로 계산을 하고 그래프에 추가되도록 했다.

조금만 해보면 간단해서 딱히 이곳에 코드를 넣지는 않았다.

(참고로 저거 Attention의 범위는 딱히 지정하지는 못했다. 지금 와서 생각해보면 2~3이 적당했을 텐데.. 암튼 영상은 미리 찍었기 때문에.. 4로 되어있다는 점..)

 

설치해야할 라이브러리는 아래다! (PyQT6도 실행 가능)

pip install pyqtgraph PyQt5 brainflow

 

암튼 저걸 실행한 후 머리에 착용하고 게임을 해봤다!

 

게임 영상

DJMAX RESPECT V

https://youtu.be/5GIg4USKRSc

https://youtu.be/MI4KGSuK3YY

 

Beat Saber

https://youtu.be/l68sUCtNqFc

https://youtu.be/GU2_KSvK4Ps

https://youtu.be/Z0MRK22TLKE

https://youtu.be/WJNhG9nXO-g

 

결론

일단 DJMAX와 Beat Saber를 선택한 이유는 리듬게임이며 집중도가 높은 게임이기 때문에 선택했다. BeatSaber의 경우 VR를 착용하고 하기 때문에 몰입이 될 수 있어서 집중도를 측정하기에 더 좋았다.

참고로 VR의 경우 VIVE PRO 1을 착용하고 했었다.

 

일단 영상 찍고 확인을 해보니.. 의외로 집중도가 낮게 나온다..

내가 이전 부터 이 기기를 테스트 하면서도 집중도가 확실히 낮게 나오기는 했었는데.. (ADHD인가..?)

 

DJMAX에서는 짧은 노트의 경우 집중도가 의외로 낮게 나온다. 그에 반면 긴 노트에서는 집중도가 높게 나왔다..

나도 게임을 클리어 하면서 짧은 노트들은 어느정도 칠 수 있어서 그나마 쉽게 넘어가는 반면 긴 노트의 경우 긴 노트를 눌르며 다른 노트들도 쳐야하다 보니 집중을 많이 하게 되는 것 같은데.. 심지어 지금도 그렇고 이때도 그렇고 장갑을 끼고 있다보니.. 더 키보드 치는 느낌이 잘 안들어서 저렇게 된 것 같다.

뭐 그래도 대부분 높게 나오기는 했다.

(장갑 끼는건 그냥 키보드 더러워질까봐.. 다한증..)


Beat Saber에서는 이상하게 전체적으로 낮게 나왔다..

이건 잘 모르겠다.. 내가 게임을 잘 못하는게 이것 때문인건가.. 하는 생각도 들긴 하는데..

일단 의심되는건.. 내 방이 덥다. 그래서 땀이 많이 나기도 하는데 그것 때문에 전극에 수분 때문에 전기가 잘 통해서 전극이 잘 요동치고 있다는 것을 알 수 있다. 이것 때문일 가능성도 있고.. 또 손을 엄청 움직이고 하기에 그 움직임도 같이 반영됬을 것으로 추정된다.. 또한 VR과 Muse 2를 같이 착용하고 측정하기 때문에 Muse 2가 제대로 측정이 안되었거나 VIVE PRO의 안면 폼이 방해했을 가능성이 있을 수 있다. 그리고 운동을 안해서인지.. FitBeat 하면서 다리를 굽혔다 피니깐.. 이후에 몇시간 동안 일어나거나 앉을려 하면 힘이 빠져서 움직이기도 어려울 정도였다.

그런데 그걸 제외해서라도 집중도가 낮은건 좀 이상하긴 하다.. 아니면 그냥 내가 게임에 집중을 잘 안했던 것일 수도 있고..

 

그리고 위에서도 말했지만 공통적으로 한가지 문제라면 Muse 2가 민감한건지 뭔지 자세를 움직인다거나 키보드를 친다거나 손을 많이 움직인다거나 이를 쎄게 닫는 경우 뇌파가 심하게 요동친다.. 이것 때문에 뇌파가 제대로 측정이 안되기도 한다. 그래도 모든 전극이 같이 반영되기 때문에 아마도 그에 따라서 바뀌니깐 딱히 상관은 없을 수도 있을 것 같다.

 

아무튼 재밌긴 했다~

반응형
반응형

이번껀 전문가가 아니기에 틀린 정보가 많을 수 있습니다.

이번에도 집중도 구하기다!

다만 이번엔 인공지능을 곁들인..

 

내가 이전 부터 인공지능이라고 말하기는 했지만.. 이번껀 머신러닝에 가깝다고 볼 수 있다.

보통 인공지능 하면 딥러닝을 생각하겠지만.. 여기서는 머신러닝이다.

뭐 인공지능 안에 머신러닝이 포함되어있으니 상관은 없겠지만..

 

이번에 적을 내용은 이전 글 보다는? 적을테고 쉬울 것이다.

대부분이 이미 만들어진 것을 쓰기 때문에..

하지만 자세하게 들어가면 역시 어렵긴 하지만.. 최대한 내가 이해한 배경으로 설명해보겠다..!

틀린 정보가 있을 수도 있다.. 작년인 대학교 1학년 때 했던 작업들이고.. 2~4개월 밖에 안했었기 때문에..

 

그리고.. 28일이 아닌 25 ~ 26일에 기기를 반납해야해서 서둘러야 한다..!!!

 

암튼 먼저 코드부터!

 

Brainflow ML로 집중도 구하는 코드 공유!

from time import sleep
from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds
from brainflow.data_filter import DataFilter
from brainflow.ml_model import MLModel, BrainFlowModelParams, BrainFlowMetrics, BrainFlowClassifiers

board_id = BoardIds.MUSE_2_BOARD
params = BrainFlowInputParams()
params.serial_number = "Muse-0465" # Muse 2의 고유 시리얼 넘버
board_shim = BoardShim(board_id, params)

use_data_seconds = 5 # n초 동안 데이터 수집 
sampling_rate = BoardShim.get_sampling_rate(board_id)
eeg_channels = BoardShim.get_eeg_channels(board_id)
num_points = use_data_seconds * sampling_rate # 몇 초 동안의 데이터를 가져올지

# 머신러닝 모델 준비
mindfulness_params = BrainFlowModelParams(BrainFlowMetrics.MINDFULNESS, BrainFlowClassifiers.DEFAULT_CLASSIFIER)
mindfulness = MLModel(mindfulness_params)
mindfulness.prepare()

# Muse 2 연결
board_shim.prepare_session()

# Muse 2 데이터 수집 시작
board_shim.start_stream()

# n초 + 1초 동안 데이터 수집
sleep(use_data_seconds + 1)

# 수집한 데이터를 변수에 저장
data = board_shim.get_current_board_data(num_points)

# 예측에 필요한 데이터 추출
bands = DataFilter.get_avg_band_powers(data, eeg_channels, sampling_rate, True)
feature_vector = bands[0]

# 집중도 예측
print(f"Mindfulness: {mindfulness.predict(feature_vector)[0]}")

# 모델 해제
mindfulness.release()

# Muse 2 데이터 수집 정지
board_shim.stop_stream()

# Muse 2 연결 해제
board_shim.release_session()

이번엔 아마도 저번보다는 쉽지 않을까 한다.. 코드적인걸로는..

이전 글에 대부분의 내용들을 넣어놓은거라서..

지금 새벽 4시 40분인데 다 쓰고 나면 짧겠지..? 라 생각 중..

 

참고로 이전 글에서 말했던 것 처럼 Mindfulness를 썼던게 Brainflow에서 Mindfulness로 썼어서 그걸로 쓴거다..

암튼 그렇다..

 

코드 설명 및 이해하기

설명할 수록 점점 코드 설명할게 적어져서 좋긴 하다.

전 글에서 한가지 안쓴게 있다면 필요한 라이브러리를 불러오는 것에 대해 안적었는데.. 뭐 간단한거니 여기서도 안적겠다!

여기서 적는건 이전에 설명하지 않았던 코드들만

 

mindfulness_params = BrainFlowModelParams(BrainFlowMetrics.MINDFULNESS, BrainFlowClassifiers.DEFAULT_CLASSIFIER)
mindfulness = MLModel(mindfulness_params)
mindfulness.prepare()

여기는 모델을 정의하는 부분이다. 어떤 모델을 쓸지 어떤 분류기를 쓸지 정할 수 있다.

코드에서는 모델과 분류기를 정하고 정한 파라미터로 모델을 할당해서 모델을 쓸 수 있도록 활성화 시키는 코드이다.

 

일단 Brainflow에선 기본적으로 어떤 모델과 분류기가 가능한지 아는 것이 좋다.

그러기 위해선 BrainFlowMetrics, BrainFlowClassifiers 정의 코드를 살펴봐야 한다.. 코드를 보면

# 코드 설명을 하기 위한 코드
class BrainFlowMetrics(enum.IntEnum):
    """Enum to store all supported metrics"""

    MINDFULNESS = 0  #:
    RESTFULNESS = 1  #:
    USER_DEFINED = 2  #:


class BrainFlowClassifiers(enum.IntEnum):
    """Enum to store all supported classifiers"""

    DEFAULT_CLASSIFIER = 0  #:
    DYN_LIB_CLASSIFIER = 1  #:
    ONNX_CLASSIFIER = 2  #:

이런식으로 정의가 되어있다. 

참고로 BrainFlowMetrics는 모델이 어떤 역할을 할지 선택하는 것이고, BrainFlowClassifiers는 그 역할을 계산할 수 있는 분류기를 선택할 수 있도록 하는 것이다.

 

각각에 대해서 설명하자면

BrainFlowMetrics 

  • MINDFULNESS : 마음챙김, 집중도와 비슷할 순 있지만 좀 다른 것, 현재 자연스럽게 어느정도 집중 했는지
  • RESTFULNESS : 휴식상태, 어느정도 휴식 상태인지
  • USER_DEFINED : 사용자가 직접 정의

BrainFlowClassifiers

  • DEFAULT_CLASSIFIER : 기본 분류기 (MINDFULNESS, RESTFULNESS 사용할 때)
  • DYN_LIB_CLASSIFIER : .dll, .so 같은 C/C++로 만든 알고리즘을 적용하고 싶을 때
  • ONNX_CLASSIFIER : ONNX 모델을 사용할 때 (USER_DEFINED 사용할 때)

여기에서 예시로 들 것은 Mindfulness이다. 설명을 적어놓기는 했지만 사실 나도 잘은 이해 못했다. 솔직히 저 설명으론 부족해서 추가로 말하자면, 내가 어느 순간에 공부나 무언가를 뚫어져라 보면서 갑자기 집중하는 것이 아닌.. 자연스럽게 무언가의 변화 등으로 자연스럽게 그것에 관심을 기울이는 것을 말하는 것 같다.

예를 들면 이전에서 한 Attention은 한 곳을 뚫어져라 바라볼 때 지표가 올라가고

Mindfulness는 밥 먹다가 수저가 바닥으로 떨어지며 그 소리에 기울인다 생각하면 된다.

수업 자료를 만들 때는 Mindfulness로 집중도를 구해서 게임할 수 있도록 했었는데.. 이젠 수정해야할 것 같다.. 하하하..

만약 이전 글에서 말한 수식으로 모델을 만든다면 집중하거나 안하는 데이터를 모두 수집한 후 수식으로 계산시키고 정규화 시킨 후에 학습시켜서 사용자 정의 모델로 등록하면 될 것 같긴 하다. (Brainflow에 등록 요청해볼까 생각중..)

 

기본 분류기는 아마도 Mindfulness나 Restfulness를 계산하는데만 쓰는 것 같다. 이에 대한건 predict 부분에서 더 자세하게 얘기할 것이다.

ONNX 분류기는 User_Defined로 선택했을 때 쓸 수 있는 것 같은데, 직접 Python으로 모델을 학습해서 만든 모델을 적용할 수 있도록 해주는 것이다. 이 분류기를 제작하는건 내가 반납 전에 쓸 분량을 다 쓰고 시간이 남는다면 써보고.. 안되면 아래에 링크한 튜토리얼을 보고 하면 될 것 같다.

 

추가로 여기서 한가지 생각이 들 것이다. 모델을 직접 정의할 수 있으면 BrainFlowMetrics는 왜 있는걸까? 라는 생각을 할 수 있다. 나도 제대로는 모르겠지만.. 내가 생각하기에는 Mindfulness랑 Restfulness를 쓸 수 있도록 하기 위해서 인 것 같다. 오픈소스다 보니 코드를 직접 수정할 수도 있는데 거기에서 추가적인 모델을 넣을 수 있도록 하거나 나중에 추가하기 위해서 저렇게 구분한 것 같다고 생각이 든다.

 

아무튼 여기에서는 Mindfulness를 계산하고 이 때문에 Default Classifier를 사용하게 된다.

 

# 예측에 필요한 데이터 추출
bands = DataFilter.get_avg_band_powers(data, eeg_channels, sampling_rate, True)
feature_vector = bands[0]

# 집중도 예측
print(f"Mindfulness: {mindfulness.predict(feature_vector)[0]}")

위에 2줄은 이전에 설명했기 때문에 패스하고

 

여기에서 볼 것은 저 아래 출력문이다.. 이전에 할당한 Mindfulness 모델에 수집한 데이터의 평균 파워를 넣어 예측하게 하는 코드이다.

즉 이전 글에서 설명한 평균의 Delta, Theta, Alpha, Beta, Gamma 값을 넣어 예측시키는 코드라고 보면 된다.

 

그런데 또 의문이 들것이다. 왜 예측한 것의 0번 인덱스 값을 가져오라고 하는지.. 일단 확인해보니 0번 인덱스 외의 값은 없다. 그런데 리스트로 반환하는 이유가 뭔지 생각해보니.. 아마도 다른 사용자 정의 분류기를 사용하게 되면 여러 값을 리턴해야하는 경우가 있을테니 그것 때문인 듯 하다.

아무튼 리스트로 반환되기 때문에 [값] 이런식으로 출력되지 않게 하기 위해 0 인덱스로 접근해서 데이터를 가져와 출력하게 되어있다.

 

참고로 찾으면서 방금 발견한게 있는데.. 수업 자료를 만들 때는 저거를 1초나 2초로 했었다..

그런데 갑자기 최소 몇초를 해야하는 생각이 들어서 더 찾아봤는데.. 당시에는 못 찾은 주석이 있었다..

# recommended window size for eeg metric calculation is at least 4 seconds, bigger is better

음.. EEG로 어떤 것을 계산해야한다면 4초 이상의 데이터는 필요하다고.. 한다.. 클 수록 좋다고 하고.. 흐음.. 

수업 자료를 고쳐서 다시 교수님께 드려야 할 것 같다는 생각이 든다.. 하하;;

 

그럼 Mindfulness의 계산 방법에 대해 궁금한점이 생길 것이다.

위에서 말했듯이 머신러닝이다. 하지만 더 자세히 보기 위해 코드로 보겠다!

# 코드 설명을 하기 위한 코드
# src/ml/generated/mindfulness_model.cpp

const double mindfulness_coefficients[5] = {-1.4060899708538128,2.597693987367105,-30.96470526503066,12.04593986553724,45.773017975354556};
double mindfulness_intercept = 0.000000;
# 코드 설명을 하기 위한 코드
# src/ml/mindfulness_classifier.cpp

int MindfulnessClassifier::predict (double *data, int data_len, double *output, int *output_len)
{
    if ((data_len < 5) || (data == NULL) || (output == NULL))
    {
        safe_logger (spdlog::level::err,
            "Incorrect arguments. Null pointers or invalid feature vector size.");
        return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
    }
    double value = 0.0;
    for (int i = 0; i < std::min (data_len, 5); i++)
    {
        value += mindfulness_coefficients[i] * data[i];
    }
    double mindfulness = 1.0 / (1.0 + exp (-1.0 * (mindfulness_intercept + value)));
    *output = mindfulness;
    *output_len = 1;
    return (int)BrainFlowExitCodes::STATUS_OK;
}

이게 Mindfulness를 계산하는 코드이다. Python이 아닌 이유는 Brainflow는 C++로 만든걸 Python에 이식한 것이기 때문이다.. 저건 메인 C++에 있는 코드..

 

하나씩 보자면 일단 mindfulness_coefficients, mindfulness_intercept 이거는 인공지능을 어느정도 했었다면 알 수 있다.

가중치와 편향 값이다. mindfulness_coefficients가 가중치 값, mindfulness_intercept 편향 값..

5개인 이유는 입력 값인 Delta, Theta, Alpha, Beta, Gamma를 입력 값으로 계산하기 때문..

 

그러면 예측 코드를 하나씩 봐보자!

아래에서 설명할껀 퍼셉트론 대로 계산한다고 생각하면 된다.

퍼셉트론은 입력 값과 가중치 값을 각각 곱하고 만나는 노드에서 모두 더해 편향 값을 더한 후 활성 함수를 거치는거라 생각하면 된다. (말로는 이해하기 어렵고 모르면 퍼셉트론에 대해서 공부하고 오면 될 것 같다.)

# 코드 설명을 하기 위한 코드
double value = 0.0;
for (int i = 0; i < std::min (data_len, 5); i++)
{
    value += mindfulness_coefficients[i] * data[i];
}

 

 

그 중 위 코드는 입력값과 가중치를 각각 곱한 후 모두 더하는 코드라 보면 된다.

# 코드 설명을 하기 위한 코드
double mindfulness = 1.0 / (1.0 + exp (-1.0 * (mindfulness_intercept + value)));

이건 위에서 곱하고 더한 값인 value에 편향 값을 더하고 활성화 함수를 거치는 것이다. 

그리고 활성화 함수는 시그모이드 함수를 사용하는데 f(x) = 1 / (1 + e^(-x)) 이런 수식이다. 솔직히 몰라도 된다.

 

그리고 실제 계산 과정으로 예를 보여주겠다!

먼저 계산하기 위해서 입력 값을 정의하면..

  • Delta : 0.53311590
  • Theta : 0.30351431
  • Alpha : 0.07848158
  • Beta : 0.06465923
  • Gamma : 0.02022897

이렇다. 이건 실제로 내가 방금 착용해서 얻은 값이다. 참고로 미리 내부에서 계산된 것은 0.33481021 이 값이다.

 

아무튼 계산해보면

일단 처음에 입력 값과 가중치를 곱한다.

  • Value0 : Delta(0.53311590) * Weight0(-1.4060899708538128) = -0.7496089202927042
  • Value1 : Theta(0.30351431) * Weight1(2.597693987367105) = 0.7884372981668756
  • Value2 : Alpha(0.07848158) * Weight2(-30.96470526503066) = -2.430158993433925
  • Value3 : Beta(0.06465923) * Weight3(12.04593986553724) = 0.7788811963319415
  • Value4 : Gamma(0.02022897) * Weight4(45.773017975354556) = 0.925941007432908

그 후에는 곱해진 모두를 더한다.

  • Value : Value0(-0.7496089202927042) + Value1(0.7884372981668756) + Value2(-2.430158993433925) + Value3(0.7788811963319415) + Value4(0.925941007432908) = -0.6865084117949039

그 후 편향 값을 더한다.

  • Value : Value(-0.6865084117949039) + Bias(0.000000) = -0.6865084117949039

참고로 편향 값이 0이기에 값의 변화는 없다.

그 후 활성화 함수를 거친다.

  • Result : 1.0 / (1.0 + math.exp(-1.0 * Value)) = 0.3348102440015052

이런 과정으로 계산되게 된다. 결론적으로 내부적으로 계산된 값인 0.33481021과 비교하면 반올림되서 잘린거 빼고는 결과값의 차이는 없다. 그렇다는건 위 계산 과정이 맞다는 것이 되니 저걸 보면 된다!

 

아무튼 계산 과정이 이렇다. 어떻게 보면 간단할 수도 있고 복잡할 수도 있다.

참고로 DNN(깊은 신경망)은 저런 계산하는 것이 겁나게 많은 것 뿐이다.

 

당시 수업 자료 만들 때의 PPT에 내가 만들어둔 사진이다. 아래 사진을 보면 이해가 더 쉬울지도 몰라서 올려놓겠다.

지금 봤는데.. 가중치 값이 업데이트 되었나보다.. 사진에 있는건 대략 5개월 전의 가중치 값..

 

참고로 재미있는점이 한가지 있는데.. Restfulness를 계산하는 과정이다..

예전에도 찾았었던 것 같은데.. 지금봐도 어이가 없다.

# 코드 설명을 하기 위한 코드
# src/ml/inc/restfulness_classifier.h

#pragma once

#include "brainflow_constants.h"
#include "mindfulness_classifier.h"


class RestfulnessClassifier : public MindfulnessClassifier
{
public:
    RestfulnessClassifier (struct BrainFlowModelParams params) : MindfulnessClassifier (params)
    {
    }

    int predict (double *data, int data_len, double *output, int *output_len)
    {
        int res = MindfulnessClassifier::predict (data, data_len, output, output_len);
        if (res != (int)BrainFlowExitCodes::STATUS_OK)
        {
            return res;
        }
        *output = 1.0 - (*output);
        return res;
    }
};

안믿을 것 같아서 Restfulness의 전체 코드를 가져왔다. 

해석해보면 MindfulnessClassifier를 할당 받아서 MindfulnessClassifier에 있는 예측하는 코드로 예측시킨 후

그 값을 (1.0 - 값) 이걸로 계산한다는 것이다.

즉 (1.0 - Mindfulness 예측 값)이다. 이 말은 Restfulness는 Mindfulness의 반대 값이라고 생각하면 될 것 같다..

그래서 더 해보면 1이 나오는걸 알 수 있다.

 

암튼 저런 계산 과정으로 마음챙김도가 나오는 것이다.

저런 마음 챙김 모델도 학습하는 방법도 나와있는데 그건 맨 아래 링크에 달아두었다.

 

mindfulness.release()

위에서 할당한 모델을 해제하는 것이다.

 

암튼 이제 설명을 다 했으니 코드를 실행해봐야 한다. (위에서 이미 실행한 결과는 무시하시길..)

 

코드 실행

[2025-02-21 09:47:34.717] [board_logger] [info] incoming json: {
    "file": "",
    "file_anc": "",
    "file_aux": "",
    "ip_address": "",
    "ip_address_anc": "",
    "ip_address_aux": "",
    "ip_port": 0,
    "ip_port_anc": 0,
    "ip_port_aux": 0,
    "ip_protocol": 0,
    "mac_address": "",
    "master_board": -100,
    "other_info": "",
    "serial_number": "Muse-0465",
    "serial_port": "",
    "timeout": 0
}
[2025-02-21 09:47:34.717] [board_logger] [info] Use timeout for discovery: 6
[INFO] SimpleBLE: D:\a\brainflow\brainflow\third_party\SimpleBLE\simpleble\src\backends\windows\Utils.cpp:33 in initialize_winrt: CoGetApartmentType: cotype=-1, qualifier=0, result=800401F0
[INFO] SimpleBLE: D:\a\brainflow\brainflow\third_party\SimpleBLE\simpleble\src\backends\windows\Utils.cpp:41 in initialize_winrt: RoInitialize: result=0
[2025-02-21 09:47:34.764] [board_logger] [info] found 1 BLE adapter(s)
[2025-02-21 09:47:34.958] [board_logger] [info] Found Muse device
[2025-02-21 09:47:36.400] [board_logger] [info] Connected to Muse Device
[2025-02-21 09:47:37.405] [board_logger] [info] found control characteristic
Mindfulness: 0.97519466

이런식으로 뜬다. 로그 정보들은 이전에도 설명한 것과 같이 똑같으니 무시하고

 

"Mindfulness: 0.97519466" 값만 보면 된다.

다만 전에 이 집중도하고 전 글의 집중도하고 다르긴 하지만 비슷하기 때문에 자세하게 측정결과는 작성 안할 것이다.

어차피.. 내가 설명한 여기에서의 Mindfulness 집중도는.. 나도 잘 만들어내기가 어렵다..

 

참고로 Restfulness는 Mindfulness를 전부 Restfulness로 바꾸면 된다.

 

그럼으로 이번 글은 여기에서 끝내는걸로..

 

추가로 이전 글에서도 올린 것 처럼 실시간으로 돌릴 수 있는 코드!

import keyboard
from time import sleep
from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds
from brainflow.data_filter import DataFilter
from brainflow.ml_model import MLModel, BrainFlowModelParams, BrainFlowMetrics, BrainFlowClassifiers

board_id = BoardIds.MUSE_2_BOARD
params = BrainFlowInputParams()
params.serial_number = "Muse-0465" # Muse 2의 고유 시리얼 넘버
board_shim = BoardShim(board_id, params)

use_data_seconds = 5 # n초 동안 데이터 수집
sampling_rate = BoardShim.get_sampling_rate(board_id)
eeg_channels = BoardShim.get_eeg_channels(board_id)
num_points = use_data_seconds * sampling_rate # 몇 초 동안의 데이터를 가져올지

# 머신러닝 모델 준비
mindfulness_params = BrainFlowModelParams(BrainFlowMetrics.MINDFULNESS, BrainFlowClassifiers.DEFAULT_CLASSIFIER)
mindfulness = MLModel(mindfulness_params)
mindfulness.prepare()

# Muse 2 연결
board_shim.prepare_session()

# Muse 2 데이터 수집 시작
board_shim.start_stream()

# n초 + 1초 동안 데이터 수집 - 안하면 오류남
sleep(use_data_seconds + 1)

while True:
    # 나가기 조건
    if keyboard.is_pressed('q'):
        break
   
    # 수집한 데이터를 변수에 저장
    data = board_shim.get_current_board_data(num_points)
    
    # 예측에 필요한 데이터 추출
    bands = DataFilter.get_avg_band_powers(data, eeg_channels, sampling_rate, True)
    feature_vector = bands[0]

    # 집중도 예측
    print(f"Mindfulness: {mindfulness.predict(feature_vector)[0]}")

# 모델 해제
mindfulness.release()

# Muse 2 데이터 수집 정지
board_shim.stop_stream()

# Muse 2 연결 해제
board_shim.release_session()

 

이제 올릴려 한 것들은 다 올렸고.. 추가로 나머지는 인공지능을 만들어서 적용해보거나 게임을 하면서 집중도는 어떤지 측정해서 올려볼려고 한다.

 

암튼 짧게 끝냈다! 다행히 이번엔 쓰는 시간이 4시간 정도 걸렸다.

 

위에서 언급한 내용들의 관련 링크

Tensorflow로 모델을 제작하여 적용

https://brainflow.org/2022-09-08-onnx-tf/

 

BrainFlow with onnxruntime (TensorFlow edition)

ONNX Inference ONNX is an open format built to represent machine learning models. ONNX defines a common set of operators - the building blocks of machine learning and deep learning models - and a common file format to enable AI developers to use models wit

brainflow.org

Scikit Learn으로 모델을 제작하여 적용

https://brainflow.org/2022-06-09-onnx/

 

BrainFlow with onnxruntime

ONNX Inference ONNX is an open format built to represent machine learning models. ONNX defines a common set of operators - the building blocks of machine learning and deep learning models - and a common file format to enable AI developers to use models wit

brainflow.org

BrainFlow 학습 코드

https://github.com/brainflow-dev/brainflow/blob/master/src/ml/train/train_classifiers.py

 

brainflow/src/ml/train/train_classifiers.py at master · brainflow-dev/brainflow

BrainFlow is a library intended to obtain, parse and analyze EEG, EMG, ECG and other kinds of data from biosensors - brainflow-dev/brainflow

github.com

반응형

+ Recent posts