이전 글에서 설명한 API와 logistic regression을 이용하여 얼굴 비대칭성을 계산하고 정상인과 환자 사진을 학습시켜 결과를 예측하도록 하였다. 뇌졸중 자가진단에 머신러닝을 사용하기 위해선 3단계의 과정이 필요하다. 첫 번째는 비대칭성 계산, 두 번째는 학습, 세 번째는 예측이다. 이 세 가지 단계는 다음과 같이 이루어져있다.
비대칭성 계산
우리가 구현하고자 하는 기능을 위해선 얼굴의 눈, 코, 입을 인식하고 위치를 알 수 있는 API가 필요했다. 이 API는 github에 있는 cv2, dlib를 사용한 코드를 얻어올 수 있었다. API를 이용하여 아래 그림처럼 얼굴의 좌표를 얻을 수 있다.
뇌졸중의 초기 증상중 하나인 안면마비를 검증하기 위해 안면마비 환자들의 특징을 알아보았고 환자가 웃었을 때 왼쪽과 오른쪽의 비대칭성을 통해 의사가 판단한다는 것을 알 수 있었다. 따라서 얼굴의 좌표를 이용해 얼굴 중앙을 중심으로 3가지를 특징을 종합하여 왼쪽과 오른쪽의 비대칭성을 계산해보았다. 특징은 다음 3가지이다. 괄호 안에 있는 숫자는 아래 사진에서의 좌표 번호이다.
1. 중심(34)에서 왼쪽 눈 끝(37)까지의 거리 : 중심(34)에서 오른쪽 눈 끝(46)까지의 거리
2. 중심(34)에서 왼쪽 코 끝(32)까지의 거리 : 중심(34)에서 오른쪽 코 끝(36)까지의 거리
3. 중심(34)에서 왼쪽 입술 끝(49)까지의 거리 : 중심(34)에서 오른쪽 입술 끝(55)까지의 거리
얼굴의 비대칭성이 심할수록 왼쪽과 오른쪽 거리의 차이가 더 커질 것이다. 따라서 비대칭성을 표현하는 수는 (작은 거리)/(큰 거리)를 이용하여 비율로 나타내었다. 즉 이 값이 1에 가까울수록 얼굴이 대칭적이고 1에서 멀어질수록 얼굴이 비대칭적이라는 말이다. 눈, 코, 입에 (작은 거리)/(큰 거리) 식을 이용하여 각각 계산하고 그 합을 더하였다. 따라서 3가지를 합하므로 3에 가까울수록 얼굴이 대칭적이라는 것이다.
학습
실제 환자 사진과 정상인 사진으로부터 계산한 비대칭성을 나타낸 수를 이용하여 학습을 시켜야한다. 실제 환자 얼굴은 개인정보이기 때문에 많은 사진을 구할 수 없었다. 따라서 크롤링을 이용해 구글에서 찾을 수 있는 환자의 사진을 최대한 많이 모아보았다. 그 결과 160장의 사진을 구할 수 있었다. 정상인의 사진도 비슷한 개수로 구글링을 통해 154장을 구하여 총 314장의 사진으로 학습을 진행하였다. 1번 과정을 통해 얼굴의 비대칭성을 수로 표현할 수 있었다. 그 다음엔 각 사진이 하나의 숫자로 표현되기 때문에 logistic regression의 Classification을 이용하여 뇌졸중이 의심된다(1) 아니다(0)로 판단할 수 있다. 학습 과정은 다음과 같다.
- linear regression(선형 회귀)
선형 회귀로 환자와 정상인으로부터 계산한 비대칭성을 나타내는 수들의 분포로부터 최적의 직선을 하나 만든다. 수치미분을 하며 학습시킬 비대칭성 수들로부터 최적의 직선을 만든다. 이 직선의 기울기가 W, y절편이 b이다. x가 뇌졸중이 의심되는지 판단하고자 하는 사람의 비대칭성을 계산한 수라고하면 (W*x + b) 값은 학습한 점들로부터 유추되는 예측 값이다. 매번 학습시킬 수 없기 때문에 학습한 결과인 W값과 b값은 파일에 저장하여 예측을 할 때 사용된다.
- Classification(분류)
과정 1에서 한 선형 회귀의 결과 값은 뇌졸중이 의심되는지 판단하기 위해 1 또는 0의 값만을 가져야한다. 따라서 분류에 자주 사용되는 함수인 sigmoid 함수를 이용하여 1과 0 사이의 값으로 나타낸다. sigmoid함수는 오른쪽과 같은 수식과 함수 그래프로 나타난다. 따라서 sigmoid함수의 결과 값이 0.5보다 크면 안면마비일 확률이 높다는 뜻이므로 1을 리턴하고 0.5보다 작으면 안면마비일 확률이 낮으므로 0을 리턴한다.
- 학습 과정 구성도
예측
이제 학습된 결과를 이용해 사용자로부터 사진을 받으면 안면마비인지 예측할 수 있다. 우선 사진의 비대칭성을 나타내는 수를 구하여 Wx + b값을 얻는다. 그 다음 결과 값을 sigmoid함수에 넣어 0.5보다 클 경우 안면마비로 판단, 0.5보다 작을 경우 안면마비가 아닌 것으로 판단할 수 있다. 결과를 예측하는 과정은 아래와 같은 구성도와 같이 동작한다.
예시
환자 사진을 예측한 결과이다. 아래서 세 번째 줄에 있는 0.2604..라는 값은 0이 완전 대칭이라고 할 때 얼마나 비대칭적인지를 나타낸 값이다. numpy배열로 나타난 아래서 두 번째 줄의 첫 번째 원소인 0.67138494는 sigmoid함수 결과 값으로 0.5보다 클 경우 뇌졸중으로, 0.5보다 작을 경우 정상으로 나온다. 0.67138494은 0.5보다 크므로 뒤에 1이라는 결과가 나와 뇌졸중 의심으로 판단한 것을 알 수 있다.
정산인 사진을 예측한 결과이다. 환자 사진과 비교해보면 0.0469..라는 값으로 0에서 크게 벗어나지 않은 것을 볼 수 있다. 또 0.28130981의 sigmoid 결과값은 0.5보다 훨씬 작은 수치로 뇌졸중 의심이 되지 않는다고 예측한 것을 알 수 있다.
머신러닝과 딥러닝API를 이용하여 안면비대칭을 진단하는 과정은 이렇게 이루어진다. 이제 사용자가 이용할 수 있게 웹사이트에 올려 사진을 받고 결과를 보여주는 작업이 남았다.
'프로젝트 > 2021 소프트웨어 공모전' 카테고리의 다른 글
[2021 소프트웨어 공모전] 뇌졸중 의심 자가진단 프로그램 개발환경 및 소스 코드 그리고 느낀점 (0) | 2021.08.26 |
---|---|
[2021 소프트웨어 공모전] 장고 프레임 워크를 활용한 백엔드 구현기능 (0) | 2021.08.26 |
[2021 소프트웨어 공모전] 리액트를 활용한 프론트엔드 구현기능 (0) | 2021.08.26 |
[2021 소프트웨어 공모전] 작품 설명 (0) | 2021.08.21 |
[2021 소프트웨어 공모전] 기획 의도 (0) | 2021.08.21 |