ML 코드들을 보다보면 OOP + 모듈화를 시키다 보니 스크립트로 모델을 실행시키는 경우가 많습니다. 그런 코드들을 잠깐 들여다 보면 아래와 같은 코드들이 눈에 띕니다.
python train.py --img 640 --batch 32 --epochs 100 --data yamlyaml.yaml --cfg config.yaml --weights yolov5l.pt --name model_name
이런 식으로 Terminal에서 스크립트로 파일을 직접 실행시킴과 동시에 설정할 수 있습니다. 이 기능을 도와주는 것이 바로 argparser
입니다.
일단 파라미터 관리가 진짜 편합니다. parameter 관리는 물론 나중에 config 파일에서 관리한다고 하지만 Script에서 실행 시킬 때 바로바로 파일을 실행시키면서 결과 변화를 확인할 수 있어서 좋긴 하죠.
모델링을 하다보면 결국 다양한 파라미터 실험을 통해 모델의 성능을 끌어 올리는 것이 중요합니다. argparse를 이용 그 활동이 좀 더 수월해진다고 할 수 있습니다.
import argparse
parser = argparse.ArgumentParser('테스트')
parser.add_argument('--first', help='첫번째 arg', required=True)
parser.add_argument('--second', help='두번째 arg', default = 123)
args = parser.parse_args()
print(args.first)
위의 코드에서 하나하나 설명해드리도록 하겠습니다.
import argparse
넘어가도록 하겠습니다.
ArgumentParser()
라는 객체를 생성해줍니다.
파라미터로 이 객체에 대한 설명을 넣을 수 있지만, 넣지 않는다고 해서 에러가 뜨는 것은 아닙니다.
우리는 ArgumentParser()
로 생성된 객체에 하나하나씩 우리가 원하는 옵션들을 넣어줄 겁니다.
위에서 생성한 parser
객체에 add_argument()
를 통해 원하는 옵션을 입력합니다.
제가 하면서 제일 유효하게 사용했던 파라미터들을 소개합니다.
{}는 빼고 치시면 됩니다.
name_of_flags : 가장 첫번째에 오는 파라미터로 '--{실행시킬 이름}' 형태로 입력합니다. 이걸 하게 되면 terminal에서
python main.py --xxx
로 해당 옵션을 실행시킬 수 있습니다.
help : terminal에서pathon main.py -h
를 치면 나올 설정해둔 옵션들에 대한 설명입니다.
type : 입력되어야할 type을 지정할 수 있습니다.
required : 해당 옵션이 입력 되지 않으면 실행되지 않게 해줍니다!
음.. 이거 외에도 True False 형으로 지정할지 등등의 옵션이 있지만 일단은 이 정도로만 알고 넘어가도 argparse
에 대한 이해는 가능합니다.
지금까지 작성한 옵션들이 담겨져 있는 parser 객체를 하나로 묶어줍니다.
묶여있는 객체에 .옵션이름
으로 해당 옵션에 접근할 수 있습니다.
terminal에서 해당 파일이 있는 경로에 접속하신 뒤 (cd ~~ )python {파일이름}.py --{옵션} {옵션 내용}
을 적고 실행시켜 줍니다.
위의 코드를 예시로 작성해보면
(Terminal)python main.py --first Hi
Output
HI
코드에 작성된 print(args.first)
대로 args의 first 파라미터에 담긴 내용이 출력되었습니다. 이런식으로 파일을 실행시킬 때 내부에 있는 파라미터를 터미널 단계에서 다양하게 조절해가며 실행시킬 수 있다는 것이죠.
지이이이이이이이인짜 간단한 예시지만 이런 식으로 활용된다는 걸 보여드리면서 마무리하도록 하겠습니다.
import argparse
def parser() :
ps = argparse.ArgumentParser('모델 파라미터')
## Train Args
ps.add_argument('--epochs', type=int , required=True, default=100)
ps.add_argument('--lr', required=True, default=0.01)
ps.add_argument('--batch_size', required=True, default=32)
## models
ps.add_argument('--drop_out', default=0.3)
## 저장
params = ps.parse_args()
return params
def main(params) :
print(f'EPOCH : {params.epochs}')
print(f'LEARNING RATE : {params.lr}')
print(f'BATCH SIZE : {params.batch_size}')
print(f'DROP OUT RATE : {params.drop_out}')
print('\n'+'Train Start'+'\n')
for idx, i in enumerate(range(params.epochs)) :
if idx % 100 == 0 :
print(f'\n||||||||{idx}번째 epoch||||||||')
print(f'{idx}번째 배치에서 {params.batch_size}개의 x와 y를 가져옴')
print('가중치 초기화')
print(f'모델에 x를 넣음 ---> drop out rate : {params.drop_out}')
print('로스 값이 나옴')
print('오차역전법')
print(f'가중치 업데이트 ---> lr : {params.lr}')
if __name__ == '__main__' :
params = parser()
main(params)
실행 Script
python model.py --epochs 500 --lr 0.01 --batch_size 32
required = True
로 되어있는 파라미터만 입력하고 필수로 지정되어 있지 않은 drop_out
파라미터는 나뒀습니다. 어떤 결과가 나올까요?
Output
EPOCH : 500
LEARNING RATE : 0.01
BATCH SIZE : 32
DROP OUT RATE : 0.3
Train Start
||||||||0번째 epoch||||||||
0번째 배치에서 32개의 x와 y를 가져옴
가중치 초기화
모델에 x를 넣음 ---> drop out rate : 0.3
로스 값이 나옴
오차역전법
가중치 업데이트 ---> lr : 0.01
||||||||100번째 epoch||||||||
100번째 배치에서 32개의 x와 y를 가져옴
가중치 초기화
모델에 x를 넣음 ---> drop out rate : 0.3
로스 값이 나옴
오차역전법
가중치 업데이트 ---> lr : 0.01
||||||||200번째 epoch||||||||
200번째 배치에서 32개의 x와 y를 가져옴
가중치 초기화
모델에 x를 넣음 ---> drop out rate : 0.3
로스 값이 나옴
오차역전법
가중치 업데이트 ---> lr : 0.01
||||||||300번째 epoch||||||||
300번째 배치에서 32개의 x와 y를 가져옴
가중치 초기화
모델에 x를 넣음 ---> drop out rate : 0.3
로스 값이 나옴
오차역전법
가중치 업데이트 ---> lr : 0.01
||||||||400번째 epoch||||||||
400번째 배치에서 32개의 x와 y를 가져옴
가중치 초기화
모델에 x를 넣음 ---> drop out rate : 0.3
로스 값이 나옴
오차역전법
가중치 업데이트 ---> lr : 0.01
지정한 파라미터 대로 모델이 잘 작동함을 알 수 있습니다. drop_out
은 지정해주지 않았지만 argparse에 default 값을 지정해주었기 때문에 0.3으로 정상적으로 잘 작동하네요!