본문 바로가기

개발/Python

[Python] tqdm으로 진행현황 한 눈에 보기

반복문은 조건문과 더불어 프로그래밍을 배울 때 초반에 배우는 내용이자 가장 많이 사용하는 구문이라고 생각한다.

반복문을 수행하다 보면 어느 정도 작업이 진행되었는지를 확인하고 싶을 때가 있다. 특히, 반복 횟수가 많으면 많을 수록 실행에 걸리는 시간이 오래 걸리기 때문에 작업 현황을 파악하는 것은 꽤나 중요하다.

 

개인적으로 작업 진행 현황을 찾아보기 위해 print문이나 console.log과 같은 출력문을 통해 실제로 눈으로 볼 수 있는 방법을 많이 사용해왔다. 이는 실제 프로그램의 동작과 필요없는 구문이 추가되어 코드의 가시성에 좋은 영향을 주지 않고 실제 원하는 대로 예쁘게 출력하기 어렵다.

 

tqdm은 파이썬에서 반복문에서 이루어지는 과정을 쉽게 볼 수 있도록 해준다.

 

tqdm/tqdm

A Fast, Extensible Progress Bar for Python and CLI - tqdm/tqdm

github.com

이번 포스팅에서는 코드 예제를 통해 tqdm이 제공하는 편리함에 대해서 소개하고자 한다.
들어가기에 앞서 예제를 위해 사용한 코드는 Pytorch 튜토리얼에서 제공하는 최근 공부하고 있던 FGSM 공격 코드를 사용하였다.

 

사용한 코드 출처 : Pytorch FGSM

 

적대적 예제 생성(Adversarial Example Generation) — PyTorch Tutorials 1.6.0 documentation

Note Click here to download the full example code 적대적 예제 생성(Adversarial Example Generation) 저자: Nathan Inkawhich 번역: BONGMO KIM 이 글을 읽고 있다면, 여러분은 이미 머신러닝 모델이 얼마나 효과적인지 그 진

tutorials.pytorch.kr


tqdm 설치 방법

pip install tqdm

 

tqdmpip를 통해서 간단히 설치할 수 있다.

 

tqdm을 사용하지 않는 코드

def test( model, device, test_loader, epsilon ):
    correct = 0
    adv_examples = []

    for data, target in test_loader:
        data, target = data.to(device), target.to(device)

        # 이하 생략

 

위 코드는 test 함수의 일부분이다. 해당 반복문에서는 테스트 데이터가 들어있는 test_loader에서 배치에 해당하는 데이터와 라벨을 불러온다.


이렇게 작성한 코드에서 진행상황을 살펴보기 위해서는 다음과 같은 방법을 택할 수 있다.

 

    for i, (data, target) in enumerate(test_loader):
        data, target = data.to(device), target.to(device)

        # 중략

        print(i, '번째 데이터가 처리되었음.')

 

더 나은 방법이 있겠지만 일단 다음과 같이 사용하였다. test_loader에서 가져오는 데이터를 enumerate에 넣어 인덱스 정보 i를 활용하는 방법이 있겠다. 이 방법도 좋은 방법이 될 수 있지만 (볼드)전체 몇 개의 데이터 중 처리 완료된 데이터가 몇 번째인지 한 눈에 확인하기는 다소 불편하다.

 

tqdm을 활용하면 단 한줄의 코드로 이런 점을 개선할 수 있다.

 

tqdm을 적용한 코드

tqdm을 사용하는 방법은 단순하다. 반복문에서 iterable한 객체를 tqdm으로 감싸주기만 하면 된다. 아래와 같이 말이다.

 

from tqdm import tqdm

def test( model, device, test_loader, epsilon ):
    correct = 0
    adv_examples = []

    # without tqdm
    # for data, target in test_loader:
    # with tqdm
    for data, target in tqdm(test_loader):
        data, target = data.to(device), target.to(device)

        # 이하 생략

 

위 코드와 차이점은 반복 가능한 test_loaderenumerate가 아닌 tqdm으로 감쌌다는 점이다. 그럼 결국 enumerate를 쓰느냐 tqdm을 쓰느냐의 차이지 않느냐 ! 라고 말할 수 있지만 출력 결과를 보면 이야기가 달라진다.

 

 

진행 중인 데이터와 총 데이터, 진행 시간을 별도의 작업 없이 활용할 수 있다.

 

이처럼 별도의 출력문을 걸지 않더라도 진행 상황이 어떻게 진행되는지 실시간으로 확인할 수 있다. 추가적으로 처리하는 시간에 대한 정보도 주어진다.


반복문에서 인덱스 정보 등을 활용하여 출력문을 통해 진행 상황을 확인하는 작업은 생각보다 귀찮은 작업이다. 원하는 대로 출력을 하려면 더더욱 말이다. tqdm은 이러한 과정에서 오는 불편함을 단순히 tqdm으로 감싸주는 것으로 전체 흐르는 과정을 동적이고 보기 좋게 만들어준다.

 

이 포스트에서는 단순히 반복적인 객체를 tqdm에 넣는 방식만 소개했지만 tqdm의 여러 변수를 조정해주면 더 원하는 대로 진행 상황을 확인할 수 있다. 뿐만 아니라 터미널 창에서 작업에 대해서도 활용할 수가 있다고 한다.

 

tqdm을 활용하여 반복적인 작업에서 쉽게 진행 상황을 파악할 수 있기를 바라며 오늘 포스팅을 마친다.

반응형