(student, teacher, teacher_without_ddp, dino_loss, data_loader,
optimizer, lr_schedule, wd_schedule, momentum_schedule,epoch,
fp16_scaler, args)
| 315 | |
| 316 | |
| 317 | def train_one_epoch(student, teacher, teacher_without_ddp, dino_loss, data_loader, |
| 318 | optimizer, lr_schedule, wd_schedule, momentum_schedule,epoch, |
| 319 | fp16_scaler, args): |
| 320 | metric_logger = utils.MetricLogger(delimiter=" ") |
| 321 | header = 'Epoch: [{}/{}]'.format(epoch, args.epochs) |
| 322 | for it, (images, _) in enumerate(metric_logger.log_every(data_loader, 100, header)): |
| 323 | # update weight decay and learning rate according to their schedule |
| 324 | it = len(data_loader) * epoch + it # global training iteration |
| 325 | for i, param_group in enumerate(optimizer.param_groups): |
| 326 | param_group["lr"] = lr_schedule[it] |
| 327 | if i == 0: # only the first group is regularized |
| 328 | param_group["weight_decay"] = wd_schedule[it] |
| 329 | |
| 330 | # move images to gpu |
| 331 | images = [im.cuda(non_blocking=True) for im in images] |
| 332 | # teacher and student forward selfpatches + compute dino loss |
| 333 | with torch.cuda.amp.autocast(fp16_scaler is not None): |
| 334 | with torch.no_grad(): |
| 335 | teacher_output = [teacher(torch.cat(images[:2]), head_only=True, loc=True), teacher(torch.cat(images[2:]), head_only=True, loc=True)] # only the 2 global views selfpatch through the teacher |
| 336 | student_output = [student(torch.cat(images[:2]), head_only=True, loc=False), student(torch.cat(images[2:]), head_only=True, loc=False)] |
| 337 | loss, c_loss, p_loss = dino_loss(teacher, student, student_output, teacher_output, epoch, it) |
| 338 | loss_value = loss.item() |
| 339 | |
| 340 | if not math.isfinite(loss.item()): |
| 341 | print("Loss is {}, stopping training".format(loss.item()), force=True) |
| 342 | sys.exit(1) |
| 343 | |
| 344 | # student update |
| 345 | optimizer.zero_grad() |
| 346 | param_norms = None |
| 347 | if fp16_scaler is None: |
| 348 | loss.backward() |
| 349 | if args.clip_grad: |
| 350 | param_norms = utils.clip_gradients(student, args.clip_grad) |
| 351 | utils.cancel_gradients_last_layer(epoch, student, |
| 352 | args.freeze_last_layer) |
| 353 | optimizer.step() |
| 354 | else: |
| 355 | fp16_scaler.scale(loss).backward() |
| 356 | if args.clip_grad: |
| 357 | fp16_scaler.unscale_(optimizer) # unscale the gradients of optimizer's assigned params in-place |
| 358 | param_norms = utils.clip_gradients(student, args.clip_grad) |
| 359 | utils.cancel_gradients_last_layer(epoch, student, |
| 360 | args.freeze_last_layer) |
| 361 | fp16_scaler.step(optimizer) |
| 362 | fp16_scaler.update() |
| 363 | |
| 364 | # EMA update for the teacher |
| 365 | with torch.no_grad(): |
| 366 | m = momentum_schedule[it] # momentum parameter |
| 367 | for param_q, param_k in zip(student.module.parameters(), teacher_without_ddp.parameters()): |
| 368 | param_k.data.mul_(m).add_((1 - m) * param_q.detach().data) |
| 369 | |
| 370 | # logging |
| 371 | torch.cuda.synchronize() |
| 372 | metric_logger.update(loss=loss_value) |
| 373 | metric_logger.update(clsloss=c_loss) |
| 374 | metric_logger.update(patchloss=p_loss) |
no test coverage detected