요즘 강화학습 / 딥러닝 하퍼파라미터 튜닝등 반복적인 실험이 필요한경우
이를 효율적으로 관리하는 것은 매우 중요하다고 느낀다.
이때 유용하게 사용할 수있는 argparser 모듈에 대해서 알아 보고자 한다.
reference : Johnny Metz Youtube
먼저 원통의 부피를 구하는 간단한 프로그램을 작성해보면서 살펴 보자
import math
def cylinder_volume(radius, height):
vol = (math.pi)*(radius**2)*(height)
return vol
if __name__ =='__main__':
print(cylinder_volume(2,4))
위와 같이 원의 부피를 구하는 cylinder_volume(radius,height) 함수를 간단하게 작성하였다.
import math
import argparse
# 1. parser 객체 생성
parser = argparse.ArgumentParser(description='Calculate volume of a Cylinder')
# 2. 사용할 인수 등록, 이름/타입/help
parser.add_argument('radius', type=int, help='Radius of Cylinder')
parser.add_argument('height', type=int, help='Height of Cylinder')
# 3. 사용자에게 전달받은 인수를 args에 저장
args = parser.parse_args()
def cylinder_volume(radius, height):
vol = (math.pi)*(radius**2)*(height)
return vol
if __name__ =='__main__':
# 4. args에 전달된 인수를 이용해 함수 결과값 출력
print(cylinder_volume(args.radius, args.height))
argparse 모듈을 import하고 parser 객체를 생성한다 (parameter를 담는 일종의 container라 생각하면 편하다), description에는 설명 내용을 적어준다(뒤의 파트에서 보면 왜 적는지 알 수 있다.)
객체에 우리가 원하는 파라미터를 전달해준다.
커맨드라인에서 실행을 하는 방법은 다음과 같다. py 파일 뒤에 인수를 전달하면 되는데 지금 상태에서는 postional argument로 들어가기 때문에 순서를 유의해서 실행해야한다.
이제 *.py -h 를 실행해보자 (help문으로 인자에 대한 설명을 확인 할 수 있다.)
실행결과를 보게 되면, 이전에 작성했던 description, help 설명문이 나오는 것을 확인할수있다.
만약 전달해야할 인자가 많다면, 위와 같이 positional argumnet 형식으로 전달하는 것은 무리가 있다.
이번에는 optional argument 형식으로 전달하는 방법을 알아보자.
import math
import argparse
# parser 객체 생성
parser = argparse.ArgumentParser(description='Calculate volume of a Cylinder')
parser.add_argument('-r','--radius', type = int, help = 'Radius of Cylinder' )
parser.add_argument('-H','--height', type = int, help = 'Height of Cylinder' )
args = parser.parse_args()
def cylinder_volume(radius, height):
vol = (math.pi)*(radius**2)*(height)
return vol
if __name__ =='__main__':
print(cylinder_volume(args.radius, args.height))
달라진 사항은 없다.
이런 경우 metavar option을 추가해서 format 형식을 바꿀 수 있다.
또한 추가적으로 required option을 추가해서 특정 argument값이 전달 되지 않으면 error가 발생하도록 설정 할 수 있다. (아무 값이 전달 되지 않으면, default는 None으로 전달한다)
import math
import argparse
# parser 객체 생성
parser = argparse.ArgumentParser(description='Calculate volume of a Cylinder')
parser.add_argument('-r','--radius', type = int, metavar='', required=True, help = 'Radius of Cylinder' )
parser.add_argument('-H','--height', type = int, metavar='', required=True, help = 'Height of Cylinder' )
args = parser.parse_args()
def cylinder_volume(radius, height):
vol = (math.pi)*(radius**2)*(height)
return vol
if __name__ =='__main__':
print(cylinder_volume(args.radius, args.height))
실행을 시켜보면 이제는 다음과 같이 깔끔하게 help 명령문이 실행되는 것을 확인 할 수 있다.
이번에는 parser.add_mutually_exclusive_group()에 대해서 알아보자.
우리가 실행하는 함수에 input을 직접적으로 들어가지는 않지만, 다른 option을 부여해서 어떠한 특수한 동작을 하길 원할때 사용할 수 있다(현재 training 진행 상황을 출력하길 원한다던지..)
import math
import argparse
# 1. parser 객체 생성
parser = argparse.ArgumentParser(description='Calculate volume of a Cylinder')
parser.add_argument('-r','--radius', type = int, metavar='', required=True, help = 'Radius of Cylinder' )
parser.add_argument('-H','--height', type = int, metavar='', required=True, help = 'Height of Cylinder' )
group = parser.add_mutually_exclusive_group()
group.add_argument('-q', '--quiet', action ='store_true', help='print queit')
group.add_argument('-v', '--verbose', action ='store_true', help='print verbose')
args = parser.parse_args()
def cylinder_volume(radius, height):
vol = (math.pi)*(radius**2)*(height)
return vol
if __name__ =='__main__':
volume = cylinder_volume(args.radius, args.height)
if args.queit :
print(volume)
elif args.verbose :
print(f"Volume of a Cylinder with radius {args.radius} and height {args.height} is {volume}")
else :
print(f"Volume of Cylinder = {volume}")
만약 -v 인자를 전달 하게 된다면, True가 arg.verbose에 저장되게 되고, if-else문을 거쳐 원하는 동작을 하게끔 만들 수 있는 것이다.
이제까지 간단한 argparser의 사용법에 대해 알아보았다!
좋은 글 감사합니다 ! 맨 마지막 코드 블럭 if args.queit : 에 오타가 있는 것 같습니다 :)