(opt, val_loader, model)
| 239 | |
| 240 | |
| 241 | def validate(opt, val_loader, model): |
| 242 | |
| 243 | logger = logging.getLogger(__name__) |
| 244 | |
| 245 | model.eval() |
| 246 | |
| 247 | with torch.no_grad(): |
| 248 | img_embs, cap_embs, cap_lens = encode_data(model, val_loader, opt.log_step, logging.info) |
| 249 | |
| 250 | # have repetitive image features |
| 251 | img_embs = img_embs[::5] |
| 252 | |
| 253 | start_time = time.time() |
| 254 | |
| 255 | if opt.multi_gpu: |
| 256 | sims = torch.zeros((len(img_embs), len(cap_embs))).cuda() |
| 257 | |
| 258 | num_tasks = utils.get_world_size() |
| 259 | rank = utils.get_rank() |
| 260 | |
| 261 | step = img_embs.size(0) // num_tasks + 1 |
| 262 | start = rank * step |
| 263 | end = min(img_embs.size(0), start + step) |
| 264 | |
| 265 | sims_part = shard_attn_scores(model, img_embs[start:end], cap_embs, cap_lens, opt, gpu=True) |
| 266 | sims[start:end] = sims_part |
| 267 | |
| 268 | # wait for synchronization |
| 269 | torch.distributed.barrier() |
| 270 | # Aggregating results on different GPUs |
| 271 | torch.distributed.all_reduce(sims, op=torch.distributed.ReduceOp.SUM) |
| 272 | sims = sims.cpu().numpy() |
| 273 | else: |
| 274 | sims = shard_attn_scores(model, img_embs, cap_embs, cap_lens, opt) |
| 275 | sims = sims.numpy() |
| 276 | |
| 277 | # compute metric |
| 278 | if utils.is_main_process(): |
| 279 | |
| 280 | logging.info("calculate similarity time: %.3f" % float(time.time() - start_time)) |
| 281 | |
| 282 | npts = img_embs.shape[0] |
| 283 | # print(npts) |
| 284 | |
| 285 | # caption retrieval |
| 286 | (r1, r5, r10, medr, meanr) = i2t(npts, sims) |
| 287 | logging.info("Image to text (R@1, R@5, R@10): %.1f, %.1f, %.1f" % (r1, r5, r10)) |
| 288 | |
| 289 | # image retrieval |
| 290 | (r1i, r5i, r10i, medri, meanr) = t2i(npts, sims) |
| 291 | logging.info("Text to image (R@1, R@5, R@10): %.1f, %.1f, %.1f" % (r1i, r5i, r10i)) |
| 292 | |
| 293 | # sum of recalls to be used for early stopping |
| 294 | currscore = r1 + r5 + r10 + r1i + r5i + r10i |
| 295 | logger.info('Current rsum is {}'.format(round(currscore, 1))) |
| 296 | |
| 297 | # record metrics in tensorboard |
| 298 | tb_logger.log_value('r1', r1, step=model.Eiters) |
no test coverage detected