머신러닝 튜토리얼에서 모델을 만들 때는 코드 내에서 각종 변수를 직접 입력하면서 테스트하지만,

실제 모델을 이용할 때는 각종 옵션을 argument로 정의해서 CLI 스크립트에서 입력할 수 있어야 한다

 

여기서부터는 머신러닝 라이브러리가 아닌 파이썬 프로그래밍의 영역이라 좀 낯설지만 한번 공부해봅시다!

 

 

 

파이썬에 내장된 argparse 라이브러리를 이용해야한다.

라이브러리 공부는 공식문서가 깔끔하니까 쭉 정리해보자 ( https://docs.python.org/3/library/argparse.html  )

The argparse module makes it easy to write user-friendly command-line interfaces. 
The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv.

서두에 말한 것과 같이 argparse 모듈을 이용하면 CLI 에서 머신러닝의 모델, 데이터, 환경 등등 여러 옵션과 파라미터를 설정할 수 있다. argparse는 입력된 스크립트에서 어떻게 argument 를 파싱할지 정의할 수 있는 모듈이다.

 

여기서 sys.argv란 파이썬 스크립트에 입력되는 argument 덩어리들이라고 생각하면 된다

sys.argv : The list of command line arguments passed to a Python script.

 

 

이제 간단한 예제로 실습을 해보자

#arg_test.py

import argparse

# (1) 인스턴스 생성
parser = argparse.ArgumentParser(description='parser for argparse test')

# (2) argument 추가
parser.add_argument('--number', default=int(0), type=int, help='number to print')

# (3) parse 결과 
args = parser.parse_args()

print('your number is {}'.format(args.number))

(1)  ArgumentParser() 를 이용해서 parser 라는 인스턴스를 생성한다.

parser는 파이썬 스크립트로 입력된 값들을 저장하고 처리할 수 있는 인스턴스이다

description 으로 인스턴스 설명을 추가해도 되고 생략해도 된다.

The ArgumentParser object will hold all the information necessary to parse the command line into Python data types.

 

 

(2) add_argument() 메서드로  파싱할 argument 정의를 추가한다.

메서드 파라미터들이 다양한데, 머신러닝할 때는 위의 5개 정도를 쓰지않을까 생각해서 강조해봤다.

name or flags - Either a name or a list of option strings, e.g. foo or -f, --foo.
object.type - The type to which the command-line argument should be converted.
dest  - The name of the attribute to be added to the object returned by parse_args().
default  - The value produced if the argument is absent from the command line and if it is absent from the namespace
help - A brief description of what the argument does.
action - The basic type of action to be taken when this argument is encountered at the command line.
nargs - The number of command-line arguments that should be consumed.
const - A constant value required by some action and nargs selections.
choices - A container of the allowable values for the argument.
required - Whether or not the command-line option may be omitted (optionals only).
metavar - A name for the argument in usage messages.

 

 

 

(3) parse_args() 메소드로 파싱한 결과로 args 라는 인스턴스를 생성한다

parser.parse_args() 로 스크립트로 입력된 값들을 파싱한다.

그 결과 생성된 Namespace 오브젝트를 args 라는 이름으로 정의하여 저장하면 된다

parse_args() method will inspect the command line, convert each argument to the appropriate type and then invoke the appropriate action.
In most cases, this means a simple Namespace object will be built up from attributes parsed out of the command line:

 

Namespace 는 별거아니고 그냥 parse_args 결과로 생성되는 클래스이다

Namespace : Simple class used by default by parse_args()  to create an object holding attributes and return it.

 

 

이제 커맨드 창을 열어서 테스트 해보자!

.py 파일을 실행시키면 default 값인 0으로 출력되지만

.py 뒤에 --number 10 을 적어주면 arg.number 이 10이라는 뜻으로 파싱하고, 결과로 10을 출력해준다.

오케이 간단한 테스트는 성공

 

 

 

 

그럼 이제 머신러닝 모델에서 쓸법한 argparse 코드구조를 생각해보자.

(실제로 구동되는 코드는 아니며 argparse의 사용되는 부분만 작성합니다)

# __main__.py
import os
import argparse
import subprocess

parser = argparse.ArgumentParser()

parser.add_argument('--model', default='run_my_model', type=str)
parser.add_argument('--data', default='my_data', type=str)
parser.add_argument('--n_epoch', default=int(100), type=int)

args = parser.parse_args()

subprocess.run(["python" , 
                os.path.join('.',arg.model,'.py'),
                "--data",
                args.data,
                "--n_epoch",
                args.n_epoch
                ])

모델연산하는 run_my_model.py파일을 바로 실행시킬 수도 있지만, __main__은 여러 다른 기능을 포함할 수 있으니

__main__에서 subprocess 를 이용해서 모델실행 코드를 실행시키도록 만들 수 있다.

 

__main__.py 파일을 실행하면서 스크립트에 입력된 argument를 파싱해서 args로 저장하고,

이 값을 subprocess 스크립트로 my_model.py 를 실행시킬 때 다시 argument로 넘겨준다

 

 

 

 

# run_my_model.py

import argparser
import os
import tensorflow as tf

# argument parse
parser = argparse.ArgumentParser()
parser.add_argument('--n-epoch',default=int(100),type =int)
parser.add_argument('--data', default = "my_data")
args = parser.argparser()



# 모델 생성 예시
model = Model_Dev()

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
              loss=tf.keras.losses.BinaryCrossentropy(),
              metrics=[tf.keras.metrics.BinaryAccuracy(),
                       tf.keras.metrics.FalseNegatives()])

model.compile(optimizer='adam', loss='mse')
model.fit(os.listdir("datasource/" + args.data + ".csv"),
          epochs=args.n_epochs)

이렇게 학습에 필요한 데이터경로와, 학습 하이퍼파라미터인 n_epoch 등 을

argument로 파싱해서 적용할 수 있다.

 

 

연구단계에서 여러 하이퍼파라미터의 학습결과를 비교해보고 싶다거나

online으로 운영중인 모델의 경우 데이터 경로가 새로 생성될 때 , 또는 cross-validation 할 때

위의 방법처럼 커맨드에서 argument로 입력해서 전체 프로그램을 돌릴 수 있다.

 

 

 

 

[참고한 블로그]

https://greeksharifa.github.io/references/2019/02/12/argparse-usage/

 

Python, Machine & Deep Learning

Python, Machine Learning & Deep Learning

greeksharifa.github.io

 

+ Recent posts