| 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} |