| import numpy as np
|
|
|
| import torch
|
| import torch.nn as nn
|
| import torch.nn.functional as F
|
|
|
|
|
| class MappingNet(nn.Module):
|
| def __init__(self, coeff_nc, descriptor_nc, layer, num_kp, num_bins):
|
| super( MappingNet, self).__init__()
|
|
|
| self.layer = layer
|
| nonlinearity = nn.LeakyReLU(0.1)
|
|
|
| self.first = nn.Sequential(
|
| torch.nn.Conv1d(coeff_nc, descriptor_nc, kernel_size=7, padding=0, bias=True))
|
|
|
| for i in range(layer):
|
| net = nn.Sequential(nonlinearity,
|
| torch.nn.Conv1d(descriptor_nc, descriptor_nc, kernel_size=3, padding=0, dilation=3))
|
| setattr(self, 'encoder' + str(i), net)
|
|
|
| self.pooling = nn.AdaptiveAvgPool1d(1)
|
| self.output_nc = descriptor_nc
|
|
|
| self.fc_roll = nn.Linear(descriptor_nc, num_bins)
|
| self.fc_pitch = nn.Linear(descriptor_nc, num_bins)
|
| self.fc_yaw = nn.Linear(descriptor_nc, num_bins)
|
| self.fc_t = nn.Linear(descriptor_nc, 3)
|
| self.fc_exp = nn.Linear(descriptor_nc, 3*num_kp)
|
|
|
| def forward(self, input_3dmm):
|
| out = self.first(input_3dmm)
|
| for i in range(self.layer):
|
| model = getattr(self, 'encoder' + str(i))
|
| out = model(out) + out[:,:,3:-3]
|
| out = self.pooling(out)
|
| out = out.view(out.shape[0], -1)
|
|
|
|
|
| yaw = self.fc_yaw(out)
|
| pitch = self.fc_pitch(out)
|
| roll = self.fc_roll(out)
|
| t = self.fc_t(out)
|
| exp = self.fc_exp(out)
|
|
|
| return {'yaw': yaw, 'pitch': pitch, 'roll': roll, 't': t, 'exp': exp} |