| 42 | return x |
| 43 | |
| 44 | class STNkd(nn.Module): |
| 45 | def __init__(self, k=64): |
| 46 | super(STNkd, self).__init__() |
| 47 | self.conv1 = torch.nn.Conv1d(k, 64, 1) |
| 48 | self.conv2 = torch.nn.Conv1d(64, 128, 1) |
| 49 | self.conv3 = torch.nn.Conv1d(128, 1024, 1) |
| 50 | self.fc1 = nn.Linear(1024, 512) |
| 51 | self.fc2 = nn.Linear(512, 256) |
| 52 | self.fc3 = nn.Linear(256, k * k) |
| 53 | self.relu = nn.ReLU() |
| 54 | |
| 55 | self.bn1 = nn.BatchNorm1d(64) |
| 56 | self.bn2 = nn.BatchNorm1d(128) |
| 57 | self.bn3 = nn.BatchNorm1d(1024) |
| 58 | self.bn4 = nn.BatchNorm1d(512) |
| 59 | self.bn5 = nn.BatchNorm1d(256) |
| 60 | |
| 61 | self.k = k |
| 62 | |
| 63 | def forward(self, x): |
| 64 | batchsize = x.size()[0] |
| 65 | x = F.relu(self.bn1(self.conv1(x))) |
| 66 | x = F.relu(self.bn2(self.conv2(x))) |
| 67 | x = F.relu(self.bn3(self.conv3(x))) |
| 68 | x = torch.max(x, 2, keepdim=True)[0] |
| 69 | x = x.view(-1, 1024) |
| 70 | |
| 71 | x = F.relu(self.bn4(self.fc1(x))) |
| 72 | x = F.relu(self.bn5(self.fc2(x))) |
| 73 | x = self.fc3(x) |
| 74 | |
| 75 | iden = Variable(torch.from_numpy(np.eye(self.k).flatten().astype(np.float32))).view(1, self.k * self.k).repeat( |
| 76 | batchsize, 1) |
| 77 | if x.is_cuda: |
| 78 | iden = iden.cuda() |
| 79 | x = x + iden |
| 80 | x = x.view(-1, self.k, self.k) |
| 81 | return x |
| 82 | |
| 83 | class pointnet_encoder(nn.Module): |
| 84 | def __init__(self): |