Python: tqdm не показывает индикатор выполнения

Я написал код PyTorch для функции fit моей сети. Но когда я использую tqdm в цикле внутри него, он не увеличивается с 0% по причине, по которой я не могу понять.

Вот код:

from tqdm.notebook import tqdm

def fit(model, train_dataset, val_dataset, epochs=1, batch_size=32, warmup_prop=0, lr=5e-5):

    device = torch.device('cuda:1')
    model.to(device)
    
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)

    optimizer = AdamW(model.parameters(), lr=lr)
    
    num_warmup_steps = int(warmup_prop * epochs * len(train_loader))
    num_training_steps = epochs * len(train_loader)
    
    scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps, num_training_steps)

    loss_fct = nn.BCEWithLogitsLoss(reduction='mean').to(device)
    
    for epoch in range(epochs):
        model.train()
        start_time = time.time()
        
        optimizer.zero_grad()
        avg_loss = 0
        
        for step, (x, y_batch) in tqdm(enumerate(train_loader), total=len(train_loader)): 
            y_pred = model(x.to(device))
            
            loss = loss_fct(y_pred.view(-1).float(), y_batch.float().to(device))
            loss.backward()
            avg_loss += loss.item() / len(train_loader)


            optimizer.step()
            scheduler.step()
            model.zero_grad()
            optimizer.zero_grad()
                
        model.eval()
        preds = []
        truths = []
        avg_val_loss = 0.

        with torch.no_grad():
            for x, y_batch in val_loader:                
                y_pred = model(x.to(device))
                loss = loss_fct(y_pred.detach().view(-1).float(), y_batch.float().to(device))
                avg_val_loss += loss.item() / len(val_loader)
                
                probs = torch.sigmoid(y_pred).detach().cpu().numpy()
                preds += list(probs.flatten())
                truths += list(y_batch.numpy().flatten())
            score = roc_auc_score(truths, preds)
            
        
        dt = time.time() - start_time
        lr = scheduler.get_last_lr()[0]
        print(f'Epoch {epoch + 1}/{epochs} \t lr={lr:.1e} \t t={dt:.0f}s \t loss={avg_loss:.4f} \t val_loss={avg_val_loss:.4f} \t val_auc={score:.4f}')

Вывод
Вывод после выполнения функции fit с требуемыми параметрами выглядит так:
0%| | 0/6986 [00:00<?, ?it/s]

Как это исправить?


person Ishan Dutta    schedule 14.05.2021    source источник
comment
Вы уверены, что выполнение всей функции завершено? Выполнены ли отпечатки в нижней части цикла?   -  person GoodDeeds    schedule 14.05.2021
comment
Да, вся функция выполняется, и я также получаю значения потерь, код работает, но в индикаторе выполнения нет ответа @GoodDeeds   -  person Ishan Dutta    schedule 14.05.2021
comment
Может enumerate(tqdm(train_loader)) работает?   -  person Mike Xydas    schedule 14.05.2021
comment
Я попробовал это @MikeXydas, но это не сработало.   -  person Ishan Dutta    schedule 14.05.2021
comment
tqdm вообще работает? Попробуйте пример примера, как в ответе на этот пост: stackoverflow.com/a/63427058/6025629   -  person Mike Xydas    schedule 14.05.2021


Ответы (1)


Поскольку вы импортируете из tqdm.notebook, это означает, что вы используете блокнот Jupyter, верно? Если нет, вы должны сделать from tqdm import tqdm.

Я упростил ваш примерный код, чтобы сделать его действительно минимальным, например:

import time
from tqdm.notebook import tqdm

l = [None] * 10000

for i, e in tqdm(enumerate(l), total = len(l)): 
    time.sleep(0.01)

и выполняется в блокноте Google Colab Jupyter. Он показал мне хороший индикатор выполнения, например:

введите здесь описание изображения

Значит tqdm корректно работает в режиме ноутбука. Следовательно, у вас есть проблемы с итерируемым или циклическим кодом, а не с tqdm. Возможная причина может заключаться в том, что ваш внутренний цикл занимает много времени, поэтому даже 1 итерация (из общего числа 6986 в вашем случае) занимает вечность и не отображается на индикаторе выполнения.

Еще одна причина заключается в том, что для создания второго элемента вашей итерации требуется вечность, и вам также нужно проверить, работает ли она.

Также я вижу, что вы показали нам индикатор выполнения ASCII, который не тот, который обычно отображается в блокноте (ноутбук обычно показывает графическую полосу). Так может ты вообще не внутри блокнота? Тогда вам нужно сделать from tqdm import tqdm вместо from tqdm.notebook import tqdm.

Также сначала попытайтесь упростить свой код, только временно, чтобы выяснить, действительно ли причина была в модуле tqdm в вашем случае, а не в вашем итерируемом или циклическом коде. Попробуйте начать с моего кода, приведенного выше.

Кроме того, вместо tqdm попробуйте просто напечатать что-то вроде print(step) внутри вашего цикла, печатает ли он хотя бы две строки на экране?

Если в моем коде я делаю from tqdm import tqdm, а затем запускаю его в консоли Python, я получаю:

10%|███████████▉              | 950/10000 [00:14<02:20, 64.37it/s]

а это значит, что консольная версия тоже работает.

person Arty    schedule 14.05.2021