|
- import numpy as np
- import mindspore
- import mindspore.nn as nn
- from mindspore import Tensor
- from mindspore.ops import operations as P
- from mindspore.ops import functional as F
- from mindspore.common import dtype as mstype
- from mindspore.common.initializer import initializer
- from mindspore.common.parameter import Parameter
- import math
-
- def weight_variable(shape):
- return initializer('XavierUniform', shape=shape, dtype=mstype.float32)
-
- def weight_variable_0(shape):
- zeros = np.zeros(shape).astype(np.float32)
- return Tensor(zeros)
-
- def weight_variable_1(shape):
- ones = np.ones(shape).astype(np.float32)
- return Tensor(ones)
-
- def weight_variable_uniform(shape):
- return initializer('Uniform', shape=shape, dtype=mstype.float32)
-
- def fc_with_initialize(input_channels, out_channels):
- weight_shape = (out_channels, input_channels)
- weight = weight_variable(weight_shape)
- bias_shape = (out_channels)
- bias = weight_variable_uniform(bias_shape)
- return nn.Dense(input_channels, out_channels, weight, bias)
-
- def conv(inp, oup, k, s, p, bias=False):
- if isinstance(k, int):
- weight_shape = (oup, inp, k, k)
- else:
- weight_shape = (oup, inp, k[0], k[1])
- weight = weight_variable(weight_shape)
- return nn.Conv2d(inp, oup, kernel_size=k,
- stride=s, padding=p, weight_init=weight,
- has_bias=bias, pad_mode="pad")
-
-
- def dw_conv(inp, oup, k, s, p, bias=False):
- if isinstance(k, int):
- weight_shape = (inp, 1, k, k)
- else:
- weight_shape = (inp, 1, k[0], k[1])
- weight = weight_variable(weight_shape)
- return nn.Conv2d(inp, oup, kernel_size=k,
- stride=s, padding=p, weight_init=weight,
- has_bias=bias, pad_mode="pad", group=inp)
-
- def bn(oup):
- shape = (oup)
- mean = weight_variable_0(shape)
- var = weight_variable_1(shape)
- beta = weight_variable_0(shape)
- gamma = weight_variable_uniform(shape)
- return nn.BatchNorm2d(oup, momentum=0.99,
- eps=0.00001, gamma_init=gamma,
- beta_init=beta, moving_mean_init=mean,
- moving_var_init=var)
-
- class Bottleneck(nn.Cell):
- def __init__(self, inp, oup, stride, expansion):
- super(Bottleneck, self).__init__()
- self.connect = stride==1 and inp==oup
- self.conv1 = conv(inp, inp*expansion, 1, 1, 0)
- self.bn1 = bn(inp*expansion)
- self.prelu = P.ReLU()
- self.conv2 = dw_conv(inp*expansion, inp*expansion, 3, stride, 1)
- self.bn2 = bn(inp*expansion)
- self.conv3 = conv(inp*expansion, oup, 1, 1, 0)
- self.bn3 = bn(oup)
- self.add = P.Add()
-
- def construct(self, x):
- identity = x
- x = self.conv1(x)
- x = self.bn1(x)
- x = self.prelu(x)
- x = self.conv2(x)
- x = self.bn2(x)
- x = self.prelu(x)
- x = self.conv3(x)
- x = self.bn3(x)
- if self.connect:
- return self.add(identity, x)
- else:
- return x
-
- class ConvBlock(nn.Cell):
- def __init__(self, inp, oup, k, s, p, dw=False, linear=False):
- super(ConvBlock, self).__init__()
- self.linear=linear
- if dw:
- self.conv = dw_conv(inp, oup, k, s, p)
- else:
- self.conv = conv(inp, oup, k, s, p)
- self.bn = bn(oup)
- if not linear:
- self.prelu = P.ReLU()
-
- def construct(self, x):
- x = self.conv(x)
- x = self.bn(x)
- if self.linear:
- return x
- else:
- return self.prelu(x)
-
- Mobilefacenet_bottleneck_setting = [
- [2, 64, 5, 2],
- [4, 128, 1, 2],
- [2, 128, 6, 1],
- [4, 128, 1, 2],
- [2, 128, 2, 1]
- ]
-
- class MakeLayer(nn.Cell):
- def __init__(self, inplaces, block, blockneck_setting):
- super(MakeLayer, self).__init__()
- self.inplaces = inplaces
- self.layers = []
- for t, c, n, s in blockneck_setting:
- for i in range(n):
- if i == 0:
- self.layers.append(block(self.inplaces, c, s, t))
- else:
- self.layers.append(block(self.inplaces, c, 1, t))
- self.inplaces = c
- def construct(self, x):
- for layer in self.layers:
- x = layer(x)
- return x
-
- class MakeLayer1(nn.Cell):
- def __init__(self, inplaces, blockneck_setting):
- super(MakeLayer1, self).__init__()
- t, c, n, s = blockneck_setting
- self.layer1 = Bottleneck(inplaces, c, s, t)
- self.layer2 = Bottleneck(c, c, 1, t)
- self.layer3 = Bottleneck(c, c, 1, t)
- self.layer4 = Bottleneck(c, c, 1, t)
- self.layer5 = Bottleneck(c, c, 1, t)
- def construct(self, x):
- x = self.layer1(x)
- x = self.layer2(x)
- x = self.layer3(x)
- x = self.layer4(x)
- x = self.layer5(x)
- return x
-
- class MakeLayer2(nn.Cell):
- def __init__(self, inplaces, blockneck_setting):
- super(MakeLayer2, self).__init__()
- t, c, n, s = blockneck_setting
- self.layer1 = Bottleneck(inplaces, c, s, t)
- def construct(self, x):
- x = self.layer1(x)
- return x
-
- class MakeLayer3(nn.Cell):
- def __init__(self, inplaces, blockneck_setting):
- super(MakeLayer3, self).__init__()
- t, c, n, s = blockneck_setting
- self.layer1 = Bottleneck(inplaces, c, s, t)
- self.layer2 = Bottleneck(c, c, 1, t)
- self.layer3 = Bottleneck(c, c, 1, t)
- self.layer4 = Bottleneck(c, c, 1, t)
- self.layer5 = Bottleneck(c, c, 1, t)
- self.layer6 = Bottleneck(c, c, 1, t)
- def construct(self, x):
- x = self.layer1(x)
- x = self.layer2(x)
- x = self.layer3(x)
- x = self.layer4(x)
- x = self.layer5(x)
- x = self.layer6(x)
- return x
-
- class MakeLayer4(nn.Cell):
- def __init__(self, inplaces, blockneck_setting):
- super(MakeLayer4, self).__init__()
- t, c, n, s = blockneck_setting
- self.layer1 = Bottleneck(inplaces, c, s, t)
- def construct(self, x):
- x = self.layer1(x)
- return x
-
- class MakeLayer5(nn.Cell):
- def __init__(self, inplaces, blockneck_setting):
- super(MakeLayer5, self).__init__()
- t, c, n, s = blockneck_setting
- self.layer1 = Bottleneck(inplaces, c, s, t)
- self.layer2 = Bottleneck(c, c, 1, t)
- def construct(self, x):
- x = self.layer1(x)
- x = self.layer2(x)
- return x
-
- class MobileFaceNet(nn.Cell):
- def __init__(self, bottleneck_setting=Mobilefacenet_bottleneck_setting):
- super(MobileFaceNet, self).__init__()
- self.conv1 = ConvBlock(3, 64, 3, 2, 1)
- self.dw_conv1 = ConvBlock(64, 64, 3, 1, 1, dw=True)
- self.block1 = MakeLayer1(inplaces=64, blockneck_setting=bottleneck_setting[0])
- self.block2 = MakeLayer2(inplaces=64, blockneck_setting=bottleneck_setting[1])
- self.block3 = MakeLayer3(inplaces=128, blockneck_setting=bottleneck_setting[2])
- self.block4 = MakeLayer4(inplaces=128, blockneck_setting=bottleneck_setting[3])
- self.block5 = MakeLayer5(inplaces=128, blockneck_setting=bottleneck_setting[4])
- self.conv2 = ConvBlock(128, 512, 1, 1, 0)
- self.linear7 = ConvBlock(512, 512, (7, 6), 1, 0, dw=True, linear=True)
- self.linear1 = ConvBlock(512, 128, 1, 1, 0, linear=True)
- self.squeeze = P.Squeeze(axis=(2, 3))
-
- def construct(self, x):
- x = self.conv1(x)
- x = self.dw_conv1(x)
- x = self.block1(x)
- x = self.block2(x)
- x = self.block3(x)
- x = self.block4(x)
- x = self.block5(x)
- x = self.conv2(x)
- x = self.linear7(x)
- x = self.linear1(x)
- x = self.squeeze(x)
- return x
-
- class CosMarginProduct(nn.Cell):
- def __init__(self, in_features=128, out_features=200, s=32.0, m=0.50, easy_margin=False):
- super(CosMarginProduct, self).__init__()
- self.in_features = in_features
- self.out_features = out_features
- self.s = s
- self.m = m
- shape = (out_features, in_features)
- self.weight = Parameter(initializer('XavierUniform', shape=shape, dtype=mstype.float32), name='weight')
- self.matmul = P.MatMul(transpose_b=True)
- self.one_hot = P.OneHot()
- self.on_value = Tensor(1.0, mstype.float32)
- self.off_value = Tensor(0.0, mstype.float32)
- self.l2_norm = P.L2Normalize(axis=1)
- def construct(self, x, label):
- cosine = self.matmul(self.l2_norm(x), self.l2_norm(self.weight))
- phi = cosine - self.m
- one_hot = self.one_hot(label, phi.shape[1], self.on_value, self.off_value)
- output = (one_hot * phi) + ((1.0 - one_hot) * cosine)
- output *= self.s
- return output
-
- class WholeNet(nn.Cell):
- # 改了,加了几个参数
- def __init__(self, train_phase=True, num_class = 10575, num_s= 32.0, num_m=0.50):
- super(WholeNet, self).__init__()
- self.train_phase = train_phase
- self.backbone = MobileFaceNet()
- # 改了,加了几个参数
- self.product = CosMarginProduct(out_features=num_class, s=num_s, m=num_m )
- def construct(self, x, y):
- x = self.backbone(x)
- if not self.train_phase:
- return x
- else:
- return self.product(x, y)
-
-
-
-
|