| import numpy as np |
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
|
|
|
|
| class PositionalEncoding(nn.Module): |
| def __init__(self, d_model, dropout=0.1, max_len=5000): |
| super(PositionalEncoding, self).__init__() |
| self.dropout = nn.Dropout(p=dropout) |
|
|
| pe = torch.zeros(max_len, d_model) |
| position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) |
| div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-np.log(10000.0) / d_model)) |
| pe[:, 0::2] = torch.sin(position * div_term) |
| pe[:, 1::2] = torch.cos(position * div_term) |
| pe = pe.unsqueeze(0).transpose(0, 1) |
|
|
| self.register_buffer('pe', pe) |
|
|
| def forward(self, x): |
| |
| x = x + self.pe[:x.shape[0], :] |
| return self.dropout(x) |
|
|
|
|
| |
| class TimeEncoding(nn.Module): |
| def __init__(self, d_model, dropout=0.1, max_len=5000): |
| super(TimeEncoding, self).__init__() |
| self.dropout = nn.Dropout(p=dropout) |
|
|
| def forward(self, x, mask, lengths): |
| time = mask * 1/(lengths[..., None]-1) |
| time = time[:, None] * torch.arange(time.shape[1], device=x.device)[None, :] |
| time = time[:, 0].T |
| |
| x = x + time[..., None] |
| return self.dropout(x) |
|
|
|
|
| class Encoder_TRANSFORMER(nn.Module): |
| def __init__(self, modeltype, njoints, nfeats, num_frames, num_classes, translation, pose_rep, glob, glob_rot, |
| latent_dim=256, ff_size=1024, num_layers=4, num_heads=4, dropout=0.1, |
| ablation=None, activation="gelu", **kargs): |
| super().__init__() |
|
|
| self.modeltype = modeltype |
| self.njoints = njoints |
| self.nfeats = nfeats |
| self.num_frames = num_frames |
| self.num_classes = num_classes |
|
|
| self.pose_rep = pose_rep |
| self.glob = glob |
| self.glob_rot = glob_rot |
| self.translation = translation |
|
|
| self.latent_dim = latent_dim |
|
|
| self.ff_size = ff_size |
| self.num_layers = num_layers |
| self.num_heads = num_heads |
| self.dropout = dropout |
|
|
| self.ablation = ablation |
| self.activation = activation |
|
|
| self.input_feats = self.njoints*self.nfeats |
|
|
| if self.ablation == "average_encoder": |
| self.mu_layer = nn.Linear(self.latent_dim, self.latent_dim) |
| self.sigma_layer = nn.Linear(self.latent_dim, self.latent_dim) |
| else: |
| self.muQuery = nn.Parameter(torch.randn(self.num_classes, self.latent_dim)) |
| self.sigmaQuery = nn.Parameter(torch.randn(self.num_classes, self.latent_dim)) |
|
|
| self.skelEmbedding = nn.Linear(self.input_feats, self.latent_dim) |
|
|
| self.sequence_pos_encoder = PositionalEncoding(self.latent_dim, self.dropout) |
|
|
| |
|
|
| seqTransEncoderLayer = nn.TransformerEncoderLayer(d_model=self.latent_dim, |
| nhead=self.num_heads, |
| dim_feedforward=self.ff_size, |
| dropout=self.dropout, |
| activation=self.activation) |
| self.seqTransEncoder = nn.TransformerEncoder(seqTransEncoderLayer, |
| num_layers=self.num_layers) |
|
|
| def forward(self, batch): |
| x, y, mask = batch["x"], batch["y"], batch["mask"] |
| bs, njoints, nfeats, nframes = x.shape |
| x = x.permute((3, 0, 1, 2)).reshape(nframes, bs, njoints*nfeats) |
|
|
| |
| x = self.skelEmbedding(x) |
|
|
| |
| if self.ablation == "average_encoder": |
| |
| x = self.sequence_pos_encoder(x) |
|
|
| |
| final = self.seqTransEncoder(x, src_key_padding_mask=~mask) |
| |
| z = final.mean(axis=0) |
|
|
| |
| mu = self.mu_layer(z) |
| logvar = self.sigma_layer(z) |
| else: |
| |
| xseq = torch.cat((self.muQuery[y][None], self.sigmaQuery[y][None], x), axis=0) |
|
|
| |
| xseq = self.sequence_pos_encoder(xseq) |
|
|
| |
| muandsigmaMask = torch.ones((bs, 2), dtype=bool, device=x.device) |
| maskseq = torch.cat((muandsigmaMask, mask), axis=1) |
|
|
| final = self.seqTransEncoder(xseq, src_key_padding_mask=~maskseq) |
| mu = final[0] |
| logvar = final[1] |
|
|
| return {"mu": mu, "logvar": logvar} |
|
|
|
|
| class Decoder_TRANSFORMER(nn.Module): |
| def __init__(self, modeltype, njoints, nfeats, num_frames, num_classes, translation, pose_rep, glob, glob_rot, |
| latent_dim=256, ff_size=1024, num_layers=4, num_heads=4, dropout=0.1, activation="gelu", |
| ablation=None, **kargs): |
| super().__init__() |
|
|
| self.modeltype = modeltype |
| self.njoints = njoints |
| self.nfeats = nfeats |
| self.num_frames = num_frames |
| self.num_classes = num_classes |
|
|
| self.pose_rep = pose_rep |
| self.glob = glob |
| self.glob_rot = glob_rot |
| self.translation = translation |
|
|
| self.latent_dim = latent_dim |
|
|
| self.ff_size = ff_size |
| self.num_layers = num_layers |
| self.num_heads = num_heads |
| self.dropout = dropout |
|
|
| self.ablation = ablation |
|
|
| self.activation = activation |
|
|
| self.input_feats = self.njoints*self.nfeats |
|
|
| |
| if self.ablation == "zandtime": |
| self.ztimelinear = nn.Linear(self.latent_dim + self.num_classes, self.latent_dim) |
| else: |
| self.actionBiases = nn.Parameter(torch.randn(self.num_classes, self.latent_dim)) |
|
|
| |
| if self.ablation == "time_encoding": |
| self.sequence_pos_encoder = TimeEncoding(self.dropout) |
| else: |
| self.sequence_pos_encoder = PositionalEncoding(self.latent_dim, self.dropout) |
|
|
| seqTransDecoderLayer = nn.TransformerDecoderLayer(d_model=self.latent_dim, |
| nhead=self.num_heads, |
| dim_feedforward=self.ff_size, |
| dropout=self.dropout, |
| activation=activation) |
| self.seqTransDecoder = nn.TransformerDecoder(seqTransDecoderLayer, |
| num_layers=self.num_layers) |
|
|
| self.finallayer = nn.Linear(self.latent_dim, self.input_feats) |
|
|
| def forward(self, batch): |
| z, y, mask, lengths = batch["z"], batch["y"], batch["mask"], batch["lengths"] |
|
|
| latent_dim = z.shape[1] |
| bs, nframes = mask.shape |
| njoints, nfeats = self.njoints, self.nfeats |
|
|
| |
| if self.ablation == "zandtime": |
| yoh = F.one_hot(y, self.num_classes) |
| z = torch.cat((z, yoh), axis=1) |
| z = self.ztimelinear(z) |
| z = z[None] |
| else: |
| |
| if self.ablation == "concat_bias": |
| |
| z = torch.stack((z, self.actionBiases[y]), axis=0) |
| else: |
| |
| z = z + self.actionBiases[y] |
| z = z[None] |
|
|
| timequeries = torch.zeros(nframes, bs, latent_dim, device=z.device) |
|
|
| |
| if self.ablation == "time_encoding": |
| timequeries = self.sequence_pos_encoder(timequeries, mask, lengths) |
| else: |
| timequeries = self.sequence_pos_encoder(timequeries) |
|
|
| output = self.seqTransDecoder(tgt=timequeries, memory=z, |
| tgt_key_padding_mask=~mask) |
|
|
| output = self.finallayer(output).reshape(nframes, bs, njoints, nfeats) |
|
|
| |
| output[~mask.T] = 0 |
| output = output.permute(1, 2, 3, 0) |
|
|
| batch["output"] = output |
| return batch |
|
|