|
- # Copyright 2020 Huawei Technologies Co., Ltd
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- # ============================================================================
- """Face Quality Assessment loss."""
- import mindspore.nn as nn
- from mindspore.ops import operations as P
- from mindspore.ops import functional as F
- from mindspore.common import dtype as mstype
- from mindspore.nn.loss.loss import _Loss
- from mindspore import Tensor
-
- eps = 1e-24
-
-
- class CEWithIgnoreIndex3D(_Loss):
- '''CEWithIgnoreIndex3D'''
- def __init__(self):
- super(CEWithIgnoreIndex3D, self).__init__()
-
- self.exp = P.Exp()
- self.sum = P.ReduceSum()
- self.reshape = P.Reshape()
- self.log = P.Log()
- self.cast = P.Cast()
- self.eps_const = Tensor(eps, dtype=mstype.float32)
- self.ones = P.OnesLike()
- self.onehot = P.OneHot()
- self.on_value = Tensor(1.0, mstype.float32)
- self.off_value = Tensor(0.0, mstype.float32)
- self.relu = P.ReLU()
- self.maximum = P.Maximum()
- self.resum = P.ReduceSum(keep_dims=False)
-
- def construct(self, logit, label):
- '''construct'''
- mask = self.reshape(label, (F.shape(label)[0], F.shape(label)[1], 1))
- mask = self.cast(mask, mstype.float32)
- mask = mask + F.scalar_to_array(0.00001)
- mask = self.relu(mask) / (mask)
- logit = logit * mask
-
- exp = self.exp(logit)
- exp_sum = self.sum(exp, -1)
- exp_sum = self.reshape(exp_sum, (F.shape(exp_sum)[0], F.shape(exp_sum)[1], 1))
- softmax_result = self.log(exp / exp_sum + self.eps_const)
- one_hot_label = self.onehot(
- self.cast(label, mstype.int32), F.shape(logit)[2], self.on_value, self.off_value)
- loss = (softmax_result * self.cast(one_hot_label, mstype.float32) * self.cast(F.scalar_to_array(-1),
- mstype.float32))
-
- loss = self.sum(loss, -1)
- loss = self.sum(loss, -1)
- loss = self.sum(loss, 0)
- loss = loss
-
- return loss
-
-
- class CriterionsFaceQA(nn.Cell):
- '''CriterionsFaceQA'''
- def __init__(self):
- super(CriterionsFaceQA, self).__init__()
- self.gatherv2 = P.Gather()
- self.squeeze = P.Squeeze(axis=1)
- self.shape = P.Shape()
- self.reshape = P.Reshape()
-
- self.euler_label_list = Tensor([0, 1, 2], dtype=mstype.int32)
- self.mse_loss = nn.MSELoss(reduction='sum')
-
- self.kp_label_list = Tensor([3, 4, 5, 6, 7], dtype=mstype.int32)
- self.kps_loss = CEWithIgnoreIndex3D()
-
- def construct(self, x1, x2, label):
- '''construct'''
- # euler
- euler_label = self.gatherv2(label, self.euler_label_list, 1)
- loss_euler = self.mse_loss(x1, euler_label)
-
- # key points
- b, _, _, _ = self.shape(x2)
- x2 = self.reshape(x2, (b, 5, 48 * 48))
-
- kps_label = self.gatherv2(label, self.kp_label_list, 1)
- loss_kps = self.kps_loss(x2, kps_label)
-
- loss_tot = (loss_kps + loss_euler) / b
- return loss_tot
|