| 228 | |
| 229 | @torch.no_grad() |
| 230 | def validate(config, data_loader, model): |
| 231 | criterion = torch.nn.CrossEntropyLoss() |
| 232 | model.eval() |
| 233 | |
| 234 | batch_time = AverageMeter() |
| 235 | loss_meter = AverageMeter() |
| 236 | acc1_meter = AverageMeter() |
| 237 | acc5_meter = AverageMeter() |
| 238 | |
| 239 | end = time.time() |
| 240 | for idx, (images, target) in enumerate(data_loader): |
| 241 | images = images.cuda(non_blocking=True) |
| 242 | target = target.cuda(non_blocking=True) |
| 243 | |
| 244 | # compute output |
| 245 | output = model(images) |
| 246 | |
| 247 | # measure accuracy and record loss |
| 248 | loss = criterion(output, target) |
| 249 | acc1, acc5 = accuracy(output, target, topk=(1, 5)) |
| 250 | |
| 251 | acc1 = reduce_tensor(acc1) |
| 252 | acc5 = reduce_tensor(acc5) |
| 253 | loss = reduce_tensor(loss) |
| 254 | |
| 255 | loss_meter.update(loss.item(), target.size(0)) |
| 256 | acc1_meter.update(acc1.item(), target.size(0)) |
| 257 | acc5_meter.update(acc5.item(), target.size(0)) |
| 258 | |
| 259 | # measure elapsed time |
| 260 | batch_time.update(time.time() - end) |
| 261 | end = time.time() |
| 262 | |
| 263 | if idx % config.PRINT_FREQ == 0: |
| 264 | memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) |
| 265 | logger.info( |
| 266 | f'Test: [{idx}/{len(data_loader)}]\t' |
| 267 | f'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' |
| 268 | f'Loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' |
| 269 | f'Acc@1 {acc1_meter.val:.3f} ({acc1_meter.avg:.3f})\t' |
| 270 | f'Acc@5 {acc5_meter.val:.3f} ({acc5_meter.avg:.3f})\t' |
| 271 | f'Mem {memory_used:.0f}MB') |
| 272 | logger.info(f' * Acc@1 {acc1_meter.avg:.3f} Acc@5 {acc5_meter.avg:.3f}') |
| 273 | return acc1_meter.avg, acc5_meter.avg, loss_meter.avg |
| 274 | |
| 275 | |
| 276 | @torch.no_grad() |