MATLAB

MATLAB-Python 연결하는 방법 3

qlsenddl 2020. 10. 22. 22:02
728x90

 MATLAB함수를 Python에서 쓸 일이 있거나, Python에서 정의한 함수 또는 라이브러리를 MATLAB에서 쓰는 방법을 정리했다. 나는 개인적으로 Python으로 AI model을 만들고 그 결과를 MATLAB에서 가져오려고 했다. 다양하게 시도를 해봤고 그 결과를 정리해보고자 한다.

- 결론적으로 나는 3번 방식으로 겨우 성공했는데, 1, 2번 방식도 되는 상황도 있을 테니 가능하다면 1번이나 2번 방법을 사용하는 것이 좋을 것 같다.


3. MATLAB에서 command 창 명령으로 Python 파일을 함수처럼 이용하기

 나의 경우 Python 파일에서 AI model을 만들고, 이 AI model의 input을 MATLAB을 통해 넣고, output을 MATLAB에서 받아와 이 함수 정보를 통해 fmincon으로 최적화를 하려고 했다. 이를 위해서 MATLAB에서 command 명령을 할 수 있다는 것에 착안해서 command 창에 MATLAB input을 입력하고 output을 읽어 MATLAB이 Python의 함숫값을 읽어오도록 했다.

 이 경우 MATLAB에서는 command 창에서 Python을 실행시키는 코드가 필요하고, Python에서도 command 창의 값을 읽어올 수 있도록 코딩을 해줘야 한다.


1) MATLAB에서 command 창에서 Python 실행시키기

 MATLAB에서는 system이라는 함수를 통해 command 창에 명령을 할 수 있다. 우선 Python을 실행시키려면 command 상에서도 Python 파일이 있는 directory로 이동해야 하므로 system('cd Python이 있는 directory') 형식으로 코딩하면 된다.

 이 후, system('python Python module 이름.py') 를 하면 해당 파일을 실행하게 된다.


ex>

system('cd C:\Users\user\Documents\MATLAB');

system('python python_module.py ');


system 함수는 string(문자열) 자료형을 인수로 받는다는 것을 기억하자.


2) Python에서 command 창 입력값 받아오기

 MATLAB에서 system 함수를 통해 command 창으로 값을 입력하면, Python 파일에서는 그 입력값을 받아와서 Python 함수에 입력해야 한다.

 Python에서 command 창의 입력값을 읽어오는 함수는 sys.argv로 할 수 있다. sys.argv는 python 명령 이후의 command창의 문자열을 공백을 기준으로 split하여 list로 만들어준다. 예를 들면 다음과 같다.


ex>

Python code

print(sys.argv)


command 창


여기에서 abcd는 임의로 입력을 넣은 것이다. 이 경우 파일을 실행시키기 위한 명령까지 입력으로 받아들이는 것을 확인할 수 있다. 때문에 sys.argv의 첫 번째 요소는 제외하고 입력으로 받아들여야 한다. 그래서 결과적으로 코드는 다음과 같이 짜여져야 한다.

MATLAB_input = sys.argv[1:]


3) MATLAB에서 command 창에 함수 입력값 넣기

 2)번과 같은 방식으로 Python이 command 창의 입력을 받아내기 때문에 Python을 실행시키는 명령어 뒤에 입력값을 넣어주면 된다. 하지만 system 함수는 string 문자열을 인수로 받기 때문에 string으로 변환한 후 python 실행 명령과 합쳐주면 된다. 이 때 system의 출력값은 해당 명령을 하고 난 후, 명령 실행의 완료 여부를 나타내는 status 변수와 command 창에 출력되는 값이다.(https://kr.mathworks.com/help/matlab/ref/system.html 참고) 때문에 이를 output 변수로 받아오면 input에 대한 python 함수의 함숫값을 얻을 수 있다. 결과적으로 MATLAB 코드는 다음과 같다.


ex> 

% python이 있는 directory로 이동

system('cd C:\Users\user\Documents\MATLAB');


% 함수 입력값

a = 2; b = 3;

c = [a, b];


% double 자료형인 배열을 string으로 변환

ip = num2str(c);


% python 실행 명령

% .py 뒤에 공백이 있어야 실행 시 오류가 나지 않는다.

command = "python python_module.py ";


% python 실행 및 input 입력

[status, output] = system(strcat(command, ip))


참고: 이 때 output 값은 string 자료형이다. 때문에 이 함숫값을 사용하려면 숫자 자료형으로 변환해야 한다. -> str2num(output)


4) Python에서 input 처리해서 Python 함수값 얻기

 sys.argv로 얻은 MATLAB_input은 여러 input들이 string(문자열) 자료형으로 된 list이다. 때문에 이를 Python 함수에 넣어서 결과를 얻기 위해서는 list에 있는 각각의 string(문자열) 자료형을 숫자 자료형으로 변환해줘야 한다. 그 후 함수에 넣고 그 값을 print해주면, command 창에 출력되므로 그 값을 MATLAB에서 읽을 수 있다. 결과적으로 Python 코드는 다음과 같다.


ex1> input을 받아와서 함수에 넣고 그 값을 print

import torch
import sys

def add(a, b):
return a+b

def add_double(a, b):
return add(a, b)*2

MATLAB_input = sys.argv[1:]


lst = []
for i in MATLAB_input:
try:
num = float(i)
lst.append(num)
except:
continue

a = lst[0]
b = lst[1]
print(add_double(a, b))


ex2> input이 여러 개여서 이후 numpy array input으로 변경하는 경우의 예시이다. 이 코드에서는 input을 구성하는 것까지만 나와있다.

lst = []
for i in MATLAB_input:
try:
num = float(i)
lst.append(num)
except:
continue
z = np.array(lst)


 참고: ex1에서 보면 해당 Python 코드에 쓰이지는 않지만 torch가 import 된 것을 알 수 있다. 즉, 이 방법은 이전의 1번 방법과는 달리 torch를 import한 코드에서도 사용 가능하다.


한계점

1. system 함수의 출력값은 해당 명령 이후 나오는 모든 command 창의 출력값이다. 때문에 코드에서 오류 메시지가 같이 출력된다면 제대로 된 output값을 받아내지 못할 수 있다. 개발한 코드에서 오류 메시지가 불가피하게 출력된다면 이 방법을 사용할 수 없다.

2. 이유는 모르겠지만, 정상적인 MATLAB code여도 파일을 실행할 때 MATLAB directory가 Python이 있는 파일에 있지 않으면 "python: can't open file 'python_module.py': [Errno 2] No such file or directory" 에러가 발생하고 output 역시 잘못된 값이 나오는 것을 확인할 수 있다.


728x90