Dream Olfactory Challenge 2024 회고록
(2024.05.01 ~ 2024.08.02)
나의 첫 인공지능 프로젝트로, Synapse에서 진행하는 Dream Olfactory Challenge이다. 해당 챌린지에서 요구한 Task는 2개의 분자 혼합물 간의 냄새 유사도 예측이다. 우리에게 주어진 데이터로는, Mixture의 구성 요소인 CID 리스트와, 2개의 Mixture 쌍과 유사도 수치가 있다. 최종적으로 제출한 모델의 아키텍처는 아래와 같다.
프로젝트 내의 역할
초기에 전체적인 모델의 아키텍처를 구상할 때, 화학 분자와 후각 수용체 단백질로 2가지 컴포넌트로 이루어져 있었다. 아무래도 후각을 예측하기 위해서 Mixture를 구성하는 화학 성분도 중요하지만, 이에 반응하는 사람의 후각 수용체 단백질 또한 고려할 필요가 있기 때문이다. 이 중에서 나는 각 CID(화학 분자)에 반응하는 후각 수용체 단백질 컴포넌트를 중점적으로 맡아 진행하였다. 모델에서 후각 수용체 단백질 컴포넌트를 추가한 경우 모델의 성능이 더 떨어지는 상황이 발생하여 최종 모델에서는 제외되었다ㅠㅠ 수용체 단백질을 추가했을 때 일반적으로 생각했을 때는 성능이 높아져야 하지만, 후각 수용체에 반응하는 CID가 약 46% 정도 밖에 안되기 때문으로 생각된다. 그래도 후각 수용체 단백질 컴포넌트를 구현을 포함하여 맡은 역할은 다음과 같다.
#1. Cytoscape를 활용한 혼합물의 분포 시각화
주어진 혼합물 쌍에 대한 데이터셋을 이해하기 위해 Cytoscape를 활용하여 화합물 종류를 노드로, 유사도를 엣지로 하여 그래프로 생성하였다. Cytoscape의 메뉴얼이 많지 않아 조금 힘들었던 기억이 나서 추후에 블로그에서 다루면 좋을 것 같다는 생각이 들었다.
#2. M2OR DB에서 얻은 후각 수용체 단백질과 STRING DB에서의 단백질 간의 유사도 매핑
데이터셋에 주어진 모든 CID에 대해 반응하는 후각 수용체 단백질을 M2OR DB에서 가져왔다. 그 후, STRING 데이터에서 제공되는 단백질 간의 유사도 수치를 각각에 대해 매칭하는 작업을 진행하였다. 쉽게 해결할 수 있는 작업이라고 생각했지만, 생각보다 쉽지만은 않은 작업이었다.
M2OR DB와 STRING DB 간의 단백질 명명법 차이
M2OR에서는 Gene Symbol로, STRING에서는 Ensembl ID로 단백질에 대한 유전자를 명명하고 있었다. 이에 두 DB 간의 정보를 매핑하려면 결국은 하나의 명명법으로 변환하는 절차가 필요했다. Ensembl ID를 Gene Symbol로 변환하기 위해 Biomart와 myGene 라이브러리를 이용하여 처리하였다. 2개의 라이브러리를 사용한 이유는 하나의 라이브러리만으로 변환되지 않는 ID가 존재하였기 때문이다.
대용량 데이터 처리
STRING 데이터를 다운 받았을 때 거의 180GB 정도의 파일이라서, 텍스트 편집기를 사용하여 보는 것에 엄청난 로딩이 필요하였다. 이 데이터는 후각 수용체 단백질만이 아닌 다양한 부위의 단백질이 포함되어있기 때문이다. STRING 데이터 파일에서 단백질 명명법을 변환하려 하였을 때 동일한 단백질에 대해 쿼리를 요청을 반복하여 한도를 초과하는 문제가 발생했다. 이를 해결하기 위해 STRING 데이터 파일에서 고유한 단백질 리스트를 추출하는 작업을 진행하고 딕셔너리 형식으로 저장하였다.
부족한 후각 수용체 단백질 데이터
Bioinformatics 분야는 타 응용 분야에 비해 데이터가 충분하지 않는데, 그 중에서도 후각 단백질에 대해 더 정보가 부족하다고 한다. 전체 단백질이 STRING 데이터에서 117,066개 중 116,600만을 Gene Symbol로 변환하는데 성공하였으며 이 중 후각에 대한 단백질은 총 139개 뿐이었다. 이를 다시 주어진 혼합물의 구성 CID에 반응하는 후각 단백질만을 추리면 오직 85개만이 남았다.
#3. 후각 수용체 단백질의 임베딩 벡터 생성
후각 수용체 단백질에 대한 그래프를 생성하기 이전에, 단백질을 그래프로 노드로 하려면 해당 노드에 대한 feature가 필요하다. 이를 위해 단백질의 임베딩 벡터를 생성하였다. 각각의 임베딩 벡터를 생성하기 위해서 pre-trained 된 ProtBert 모델을 사용하였다. 입력된 모든 sequence가 잘리지 않도록 sequence의 max-length로 설정해 임베딩 벡터가 370으로 출력되었다. 하지만, 이를 학습에 바로 이용하기에는 너무 커 32로 변환하는 작업이 필요했고 이를 위해 Linear Transformation을 이용하였다.
* ProtBert 모델 Reference
#4. 혼합물을 구성하는 CID 리스트에 반응하는 단백질에 관한 그래프 생성
혼합물을 구성하는 CID 리스트에 반응하는 단백질을 노드로, 두 단백질 간의 공통 CID가 존재할 경우 엣지로 연결하는 방식으로 생성했다. 엣지를 유사도 수치로 설정하려 했지만 부족한 데이터로 인해 수정되었다. 참 기괴한 그래프가 많이 생성되었다... 이후에 GNN에 해당 그래프를 입력으로 넣었을 때 엄청난 오류가 여기에서 발생하였다. GNN에 넣었을 때 'x' feature가 존재하지 않는다는 오류로 며칠 동안 시달렸는데, 알고 보니 그래프 생성 과정에서 엣지가 존재하지 않는 경우에 대한 처리가 잘못 되어 있었다. CID 컴포넌트를 GNN에 동일한 방식으로 넣었는데, 오류가 나서 디버깅하는 데 매우 힘들었다. 결국은 그래프 생성할 때도 예외 처리가 중요하다는 점을 느꼈다.
#5. 하이퍼 파라미터 튜닝
모델의 파라미터는 물론, 모델의 종류에 따라 성능을 비교하는 과정에서 코딩의 편리함을 많이 느꼈다. 처음에는 비교하는 하이퍼 파라미터도 적었고 한 가지 모델 위주로 실행하다 보니, 단순히 VS code에서 실행 버튼 하나로 해결했다. 모델이 점점 커지고 동시에 여러 모델을 돌리다 보니 실행 시간이 2시간? 3시간? 을 넘어가니 실행 결과를 표로 정리하고 다시 실행시키고 하느라 몇 일은 밤 새면서 헤롱헤롱한 상태였다. 그런데, 모델을 python 파일로 통일하고 표 작성까지 자동화하니 너무 편하였다. 아주 단순한 생각이었는데 맨날 하던대로만 하니 생각하지 못했던 것 같다.
#6. 가상 환경
올해 3월까지만 해도 왜 가상 환경을 사용해야하는 것인지 의문이 많이 들었는데, 왜 사용하는지 깨달아 버렸다. 이번 프로젝트에서도 코드를 구현하기 위해 정말로 다양한 패키지 및 라이브러리가 사용되며 설치된 버전마다 사용할 수 범위 및 방법이 다르다. 그렇기에 가상 환경을 설치하는 과정에서 버전 충돌도 많이 나고 자칫 잘못하면 이미 설치한 환경도 다시 처음부터 설치해야 하는 상황까지 오기도 한다. 단백질 컴포넌트만을 담당할 때에는 나의 코드만 실행하면 되니 버전 충돌이 나지 않았는데, 화학 분자 컴포넌트까지 포함한 모델을 실행하기 위해서 다시 가상 환경을 설정하였다.
또한, 하나의 GPU만으로 모델 성능 평가를 하는데에 너무 오랜 시간이 걸렸지만 번거로운 가상 환경 설정 탓에 또 다른 GPU를 사용하는 것을 꺼렸다. 이를 해결하기 위해 SCP 명령어를 사용하여 가상 환경을 tar 파일로 만들어 전송하고 가상 환경을 한번에 설치함으로써 2개의 GPU를 사용하여 더 원활하게 작업을 이어갈 수 있었다. 이때 직접 공부하고 정리하여 다음과 같은 포스트를 작성했다.
#7. Linux의 편리함
아직도 Linux에 대해 완전히 아는 것은 아니지만, 이번 프로젝트를 하면서 Linux와 조금은 친숙해진 것 같다. Linux Shell Scripting이나 CPU, GPU의 메모리 관리나 간단한 명령어를 사용하는게 python을 사용할 때보다 더 간단하고 빠름을 느꼈다. 백그라운드 재생도 하이퍼파라미터 튜닝할 때 매우 유용하게 사용할 것 같고 다음 학기 시스템 소프트웨어에서 Linux를 왜 배우는지에 대해 미리 느껴 더 열심히 수강할 수 있을 것 같다. (본 수강 신청 때는 실패하였지만.. 수강 정정 때는 꼭 시소프 잡을 수 있기를!!!)
인공지능에 대해 아무것도 모르는 상태로 처음 맡은 프로젝트이다 보니,
아무래도 모델을 변형하는 것보다 데이터 전처리, 모델 성능 평가 등에 많은 시간을 할애하였다.
내가 맡은 후각 수용체 단백질 컴포넌트를 포함하였을 때 성능이 오히려 떨어지는
결과가 나와 아쉽게도 열심히 진행한 부분이 최종 모델로 이어지지는 않았다.
처음에는 지금까지 해왔던 노력이 사라지는 느낌이 들어 허무했는데, 다 피가 되고 살이 되는 경험이었던 것 같다.