| 390 | |
| 391 | # PoseNet (SE(3)) w/ mobilev2 backbone |
| 392 | class PoseNetV2(nn.Module): |
| 393 | def __init__(self, feat_dim=12): |
| 394 | super(PoseNetV2, self).__init__() |
| 395 | self.backbone_net = models.mobilenet_v2(pretrained=True) |
| 396 | self.feature_extractor = self.backbone_net.features |
| 397 | self.avgpool = nn.AdaptiveAvgPool2d(1) |
| 398 | self.fc_pose = nn.Linear(1280, feat_dim) |
| 399 | |
| 400 | def _aggregate_feature(self, x, upsampleH, upsampleW): |
| 401 | ''' |
| 402 | assume target and nerf rgb are inferenced at the same time, |
| 403 | slice target batch and nerf batch and aggregate features |
| 404 | :param x: image blob (2B x C x H x W) |
| 405 | :param upsampleH: New H |
| 406 | :param upsampleW: New W |
| 407 | :return feature: (2 x B x H x W) |
| 408 | ''' |
| 409 | batch = x.shape[0] # should be target batch_size + rgb batch_size |
| 410 | feature_t = torch.mean(torch.nn.UpsamplingBilinear2d(size=(upsampleH, upsampleW))(x[:batch//2]), dim=1) |
| 411 | feature_r = torch.mean(torch.nn.UpsamplingBilinear2d(size=(upsampleH, upsampleW))(x[batch//2:]), dim=1) |
| 412 | feature = torch.stack([feature_t, feature_r]) |
| 413 | return feature |
| 414 | |
| 415 | def _aggregate_feature2(self, x): |
| 416 | ''' |
| 417 | assume target and nerf rgb are inferenced at the same time, |
| 418 | slice target batch and nerf batch and output stacked features |
| 419 | :param x: image blob (2B x C x H x W) |
| 420 | :return feature: (2 x B x C x H x W) |
| 421 | ''' |
| 422 | batch = x.shape[0] # should be target batch_size + rgb batch_size |
| 423 | feature_t = x[:batch//2] |
| 424 | feature_r = x[batch//2:] |
| 425 | feature = torch.stack([feature_t, feature_r]) |
| 426 | return feature |
| 427 | |
| 428 | def forward(self, x, upsampleH=224, upsampleW=224, isTrain=False, isSingleStream=False): |
| 429 | ''' |
| 430 | Currently under dev. |
| 431 | :param x: image blob () |
| 432 | :param upsampleH: New H obsolete |
| 433 | :param upsampleW: New W obsolete |
| 434 | :param isTrain: True to extract features, False only return pose prediction. Really should be isExtractFeature |
| 435 | :param isSingleStrea: True to inference single img, False to inference two imgs in siemese network fashion |
| 436 | ''' |
| 437 | feat_out = [] # we only use high level features |
| 438 | for i in range(len(self.feature_extractor)): |
| 439 | # print("layer {} encoder layer: {}".format(i, self.feature_extractor[i])) |
| 440 | x = self.feature_extractor[i](x) |
| 441 | |
| 442 | if isTrain: # collect aggregate features |
| 443 | if i >= 17 and i <= 17: # 17th block |
| 444 | if isSingleStream: |
| 445 | feature = torch.stack([x]) |
| 446 | else: |
| 447 | feature = self._aggregate_feature2(x) |
| 448 | feat_out.append(feature) |
| 449 | x = self.avgpool(x) |
nothing calls this directly
no outgoing calls
no test coverage detected